def test_twoq_equivalence(self):
     """Test GMS on 2 qubits is same as RXX."""
     circuit = GMS(num_qubits=2, theta=[[0, np.pi / 3], [0, 0]])
     expected = RXXGate(np.pi / 3)
     expected = Operator(expected)
     simulated = Operator(circuit)
     self.assertTrue(expected.equiv(simulated))
Example #2
0
def canonical_matrix(a=0.0, b=0.0, c=0.0):
    """
    Produces the matrix form of a "canonical operator"

        exp(-i (a XX + b YY + c ZZ)) .
    """
    return RXXGate(2 * a).to_matrix() @ RYYGate(2 * b).to_matrix() @ RZZGate(-2 * c).to_matrix()
Example #3
0
    def test_euler_basis_selection(self):
        """Verify decomposition uses euler_basis for 1q gates."""

        euler_bases = [
            ('U3', ['u3']),
            ('U1X', ['u1', 'rx']),
            ('RR', ['r']),
            ('ZYZ', ['rz', 'ry']),
            ('ZXZ', ['rz', 'rx']),
            ('XYX', ['rx', 'ry']),
        ]

        kak_gates = [
            (CXGate(), 'cx'),
            (CZGate(), 'cz'),
            (iSwapGate(), 'iswap'),
            (RXXGate(np.pi / 2), 'rxx'),
        ]

        for basis in product(euler_bases, kak_gates):
            (euler_basis, oneq_gates), (kak_gate, kak_gate_name) = basis

            with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
                decomposer = TwoQubitBasisDecomposer(kak_gate,
                                                     euler_basis=euler_basis)
                unitary = random_unitary(4)
                self.check_exact_decomposition(unitary.data, decomposer)

                decomposition_basis = set(decomposer(unitary).count_ops())
                requested_basis = set(oneq_gates + [kak_gate_name])
                self.assertTrue(decomposition_basis.issubset(requested_basis))
Example #4
0
 def test_operations(self):
     self.assertEqual(self.empty_target.operations, [])
     ibm_expected = [
         RZGate(self.theta),
         IGate(),
         SXGate(),
         XGate(),
         CXGate(),
         Measure()
     ]
     for gate in ibm_expected:
         self.assertIn(gate, self.ibm_target.operations)
     aqt_expected = [
         RZGate(self.theta),
         RXGate(self.theta),
         RYGate(self.theta),
         RGate(self.theta, self.phi),
         RXXGate(self.theta),
     ]
     for gate in aqt_expected:
         self.assertIn(gate, self.aqt_target.operations)
     fake_expected = [
         UGate(self.fake_backend._theta, self.fake_backend._phi,
               self.fake_backend._lam),
         CXGate(),
         Measure(),
         ECRGate(),
         RXGate(math.pi / 6),
         RXGate(self.fake_backend._theta),
     ]
     for gate in fake_expected:
         self.assertIn(gate, self.fake_backend_target.operations)
     ideal_sim_expected = [
         UGate(self.theta, self.phi, self.lam),
         RXGate(self.theta),
         RYGate(self.theta),
         RZGate(self.theta),
         CXGate(),
         ECRGate(),
         CCXGate(),
         Measure(),
     ]
     for gate in ideal_sim_expected:
         self.assertIn(gate, self.ideal_sim_target.operations)
Example #5
0
    def setUp(self):
        super().setUp()
        self.fake_backend = FakeBackendV2()
        self.fake_backend_target = self.fake_backend.target
        self.theta = Parameter("theta")
        self.phi = Parameter("phi")
        self.ibm_target = Target()
        i_props = {
            (0, ): InstructionProperties(duration=35.5e-9, error=0.000413),
            (1, ): InstructionProperties(duration=35.5e-9, error=0.000502),
            (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003),
            (3, ): InstructionProperties(duration=35.5e-9, error=0.000614),
            (4, ): InstructionProperties(duration=35.5e-9, error=0.006149),
        }
        self.ibm_target.add_instruction(IGate(), i_props)
        rz_props = {
            (0, ): InstructionProperties(duration=0, error=0),
            (1, ): InstructionProperties(duration=0, error=0),
            (2, ): InstructionProperties(duration=0, error=0),
            (3, ): InstructionProperties(duration=0, error=0),
            (4, ): InstructionProperties(duration=0, error=0),
        }
        self.ibm_target.add_instruction(RZGate(self.theta), rz_props)
        sx_props = {
            (0, ): InstructionProperties(duration=35.5e-9, error=0.000413),
            (1, ): InstructionProperties(duration=35.5e-9, error=0.000502),
            (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003),
            (3, ): InstructionProperties(duration=35.5e-9, error=0.000614),
            (4, ): InstructionProperties(duration=35.5e-9, error=0.006149),
        }
        self.ibm_target.add_instruction(SXGate(), sx_props)
        x_props = {
            (0, ): InstructionProperties(duration=35.5e-9, error=0.000413),
            (1, ): InstructionProperties(duration=35.5e-9, error=0.000502),
            (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003),
            (3, ): InstructionProperties(duration=35.5e-9, error=0.000614),
            (4, ): InstructionProperties(duration=35.5e-9, error=0.006149),
        }
        self.ibm_target.add_instruction(XGate(), x_props)
        cx_props = {
            (3, 4): InstructionProperties(duration=270.22e-9, error=0.00713),
            (4, 3): InstructionProperties(duration=305.77e-9, error=0.00713),
            (3, 1): InstructionProperties(duration=462.22e-9, error=0.00929),
            (1, 3): InstructionProperties(duration=497.77e-9, error=0.00929),
            (1, 2): InstructionProperties(duration=227.55e-9, error=0.00659),
            (2, 1): InstructionProperties(duration=263.11e-9, error=0.00659),
            (0, 1): InstructionProperties(duration=519.11e-9, error=0.01201),
            (1, 0): InstructionProperties(duration=554.66e-9, error=0.01201),
        }
        self.ibm_target.add_instruction(CXGate(), cx_props)
        measure_props = {
            (0, ): InstructionProperties(duration=5.813e-6, error=0.0751),
            (1, ): InstructionProperties(duration=5.813e-6, error=0.0225),
            (2, ): InstructionProperties(duration=5.813e-6, error=0.0146),
            (3, ): InstructionProperties(duration=5.813e-6, error=0.0215),
            (4, ): InstructionProperties(duration=5.813e-6, error=0.0333),
        }
        self.ibm_target.add_instruction(Measure(), measure_props)

        self.aqt_target = Target(description="AQT Target")
        rx_props = {
            (0, ): None,
            (1, ): None,
            (2, ): None,
            (3, ): None,
            (4, ): None,
        }
        self.aqt_target.add_instruction(RXGate(self.theta), rx_props)
        ry_props = {
            (0, ): None,
            (1, ): None,
            (2, ): None,
            (3, ): None,
            (4, ): None,
        }
        self.aqt_target.add_instruction(RYGate(self.theta), ry_props)
        rz_props = {
            (0, ): None,
            (1, ): None,
            (2, ): None,
            (3, ): None,
            (4, ): None,
        }
        self.aqt_target.add_instruction(RZGate(self.theta), rz_props)
        r_props = {
            (0, ): None,
            (1, ): None,
            (2, ): None,
            (3, ): None,
            (4, ): None,
        }
        self.aqt_target.add_instruction(RGate(self.theta, self.phi), r_props)
        rxx_props = {
            (0, 1): None,
            (0, 2): None,
            (0, 3): None,
            (0, 4): None,
            (1, 0): None,
            (2, 0): None,
            (3, 0): None,
            (4, 0): None,
            (1, 2): None,
            (1, 3): None,
            (1, 4): None,
            (2, 1): None,
            (3, 1): None,
            (4, 1): None,
            (2, 3): None,
            (2, 4): None,
            (3, 2): None,
            (4, 2): None,
            (3, 4): None,
            (4, 3): None,
        }
        self.aqt_target.add_instruction(RXXGate(self.theta), rxx_props)
        measure_props = {
            (0, ): None,
            (1, ): None,
            (2, ): None,
            (3, ): None,
            (4, ): None,
        }
        self.aqt_target.add_instruction(Measure(), measure_props)
        self.empty_target = Target()
        self.ideal_sim_target = Target(num_qubits=3,
                                       description="Ideal Simulator")
        self.lam = Parameter("lam")
        for inst in [
                UGate(self.theta, self.phi, self.lam),
                RXGate(self.theta),
                RYGate(self.theta),
                RZGate(self.theta),
                CXGate(),
                ECRGate(),
                CCXGate(),
                Measure(),
        ]:
            self.ideal_sim_target.add_instruction(inst, {None: None})
Example #6
0
class TestTwoQubitDecomposeExact(CheckDecompositions):
    """Test TwoQubitBasisDecomposer() for exact decompositions
    """

    def test_cnot_rxx_decompose(self):
        """Verify CNOT decomposition into RXX gate is correct"""
        cnot = Operator(CXGate())
        decomps = [cnot_rxx_decompose(),
                   cnot_rxx_decompose(plus_ry=True, plus_rxx=True),
                   cnot_rxx_decompose(plus_ry=True, plus_rxx=False),
                   cnot_rxx_decompose(plus_ry=False, plus_rxx=True),
                   cnot_rxx_decompose(plus_ry=False, plus_rxx=False)]
        for decomp in decomps:
            self.assertTrue(cnot.equiv(decomp))

    @combine(seed=range(10), name='test_exact_two_qubit_cnot_decompose_random_{seed}')
    def test_exact_two_qubit_cnot_decompose_random(self, seed):
        """Verify exact CNOT decomposition for random Haar 4x4 unitary (seed={seed}).
        """
        unitary = random_unitary(4, seed=seed)
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    def test_exact_two_qubit_cnot_decompose_paulis(self):
        """Verify exact CNOT decomposition for Paulis
        """
        unitary = Operator.from_label('XZ')
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    @combine(seed=range(10), name='test_exact_supercontrolled_decompose_random_{seed}')
    def test_exact_supercontrolled_decompose_random(self, seed):
        """Exact decomposition for random supercontrolled basis and random target (seed={seed})"""
        # pylint: disable=invalid-name
        k1 = np.kron(random_unitary(2, seed=seed).data, random_unitary(2, seed=seed + 1).data)
        k2 = np.kron(random_unitary(2, seed=seed + 2).data, random_unitary(2, seed=seed + 3).data)
        basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2
        decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary))
        self.check_exact_decomposition(random_unitary(4, seed=seed + 4).data, decomposer)

    def test_exact_nonsupercontrolled_decompose(self):
        """Check that the nonsupercontrolled basis throws a warning"""
        with self.assertWarns(UserWarning, msg="Supposed to warn when basis non-supercontrolled"):
            TwoQubitBasisDecomposer(UnitaryGate(Ud(np.pi / 4, 0.2, 0.1)))

    def test_cx_equivalence_0cx(self, seed=0):
        """Check circuits with  0 cx gates locally equivalent to identity
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=6)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 0)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_1cx(self, seed=1):
        """Check circuits with  1 cx gates locally equivalent to a cx
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=12)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 1)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_2cx(self, seed=2):
        """Check circuits with  2 cx gates locally equivalent to some circuit with 2 cx.
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=18)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        qc.cx(qr[0], qr[1])

        qc.u(rnd[12], rnd[13], rnd[14], qr[0])
        qc.u(rnd[15], rnd[16], rnd[17], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 2)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_cx_equivalence_3cx(self, seed=3):
        """Check circuits with 3 cx gates are outside the 0, 1, and 2 qubit regions.
        """
        state = np.random.default_rng(seed)
        rnd = 2 * np.pi * state.random(size=24)

        qr = QuantumRegister(2, name='q')
        qc = QuantumCircuit(qr)

        qc.u(rnd[0], rnd[1], rnd[2], qr[0])
        qc.u(rnd[3], rnd[4], rnd[5], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[6], rnd[7], rnd[8], qr[0])
        qc.u(rnd[9], rnd[10], rnd[11], qr[1])

        qc.cx(qr[0], qr[1])

        qc.u(rnd[12], rnd[13], rnd[14], qr[0])
        qc.u(rnd[15], rnd[16], rnd[17], qr[1])

        qc.cx(qr[1], qr[0])

        qc.u(rnd[18], rnd[19], rnd[20], qr[0])
        qc.u(rnd[21], rnd[22], rnd[23], qr[1])

        sim = UnitarySimulatorPy()
        unitary = execute(qc, sim).result().get_unitary()
        self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(unitary), 3)
        self.assertTrue(Operator(two_qubit_cnot_decompose(unitary)).equiv(unitary))

    def test_seed_289(self):
        """This specific case failed when PR #3585 was applied
        See https://github.com/Qiskit/qiskit-terra/pull/3652"""
        unitary = random_unitary(4, seed=289)
        self.check_exact_decomposition(unitary.data, two_qubit_cnot_decompose)

    @combine(seed=range(10),
             euler_bases=[('U3', ['u3']), ('U', ['u']), ('U1X', ['u1', 'rx']), ('RR', ['r']),
                          ('PSX', ['p', 'sx']), ('ZYZ', ['rz', 'ry']), ('ZXZ', ['rz', 'rx']),
                          ('XYX', ['rx', 'ry']), ('ZSX', ['rz', 'sx'])],
             kak_gates=[(CXGate(), 'cx'), (CZGate(), 'cz'), (iSwapGate(), 'iswap'),
                        (RXXGate(np.pi / 2), 'rxx')],
             name='test_euler_basis_selection_{seed}_{euler_bases[0]}_{kak_gates[1]}')
    def test_euler_basis_selection(self, euler_bases, kak_gates, seed):
        """Verify decomposition uses euler_basis for 1q gates."""
        (euler_basis, oneq_gates) = euler_bases
        (kak_gate, kak_gate_name) = kak_gates

        with self.subTest(euler_basis=euler_basis, kak_gate=kak_gate):
            decomposer = TwoQubitBasisDecomposer(kak_gate, euler_basis=euler_basis)
            unitary = random_unitary(4, seed=seed)
            self.check_exact_decomposition(unitary.data, decomposer)

            decomposition_basis = set(decomposer(unitary).count_ops())
            requested_basis = set(oneq_gates + [kak_gate_name])
            self.assertTrue(
                decomposition_basis.issubset(requested_basis))
Example #7
0
class TestCollect2qBlocks(QiskitTestCase):
    """
    Tests to verify that blocks of 2q interactions are found correctly.
    """
    def test_blocks_in_topological_order(self):
        """the pass returns blocks in correct topological order
                                                    ______
        q0:--[p]-------.----      q0:-------------|      |--
                       |                 ______   |  U2  |
        q1:--[u]--(+)-(+)---   =  q1:---|      |--|______|--
                   |                    |  U1  |
        q2:--------.--------      q2:---|______|------------
        """
        qr = QuantumRegister(3, "qr")
        qc = QuantumCircuit(qr)
        qc.p(0.5, qr[0])
        qc.u(0.0, 0.2, 0.6, qr[1])
        qc.cx(qr[2], qr[1])
        qc.cx(qr[0], qr[1])
        dag = circuit_to_dag(qc)

        topo_ops = list(dag.topological_op_nodes())
        block_1 = [topo_ops[1], topo_ops[2]]
        block_2 = [topo_ops[0], topo_ops[3]]

        pass_ = Collect2qBlocks()
        pass_.run(dag)
        self.assertTrue(pass_.property_set["block_list"], [block_1, block_2])

    def test_block_interrupted_by_gate(self):
        """Test that blocks interrupted by a gate that can't be added
        to the block can be collected correctly

        This was raised in #2775 where a measure in the middle of a block
        stopped the block collection from working properly. This was because
        the pass didn't expect to have measures in the middle of the circuit.

        blocks : [['cx', 'id', 'id', 'id'], ['id', 'cx']]

                ┌───┐┌───┐┌─┐     ┌───┐┌───┐
        q_0: |0>┤ X ├┤ I ├┤M├─────┤ I ├┤ X ├
                └─┬─┘├───┤└╥┘┌───┐└───┘└─┬─┘
        q_1: |0>──■──┤ I ├─╫─┤ I ├───────■──
                     └───┘ ║ └───┘
         c_0: 0 ═══════════╩════════════════

        """
        qc = QuantumCircuit(2, 1)
        qc.cx(1, 0)
        qc.i(0)
        qc.i(1)
        qc.measure(0, 0)
        qc.i(0)
        qc.i(1)
        qc.cx(1, 0)

        dag = circuit_to_dag(qc)
        pass_ = Collect2qBlocks()
        pass_.run(dag)

        # list from Collect2QBlocks of nodes that it should have put into blocks
        good_names = ["cx", "u1", "u2", "u3", "id"]
        dag_nodes = [
            node for node in dag.topological_op_nodes()
            if node.name in good_names
        ]

        # we have to convert them to sets as the ordering can be different
        # but equivalent between python 3.5 and 3.7
        # there is no implied topology in a block, so this isn't an issue
        dag_nodes = [set(dag_nodes[:4]), set(dag_nodes[4:])]
        pass_nodes = [set(bl) for bl in pass_.property_set["block_list"]]

        self.assertEqual(dag_nodes, pass_nodes)

    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_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 ═══════════╡     ╞═══╡     ╞═══════╡     ╞╡     ╞
                            └─────┘   └─────┘       └─────┘└─────┘

        Previously the blocks collected were : [['p', 'p', 'p', 'cx', 'cx', 'cx']]
        This is now corrected to : [['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"]])

    @unpack
    @data(
        (CXGate(), U1Gate(0.1), U2Gate(0.2, 0.3)),
        (RXXGate(pi / 2), RZGate(0.1), RXGate(pi / 2)),
        (
            Gate("custom2qgate", 2, []),
            Gate("custom1qgate1", 1, []),
            Gate("custom1qgate2", 1, []),
        ),
    )
    def test_collect_arbitrary_gates(self, twoQ_gate, oneQ_gate1, oneQ_gate2):
        """Validate we can collect blocks irrespective of gate types in the circuit."""

        qc = QuantumCircuit(3)

        # Block 1 - q[0] and q[1]
        qc.append(oneQ_gate1, [0])
        qc.append(oneQ_gate2, [1])
        qc.append(twoQ_gate, [0, 1])
        qc.append(oneQ_gate1, [0])
        qc.append(oneQ_gate2, [1])

        # Block 2 - q[1] and q[2]
        qc.append(oneQ_gate1, [1])
        qc.append(oneQ_gate2, [2])
        qc.append(twoQ_gate, [1, 2])
        qc.append(oneQ_gate1, [1])
        qc.append(oneQ_gate2, [2])

        # Block 3 - q[0] and q[1]
        qc.append(oneQ_gate1, [0])
        qc.append(oneQ_gate2, [1])
        qc.append(twoQ_gate, [0, 1])
        qc.append(oneQ_gate1, [0])
        qc.append(oneQ_gate2, [1])

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

        pass_manager.run(qc)
        self.assertEqual(len(pass_manager.property_set["block_list"]), 3)