def pyquil_to_tk(prog: Program) -> Circuit: """ Convert a :py:class:`pyquil.Program` to a tket :py:class:`Circuit` . Note that not all pyQuil operations are currently supported by pytket. :param prog: A circuit to be converted :return: The converted circuit """ tkc = Circuit() qmap = {} for q in prog.get_qubits(): uid = Qubit("q", q) tkc.add_qubit(uid) qmap.update({q: uid}) cregmap: Dict = {} for i in prog.instructions: if isinstance(i, Gate): try: optype = _known_quil_gate[i.name] except KeyError as error: raise NotImplementedError("Operation not supported by tket: " + str(i)) from error qubits = [qmap[q.index] for q in i.qubits] params = [param_from_pyquil(p) for p in i.params] # type: ignore tkc.add_gate(optype, params, qubits) elif isinstance(i, Measurement): qubit = qmap[i.qubit.index] reg = cregmap[i.classical_reg.name] # type: ignore bit = reg[i.classical_reg.offset] # type: ignore tkc.Measure(qubit, bit) elif isinstance(i, Declare): if i.memory_type == "BIT": new_reg = tkc.add_c_register(i.name, i.memory_size) cregmap.update({i.name: new_reg}) elif i.memory_type == "REAL": continue else: raise NotImplementedError("Cannot handle memory of type " + i.memory_type) elif isinstance(i, Pragma): continue elif isinstance(i, Halt): return tkc else: raise NotImplementedError("PyQuil instruction is not a gate: " + str(i)) return tkc
def test_multireg() -> None: b = HoneywellBackend(device_name="HQS-LT-1.0-APIVAL", label="test 3") c = Circuit() q1 = Qubit("q1", 0) q2 = Qubit("q2", 0) c1 = Bit("c1", 0) c2 = Bit("c2", 0) for q in (q1, q2): c.add_qubit(q) for cb in (c1, c2): c.add_bit(cb) c.H(q1) c.CX(q1, q2) c.Measure(q1, c1) c.Measure(q2, c2) b.compile_circuit(c) n_shots = 10 shots = b.get_shots(c, n_shots) assert np.array_equal(shots, np.zeros((10, 2)))
from pytket.circuit import Circuit c = Circuit(3, 2) print(c.qubits) print(c.bits) # The qubits have automatically been assigned to a register with name `q` and indices 0, 1 and 2, while the bits have been assigned to a register with name `c` and indices 0 and 1. # # We can give these units arbitrary names and indices of arbitrary dimension: from pytket.circuit import Qubit new_q1 = Qubit("alpha", 0) new_q2 = Qubit("beta", 2, 1) new_q3 = Qubit("gamma", (0, 0, 0)) c.add_qubit(new_q1) c.add_qubit(new_q2) c.add_qubit(new_q3) print(c.qubits) # We can also add a new register of qubits in one go: c.add_q_register("delta", 4) print(c.qubits) # Similar commands are available for classical bits. # # We can add gates to the circuit as follows: c.CX(0, 1)
def cirq_to_tk(circuit: cirq.circuits.Circuit) -> Circuit: """Converts a Cirq :py:class:`Circuit` to a tket :py:class:`Circuit` object. :param circuit: The input Cirq :py:class:`Circuit` :raises NotImplementedError: If the input contains a Cirq :py:class:`Circuit` operation which is not yet supported by pytket :return: The tket :py:class:`Circuit` corresponding to the input circuit """ tkcirc = Circuit() qmap = {} for qb in circuit.all_qubits(): if isinstance(qb, LineQubit): uid = Qubit("q", qb.x) elif isinstance(qb, GridQubit): uid = Qubit("g", qb.row, qb.col) elif isinstance(qb, cirq.ops.NamedQubit): uid = Qubit(qb.name) else: raise NotImplementedError("Cannot convert qubits of type " + str(type(qb))) tkcirc.add_qubit(uid) qmap.update({qb: uid}) for moment in circuit: for op in moment.operations: if isinstance(op, cirq.ops.GlobalPhaseOperation): tkcirc.add_phase(cmath.phase(op.coefficient) / pi) continue gate = op.gate gatetype = type(gate) qb_lst = [qmap[q] for q in op.qubits] if isinstance(gate, cirq_common.HPowGate) and gate.exponent == 1: gate = cirq_common.H elif (gatetype == cirq_common.CNotPowGate and cast(cirq_common.CNotPowGate, gate).exponent == 1): gate = cirq_common.CNOT elif (gatetype == cirq_pauli._PauliX and cast(cirq_pauli._PauliX, gate).exponent == 1): gate = cirq_pauli.X elif (gatetype == cirq_pauli._PauliY and cast(cirq_pauli._PauliY, gate).exponent == 1): gate = cirq_pauli.Y elif (gatetype == cirq_pauli._PauliZ and cast(cirq_pauli._PauliZ, gate).exponent == 1): gate = cirq_pauli.Z if gate in _constant_gates: try: optype = _cirq2ops_mapping[gate] except KeyError as error: raise NotImplementedError( "Operation not supported by tket: " + str(op.gate)) from error params = [] elif isinstance(gate, cirq_common.MeasurementGate): uid = Bit(gate.key) tkcirc.add_bit(uid) tkcirc.Measure(*qb_lst, uid) continue elif isinstance(gate, cirq.ops.PhasedXPowGate): optype = OpType.PhasedX pe = gate.phase_exponent params = [gate.exponent, pe] elif isinstance(gate, cirq.ops.FSimGate): optype = OpType.FSim params = [gate.theta / pi, gate.phi / pi] elif isinstance(gate, cirq.ops.PhasedISwapPowGate): optype = OpType.PhasedISWAP params = [gate.phase_exponent, gate.exponent] else: try: optype = _cirq2ops_mapping[gatetype] params = [cast(Any, gate).exponent] except (KeyError, AttributeError) as error: raise NotImplementedError( "Operation not supported by tket: " + str(op.gate)) from error tkcirc.add_gate(optype, params, qb_lst) return tkcirc