Ejemplo n.º 1
0
    def test_pass_cx_cancellation_own_template(self):
        """
        Check the cancellation of CX gates for the apply of a self made template cx-cx.
        """
        qr = QuantumRegister(2, 'qr')
        circuit_in = QuantumCircuit(qr)
        circuit_in.h(qr[0])
        circuit_in.h(qr[0])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[1], qr[0])
        circuit_in.cx(qr[1], qr[0])
        dag_in = circuit_to_dag(circuit_in)

        qrt = QuantumRegister(2, 'qrc')
        qct = QuantumCircuit(qrt)
        qct.cx(0, 1)
        qct.cx(0, 1)

        template_list = [qct]
        pass_ = TemplateOptimization(template_list)
        dag_opt = pass_.run(dag_in)

        circuit_expected = QuantumCircuit(qr)
        circuit_expected.h(qr[0])
        circuit_expected.h(qr[0])
        dag_expected = circuit_to_dag(circuit_expected)

        self.assertEqual(dag_opt, dag_expected)
Ejemplo n.º 2
0
    def test_pass_cx_cancellation_template_from_library(self):
        """
        Check the cancellation of CX gates for the apply of the library template cx-cx (2a_2).
        """
        qr = QuantumRegister(2, 'qr')
        circuit_in = QuantumCircuit(qr)
        circuit_in.h(qr[0])
        circuit_in.h(qr[0])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[1], qr[0])
        circuit_in.cx(qr[1], qr[0])
        dag_in = circuit_to_dag(circuit_in)

        template_list = [template_nct_2a_2()]
        pass_ = TemplateOptimization(template_list)
        dag_opt = pass_.run(dag_in)

        circuit_expected = QuantumCircuit(qr)
        circuit_expected.h(qr[0])
        circuit_expected.h(qr[0])
        dag_expected = circuit_to_dag(circuit_expected)

        self.assertEqual(dag_opt, dag_expected)
Ejemplo n.º 3
0
    def construct_circuit(self, measurement: bool = False) -> QuantumCircuit:
        """Construct circuit.

        Args:
            measurement: Boolean flag to indicate if measurement should be included in the circuit.

        Returns:
            Quantum circuit.
        """

        # Get n value used in Shor's algorithm, to know how many qubits are used
        self._n = math.ceil(math.log(self._N, 2))
        self._qft.num_qubits = self._n + 1
        self._iqft.num_qubits = self._n + 1
        self._qft_dag = circuit_to_dag(self._qft)
        self._iqft_dag = circuit_to_dag(self._iqft)

        # quantum register where the sequential QFT is performed
        self._up_qreg = QuantumRegister(2 * self._n, name='up')
        # quantum register where the multiplications are made
        self._down_qreg = QuantumRegister(self._n, name='down')
        # auxiliary quantum register used in addition and multiplication
        self._aux_qreg = QuantumRegister(self._n + 2, name='aux')

        # Create Quantum Circuit
        circuit = QuantumCircuit(self._up_qreg, self._down_qreg,
                                 self._aux_qreg)

        # Initialize down register to 1 and create maximal superposition in top register
        circuit.u2(0, np.pi, self._up_qreg)
        circuit.u3(np.pi, 0, np.pi, self._down_qreg[0])

        tdags = []
        dag_self = circuit_to_dag(circuit)

        # Apply the multiplication gates as showed in
        # the report in order to create the exponentiation
        for i in range(0, 2 * self._n):
            tdags += self._controlled_multiple_mod_N_tdags(
                self._up_qreg[i], self._down_qreg, self._aux_qreg,
                int(pow(self._a, pow(2, i))))

        for tdag in tdags:
            dag_compose_with_tagged(dag_self, tdag)
        composed_circuit = dag_to_circuit(dag_self)
        circuit.__dict__.update(composed_circuit.__dict__)

        # Apply inverse QFT
        iqft = QFT(len(self._up_qreg), inverse=True)
        circuit.compose(iqft, qubits=self._up_qreg)

        if measurement:
            up_cqreg = ClassicalRegister(2 * self._n, name='m')
            circuit.add_register(up_cqreg)
            circuit.measure(self._up_qreg, up_cqreg)

        logger.info(summarize_circuits(circuit))

        return circuit
Ejemplo n.º 4
0
    def test_rotation_gates(self):
        """Test controlled rotation gates"""
        import qiskit.extensions.standard.u1 as u1
        import qiskit.extensions.standard.rx as rx
        import qiskit.extensions.standard.ry as ry
        import qiskit.extensions.standard.rz as rz
        num_ctrl = 2
        num_target = 1
        qreg = QuantumRegister(num_ctrl + num_target)

        gu1 = u1.U1Gate(pi)
        grx = rx.RXGate(pi)
        gry = ry.RYGate(pi)
        grz = rz.RZGate(pi)

        ugu1 = ac._unroll_gate(gu1, ['u1', 'u3', 'cx'])
        ugrx = ac._unroll_gate(grx, ['u1', 'u3', 'cx'])
        ugry = ac._unroll_gate(gry, ['u1', 'u3', 'cx'])
        ugrz = ac._unroll_gate(grz, ['u1', 'u3', 'cx'])

        cgu1 = ugu1.q_if(num_ctrl)
        cgrx = ugrx.q_if(num_ctrl)
        cgry = ugry.q_if(num_ctrl)
        cgrz = ugrz.q_if(num_ctrl)

        simulator = BasicAer.get_backend('unitary_simulator')
        for gate, cgate in zip([gu1, grx, gry, grz], [cgu1, cgrx, cgry, cgrz]):
            with self.subTest(i=gate.name):
                qc = QuantumCircuit(num_target)
                qc.append(gate, qc.qregs[0])
                op_mat = execute(qc, simulator).result().get_unitary(0)
                cqc = QuantumCircuit(num_ctrl + num_target)
                cqc.append(cgate, cqc.qregs[0])
                ref_mat = execute(cqc, simulator).result().get_unitary(0)
                cop_mat = _compute_control_matrix(op_mat, num_ctrl)
                self.assertTrue(
                    matrix_equal(cop_mat, ref_mat, ignore_phase=True))
                dag = circuit_to_dag(cqc)
                unroller = Unroller(['u3', 'cx'])
                uqc = dag_to_circuit(unroller.run(dag))
                self.log.info('%s gate count: %d', cgate.name, uqc.size())
                self.log.info('\n%s', str(uqc))
                # these limits could be changed
                if gate.name == 'ry':
                    self.assertTrue(uqc.size() <= 32)
                else:
                    self.assertTrue(uqc.size() <= 20)
        qc = QuantumCircuit(qreg, name='composite')
        qc.append(grx.q_if(num_ctrl), qreg)
        qc.append(gry.q_if(num_ctrl), qreg)
        qc.append(gry, qreg[0:gry.num_qubits])
        qc.append(grz.q_if(num_ctrl), qreg)

        dag = circuit_to_dag(qc)
        unroller = Unroller(['u3', 'cx'])
        uqc = dag_to_circuit(unroller.run(dag))
        self.log.info('%s gate count: %d', uqc.name, uqc.size())
        self.assertTrue(uqc.size() <= 73)  # this limit could be changed
Ejemplo n.º 5
0
def _gate_to_dag(operation):
    from qiskit.converters.circuit_to_dag import circuit_to_dag
    if hasattr(operation, 'definition') and operation.definition:
        return circuit_to_dag(operation.definition)
    else:
        qr = QuantumRegister(operation.num_qubits)
        qc = QuantumCircuit(qr, name=operation.name)
        qc.append(operation, qr)
        return circuit_to_dag(qc)
Ejemplo n.º 6
0
    def assertEqualUnroll(self, basis, circuit, expected):
        """ Compares the dags after unrolling to basis """
        circuit_dag = circuit_to_dag(circuit)
        expected_dag = circuit_to_dag(expected)

        circuit_result = Unroller(basis).run(circuit_dag)
        expected_result = Unroller(basis).run(expected_dag)

        self.assertEqual(circuit_result, expected_result)
Ejemplo n.º 7
0
    def test_pass_template_wrong_type(self):
        """
        If a template is not equivalent to the identity, it raises an error.
        """
        qr = QuantumRegister(2, 'qr')
        circuit_in = QuantumCircuit(qr)
        circuit_in.h(qr[0])
        circuit_in.h(qr[0])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[1], qr[0])
        circuit_in.cx(qr[1], qr[0])
        dag_in = circuit_to_dag(circuit_in)

        qrt = QuantumRegister(2, 'qrc')
        qct = QuantumCircuit(qrt)
        qct.cx(0, 1)
        qct.x(0)
        qct.h(1)

        template_list = [qct]
        pass_ = TemplateOptimization(template_list)

        self.assertRaises(TranspilerError, pass_.run, dag_in)
Ejemplo n.º 8
0
    def run(self, dag):
        """Run the Unroll3qOrMore pass on `dag`.

        Args:
            dag(DAGCircuit): input dag
        Returns:
            DAGCircuit: output dag with maximum node degrees of 2
        Raises:
            QiskitError: if a 3q+ gate is not decomposable
        """
        for node in dag.multi_qubit_ops():
            # TODO: allow choosing other possible decompositions
            rule = node.op.definition.data
            if not rule:
                if rule == []:  # empty node
                    dag.remove_op_node(node)
                    continue
                raise QiskitError(
                    "Cannot unroll all 3q or more gates. "
                    "No rule to expand instruction %s." % node.op.name
                )
            decomposition = circuit_to_dag(node.op.definition)
            decomposition = self.run(decomposition)  # recursively unroll
            dag.substitute_node_with_dag(node, decomposition)
        return dag
 def test_transpile_2q_circuit(self):
     qr = QuantumRegister(2)
     cr = ClassicalRegister(4)
     circ = QuantumCircuit(qr, cr)
     circ.x(qr[0])
     circ.measure(qr[0], cr[0])
     circ.measure(qr[1], cr[1])
     circ.barrier()
     circ.reset(qr[0])
     circ.reset(qr[1])
     circ.barrier()
     circ.y(qr[0])
     dag = circuit_to_dag(circ)
     jcirc = CircuitBuilder()
     reg1 = jcirc.register("baseregister", 2)
     reg2 = jcirc.map(qr.name, reg1, slice(0, 2, 1))
     block = jcirc.block()
     block.gate("prepare_all")
     block.gate("Px", reg2[0])
     block.gate("measure_all")
     block = jcirc.block()
     block.gate("prepare_all")
     block = jcirc.block()
     block.gate("Py", reg2[0])
     block.gate("measure_all")
     self.assertEqual(
         generate_jaqal_program(jcirc.build()),
         generate_jaqal_program(jaqal_circuit_from_dag_circuit(dag)),
     )
Ejemplo n.º 10
0
    def run(self, dag):
        """Run the UnrollCustomDefinitions pass on `dag`.

        Args:
            dag (DAGCircuit): input dag

        Raises:
            QiskitError: if unable to unroll given the basis due to undefined
            decomposition rules (such as a bad basis) or excessive recursion.

        Returns:
            DAGCircuit: output unrolled dag
        """

        if self._basis_gates is None:
            return dag

        basic_insts = {'measure', 'reset', 'barrier', 'snapshot', 'delay'}
        device_insts = basic_insts | set(self._basis_gates)

        for node in dag.op_nodes():

            if node.op._directive:
                continue

            if dag.has_calibration_for(node):
                continue

            if node.name in device_insts or self._equiv_lib.has_entry(node.op):
                if isinstance(node.op, ControlledGate) and node.op._open_ctrl:
                    pass
                else:
                    continue

            try:
                rule = node.op.definition.data
            except TypeError as err:
                raise QiskitError(
                    f'Error decomposing node {node.name}: {err}') from err
            except AttributeError:
                # definition is None
                rule = None

            if not rule:
                if rule == []:
                    dag.remove_op_node(node)
                    continue

                # opaque node
                raise QiskitError(
                    "Cannot unroll the circuit to the given basis, %s. "
                    "Instruction %s not found in equivalence library "
                    "and no rule found to expand." %
                    (str(self._basis_gates), node.op.name))
            decomposition = circuit_to_dag(node.op.definition)
            unrolled_dag = UnrollCustomDefinitions(
                self._equiv_lib, self._basis_gates).run(decomposition)
            dag.substitute_node_with_dag(node, unrolled_dag)

        return dag
Ejemplo n.º 11
0
    def run(self, dag: DAGCircuit) -> DAGCircuit:
        """Run the Decompose pass on `dag`.

        Args:
            dag: input dag.

        Returns:
            output dag where ``gate`` was expanded.
        """
        # Walk through the DAG and expand each non-basis node
        for node in dag.op_nodes(self.gate):
            # opaque or built-in gates are not decomposable
            if not node.op.definition:
                continue
            if node.op.definition.global_phase:
                dag.global_phase += node.op.definition.global_phase
            # TODO: allow choosing among multiple decomposition rules
            rule = node.op.definition.data

            if len(rule) == 1 and len(node.qargs) == len(rule[0][1]) == 1:
                dag.substitute_node(node, rule[0][0], inplace=True)
            else:
                decomposition = circuit_to_dag(node.op.definition)
                dag.substitute_node_with_dag(node, decomposition)
        return dag
    def test_pass_template_too_many_qubits(self):
        """
        If the template has more qubits than the circuit, it raises an error.
        """
        qr = QuantumRegister(2, 'qr')
        circuit_in = QuantumCircuit(qr)
        circuit_in.h(qr[0])
        circuit_in.h(qr[0])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[0], qr[1])
        circuit_in.cx(qr[1], qr[0])
        circuit_in.cx(qr[1], qr[0])
        dag_in = circuit_to_dag(circuit_in)

        qrt = QuantumRegister(10, 'qrc')
        qct = QuantumCircuit(qrt)
        qct.mcx(control_qubits=[0, 1, 2, 3], target_qubit=[8])
        qct.mcx(control_qubits=[0, 1, 2, 3], target_qubit=[8])
        qct.x(0)
        qct.x(0)
        qct.h(1)
        qct.h(1)
        qct.x(8)
        qct.x(8)

        template_list = [qct]
        pass_ = TemplateOptimization(template_list)

        self.assertRaises(TranspilerError, pass_.run, dag_in)
Ejemplo n.º 13
0
    def test_skip_unentangled_qubits(self):
        """Test skipping the unentangled qubits."""
        num_qubits = 6
        entanglement_1 = [[0, 1, 3], [1, 3, 5], [0, 1, 5]]
        skipped_1 = [2, 4]

        entanglement_2 = [entanglement_1, [[0, 1, 2], [2, 3, 5]]]
        skipped_2 = [4]

        for entanglement, skipped in zip([entanglement_1, entanglement_2],
                                         [skipped_1, skipped_2]):
            with self.subTest(entanglement=entanglement, skipped=skipped):
                nlocal = NLocal(
                    num_qubits,
                    rotation_blocks=XGate(),
                    entanglement_blocks=CCXGate(),
                    entanglement=entanglement,
                    reps=3,
                    skip_unentangled_qubits=True,
                )

                skipped_set = set(nlocal.qubits[i] for i in skipped)
                dag = circuit_to_dag(nlocal)
                idle = set(dag.idle_wires())
                self.assertEqual(skipped_set, idle)
Ejemplo n.º 14
0
    def run(self, dag: DAGCircuit) -> DAGCircuit:
        """Run the Decompose pass on `dag`.

        Args:
            dag: input dag.

        Returns:
            output dag where ``gate`` was expanded.
        """
        # Walk through the DAG and expand each non-basis node
        for node in dag.op_nodes():
            if self._should_decompose(node):
                if getattr(node.op, "definition", None) is None:
                    continue
                # TODO: allow choosing among multiple decomposition rules
                rule = node.op.definition.data
                if len(rule) == 1 and len(node.qargs) == len(
                        rule[0].qubits) == 1:
                    if node.op.definition.global_phase:
                        dag.global_phase += node.op.definition.global_phase
                    dag.substitute_node(node, rule[0].operation, inplace=True)
                else:
                    decomposition = circuit_to_dag(node.op.definition)
                    dag.substitute_node_with_dag(node, decomposition)

        return dag
Ejemplo n.º 15
0
 def test_single_controlled_rotation_gates(self, gate, cgate):
     """Test the controlled rotation gates controlled on one qubit."""
     if gate.name == 'rz':
         iden = Operator.from_label('I')
         zgen = Operator.from_label('Z')
         op_mat = (np.cos(0.5 * self.theta) * iden -
                   1j * np.sin(0.5 * self.theta) * zgen).data
     else:
         op_mat = Operator(gate).data
     ref_mat = Operator(cgate).data
     cop_mat = _compute_control_matrix(op_mat, self.num_ctrl)
     self.assertTrue(matrix_equal(cop_mat, ref_mat, ignore_phase=True))
     cqc = QuantumCircuit(self.num_ctrl + self.num_target)
     cqc.append(cgate, cqc.qregs[0])
     dag = circuit_to_dag(cqc)
     unroller = Unroller(['u3', 'cx'])
     uqc = dag_to_circuit(unroller.run(dag))
     self.log.info('%s gate count: %d', cgate.name, uqc.size())
     self.log.info('\n%s', str(uqc))
     # these limits could be changed
     if gate.name == 'ry':
         self.assertTrue(uqc.size() <= 32)
     elif gate.name == 'rz':
         self.assertTrue(uqc.size() <= 40)
     else:
         self.assertTrue(uqc.size() <= 20)
Ejemplo n.º 16
0
def _unroll_gate(operation, basis_gates):
    from qiskit.converters.circuit_to_dag import circuit_to_dag
    from qiskit.converters.dag_to_circuit import dag_to_circuit
    from qiskit.transpiler.passes import Unroller
    unroller = Unroller(basis_gates)
    dag = circuit_to_dag(_gate_to_circuit(operation))
    qc = dag_to_circuit(unroller.run(dag))
    return qc.to_gate()
    def test_open_control_cxx_unrolling(self):
        """test unrolling of open control gates when gate is in basis"""
        qreg = QuantumRegister(3)
        qc = QuantumCircuit(qreg)
        ccx = CCXGate(ctrl_state=0)
        qc.append(ccx, [0, 1, 2])
        dag = circuit_to_dag(qc)
        unroller = Unroller(['x', 'ccx'])
        unrolled_dag = unroller.run(dag)

        ref_circuit = QuantumCircuit(qreg)
        ref_circuit.x(qreg[0])
        ref_circuit.x(qreg[1])
        ref_circuit.ccx(qreg[0], qreg[1], qreg[2])
        ref_circuit.x(qreg[0])
        ref_circuit.x(qreg[1])
        ref_dag = circuit_to_dag(ref_circuit)
        self.assertEqual(unrolled_dag, ref_dag)
    def test_circuit_multi(self):
        """Test circuit multi regs declared at start.
        """
        qreg0 = QuantumRegister(2, 'q0')
        creg0 = ClassicalRegister(2, 'c0')
        qreg1 = QuantumRegister(2, 'q1')
        creg1 = ClassicalRegister(2, 'c1')
        circ = QuantumCircuit(qreg0, qreg1, creg0, creg1)
        circ.x(qreg0[1])
        circ.x(qreg1[0])

        meas = QuantumCircuit(qreg0, qreg1, creg0, creg1)
        meas.measure(qreg0, creg0)
        meas.measure(qreg1, creg1)

        qc = circ + meas

        circ2 = QuantumCircuit()
        circ2.add_register(qreg0)
        circ2.add_register(qreg1)
        circ2.add_register(creg0)
        circ2.add_register(creg1)
        circ2.x(qreg0[1])
        circ2.x(qreg1[0])

        meas2 = QuantumCircuit()
        meas2.add_register(qreg0)
        meas2.add_register(qreg1)
        meas2.add_register(creg0)
        meas2.add_register(creg1)
        meas2.measure(qreg0, creg0)
        meas2.measure(qreg1, creg1)

        qc2 = circ2 + meas2

        dag_qc = circuit_to_dag(qc)
        dag_qc2 = circuit_to_dag(qc2)
        dag_circ2 = circuit_to_dag(circ2)
        dag_circ = circuit_to_dag(circ)

        self.assertEqual(dag_qc, dag_qc2)
        self.assertEqual(dag_circ, dag_circ2)
    def test_open_control_cy_unrolling(self):
        """test unrolling of open control gates when gate is in basis"""
        qc = QuantumCircuit(2)
        qc.cy(0, 1, ctrl_state=0)
        dag = circuit_to_dag(qc)
        unroller = Unroller(['u3', 'cy'])
        uqc = dag_to_circuit(unroller.run(dag))

        ref_circuit = QuantumCircuit(2)
        ref_circuit.u3(np.pi, 0, np.pi, 0)
        ref_circuit.cy(0, 1)
        ref_circuit.u3(np.pi, 0, np.pi, 0)
        self.assertEqual(uqc, ref_circuit)
 def test_open_control_composite_unrolling(self):
     """test unrolling of open control gates when gate is in basis"""
     # create composite gate
     qreg = QuantumRegister(2)
     qcomp = QuantumCircuit(qreg, name='bell')
     qcomp.h(qreg[0])
     qcomp.cx(qreg[0], qreg[1])
     bell = qcomp.to_gate()
     # create controlled composite gate
     cqreg = QuantumRegister(3)
     qc = QuantumCircuit(cqreg)
     qc.append(bell.control(ctrl_state=0), qc.qregs[0][:])
     dag = circuit_to_dag(qc)
     unroller = Unroller(['x', 'u1', 'cbell'])
     unrolled_dag = unroller.run(dag)
     # create reference circuit
     ref_circuit = QuantumCircuit(cqreg)
     ref_circuit.x(cqreg[0])
     ref_circuit.append(bell.control(), [cqreg[0], cqreg[1], cqreg[2]])
     ref_circuit.x(cqreg[0])
     ref_dag = circuit_to_dag(ref_circuit)
     self.assertEqual(unrolled_dag, ref_dag)
 def test_metadata(self):
     """Test circuit metadata is preservered through conversion."""
     meta_dict = dict(experiment_id="1234", execution_number=4)
     qr = QuantumRegister(2)
     circuit_in = QuantumCircuit(qr, metadata=meta_dict)
     circuit_in.h(qr[0])
     circuit_in.cx(qr[0], qr[1])
     circuit_in.measure_all()
     dag = circuit_to_dag(circuit_in)
     self.assertEqual(dag.metadata, meta_dict)
     dag_dependency = dag_to_dagdependency(dag)
     self.assertEqual(dag_dependency.metadata, meta_dict)
     dag_out = dagdependency_to_dag(dag_dependency)
     self.assertEqual(dag_out.metadata, meta_dict)
Ejemplo n.º 22
0
    def test_composite(self):
        """Test composite gate count."""
        qreg = QuantumRegister(self.num_ctrl + self.num_target)
        qc = QuantumCircuit(qreg, name='composite')
        qc.append(self.grx.control(self.num_ctrl), qreg)
        qc.append(self.gry.control(self.num_ctrl), qreg)
        qc.append(self.gry, qreg[0:self.gry.num_qubits])
        qc.append(self.grz.control(self.num_ctrl), qreg)

        dag = circuit_to_dag(qc)
        unroller = Unroller(['u3', 'cx'])
        uqc = dag_to_circuit(unroller.run(dag))
        self.log.info('%s gate count: %d', uqc.name, uqc.size())
        self.assertTrue(uqc.size() <= 93)  # this limit could be changed
Ejemplo n.º 23
0
    def run(self, dag: DAGCircuit) -> DAGCircuit:
        """Run the Decompose pass on `dag`.

        Args:
            dag: input DAG.

        Returns:
            Output DAG where ``U`` gates have been decomposed.
        """
        # Walk through the DAG and expand each node if required
        for node in dag.op_nodes():
            if isinstance(node.op, (PhaseGate, U1Gate, U2Gate, U3Gate, UGate)):
                subdag = circuit_to_dag(self.ugate_replacement_circuit(
                    node.op))
                dag.substitute_node_with_dag(node, subdag)
        return dag
    def test_circuit_and_dag_dependency(self):
        """Check convert to dag dependency and back"""
        qr = QuantumRegister(3)
        cr = ClassicalRegister(3)
        circuit_in = QuantumCircuit(qr, cr)
        circuit_in.h(qr[0])
        circuit_in.h(qr[1])
        circuit_in.measure(qr[0], cr[0])
        circuit_in.measure(qr[1], cr[1])
        circuit_in.x(qr[0]).c_if(cr, 0x3)
        circuit_in.measure(qr[0], cr[0])
        circuit_in.measure(qr[1], cr[1])
        circuit_in.measure(qr[2], cr[2])
        dag_in = circuit_to_dag(circuit_in)

        dag_dependency = dag_to_dagdependency(dag_in)
        dag_out = dagdependency_to_dag(dag_dependency)

        self.assertEqual(dag_out, dag_in)
Ejemplo n.º 25
0
    def __init__(self, mode: str = 'ry'):
        """
        Args:
        """
        super().__init__()
        self._subdags: List = []
        self.initial_layout = None
        self.gate = qiskit.circuit.library.CXGate

        self.decomposition = QuantumCircuit(2)
        if mode == 'ry':
            self.decomposition.ry(-np.pi / 2, 1)
            self.decomposition.cz(0, 1)
            self.decomposition.ry(np.pi / 2, 1)
        else:
            self.decomposition.h(1)
            self.decomposition.cz(0, 1)
            self.decomposition.h(1)

        self._dag = circuit_to_dag(self.decomposition)
Ejemplo n.º 26
0
    def run(self, dag):
        """Run the Unroll3qOrMore pass on `dag`.

        Args:
            dag(DAGCircuit): input dag
        Returns:
            DAGCircuit: output dag with maximum node degrees of 2
        Raises:
            QiskitError: if a 3q+ gate is not decomposable
        """
        for node in dag.multi_qubit_ops():
            if dag.has_calibration_for(node):
                continue
            if self.target is not None:
                # Treat target instructions as global since this pass can be run
                # prior to layout and routing we don't have phsyical qubits from
                # the circuit yet
                if node.name in self.target:
                    continue
            elif self.basis_gates is not None and node.name in self.basis_gates:
                continue

            # TODO: allow choosing other possible decompositions
            rule = node.op.definition.data
            if not rule:
                if rule == []:  # empty node
                    dag.remove_op_node(node)
                    continue
                raise QiskitError(
                    "Cannot unroll all 3q or more gates. "
                    "No rule to expand instruction %s." % node.op.name
                )
            decomposition = circuit_to_dag(node.op.definition)
            decomposition = self.run(decomposition)  # recursively unroll
            dag.substitute_node_with_dag(node, decomposition)
        return dag
Ejemplo n.º 27
0
    def test_rotation_gates(self):
        """Test controlled rotation gates"""
        import qiskit.extensions.standard.u1 as u1
        import qiskit.extensions.standard.rx as rx
        import qiskit.extensions.standard.ry as ry
        import qiskit.extensions.standard.rz as rz
        num_ctrl = 2
        num_target = 1
        qreg = QuantumRegister(num_ctrl + num_target)

        theta = pi / 2
        gu1 = u1.U1Gate(theta)
        grx = rx.RXGate(theta)
        gry = ry.RYGate(theta)
        grz = rz.RZGate(theta)

        ugu1 = ac._unroll_gate(gu1, ['u1', 'u3', 'cx'])
        ugrx = ac._unroll_gate(grx, ['u1', 'u3', 'cx'])
        ugry = ac._unroll_gate(gry, ['u1', 'u3', 'cx'])
        ugrz = ac._unroll_gate(grz, ['u1', 'u3', 'cx'])
        ugrz.params = grz.params

        cgu1 = ugu1.control(num_ctrl)
        cgrx = ugrx.control(num_ctrl)
        cgry = ugry.control(num_ctrl)
        cgrz = ugrz.control(num_ctrl)

        for gate, cgate in zip([gu1, grx, gry, grz], [cgu1, cgrx, cgry, cgrz]):
            with self.subTest(i=gate.name):
                if gate.name == 'rz':
                    iden = Operator.from_label('I')
                    zgen = Operator.from_label('Z')
                    op_mat = (np.cos(0.5 * theta) * iden -
                              1j * np.sin(0.5 * theta) * zgen).data
                else:
                    op_mat = Operator(gate).data
                ref_mat = Operator(cgate).data
                cop_mat = _compute_control_matrix(op_mat, num_ctrl)
                self.assertTrue(
                    matrix_equal(cop_mat, ref_mat, ignore_phase=True))
                cqc = QuantumCircuit(num_ctrl + num_target)
                cqc.append(cgate, cqc.qregs[0])
                dag = circuit_to_dag(cqc)
                unroller = Unroller(['u3', 'cx'])
                uqc = dag_to_circuit(unroller.run(dag))
                self.log.info('%s gate count: %d', cgate.name, uqc.size())
                self.log.info('\n%s', str(uqc))
                # these limits could be changed
                if gate.name == 'ry':
                    self.assertTrue(uqc.size() <= 32)
                elif gate.name == 'rz':
                    self.assertTrue(uqc.size() <= 40)
                else:
                    self.assertTrue(uqc.size() <= 20)
        qc = QuantumCircuit(qreg, name='composite')
        qc.append(grx.control(num_ctrl), qreg)
        qc.append(gry.control(num_ctrl), qreg)
        qc.append(gry, qreg[0:gry.num_qubits])
        qc.append(grz.control(num_ctrl), qreg)

        dag = circuit_to_dag(qc)
        unroller = Unroller(['u3', 'cx'])
        uqc = dag_to_circuit(unroller.run(dag))
        print(uqc.size())
        self.log.info('%s gate count: %d', uqc.name, uqc.size())
        self.assertTrue(uqc.size() <= 93)  # this limit could be changed
Ejemplo n.º 28
0
    def run(self, dag):
        """Run the Unroller pass on `dag`.

        Args:
            dag (DAGCircuit): input dag

        Raises:
            QiskitError: if unable to unroll given the basis due to undefined
            decomposition rules (such as a bad basis) or excessive recursion.

        Returns:
            DAGCircuit: output unrolled dag
        """
        if self.basis is None:
            return dag
        # Walk through the DAG and expand each non-basis node
        for node in dag.op_nodes():
            basic_insts = ['measure', 'reset', 'barrier', 'snapshot', 'delay']
            if node.name in basic_insts:
                # TODO: this is legacy behavior.Basis_insts should be removed that these
                #  instructions should be part of the device-reported basis. Currently, no
                #  backend reports "measure", for example.
                continue
            if node.name in self.basis:  # If already a base, ignore.
                if isinstance(node.op, ControlledGate) and node.op._open_ctrl:
                    pass
                else:
                    continue
            # TODO: allow choosing other possible decompositions
            try:
                rule = node.op.definition.data
            except TypeError as err:
                raise QiskitError('Error decomposing node {}: {}'.format(
                    node.name, err))

            # Isometry gates definitions can have widths smaller than that of the
            # original gate, in which case substitute_node will raise. Fall back
            # to substitute_node_with_dag if an the width of the definition is
            # different that the width of the node.
            while rule and len(rule) == 1 and len(node.qargs) == len(
                    rule[0][1]) == 1:
                if rule[0][0].name in self.basis:
                    if node.op.definition and node.op.definition.global_phase:
                        dag.global_phase += node.op.definition.global_phase
                    dag.substitute_node(node, rule[0][0], inplace=True)
                    break
                try:
                    rule = rule[0][0].definition.data
                except (TypeError, AttributeError) as err:
                    raise QiskitError('Error decomposing node {}: {}'.format(
                        node.name, err))

            else:
                if not rule:
                    if rule == []:  # empty node
                        dag.remove_op_node(node)
                        continue
                    # opaque node
                    raise QiskitError(
                        "Cannot unroll the circuit to the given basis, %s. "
                        "No rule to expand instruction %s." %
                        (str(self.basis), node.op.name))
                decomposition = circuit_to_dag(node.op.definition)
                unrolled_dag = self.run(
                    decomposition)  # recursively unroll ops
                if unrolled_dag.global_phase:
                    dag.global_phase += unrolled_dag.global_phase
                    unrolled_dag.global_phase = 0
                dag.substitute_node_with_dag(node, unrolled_dag)
        return dag
Ejemplo n.º 29
0
def circuit_to_tdag(circuit, qubits=None):
    return TaggedDAG(circuit_to_dag(circuit), qubits=qubits)
Ejemplo n.º 30
0
def layer_parser(circ, two_qubit_gate='cx', coupling_map=None):
    """
    Tranforms general circuits into a nice form for a qotp.

    Args:
        circ (QuantumCircuit): A generic quantum circuit
        two_qubit_gate (str): a flag as to which 2 qubit
            gate to compile with, can be cx or cz
        coupling_map (list): some particular device topology as list
            of list (e.g. [[0,1],[1,2],[2,0]])
    Returns:
        dict: A dictionary of the parsed layers with the following keys:
            ``singlequbit_layers`` (lsit):  a list of circuits describing
                the single qubit gates
            ``cz_layers`` (list): a list of circuits describing the cz layers
            ``meas_layer`` (QuantumCircuit): a circuit describing the final measurement

    Raises:
        QiskitError: If a circuit element is not implemented in qotp
    """

    # transpile to single qubits and cx
    # TODO: replace cx with cz when that is available
    circ_internal = transpile(circ,
                              optimization_level=2,
                              basis_gates=['u1', 'u2', 'u3', 'cx'],
                              coupling_map=coupling_map)
    # quantum and classial registers
    qregs = circ_internal.qregs[0]
    cregs = circ_internal.cregs[0]
    # conatiners for the eventual output passed to the accred code
    singlequbitlayers = [
        QuantumCircuit(qregs, cregs),
        QuantumCircuit(qregs, cregs)
    ]
    twoqubitlayers = [QuantumCircuit(qregs, cregs)]
    measlayer = QuantumCircuit(qregs, cregs)
    # some flags for simplicity
    current2qs = []
    # loop through circuit (best to use the dag object)
    dag_internal = circuit_to_dag(circ_internal)
    for dag_layer in dag_internal.layers():
        circuit_layer = dag_to_circuit(dag_layer['graph'])
        for circelem, qsub, csub in circuit_layer:
            n = circelem.name
            if n == "barrier":
                # if a barrier separates any two qubit gates
                # start a new layer
                if current2qs != []:
                    singlequbitlayers.append(QuantumCircuit(qregs, cregs))
                    twoqubitlayers.append(QuantumCircuit(qregs, cregs))
                    current2qs = []
                singlequbitlayers[-2].append(circelem, qsub, csub)
            elif n in ('u1', 'u2', 'u3'):
                # single qubit gate
                q = qsub[0]
                if q in current2qs:
                    singlequbitlayers[-1].append(circelem, qsub, csub)
                else:
                    singlequbitlayers[-2].append(circelem, qsub, csub)
            elif n == "cx":
                # cx indices
                q_0 = qsub[0]
                q_1 = qsub[1]
                # check if new cnot satisfies overlap criteria
                if q_0 in current2qs or q_1 in current2qs:
                    singlequbitlayers.append(QuantumCircuit(qregs, cregs))
                    twoqubitlayers.append(QuantumCircuit(qregs, cregs))
                    current2qs = []
                if two_qubit_gate == 'cx':
                    # append cx
                    twoqubitlayers[-1].cx(q_0, q_1)
                elif two_qubit_gate == 'cz':
                    # append and correct to cz with h gates
                    twoqubitlayers[-1].cz(q_0, q_1)
                    singlequbitlayers[-1].h(qsub[1])
                    singlequbitlayers[-2].h(qsub[1])
                else:
                    raise QiskitError(
                        "Two qubit gate {0}".format(two_qubit_gate) +
                        " is not implemented in qotp")
                # add to current
                current2qs.append(q_0)
                current2qs.append(q_1)
            elif n == "measure":
                measlayer.append(circelem, qsub, csub)
            else:
                raise QiskitError("Circuit element {0}".format(n) +
                                  " is not implemented in qotp")
    if current2qs == []:
        del singlequbitlayers[-1]
        del twoqubitlayers[-1]
    for ind, circlayer in enumerate(singlequbitlayers):
        singlequbitlayers[ind] = transpile(circlayer,
                                           basis_gates=['u1', 'u2', 'u3'])
    parsedlayers = {
        'singlequbitlayers': singlequbitlayers,
        'twoqubitlayers': twoqubitlayers,
        'measlayer': measlayer,
        'twoqubitgate': two_qubit_gate,
        'qregs': qregs,
        'cregs': cregs
    }
    return parsedlayers