示例#1
0
    def test_adding_gate_under_different_parameters(self):
        """Verify a gate can be added under different sets of parameters."""
        eq_lib = EquivalenceLibrary()

        theta = Parameter('theta')

        gate_theta = OneQubitOneParamGate(theta)
        equiv_theta = QuantumCircuit(1)
        equiv_theta.p(theta, 0)

        eq_lib.add_equivalence(gate_theta, equiv_theta)

        phi = Parameter('phi')
        gate_phi = OneQubitOneParamGate(phi)
        equiv_phi = QuantumCircuit(1)
        equiv_phi.rz(phi, 0)

        eq_lib.add_equivalence(gate_phi, equiv_phi)

        lam = Parameter('lam')
        gate_query = OneQubitOneParamGate(lam)

        entry = eq_lib.get_entry(gate_query)

        first_expected = QuantumCircuit(1)
        first_expected.p(lam, 0)

        second_expected = QuantumCircuit(1)
        second_expected.rz(lam, 0)

        self.assertEqual(len(entry), 2)
        self.assertEqual(entry[0], first_expected)
        self.assertEqual(entry[1], second_expected)
    def test_multiple_variadic(self):
        """Verify circuit with multiple instances of variadic gate."""
        eq_lib = EquivalenceLibrary()

        # e.g. MSGate
        oneq_gate = VariadicZeroParamGate(1)
        equiv = QuantumCircuit(1)
        equiv.append(OneQubitZeroParamGate(), [0])
        eq_lib.add_equivalence(oneq_gate, equiv)

        twoq_gate = VariadicZeroParamGate(2)
        equiv = QuantumCircuit(2)
        equiv.append(TwoQubitZeroParamGate(), [0, 1])
        eq_lib.add_equivalence(twoq_gate, equiv)

        qc = QuantumCircuit(2)
        qc.append(VariadicZeroParamGate(1), [0])
        qc.append(VariadicZeroParamGate(2), [0, 1])

        dag = circuit_to_dag(qc)

        expected = QuantumCircuit(2)
        expected.append(OneQubitZeroParamGate(), [0])
        expected.append(TwoQubitZeroParamGate(), [0, 1])

        expected_dag = circuit_to_dag(expected)

        pass_ = BasisTranslator(eq_lib, ['1q0p', '2q0p'])
        actual = pass_.run(dag)

        self.assertEqual(actual, expected_dag)
示例#3
0
    def test_adding_gate_and_partially_specified_gate(self):
        """Verify entries will different numbers of parameters will be returned."""
        eq_lib = EquivalenceLibrary()

        theta = Parameter('theta')
        phi = Parameter('phi')

        # e.g. RGate(theta, phi)
        gate_full = OneQubitTwoParamGate(theta, phi)
        equiv_full = QuantumCircuit(1)
        equiv_full.append(U2Gate(theta, phi), [0])

        eq_lib.add_equivalence(gate_full, equiv_full)

        gate_partial = OneQubitTwoParamGate(theta, 0)
        equiv_partial = QuantumCircuit(1)
        equiv_partial.rx(theta, 0)

        eq_lib.add_equivalence(gate_partial, equiv_partial)

        lam = Parameter('lam')
        gate_query = OneQubitTwoParamGate(lam, 0)

        entry = eq_lib.get_entry(gate_query)

        first_expected = QuantumCircuit(1)
        first_expected.append(U2Gate(lam, 0), [0])

        second_expected = QuantumCircuit(1)
        second_expected.rx(lam, 0)

        self.assertEqual(len(entry), 2)
        self.assertEqual(entry[0], first_expected)
        self.assertEqual(entry[1], second_expected)
    def test_two_single_two_gate_substitutions_with_global_phase(self):
        """Verify we correctly unroll gates through a single equivalence with global phase."""
        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1, global_phase=0.2)
        equiv.append(OneQubitOneParamGate(pi), [0])
        equiv.append(OneQubitOneParamGate(pi), [0])

        eq_lib.add_equivalence(gate, equiv)

        qc = QuantumCircuit(1, global_phase=0.1)
        qc.append(OneQubitZeroParamGate(), [0])
        qc.append(OneQubitZeroParamGate(), [0])
        dag = circuit_to_dag(qc)

        expected = QuantumCircuit(1, global_phase=0.1 + 2 * 0.2)
        expected.append(OneQubitOneParamGate(pi), [0])
        expected.append(OneQubitOneParamGate(pi), [0])
        expected.append(OneQubitOneParamGate(pi), [0])
        expected.append(OneQubitOneParamGate(pi), [0])

        expected_dag = circuit_to_dag(expected)

        pass_ = BasisTranslator(eq_lib, ['1q1p'])
        actual = pass_.run(dag)

        self.assertEqual(actual, expected_dag)
    def test_double_substitution_with_global_phase(self):
        """Verify we correctly unroll gates through multiple equivalences with global phase."""
        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1, global_phase=0.2)
        equiv.append(OneQubitOneParamGate(pi), [0])

        eq_lib.add_equivalence(gate, equiv)

        theta = Parameter('theta')
        gate = OneQubitOneParamGate(theta)
        equiv = QuantumCircuit(1, global_phase=0.4)
        equiv.append(OneQubitTwoParamGate(theta, pi / 2), [0])

        eq_lib.add_equivalence(gate, equiv)

        qc = QuantumCircuit(1, global_phase=0.1)
        qc.append(OneQubitZeroParamGate(), [0])
        dag = circuit_to_dag(qc)

        expected = QuantumCircuit(1, global_phase=0.1 + 0.2 + 0.4)
        expected.append(OneQubitTwoParamGate(pi, pi / 2), [0])
        expected_dag = circuit_to_dag(expected)

        pass_ = BasisTranslator(eq_lib, ['1q2p'])
        actual = pass_.run(dag)

        self.assertEqual(actual, expected_dag)
    def test_unroll_twice_until_we_get_to_eqlib(self):
        """Verify we unroll gates until we hit basis_gates."""
        eq_lib = EquivalenceLibrary()

        base_gate = TestGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)

        eq_lib.add_equivalence(base_gate, equiv)

        gate = TestCompositeGate()

        q = QuantumRegister(1, 'q')
        gate.definition = QuantumCircuit(q)
        gate.definition.data = [(TestGate(), [q[0]], [])]

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

        dag = circuit_to_dag(qc)
        out = UnrollCustomDefinitions(eq_lib, ['u3', 'cx']).run(dag)

        expected = QuantumCircuit(1)
        expected.append(TestGate(), [0])
        expected_dag = circuit_to_dag(expected)

        self.assertEqual(out, expected_dag)
示例#7
0
    def test_nested_loop(self):
        """Test a simple if-else with parameters."""
        qubits = [Qubit(), Qubit()]
        clbits = [Clbit(), Clbit()]
        cr = ClassicalRegister(bits=clbits)
        index1 = Parameter("index1")
        alpha = Parameter("alpha")

        gate = OneQubitOneParamGate(alpha)
        equiv = QuantumCircuit([qubits[0]])
        equiv.append(OneQubitZeroParamGate(name="1q0p_2"), [qubits[0]])
        equiv.append(OneQubitOneParamGate(alpha, name="1q1p_2"), [qubits[0]])

        eq_lib = EquivalenceLibrary()
        eq_lib.add_equivalence(gate, equiv)

        circ = QuantumCircuit(qubits, cr)
        with circ.for_loop(range(3), loop_parameter=index1) as ind:
            with circ.while_loop((cr, 0)):
                circ.append(OneQubitOneParamGate(alpha * ind), [qubits[0]])
        dag = circuit_to_dag(circ)
        dag_translated = BasisTranslator(
            eq_lib,
            ["if_else", "for_loop", "while_loop", "1q0p_2", "1q1p_2"]).run(dag)

        expected = QuantumCircuit(qubits, cr)
        with expected.for_loop(range(3), loop_parameter=index1) as ind:
            with expected.while_loop((cr, 0)):
                expected.append(OneQubitZeroParamGate(name="1q0p_2"),
                                [qubits[0]])
                expected.append(
                    OneQubitOneParamGate(alpha * ind, name="1q1p_2"),
                    [qubits[0]])
        dag_expected = circuit_to_dag(expected)
        self.assertEqual(dag_translated, dag_expected)
示例#8
0
    def test_raise_if_gate_entry_shape_mismatch(self):
        """Verify we raise if adding a circuit and gate with different shapes."""
        # This could be relaxed in the future to e.g. support ancilla management.

        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(2)
        equiv.h(0)

        with self.assertRaises(CircuitError):
            eq_lib.add_equivalence(gate, equiv)
示例#9
0
    def test_has_entry(self):
        """Verify we find an entry defined in the library."""

        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)

        eq_lib.add_equivalence(gate, equiv)

        self.assertTrue(eq_lib.has_entry(gate))
        self.assertTrue(eq_lib.has_entry(OneQubitZeroParamGate()))
示例#10
0
    def test_add_single_entry(self):
        """Verify an equivalence added to the library can be retrieved."""
        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)

        eq_lib.add_equivalence(gate, equiv)

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 1)
        self.assertIsNot(entry[0], equiv)
        self.assertEqual(entry[0], equiv)
示例#11
0
    def test_raise_if_gate_equiv_parameter_mismatch(self):
        """Verify we raise if adding a circuit and gate with different sets of parameters."""
        eq_lib = EquivalenceLibrary()

        theta = Parameter('theta')
        phi = Parameter('phi')

        gate = OneQubitOneParamGate(theta)
        equiv = QuantumCircuit(1)
        equiv.p(phi, 0)

        with self.assertRaises(CircuitError):
            eq_lib.add_equivalence(gate, equiv)

        with self.assertRaises(CircuitError):
            eq_lib.set_entry(gate, [equiv])
示例#12
0
    def test_get_through_empty_library_to_base(self):
        """Verify we find an entry defined only in the base library."""
        base = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)
        base.add_equivalence(gate, equiv)

        eq_lib = EquivalenceLibrary(base=base)

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 1)
        self.assertIsNot(entry[0], equiv)
        self.assertEqual(entry[0], equiv)
示例#13
0
    def test_set_entry(self):
        """Verify setting an entry overrides any previously added."""
        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        first_equiv = QuantumCircuit(1)
        first_equiv.h(0)

        eq_lib.add_equivalence(gate, first_equiv)

        second_equiv = QuantumCircuit(1)
        second_equiv.append(U2Gate(0, np.pi), [0])

        eq_lib.set_entry(gate, [second_equiv])

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 1)
        self.assertEqual(entry[0], second_equiv)
    def test_dont_unroll_a_gate_in_eq_lib(self):
        """Verify we don't unroll a gate found in equivalence_library."""
        eq_lib = EquivalenceLibrary()

        gate = TestGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)

        eq_lib.add_equivalence(gate, equiv)

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

        dag = circuit_to_dag(qc)
        out = UnrollCustomDefinitions(eq_lib, ['u3', 'cx']).run(dag)

        expected = qc.copy()
        expected_dag = circuit_to_dag(expected)

        self.assertEqual(out, expected_dag)
示例#15
0
    def test_add_double_entry(self):
        """Verify separately added equivalences can be retrieved."""
        eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        first_equiv = QuantumCircuit(1)
        first_equiv.h(0)

        eq_lib.add_equivalence(gate, first_equiv)

        second_equiv = QuantumCircuit(1)
        second_equiv.append(U2Gate(0, np.pi), [0])

        eq_lib.add_equivalence(gate, second_equiv)

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 2)
        self.assertEqual(entry[0], first_equiv)
        self.assertEqual(entry[1], second_equiv)
示例#16
0
    def test_set_entry(self):
        """Verify we find only equivalences from top when explicitly set."""
        base = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        first_equiv = QuantumCircuit(1)
        first_equiv.h(0)
        base.add_equivalence(gate, first_equiv)

        eq_lib = EquivalenceLibrary(base=base)

        second_equiv = QuantumCircuit(1)
        second_equiv.append(U2Gate(0, np.pi), [0])

        eq_lib.set_entry(gate, [second_equiv])

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 1)
        self.assertEqual(entry[0], second_equiv)
示例#17
0
    def test_add_equivalence(self):
        """Verify we find all equivalences if a gate is added to top and base."""
        base = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        first_equiv = QuantumCircuit(1)
        first_equiv.h(0)
        base.add_equivalence(gate, first_equiv)

        eq_lib = EquivalenceLibrary(base=base)

        second_equiv = QuantumCircuit(1)
        second_equiv.append(U2Gate(0, np.pi), [0])

        eq_lib.add_equivalence(gate, second_equiv)

        entry = eq_lib.get_entry(gate)

        self.assertEqual(len(entry), 2)
        self.assertEqual(entry[0], second_equiv)
        self.assertEqual(entry[1], first_equiv)
示例#18
0
    def test_if_else(self):
        """Test a simple if-else with parameters."""
        qubits = [Qubit(), Qubit()]
        clbits = [Clbit(), Clbit()]
        alpha = Parameter("alpha")
        beta = Parameter("beta")
        gate = OneQubitOneParamGate(alpha)
        equiv = QuantumCircuit([qubits[0]])
        equiv.append(OneQubitZeroParamGate(name="1q0p_2"), [qubits[0]])
        equiv.append(OneQubitOneParamGate(alpha, name="1q1p_2"), [qubits[0]])

        eq_lib = EquivalenceLibrary()
        eq_lib.add_equivalence(gate, equiv)

        circ = QuantumCircuit(qubits, clbits)
        circ.append(OneQubitOneParamGate(beta), [qubits[0]])
        circ.measure(qubits[0], clbits[1])
        with circ.if_test((clbits[1], 0)) as else_:
            circ.append(OneQubitOneParamGate(alpha), [qubits[0]])
            circ.append(TwoQubitZeroParamGate(), qubits)
        with else_:
            circ.append(TwoQubitZeroParamGate(), [qubits[1], qubits[0]])
        dag = circuit_to_dag(circ)
        dag_translated = BasisTranslator(
            eq_lib, ["if_else", "1q0p_2", "1q1p_2", "2q0p"]).run(dag)

        expected = QuantumCircuit(qubits, clbits)
        expected.append(OneQubitZeroParamGate(name="1q0p_2"), [qubits[0]])
        expected.append(OneQubitOneParamGate(beta, name="1q1p_2"), [qubits[0]])
        expected.measure(qubits[0], clbits[1])
        with expected.if_test((clbits[1], 0)) as else_:
            expected.append(OneQubitZeroParamGate(name="1q0p_2"), [qubits[0]])
            expected.append(OneQubitOneParamGate(alpha, name="1q1p_2"),
                            [qubits[0]])
            expected.append(TwoQubitZeroParamGate(), qubits)
        with else_:
            expected.append(TwoQubitZeroParamGate(), [qubits[1], qubits[0]])
        dag_expected = circuit_to_dag(expected)
        self.assertEqual(dag_translated, dag_expected)
示例#19
0
    def test_parameter_in_parameter_out(self):
        """Verify query parameters will be included in returned entry."""
        eq_lib = EquivalenceLibrary()

        theta = Parameter('theta')

        gate = OneQubitOneParamGate(theta)
        equiv = QuantumCircuit(1)
        equiv.p(theta, 0)

        eq_lib.add_equivalence(gate, equiv)

        phi = Parameter('phi')
        gate_phi = OneQubitOneParamGate(phi)

        entry = eq_lib.get_entry(gate_phi)

        expected = QuantumCircuit(1)
        expected.p(phi, 0)

        self.assertEqual(len(entry), 1)
        self.assertEqual(entry[0], expected)
示例#20
0
    def test_partial_parameter_in_parameter_out(self):
        """Verify numeric query parameters will be included in returned entry."""
        eq_lib = EquivalenceLibrary()

        theta = Parameter('theta')
        phi = Parameter('phi')

        gate = OneQubitTwoParamGate(theta, phi)
        equiv = QuantumCircuit(1)
        equiv.u(theta, phi, 0, 0)

        eq_lib.add_equivalence(gate, equiv)

        lam = Parameter('lam')
        gate_partial = OneQubitTwoParamGate(lam, 1.59)

        entry = eq_lib.get_entry(gate_partial)

        expected = QuantumCircuit(1)
        expected.u(lam, 1.59, 0, 0)

        self.assertEqual(len(entry), 1)
        self.assertEqual(entry[0], expected)
    def test_diamond_path(self):
        """Verify we find a path when there are multiple paths to the target basis."""
        eq_lib = EquivalenceLibrary()

        # Path 1: 1q0p -> 1q1p(pi) -> 1q2p(pi, pi/2)

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.append(OneQubitOneParamGate(pi), [0])

        eq_lib.add_equivalence(gate, equiv)

        theta = Parameter('theta')
        gate = OneQubitOneParamGate(theta)
        equiv = QuantumCircuit(1)
        equiv.append(OneQubitTwoParamGate(theta, pi / 2), [0])

        eq_lib.add_equivalence(gate, equiv)

        # Path 2: 1q0p -> 1q1p_prime(pi/2) -> 1q2p(2 * pi/2, pi/2)

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.append(OneQubitOneParamPrimeGate(pi / 2), [0])

        eq_lib.add_equivalence(gate, equiv)

        alpha = Parameter('alpha')
        gate = OneQubitOneParamPrimeGate(alpha)
        equiv = QuantumCircuit(1)
        equiv.append(OneQubitTwoParamGate(2 * alpha, pi / 2), [0])

        eq_lib.add_equivalence(gate, equiv)

        qc = QuantumCircuit(1)
        qc.append(OneQubitZeroParamGate(), [0])
        dag = circuit_to_dag(qc)

        expected = QuantumCircuit(1)
        expected.append(OneQubitTwoParamGate(pi, pi / 2), [0])
        expected_dag = circuit_to_dag(expected)

        pass_ = BasisTranslator(eq_lib, ['1q2p'])
        actual = pass_.run(dag)

        self.assertEqual(actual, expected_dag)
示例#22
0
    def test_has_entry_in_base(self):
        """Verify we find an entry defined in the base library."""

        base_eq_lib = EquivalenceLibrary()

        gate = OneQubitZeroParamGate()
        equiv = QuantumCircuit(1)
        equiv.h(0)

        base_eq_lib.add_equivalence(gate, equiv)

        eq_lib = EquivalenceLibrary(base=base_eq_lib)

        self.assertTrue(eq_lib.has_entry(gate))
        self.assertTrue(eq_lib.has_entry(OneQubitZeroParamGate()))

        gate = OneQubitZeroParamGate()
        equiv2 = QuantumCircuit(1)
        equiv.append(U2Gate(0, np.pi), [0])

        eq_lib.add_equivalence(gate, equiv2)

        self.assertTrue(eq_lib.has_entry(gate))
        self.assertTrue(eq_lib.has_entry(OneQubitZeroParamGate()))
示例#23
0
phi = Parameter('phi')
lamda = Parameter('lamda')

u3 = U3Gate(theta, phi, lamda)
u2 = U2Gate(theta, phi)
u1 = U1Gate(theta)
ccx = CCXGate()
        
q = QuantumRegister(1, 'q')
equiv_u3 = QuantumCircuit(q)
equiv_u3.append(RZGate(phi+(pi/2)), [q[0]], [])
equiv_u3.append(HGate(),[q[0]], [] )
equiv_u3.append(RZGate(theta),[q[0]], [])
equiv_u3.append(HGate(), [q[0]], [])
equiv_u3.append(RZGate(lamda-(pi/2)),[q[0]], 0)
eq_lib.add_equivalence(u3, equiv_u3)


q = QuantumRegister(1, 'q')
equiv_u2 = QuantumCircuit(q)
equiv_u2.append(RZGate(theta+(pi/2)), [q[0]], [])
equiv_u2.append(HGate(),[q[0]], [] )
equiv_u2.append(RZGate(pi/2),[q[0]], [])
equiv_u2.append(HGate(), [q[0]], [])
equiv_u2.append(RZGate(phi-(pi/2)),[q[0]], 0)
eq_lib.add_equivalence(u2, equiv_u2)

q = QuantumRegister(1, 'q')
equiv_u1 = QuantumCircuit(q)
equiv_u1.append(RZGate(theta), [q[0]], [])
eq_lib.add_equivalence(u1, equiv_u1)