示例#1
0
def dagcircuit_to_tk(dag: DAGCircuit,
                     _BOX_UNKNOWN: bool = BOX_UNKNOWN,
                     _DROP_CONDS: bool = DROP_CONDS) -> Circuit:
    """Converts a :py:class:`qiskit.DAGCircuit` into a :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit`.
    Note that not all Qiskit operations are currently supported by pytket. Classical registers are supported only as 
    the output of measurements. This does not attempt to preserve the structure 
    of the quantum registers, instead creating one big quantum register.

    :param dag: A circuit to be converted

    :return: The converted circuit
    """
    qs = dag.qubits()
    qnames = ["%s[%d]" % (r.name, i) for r, i in qs]
    g = dag._multi_graph
    circ = Circuit()
    if DEBUG:
        print("new graph w " + str(len(qs)) + " qubits")
        print(str(qs))

    # process vertices
    tk_vs = dict()
    for n in list(g.nodes(data=True)):
        node = n[0]
        if DEBUG:
            print(str(node.type) + " " + str(node.name))
        if ((node.type == "in" or node.type == "out")
                and not node.name in qnames):
            # don't create vertices for in/outs of classical registers
            if DEBUG:
                print("Dropping node " + str(node))
            continue
        else:
            tk_vs[node] = circ._add_vertex(
                _node_converter(circ,
                                node,
                                _BOX_UNKNOWN=_BOX_UNKNOWN,
                                _DROP_CONDS=_DROP_CONDS))
            if DEBUG:
                print("qiskit vertex " + str(node) + " is t|ket> vertex " +
                      str(tk_vs[node]))
    # process edges
    for e in g.edges(data=True):
        wire = e[2]["wire"]
        if wire in qs:  # ignore classical wires
            src_port = _get_port_for_edge(e[0], wire)
            tgt_port = _get_port_for_edge(e[1], wire)
            if DEBUG:
                print(
                    _make_edge_str(tk_vs[e[0]], src_port, tk_vs[e[1]],
                                   tgt_port))
            circ._add_edge(tk_vs[e[0]], src_port, tk_vs[e[1]], tgt_port)

    return circ
示例#2
0
def pyquil_to_tk(prog: Program) -> Circuit:
    """
    Convert a :py:class:`pyquil.Program` to a :math:`\\mathrm{t|ket}\\rangle` :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
    """
    reg_name = None
    qubits = prog.get_qubits()
    n_qubits = max(qubits) + 1
    tkc = Circuit(n_qubits)
    for i in prog.instructions:
        if isinstance(i, Gate):
            name = i.name
            try:
                optype = _known_quil_gate[name]
            except KeyError as error:
                raise NotImplementedError("Operation not supported by tket: " +
                                          str(i)) from error
            if len(i.params) == 0:
                tkc.add_operation(optype, [q.index for q in i.qubits])
            else:
                params = [p / PI for p in i.params]
                op = tkc._get_op(optype, params)
                tkc._add_operation(op, [q.index for q in i.qubits])
        elif isinstance(i, Measurement):
            if not i.classical_reg:
                raise NotImplementedError(
                    "Program has no defined classical register for measurement on qubit: ",
                    i.qubits[0])
            reg = i.classical_reg
            if reg_name and reg_name != reg.name:
                raise NotImplementedError(
                    "Program has multiple classical registers: ", reg_name,
                    reg.name)
            reg_name = reg.name
            op = tkc._get_op(OpType.Measure, str(reg.offset))
            tkc._add_operation(op, [i.qubit.index])
        elif isinstance(i, Declare):
            continue
        elif isinstance(i, Pragma):
            continue
        elif isinstance(i, Halt):
            return tkc
        else:
            raise NotImplementedError("Pyquil instruction is not a gate: " +
                                      str(i))
    return tkc
示例#3
0
def qiskit_to_tk(qcirc: QuantumCircuit) -> Circuit :
    """Convert a :py:class:`qiskit.QuantumCircuit` to a :py:class:`Circuit`.
    
    :param qcirc: A circuit to be converted
    :type qcirc: QuantumCircuit
    :return: The converted circuit
    :rtype: Circuit
    """
    tkc = Circuit()
    qregmap = {}
    for reg in qcirc.qregs :
        tk_reg = tkc.add_q_register(reg.name, len(reg))
        qregmap.update({reg : tk_reg})
    cregmap = {}
    for reg in qcirc.cregs :
        tk_reg = tkc.add_c_register(reg.name, len(reg))
        cregmap.update({reg : tk_reg})
    for i, qargs, cargs in qcirc.data :
        if i.control is not None :
            raise NotImplementedError("Cannot convert conditional gates from Qiskit to tket")
        optype = _known_qiskit_gate[type(i)]
        qubits = [qregmap[r][ind] for r, ind in qargs]
        bits = [cregmap[r][ind] for r, ind in cargs]
        if optype == OpType.Measure :
            tkc.add_measure(*qubits, *bits)
            continue
        params = [p/pi for p in i.params]
        tkc.add_gate(optype, params, qubits, [])
    return tkc
示例#4
0
def cirq_to_tk(circuit: cirq.Circuit) -> Circuit:
    """Converts a Cirq :py:class:`Circuit` to a :math:`\\mathrm{t|ket}\\rangle` :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 :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` corresponding to the input circuit
    """
    qubit_list = _indexed_qubits_from_circuit(circuit)
    qid_to_num = {q: i for i, q in enumerate(qubit_list)}
    n_qubits = len(circuit.all_qubits())
    tkcirc = Circuit(n_qubits)
    for moment in circuit:
        for op in moment.operations:
            gate = op.gate
            gatetype = type(gate)

            qb_lst = [qid_to_num[q] for q in op.qubits]

            n_qubits = len(op.qubits)

            if gatetype == cirq_common.HPowGate and gate.exponent == 1:
                gate = cirq_common.H
            elif gatetype == cirq_common.CNotPowGate and gate.exponent == 1:
                gate = cirq_common.CNOT
            elif gatetype == cirq_pauli._PauliX and gate.exponent == 1:
                gate = cirq_pauli.X
            elif gatetype == cirq_pauli._PauliY and gate.exponent == 1:
                gate = cirq_pauli.Y
            elif gatetype == cirq_pauli._PauliZ and 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
                o = tkcirc._get_op(optype)
            elif isinstance(gate, cirq_common.MeasurementGate):
                o = tkcirc._get_op(OpType.Measure, n_qubits, n_qubits,
                                   gate.key)
            elif isinstance(gate, cirq.PhasedXPowGate):
                pe = gate.phase_exponent
                e = gate.exponent
                o = tkcirc._get_op(OpType.PhasedX, 1, 1, [e, pe])
            else:
                try:
                    optype = _cirq2ops_mapping[gatetype]
                except KeyError as error:
                    raise NotImplementedError(
                        "Operation not supported by tket: " +
                        str(op.gate)) from error
                o = tkcirc._get_op(optype, n_qubits, n_qubits, gate.exponent)
            tkcirc._add_operation(o, qb_lst)
    return tkcirc
示例#5
0
文件: aer.py 项目: danmills0/pytket
 def run(self,
         circuit: Circuit,
         shots: int,
         fit_to_constraints=True,
         seed: int = None) -> np.ndarray:
     """Run a circuit on Qiskit Aer Qasm simulator.
     
     :param circuit: The circuit to run
     :type circuit: Circuit
     :param shots: Number of shots (repeats) to run
     :type shots: int
     :param fit_to_constraints: Compile the circuit to meet the constraints of the backend, defaults to True
     :type fit_to_constraints: bool, optional
     :param seed: random seed to for simulator
     :type seed: int
     :return: Table of shot results, each row is a shot, columns are ordered by qubit ordering. Values are 0 or 1, corresponding to qubit basis states.
     :rtype: numpy.ndarray
     """
     c = circuit.copy()
     if fit_to_constraints:
         Transform.RebaseToQiskit().apply(c)
     dag = tk_to_dagcircuit(c)
     qc = dag_to_circuit(dag)
     qobj = assemble(qc, shots=shots, seed_simulator=seed, memory=True)
     job = self._backend.run(qobj, noise_model=self.noise_model)
     shot_list = job.result().get_memory(qc)
     return np.asarray([_convert_bin_str(shot) for shot in shot_list])
示例#6
0
    def __init__(self):
        """
        Initialize the tketBackendEngine.

        Initializes local Circuit to an empty Circuit.
        """
        BasicEngine.__init__(self)
        self._circuit = Circuit()
示例#7
0
def _routed_ibmq_circuit(circuit: Circuit,
                         arc: Architecture) -> QuantumCircuit:
    c = circuit.copy()
    Transform.RebaseToQiskit().apply(c)
    physical_c = route(c, arc)
    physical_c.decompose_SWAP_to_CX()
    physical_c.redirect_CX_gates(arc)
    Transform.OptimisePostRouting().apply(physical_c)
    qc = tk_to_qiskit(physical_c)

    return qc
示例#8
0
def projectq_expectation_value(circuit:Circuit,hamiltonian:QubitOperator) -> float :
    ProjectQback = Simulator()
    fwd = ForwarderEngine(ProjectQback)
    eng = MainEngine(backend=ProjectQback,engine_list=[fwd])
    qureg = eng.allocate_qureg(circuit.n_qubits)
    c = circuit.copy()
    Transform.RebaseToProjectQ().apply(c)
    tk_to_projectq(eng,qureg,c)
    eng.flush()
    energy = eng.backend.get_expectation_value(hamiltonian,qureg)
    All(Measure) | qureg
    return energy
示例#9
0
 def get_state(self,circuit:Circuit, fit_to_constraints=True) -> list:
     c = circuit.copy()
     if fit_to_constraints :
         Transform.RebaseToProjectQ().apply(c)
     fwd = ForwarderEngine(self._backend)
     eng = MainEngine(backend=self._backend,engine_list=[fwd])
     qureg = eng.allocate_qureg(c.n_qubits)
     tk_to_projectq(eng,qureg,c)
     eng.flush()
     state = self._backend.cheat()[1] #`cheat()` returns tuple:(a dictionary of qubit indices, statevector)
     All(Measure) | qureg
     return state #list of complex numbers
示例#10
0
def pyzx_to_tk(pyzx_circ: pyzxCircuit) -> Circuit:
    """
    Convert a :py:class:`pyzx.Circuit` to a :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` .
    All PyZX basic gate operations are currently supported by pytket. Run `pyzx_circuit_name.to_basic_gates()`
    before conversion.
    
    :param prog: A circuit to be converted

    :return: The converted circuit
    """
    c = Circuit(pyzx_circ.qubits)
    for g in pyzx_circ.gates:
        if not g.name in _pyzx_to_tk_gates:
            raise Exception("Cannot parse PyZX gate of type " + g.name +
                            "into tket Circuit")
        op_type = _pyzx_to_tk_gates[g.name]
        if (hasattr(g, 'control')):
            qbs = [getattr(g, 'control'), getattr(g, 'target')]
        else:
            qbs = [getattr(g, 'target')]

        if (hasattr(g, "printphase") and op_type in _parameterised_gates):
            op = c._get_op(OpType=op_type, param=float(g.phase))
        else:
            op = c._get_op(OpType=op_type, parameters=[])

        c._add_operation(Op=op, qubits=qbs)
    return c
示例#11
0
def tk_to_qiskit(tkcirc: Circuit) -> QuantumCircuit :
    """Convert back
    
    :param tkcirc: A circuit to be converted
    :type tkcirc: Circuit
    :return: The converted circuit
    :rtype: QuantumCircuit
    """
    tkc = tkcirc
    if isinstance(tkcirc, PhysicalCircuit) :
        tkc = tkcirc._get_circuit()
    qcirc = QuantumCircuit()
    qregmap = {}
    for _, reg in tkc.q_regs.items() :
        if reg.size() == 0 :
            continue
        name = reg.name
        if len(name) == 0 :
            name = None
        qis_reg = QuantumRegister(reg.size(), name)
        qregmap.update({reg : qis_reg})
        qcirc.add_register(qis_reg)
    cregmap = {}
    for _, reg in tkc.c_regs.items() :
        if reg.size() == 0 :
            continue
        name = reg.name
        if len(name) == 0 :
            name = None
        qis_reg = ClassicalRegister(reg.size(), name)
        cregmap.update({reg : qis_reg})
        qcirc.add_register(qis_reg)
    tempregmap = {}
    for command in tkc :
        op = command.op
        qubits = command.qubits
        qargs = [qregmap[q.reg][q.index] for q in qubits]
        if len(command.controls) != 0 :
            raise NotImplementedError("Cannot convert conditional gates from tket to Qiskit")
        if op.get_type() == OpType.Measure :
            bits = [_convert_bit(b, cregmap, qcirc, tempregmap) for b in command.bits]
            qcirc.measure(*qargs, *bits)
            continue
        params = [p * pi for p in op.get_params()]
        try :
            gatetype = _known_qiskit_gate_rev[op.get_type()]
        except KeyError as error :
            raise NotImplementedError("Cannot convert tket Op to Qiskit gate: " + op.get_name()) from error
        g = gatetype(*params)
        qcirc.append(g, qargs=qargs)
    return qcirc
示例#12
0
    def receive(self, command_list):
        """
        Receives a list of commands and appends to local Circuit. If a flush gate is received, 
        optimises the Circuit using a default Transform pass and then sends the commands from
        this optimised Circuit into the next engine.
        """
        for cmd in command_list:
            if cmd.gate == pqo.FlushGate(): #flush gate --> optimize and then flush
                cmd_list = self._optimise()
                cmd_list.append(cmd)
                self._circuit = Circuit()
                self._qubit_dictionary = dict()
                self.send(cmd_list)
                continue

            _handle_gate(cmd,self)
示例#13
0
def pyquil_to_tk(prog: Program) -> Circuit:
    """
    Convert a :py:class:`pyquil.Program` to a :math:`\\mathrm{t|ket}\\rangle` :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
    """
    qubits = prog.get_qubits()
    n_qubits = max(qubits) + 1
    tkc = Circuit(n_qubits)
    qreg = tkc.q_regs["q"]
    cregmap = {}
    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 = [qreg[q.index] for q in i.qubits]
            params = [p / pi for p in i.params]
            tkc.add_gate(optype, params, qubits, [])
        elif isinstance(i, Measurement):
            qubit = qreg[i.qubit.index]
            reg = cregmap[i.classical_reg.name]
            bit = reg[i.classical_reg.offset]
            tkc.add_measure(qubit, bit)
        elif isinstance(i, Declare):
            if i.memory_type is not 'BIT':
                raise NotImplementedError("Cannot handle memory of type " +
                                          i.memory_type)
            new_reg = tkc.add_c_register(i.name, i.memory_size)
            cregmap.update({i.name: new_reg})
        elif isinstance(i, Pragma):
            continue
        elif isinstance(i, Halt):
            return tkc
        else:
            raise NotImplementedError("Pyquil instruction is not a gate: " +
                                      str(i))
    return tkc
示例#14
0
def _add_single_qubit_op_to_circuit(cmd:ProjectQCommand,circ:Circuit):
    assert len(cmd.qubits)==1
    assert len(cmd.qubits[0])==1
    qubit_no = cmd.qubits[0][0].id
    new_qubit = False
    if get_control_count(cmd) > 0:
        raise Exception("singleq gate " + str(cmd.gate) + " has " + str(get_control_count(cmd)) + " control qubits")
    else:
        if type(cmd.gate) in (pqo.Rx,pqo.Ry,pqo.Rz):
            op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)],param=cmd.gate.angle/np.pi)
        else:
            op = circ._get_op(OpType=_pq_to_tk_singleqs[type(cmd.gate)])
        if (qubit_no >= circ.n_qubits):
            circ.add_blank_wires(1+qubit_no-circ.n_qubits)
            new_qubit = True
        circ._add_operation(Op=op,qubits=[qubit_no])
    return new_qubit
示例#15
0
def _add_daggered_op_to_circuit(cmd:ProjectQCommand, circ:Circuit):
    undaggered_gate = cmd.gate.get_inverse()
    if (type(undaggered_gate) == pqo.TGate):
        op = circ._get_op(OpType=OpType.Tdg)
    elif (type(undaggered_gate) == pqo.SGate):
        op = circ._get_op(OpType=OpType.Sdg)
    else:
        raise Exception("cannot recognise daggered op of type " + str(cmd.gate))
    qubit_no = cmd.qubits[0][0].id
    assert len(cmd.qubits)==1
    assert len(cmd.qubits[0])==1
    new_qubit = False
    if (qubit_no >= circ.n_qubits):
        circ.add_blank_wires(1+qubit_no-circ.n_qubits)
        new_qubit = True
    circ._add_operation(Op=op,qubits=[qubit_no])
    return new_qubit
示例#16
0
文件: aer.py 项目: danmills0/pytket
 def raw_run_return_result(self,
                           circuit: Circuit,
                           shots: int,
                           circ_name: str,
                           seed: int = None) -> np.ndarray:
     """Run a circuit on Qiskit Aer Qasm simulator.
     
     :param circuit: The circuit to run
     :type circuit: Circuit
     :param shots: Number of shots (repeats) to run
     :type shots: int
     :param fit_to_constraints: Compile the circuit to meet the contstraints of the backend, defaults to True
     :type fit_to_constraints: bool, optional
     :param seed: random seed to for simulator
     :type seed: int
     :return: Table of shot results, each row is a shot, columns are ordered by qubit ordering. Values are 0 or 1, corresponding to qubit basis states.
     :rtype: numpy.ndarray
     """
     c = circuit.copy()
     dag = tk_to_named_dagcircuit(circ_name, c)
     qc = dag_to_circuit(dag)
     qobj = assemble(qc, shots=shots, seed_simulator=seed, memory=True)
     job = self._backend.run(qobj, noise_model=self.noise_model)
     return job.result()
示例#17
0
def _add_multi_qubit_op_to_circuit(cmd:ProjectQCommand,circ:Circuit):
    assert len(cmd.qubits) >0
    qubs = [qb for qr in cmd.all_qubits for qb in qr]
    if get_control_count(cmd) < 1:
        raise Exception("multiq gate " + str(cmd.gate) + " has no controls")
    else:
        new_qubits = []
        for q in qubs:
            qubit_no = q.id
            if (qubit_no>=circ.n_qubits):
                circ.add_blank_wires(1+qubit_no-circ.n_qubits)
                new_qubits.append(q)
        if (type(cmd.gate) == pqo.CRz):
            op = circ._get_op(OpType=_pq_to_tk_multiqs[type(cmd.gate)],param=cmd.gate.angle/np.pi)
        else:
            op = circ._get_op(OpType=_pq_to_tk_multiqs[type(cmd.gate)])
        qubit_nos = [qb.id for qr in cmd.all_qubits for qb in qr]
        circ._add_operation(Op = op, qubits=qubit_nos)
        return new_qubits
示例#18
0
def cirq_to_tk(circuit: cirq.Circuit) -> Circuit:
    """Converts a Cirq :py:class:`Circuit` to a :math:`\\mathrm{t|ket}\\rangle` :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 :math:`\\mathrm{t|ket}\\rangle` :py:class:`Circuit` corresponding to the input circuit
    """
    qubit_list = _indexed_qubits_from_circuit(circuit)
    n_qubits = len(circuit.all_qubits())
    tkcirc = Circuit(n_qubits)
    qreg = tkcirc.q_regs["q"]
    qmap = {q: qreg[i] for i, q in enumerate(qubit_list)}
    for moment in circuit:
        for op in moment.operations:
            gate = op.gate
            gatetype = type(gate)

            qb_lst = [qmap[q] for q in op.qubits]

            n_qubits = len(op.qubits)

            if gatetype == cirq_common.HPowGate and gate.exponent == 1:
                gate = cirq_common.H
            elif gatetype == cirq_common.CNotPowGate and gate.exponent == 1:
                gate = cirq_common.CNOT
            elif gatetype == cirq_pauli._PauliX and gate.exponent == 1:
                gate = cirq_pauli.X
            elif gatetype == cirq_pauli._PauliY and gate.exponent == 1:
                gate = cirq_pauli.Y
            elif gatetype == cirq_pauli._PauliZ and 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):
                creg = tkcirc.add_c_register(gate.key, 1)
                tkcirc.add_measure(*qb_lst, creg[0])
                continue
            elif isinstance(gate, cirq.PhasedXPowGate):
                optype = OpType.PhasedX
                pe = gate.phase_exponent
                e = gate.exponent
                params = [e, pe]
            else:
                try:
                    optype = _cirq2ops_mapping[gatetype]
                except KeyError as error:
                    raise NotImplementedError(
                        "Operation not supported by tket: " +
                        str(op.gate)) from error
                params = [gate.exponent]
            tkcirc.add_gate(optype, params, qb_lst, [])
    return tkcirc
示例#19
0
 def __init__(self):
     BasicEngine.__init__(self)
     self._circuit = Circuit()
     self._qubit_dictionary = dict()