Esempio n. 1
0
 def test_odd_number_self_inverse(self):
     """Test that an odd number of self-inverse gates leaves one gate remaining."""
     qc = QuantumCircuit(2, 2)
     qc.h(0)
     qc.h(0)
     qc.h(0)
     pass_ = InverseCancellation([HGate()])
     pm = PassManager(pass_)
     new_circ = pm.run(qc)
     gates_after = new_circ.count_ops()
     self.assertIn("h", gates_after)
     self.assertEqual(gates_after["h"], 1)
 def test_u_rewrites_to_phase(self):
     """Test that a phase-like U-gate gets rewritten into an RZ gate."""
     qc = QuantumCircuit(1)
     qc.u(0, 0, np.pi / 6, 0)
     basis = ["sx", "p"]
     passmanager = PassManager()
     passmanager.append(Optimize1qGatesDecomposition(basis))
     result = passmanager.run(qc)
     expected = QuantumCircuit(1)
     expected.p(np.pi / 6, 0)
     msg = f"expected:\n{expected}\nresult:\n{result}"
     self.assertEqual(expected, result, msg=msg)
Esempio n. 3
0
    def test_ccx(self):
        """Test that extra multi-qubit operations are properly adjusted.

        Here, we test that the circuit

        .. parsed-literal::

                 ┌──────────────────────────┐
            q_0: ┤0                         ├──■──
                 │                          │┌─┴─┐
            q_1: ┤1 exp(-it (IZZ + ZIZ))(1) ├┤ X ├
                 │                          │└─┬─┘
            q_2: ┤2                         ├──■──
                 └──────────────────────────┘
            q_3: ─────────────────────────────────

        becomes

        .. parsed-literal::

                 ┌─────────────────┐                      ┌───┐
            q_0: ┤0                ├─X────────────────────┤ X ├
                 │  exp(-it ZZ)(1) │ │ ┌─────────────────┐└─┬─┘
            q_1: ┤1                ├─X─┤0                ├──■──
                 └─────────────────┘   │  exp(-it ZZ)(2) │  │
            q_2: ──────────────────────┤1                ├──■──
                                       └─────────────────┘
            q_3: ──────────────────────────────────────────────


        as expected. I.e. the Toffoli is properly adjusted at the end.
        """
        cmap = CouplingMap(couplinglist=[(0, 1), (1, 2)])
        swap_strat = SwapStrategy(cmap, swap_layers=(((0, 1), ), ))

        pm_ = PassManager([
            FindCommutingPauliEvolutions(),
            Commuting2qGateRouter(swap_strat),
        ])
        op = PauliSumOp.from_list([("IZZ", 1), ("ZIZ", 2)])
        circ = QuantumCircuit(4)
        circ.append(PauliEvolutionGate(op, 1), range(3))
        circ.ccx(0, 2, 1)

        swapped = pm_.run(circ)

        expected = QuantumCircuit(4)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 1), (0, 1))
        expected.swap(0, 1)
        expected.append(PauliEvolutionGate(Pauli("ZZ"), 2), (1, 2))
        expected.ccx(1, 2, 0)

        self.assertEqual(swapped, expected)
Esempio n. 4
0
 def test_self_inverse_on_different_qubits(self):
     """Test that self_inverse gates cancel on the correct qubits."""
     qc = QuantumCircuit(2, 2)
     qc.h(0)
     qc.h(1)
     qc.h(0)
     qc.h(1)
     pass_ = InverseCancellation([HGate()])
     pm = PassManager(pass_)
     new_circ = pm.run(qc)
     gates_after = new_circ.count_ops()
     self.assertNotIn("h", gates_after)
Esempio n. 5
0
def remap_apply_layout_virtual_qubit_registers(circuit: QuantumCircuit, coupling_map: CouplingMap, layout: Layout) -> \
        Optional[QuantumCircuit]:
    dag = circuit_to_dag(circuit)
    if not check_dag_circuit_compatible(dag, coupling_map):
        return

    print("FINALIZE LAYOUT:", layout)
    remap_pass_manager = PassManager()
    remap_pass_manager.append(SetLayout(layout))
    remap_pass_manager.append(ApplyLayout())
    remap_circ = remap_pass_manager.run(circuit)
    return remap_circ
    def test_do_not_merge_conditioned_gates(self):
        """Validate that classically conditioned gates are never considered for
        inclusion in a block. Note that there are cases where gates conditioned
        on the same (register, value) pair could be correctly merged, but this
        is not yet implemented.

                 ┌────────┐┌────────┐┌────────┐      ┌───┐
        qr_0: |0>┤ P(0.1) ├┤ P(0.2) ├┤ P(0.3) ├──■───┤ X ├────■───
                 └────────┘└───┬────┘└───┬────┘┌─┴─┐ └─┬─┘  ┌─┴─┐
        qr_1: |0>──────────────┼─────────┼─────┤ X ├───■────┤ X ├─
                               │         │     └───┘   │    └─┬─┘
        qr_2: |0>──────────────┼─────────┼─────────────┼──────┼───
                            ┌──┴──┐   ┌──┴──┐       ┌──┴──┐┌──┴──┐
         cr_0: 0 ═══════════╡     ╞═══╡     ╞═══════╡     ╞╡     ╞
                            │ = 0 │   │ = 0 │       │ = 0 ││ = 1 │
         cr_1: 0 ═══════════╡     ╞═══╡     ╞═══════╡     ╞╡     ╞
                            └─────┘   └─────┘       └─────┘└─────┘

        Blocks collected: [['cx']]
        """
        # ref: https://github.com/Qiskit/qiskit-terra/issues/3215

        qr = QuantumRegister(3, "qr")
        cr = ClassicalRegister(2, "cr")

        qc = QuantumCircuit(qr, cr)
        qc.p(0.1, 0)
        qc.p(0.2, 0).c_if(cr, 0)
        qc.p(0.3, 0).c_if(cr, 0)
        qc.cx(0, 1)
        qc.cx(1, 0).c_if(cr, 0)
        qc.cx(0, 1).c_if(cr, 1)

        pass_manager = PassManager()
        pass_manager.append(Collect2qBlocks())

        pass_manager.run(qc)
        self.assertEqual(
            [["cx"]], [[n.name for n in block]
                       for block in pass_manager.property_set["block_list"]])
Esempio n. 7
0
    def test_hanh_echo_experiment_type(self):
        """Test Hahn echo experiment type circuit.

        (input)

             ┌────┐┌────────────────┐┌───┐┌────────────────┐┌────┐┌─┐
        q_0: ┤ √X ├┤ Delay(100[dt]) ├┤ X ├┤ Delay(100[dt]) ├┤ √X ├┤M├
             └────┘└────────────────┘└───┘└────────────────┘└────┘└╥┘
        c: 1/══════════════════════════════════════════════════════╩═
                                                                   0

        (output)

             ┌────┐┌────────────────┐┌───┐┌────────────────┐┌────┐┌──────────────┐┌─┐
        q_0: ┤ √X ├┤ Delay(100[dt]) ├┤ X ├┤ Delay(100[dt]) ├┤ √X ├┤ Delay(8[dt]) ├┤M├
             └────┘└────────────────┘└───┘└────────────────┘└────┘└──────────────┘└╥┘
        c: 1/══════════════════════════════════════════════════════════════════════╩═
                                                                                   0

        This type of experiment doesn't change duration of interest (two in the middle).
        However induces slight delay less than alignment * dt before measurement.
        This might induce extra amplitude damping error.
        """
        circuit = QuantumCircuit(1, 1)
        circuit.sx(0)
        circuit.delay(100, 0, unit="dt")
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.sx(0)
        circuit.measure(0, 0)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(1, 1)
        ref_circuit.sx(0)
        ref_circuit.delay(100, 0, unit="dt")
        ref_circuit.x(0)
        ref_circuit.delay(100, 0, unit="dt")
        ref_circuit.sx(0)
        ref_circuit.delay(8, 0, unit="dt")
        ref_circuit.measure(0, 0)

        self.assertEqual(aligned_circuit, ref_circuit)
Esempio n. 8
0
    def test_mid_circuit_measure(self):
        """Test circuit with mid circuit measurement.

        (input)

             ┌───┐┌────────────────┐┌─┐┌───────────────┐┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(100[dt]) ├┤M├┤ Delay(10[dt]) ├┤ X ├┤ Delay(120[dt]) ├┤M├
             └───┘└────────────────┘└╥┘└───────────────┘└───┘└────────────────┘└╥┘
        c: 2/════════════════════════╩══════════════════════════════════════════╩═
                                     0                                          1

        (output)

             ┌───┐┌────────────────┐┌─┐┌───────────────┐┌───┐┌────────────────┐┌─┐
        q_0: ┤ X ├┤ Delay(112[dt]) ├┤M├┤ Delay(10[dt]) ├┤ X ├┤ Delay(134[dt]) ├┤M├
             └───┘└────────────────┘└╥┘└───────────────┘└───┘└────────────────┘└╥┘
        c: 2/════════════════════════╩══════════════════════════════════════════╩═
                                     0                                          1

        Extra delay is always added to the existing delay right before the measurement.
        Delay after measurement is unchanged.
        """
        circuit = QuantumCircuit(1, 2)
        circuit.x(0)
        circuit.delay(100, 0, unit="dt")
        circuit.measure(0, 0)
        circuit.delay(10, 0, unit="dt")
        circuit.x(0)
        circuit.delay(120, 0, unit="dt")
        circuit.measure(0, 1)

        pm = PassManager([
            # reproduce old behavior of 0.20.0 before #7655
            # currently default write latency is 0
            SetIOLatency(clbit_write_latency=1600, conditional_latency=0),
            ALAPScheduleAnalysis(durations=self.instruction_durations),
            ConstrainedReschedule(acquire_alignment=16),
            PadDelay(),
        ])

        aligned_circuit = pm.run(circuit)

        ref_circuit = QuantumCircuit(1, 2)
        ref_circuit.x(0)
        ref_circuit.delay(112, 0, unit="dt")
        ref_circuit.measure(0, 0)
        ref_circuit.delay(10, 0, unit="dt")
        ref_circuit.x(0)
        ref_circuit.delay(134, 0, unit="dt")
        ref_circuit.measure(0, 1)

        self.assertEqual(aligned_circuit, ref_circuit)
Esempio n. 9
0
    def test_commutative_circuit3(self):
        """
        A simple circuit where three CNOTs commute, the first and the last cancel,
        also two X gates cancel and two Rz gates combine.

        qr0:-------.------------------.-------------     qr0:-------------
                   |                  |
        qr1:------(+)------(+)--[X]--(+)-------[X]--  =  qr1:--------(+)--
                            |                                         |
        qr2:------[Rz]--.---.----.---[Rz]-[T]--[S]--     qr2:--[U1]---.---
                        |        |
        qr3:-[Rz]--[X]-(+)------(+)--[X]-[Rz]-------     qr3:--[Rz]-------
        """

        qr = QuantumRegister(4, 'qr')
        circuit = QuantumCircuit(qr)

        circuit.cx(qr[0], qr[1])
        circuit.rz(np.pi / 3, qr[2])
        circuit.rz(np.pi / 3, qr[3])
        circuit.x(qr[3])
        circuit.cx(qr[2], qr[3])
        circuit.cx(qr[2], qr[1])
        circuit.cx(qr[2], qr[3])
        circuit.rz(np.pi / 3, qr[2])
        circuit.t(qr[2])
        circuit.x(qr[3])
        circuit.rz(np.pi / 3, qr[3])
        circuit.s(qr[2])
        circuit.x(qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.x(qr[1])

        passmanager = PassManager()
        passmanager.append(
            [
                CommutationAnalysis(),
                CommutativeCancellation(),
                Size(),
                FixedPoint('size')
            ],
            do_while=lambda property_set: not property_set['size_fixed_point'])
        new_circuit = passmanager.run(circuit)
        expected = QuantumCircuit(qr)
        expected.append(RZGate(np.pi * 17 / 12), [qr[2]])
        expected.append(RZGate(np.pi * 2 / 3), [qr[3]])
        expected.cx(qr[2], qr[1])

        self.assertEqual(
            expected,
            new_circuit,
            msg=f'expected:\n{expected}\nnew_circuit:\n{new_circuit}')
 def test_euler_decomposition_worse(self):
     """Ensure we don't decompose to a deeper circuit."""
     circuit = QuantumCircuit(1)
     circuit.rx(-np.pi / 2, 0)
     circuit.rz(-np.pi / 2, 0)
     basis = ['rx', 'rz']
     passmanager = PassManager()
     passmanager.append(BasisTranslator(sel, basis))
     passmanager.append(Optimize1qGatesDecomposition(basis))
     result = passmanager.run(circuit)
     # decomposition of circuit will result in 3 gates instead of 2
     # assert optimization pass doesn't use it.
     self.assertEqual(result, circuit)
    def test_optimize_u1_basis_u2(self):
        """U1(pi/4) ->  Raises. Basis [u2]"""
        qr = QuantumRegister(1, "qr")
        circuit = QuantumCircuit(qr)
        circuit.append(U1Gate(np.pi / 4), [qr[0]])

        expected = QuantumCircuit(qr)
        expected.append(U3Gate(0, 0, np.pi / 4), [qr[0]])

        passmanager = PassManager()
        passmanager.append(Optimize1qGates(["u2"]))
        with self.assertRaises(TranspilerError):
            _ = passmanager.run(circuit)
Esempio n. 12
0
    def test_do_not_go_across_barrier(self):
        """Validate that blocks are not collected across barriers
                   ░
        q_0: ──■───░───■──
             ┌─┴─┐ ░ ┌─┴─┐
        q_1: ┤ X ├─░─┤ X ├
             └───┘ ░ └───┘
        q_2: ──────░──────
                   ░
        """
        qr = QuantumRegister(3, "qr")
        qc = QuantumCircuit(qr)
        qc.cx(0, 1)
        qc.barrier()
        qc.cx(0, 1)

        pass_manager = PassManager()
        pass_manager.append(CollectMultiQBlocks())

        pass_manager.run(qc)
        for block in pass_manager.property_set["block_list"]:
            self.assertTrue(len(block) <= 1)
Esempio n. 13
0
    def test_block_with_classical_register(self):
        """Test that only blocks that share quantum wires are added to the block.
        It was the case that gates which shared a classical wire could be added to
        the same block, despite not sharing the same qubits. This was fixed in #2956.

                                    ┌─────────────────────┐
        q_0: |0>────────────────────┤ U2(0.25*pi,0.25*pi) ├
                     ┌─────────────┐└──────────┬──────────┘
        q_1: |0>──■──┤ U1(0.25*pi) ├───────────┼───────────
                ┌─┴─┐└──────┬──────┘           │
        q_2: |0>┤ X ├───────┼──────────────────┼───────────
                └───┘    ┌──┴──┐            ┌──┴──┐
        c0_0: 0 ═════════╡ = 0 ╞════════════╡ = 0 ╞════════
                         └─────┘            └─────┘

        Previously the blocks collected were : [['cx', 'u1', 'u2']]
        This is now corrected to : [['cx', 'u1']]
        """

        qasmstr = """
        OPENQASM 2.0;
        include "qelib1.inc";
        qreg q[3];
        creg c0[1];

        cx q[1],q[2];
        if(c0==0) u1(0.25*pi) q[1];
        if(c0==0) u2(0.25*pi, 0.25*pi) q[0];
        """
        qc = QuantumCircuit.from_qasm_str(qasmstr)

        pass_manager = PassManager()
        pass_manager.append(Collect2qBlocks())

        pass_manager.run(qc)

        self.assertEqual(
            [["cx"]], [[n.name for n in block]
                       for block in pass_manager.property_set["block_list"]])
 def test_two_qubit_natural_direction_true_gate_length_raises(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     for _, nduv in backend.properties()._gates["cx"].items():
         nduv["gate_length"] = (4e-7, nduv["gate_length"][1])
         nduv["gate_error"] = (7e-3, nduv["gate_error"][1])
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]])
     triv_layout_pass = TrivialLayout(coupling_map)
     qc = QuantumCircuit(qr)
     qc.unitary(random_unitary(4, seed=12), [0, 1])
     unisynth_pass = UnitarySynthesis(
         basis_gates=conf.basis_gates,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(TranspilerError):
         pm.run(qc)
Esempio n. 15
0
    def test_optimize_u1_basis_u2(self):
        """U1(pi/4) ->  Raises. Basis [u2]"""
        qr = QuantumRegister(1, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.u1(np.pi / 4, qr[0])

        expected = QuantumCircuit(qr)
        expected.u3(0, 0, np.pi / 4, qr[0])

        passmanager = PassManager()
        passmanager.append(Optimize1qGates(['u2']))
        with self.assertRaises(TranspilerError):
            _ = passmanager.run(circuit)
Esempio n. 16
0
    def test_conditional_gates_dont_commute(self):
        """Conditional gates do not commute and do not cancel"""
        circuit = QuantumCircuit(3, 2)
        circuit.h(0)
        circuit.measure(0, 0)
        circuit.cx(1, 2)
        circuit.cx(1, 2).c_if(circuit.cregs[0], 0)
        circuit.measure([1, 2], [0, 1])

        new_pm = PassManager(CommutativeCancellation())
        new_circuit = new_pm.run(circuit)

        self.assertEqual(circuit, new_circuit)
Esempio n. 17
0
    def test_no_cancellation_across_parameterized_gates(self):
        """Test that parameterized gates prevent cancellation.
        This test should be modified when inverse and commutativity checking
        get improved to handle parameterized gates.
        """
        circuit = QuantumCircuit(1)
        circuit.rz(np.pi / 2, 0)
        circuit.rz(Parameter("Theta"), 0)
        circuit.rz(-np.pi / 2, 0)

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        self.assertEqual(circuit, new_circuit)
Esempio n. 18
0
    def test_self_inverse_on_different_qubits(self):
        """Test that self_inverse gates cancel on the correct qubits."""
        circuit = QuantumCircuit(2, 2)
        circuit.h(0)
        circuit.h(1)
        circuit.h(0)
        circuit.h(1)

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        gates_after = new_circuit.count_ops()

        self.assertNotIn("h", gates_after)
Esempio n. 19
0
    def test_cx_do_not_wrongly_cancel(self):
        """Test that CX(0,1) and CX(1, 0) do not cancel out, when (CX, CX) is passed
        as an inverse pair."""
        circuit = QuantumCircuit(2, 0)
        circuit.cx(0, 1)
        circuit.cx(1, 0)

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        gates_after = new_circuit.count_ops()

        self.assertIn("cx", gates_after)
        self.assertEqual(gates_after["cx"], 2)
Esempio n. 20
0
    def test_odd_number_self_inverse(self):
        """Test that an odd number of self-inverse gates leaves one gate remaining."""
        circuit = QuantumCircuit(2, 2)
        circuit.h(0)
        circuit.h(0)
        circuit.h(0)

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        gates_after = new_circuit.count_ops()

        self.assertIn("h", gates_after)
        self.assertEqual(gates_after["h"], 1)
Esempio n. 21
0
def pick_label(circ, backend, coupling_map, optimization_level, show=False):
    '''
    Funzione che restituisce il dizionario con il mapping, scegliendo come label layout quello che minimizza la depth
    del circuito tra dense layout e noise_adaptive sommata alla depth delle operazioni dopo il routing.
    In questa maniera tengo anche conto di qual'è il layout che permette di minimizzare le operazioni di swap
    '''
    new_circ_lv3 = transpile(circ,
                             backend=backend,
                             optimization_level=optimization_level)
    new_circ_lv3_na = transpile(circ,
                                backend=backend,
                                optimization_level=optimization_level,
                                layout_method='noise_adaptive')
    #plot_circuit_layout(new_circ_lv3_na, backend).show()
    #plot_circuit_layout(new_circ_lv3, backend).show()
    cp = CouplingMap(couplinglist=coupling_map)
    depths = []
    for qc in [new_circ_lv3_na, new_circ_lv3]:
        depth = qc.depth()
        pass_manager = PassManager(LookaheadSwap(coupling_map=cp))
        lc_qc = pass_manager.run(qc)
        pass_manager = PassManager(StochasticSwap(coupling_map=cp))
        st_qc = pass_manager.run(qc)
        depths.append(depth + lc_qc.depth())
        depths.append(depth + st_qc.depth())
        #print('depth=', depth, ' depth + routing_lc_qc= ', depth + lc_qc.depth(), ' depth + routing_st_qc=',depth + st_qc.depth())

    if depths.index(min(depths)) < 2:
        print('na')
        if show == True:
            plot_circuit_layout(new_circ_lv3_na, backend).show()
        return new_circ_lv3_na._layout.get_physical_bits()

    if depths.index(min(depths)) >= 2:
        print('not na')
        if show == True:
            plot_circuit_layout(new_circ_lv3, backend).show()
        return new_circ_lv3._layout.get_physical_bits()
Esempio n. 22
0
 def test_four_alternating_inverse_gates(self):
     """Test that inverse cancellation works correctly for alternating sequences
     of inverse gates of even-length."""
     qc = QuantumCircuit(2, 2)
     qc.p(np.pi / 4, 0)
     qc.p(-np.pi / 4, 0)
     qc.p(np.pi / 4, 0)
     qc.p(-np.pi / 4, 0)
     pass_ = InverseCancellation([(PhaseGate(np.pi / 4),
                                   PhaseGate(-np.pi / 4))])
     pm = PassManager(pass_)
     new_circ = pm.run(qc)
     gates_after = new_circ.count_ops()
     self.assertNotIn("p", gates_after)
Esempio n. 23
0
    def test_optimize_u3_basis_u1(self):
        """U3(0, 0, pi/4) ->  U1(pi/4). Basis [u1]."""
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.u3(0, 0, np.pi / 4, qr[0])

        expected = QuantumCircuit(qr)
        expected.u1(np.pi / 4, qr[0])

        passmanager = PassManager()
        passmanager.append(Optimize1qGates(['u1']))
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
Esempio n. 24
0
    def test_optimize_u3_to_u1_round(self):
        """U3(1e-16, 1e-16, pi/4) ->  U1(pi/4)"""
        qr = QuantumRegister(1, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.u3(1e-16, 1e-16, np.pi / 4, qr[0])

        expected = QuantumCircuit(qr)
        expected.u1(np.pi / 4, qr[0])

        passmanager = PassManager()
        passmanager.append(Optimize1qGates())
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
Esempio n. 25
0
    def test_parameterized_gates_do_not_cancel(self):
        """Test that parameterized gates do not cancel.
        This test should be modified when inverse and commutativity checking
        get improved to handle parameterized gates.
        """
        gate = RZGate(Parameter("Theta"))

        circuit = QuantumCircuit(1)
        circuit.append(gate, [0])
        circuit.append(gate.inverse(), [0])

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        self.assertEqual(circuit, new_circuit)
Esempio n. 26
0
    def test_four_alternating_inverse_gates(self):
        """Test that inverse cancellation works correctly for alternating sequences
        of inverse gates of even-length."""
        circuit = QuantumCircuit(2, 2)
        circuit.p(np.pi / 4, 0)
        circuit.p(-np.pi / 4, 0)
        circuit.p(np.pi / 4, 0)
        circuit.p(-np.pi / 4, 0)

        passmanager = PassManager(CommutativeInverseCancellation())
        new_circuit = passmanager.run(circuit)
        gates_after = new_circuit.count_ops()

        self.assertNotIn("p", gates_after)
 def test_single_gate_block_outside_basis(self):
     """Test that a single gate block outside the configured basis gets converted."""
     qc = QuantumCircuit(2)
     qc.swap(0, 1)
     consolidate_block_pass = ConsolidateBlocks(
         basis_gates=["id", "cx", "rz", "sx", "x"])
     pass_manager = PassManager()
     pass_manager.append(Collect2qBlocks())
     pass_manager.append(consolidate_block_pass)
     expected = QuantumCircuit(2)
     expected.unitary(
         np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]),
         [0, 1])
     self.assertEqual(expected, pass_manager.run(qc))
 def test_y_simplification_rz_sx_x(self):
     """Test that a y gate gets decomposed to x-zx with ibmq basis."""
     qc = QuantumCircuit(1)
     qc.y(0)
     basis = ["id", "rz", "sx", "x", "cx"]
     passmanager = PassManager()
     passmanager.append(BasisTranslator(sel, basis))
     passmanager.append(Optimize1qGatesDecomposition(basis))
     result = passmanager.run(qc)
     expected = QuantumCircuit(1)
     expected.rz(-np.pi, 0)
     expected.x(0)
     msg = f"expected:\n{expected}\nresult:\n{result}"
     self.assertEqual(expected, result, msg=msg)
 def test_short_string(self):
     """Test that a shorter-than-universal string is still rewritten."""
     qc = QuantumCircuit(1)
     qc.h(0)
     qc.ry(np.pi / 2, 0)
     basis = ["sx", "rz"]
     passmanager = PassManager()
     passmanager.append(Optimize1qGatesDecomposition(basis))
     result = passmanager.run(qc)
     expected = QuantumCircuit(1)
     expected.sx(0)
     expected.sx(0)
     msg = f"expected:\n{expected}\nresult:\n{result}"
     self.assertEqual(expected, result, msg=msg)
    def test_classical_conditions_maintained(self):
        """Test that consolidate blocks doesn't drop the classical conditions
        This issue was raised in #2752
        """
        qc = QuantumCircuit(1, 1)
        qc.h(0).c_if(qc.cregs[0], 1)
        qc.measure(0, 0)

        pass_manager = PassManager()
        pass_manager.append(Collect2qBlocks())
        pass_manager.append(ConsolidateBlocks())
        qc1 = pass_manager.run(qc)

        self.assertEqual(qc, qc1)