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)
def test_raise_for_opaque_not_in_eq_lib(self): """Verify we raise for an opaque gate not in basis_gates or eq_lib.""" eq_lib = EquivalenceLibrary() gate = TestGate() qc = QuantumCircuit(1) qc.append(gate, [0]) dag = circuit_to_dag(qc) with self.assertRaisesRegex(QiskitError, 'Cannot unroll'): UnrollCustomDefinitions(eq_lib, ['u3', 'cx']).run(dag)
def test_basic_unroll(self): """Test decompose a single H into u2.""" qr = QuantumRegister(1, "qr") circuit = QuantumCircuit(qr) circuit.h(qr[0]) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ["u2"]) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ["u2"]) unrolled_dag = pass_.run(dag) op_nodes = unrolled_dag.op_nodes() self.assertEqual(len(op_nodes), 1) self.assertEqual(op_nodes[0].name, "u2")
def test_unroll_no_basis(self): """Test when a given gate has no decompositions.""" qr = QuantumRegister(1, "qr") cr = ClassicalRegister(1, "cr") circuit = QuantumCircuit(qr, cr) circuit.h(qr) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, []) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, []) with self.assertRaises(QiskitError): pass_.run(dag)
def test_dont_unroll_a_gate_in_basis_gates(self): """Verify we don't unroll a gate in basis_gates.""" eq_lib = EquivalenceLibrary() gate = TestGate() qc = QuantumCircuit(1) qc.append(gate, [0]) dag = circuit_to_dag(qc) out = UnrollCustomDefinitions(eq_lib, ['u3', 'cx', 'tg']).run(dag) expected = qc.copy() expected_dag = circuit_to_dag(expected) self.assertEqual(out, expected_dag)
def test_unroll_toffoli(self): """Test unroll toffoli on multi regs to h, t, tdg, cx.""" qr1 = QuantumRegister(2, "qr1") qr2 = QuantumRegister(1, "qr2") circuit = QuantumCircuit(qr1, qr2) circuit.ccx(qr1[0], qr1[1], qr2[0]) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ["h", "t", "tdg", "cx"]) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ["h", "t", "tdg", "cx"]) unrolled_dag = pass_.run(dag) op_nodes = unrolled_dag.op_nodes() self.assertEqual(len(op_nodes), 15) for node in op_nodes: self.assertIn(node.name, ["h", "t", "tdg", "cx"])
def test_definition_unroll_parameterized(self): """Verify that unrolling complex gates with parameters does not raise.""" qr = QuantumRegister(2) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.cp(theta, qr[1], qr[0]) qc.cp(theta * theta, qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(std_eqlib, ['p', 'cx']) dag = pass_.run(dag) out_dag = BasisTranslator(std_eqlib, ['p', 'cx']).run(dag) self.assertEqual(out_dag.count_ops(), {'p': 6, 'cx': 4})
def test_simple_unroll_parameterized_without_expressions(self): """Verify unrolling parameterized gates without expressions.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.rz(theta, qr[0]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(std_eqlib, ['u1', 'cx']) dag = pass_.run(dag) unrolled_dag = BasisTranslator(std_eqlib, ['u1', 'cx']).run(dag) expected = QuantumCircuit(qr, global_phase=-theta / 2) expected.append(U1Gate(theta), [qr[0]]) self.assertEqual(circuit_to_dag(expected), unrolled_dag)
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)
def test_unroll_gate_until_reach_basis_gates(self): """Verify we unroll gates until we hit basis_gates.""" eq_lib = EquivalenceLibrary() gate = TestCompositeGate() q = QuantumRegister(1, "q") gate.definition = QuantumCircuit(q) gate.definition.data = [(TestGate(), [q[0]], [])] qc = QuantumCircuit(q) qc.append(gate, [0]) dag = circuit_to_dag(qc) out = UnrollCustomDefinitions(eq_lib, ["u3", "cx", "tg"]).run(dag) expected = QuantumCircuit(1) expected.append(TestGate(), [0]) expected_dag = circuit_to_dag(expected) self.assertEqual(out, expected_dag)
def test_simple_unroll_parameterized_with_expressions(self): """Verify unrolling parameterized gates with expressions.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') phi = Parameter('phi') sum_ = theta + phi qc.rz(sum_, qr[0]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(std_eqlib, ['p', 'cx']) dag = pass_.run(dag) unrolled_dag = BasisTranslator(std_eqlib, ['p', 'cx']).run(dag) expected = QuantumCircuit(qr, global_phase=-sum_ / 2) expected.p(sum_, qr[0]) self.assertEqual(circuit_to_dag(expected), unrolled_dag)
def test_unroll_1q_chain_conditional(self): """Test unroll chain of 1-qubit gates interrupted by conditional. """ qr = QuantumRegister(1, 'qr') cr = ClassicalRegister(1, 'cr') circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.tdg(qr) circuit.z(qr) circuit.t(qr) circuit.ry(0.5, qr) circuit.rz(0.3, qr) circuit.rx(0.1, qr) circuit.measure(qr, cr) circuit.x(qr).c_if(cr, 1) circuit.y(qr).c_if(cr, 1) circuit.z(qr).c_if(cr, 1) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ['u1', 'u2', 'u3']) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ['u1', 'u2', 'u3']) unrolled_dag = pass_.run(dag) # Pick up -1 * 0.3 / 2 global phase for one RZ -> U1. ref_circuit = QuantumCircuit(qr, cr, global_phase=-0.3 / 2) ref_circuit.append(U2Gate(0, pi), [qr[0]]) ref_circuit.append(U1Gate(-pi / 4), [qr[0]]) ref_circuit.append(U1Gate(pi), [qr[0]]) ref_circuit.append(U1Gate(pi / 4), [qr[0]]) ref_circuit.append(U3Gate(0.5, 0, 0), [qr[0]]) ref_circuit.append(U1Gate(0.3), [qr[0]]) ref_circuit.append(U3Gate(0.1, -pi / 2, pi / 2), [qr[0]]) ref_circuit.measure(qr[0], cr[0]) ref_circuit.append(U3Gate(pi, 0, pi), [qr[0]]).c_if(cr, 1) ref_circuit.append(U3Gate(pi, pi / 2, pi / 2), [qr[0]]).c_if(cr, 1) ref_circuit.append(U1Gate(pi), [qr[0]]).c_if(cr, 1) ref_dag = circuit_to_dag(ref_circuit) self.assertEqual(unrolled_dag, ref_dag)
def test_unroll_1q_chain_conditional(self): """Test unroll chain of 1-qubit gates interrupted by conditional. """ qr = QuantumRegister(1, 'qr') cr = ClassicalRegister(1, 'cr') circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.tdg(qr) circuit.z(qr) circuit.t(qr) circuit.ry(0.5, qr) circuit.rz(0.3, qr) circuit.rx(0.1, qr) circuit.measure(qr, cr) circuit.x(qr).c_if(cr, 1) circuit.y(qr).c_if(cr, 1) circuit.z(qr).c_if(cr, 1) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ['u1', 'u2', 'u3']) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ['u1', 'u2', 'u3']) unrolled_dag = pass_.run(dag) ref_circuit = QuantumCircuit(qr, cr) ref_circuit.u2(0, pi, qr[0]) ref_circuit.u1(-pi / 4, qr[0]) ref_circuit.u1(pi, qr[0]) ref_circuit.u1(pi / 4, qr[0]) ref_circuit.u3(0.5, 0, 0, qr[0]) ref_circuit.u1(0.3, qr[0]) ref_circuit.u3(0.1, -pi / 2, pi / 2, qr[0]) ref_circuit.measure(qr[0], cr[0]) ref_circuit.u3(pi, 0, pi, qr[0]).c_if(cr, 1) ref_circuit.u3(pi, pi / 2, pi / 2, qr[0]).c_if(cr, 1) ref_circuit.u1(pi, qr[0]).c_if(cr, 1) ref_dag = circuit_to_dag(ref_circuit) self.assertEqual(unrolled_dag, ref_dag)
def test_unrolling_parameterized_composite_gates(self): """Verify unrolling circuits with parameterized composite gates.""" mock_sel = EquivalenceLibrary(base=std_eqlib) qr1 = QuantumRegister(2) subqc = QuantumCircuit(qr1) theta = Parameter('theta') subqc.rz(theta, qr1[0]) subqc.cx(qr1[0], qr1[1]) subqc.rz(theta, qr1[1]) # Expanding across register with shared parameter qr2 = QuantumRegister(4) qc = QuantumCircuit(qr2) sub_instr = circuit_to_instruction(subqc, equivalence_library=mock_sel) qc.append(sub_instr, [qr2[0], qr2[1]]) qc.append(sub_instr, [qr2[2], qr2[3]]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(mock_sel, ['p', 'cx']) dag = pass_.run(dag) out_dag = BasisTranslator(mock_sel, ['p', 'cx']).run(dag) # Pick up -1 * theta / 2 global phase four twice (once for each RZ -> P # in each of the two sub_instr instructions). expected = QuantumCircuit(qr2, global_phase=-1 * 4 * theta / 2.0) expected.p(theta, qr2[0]) expected.p(theta, qr2[2]) expected.cx(qr2[0], qr2[1]) expected.cx(qr2[2], qr2[3]) expected.p(theta, qr2[1]) expected.p(theta, qr2[3]) self.assertEqual(circuit_to_dag(expected), out_dag) # Expanding across register with shared parameter qc = QuantumCircuit(qr2) phi = Parameter('phi') gamma = Parameter('gamma') sub_instr = circuit_to_instruction(subqc, {theta: phi}, mock_sel) qc.append(sub_instr, [qr2[0], qr2[1]]) sub_instr = circuit_to_instruction(subqc, {theta: gamma}, mock_sel) qc.append(sub_instr, [qr2[2], qr2[3]]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(mock_sel, ['p', 'cx']) dag = pass_.run(dag) out_dag = BasisTranslator(mock_sel, ['p', 'cx']).run(dag) expected = QuantumCircuit(qr2, global_phase=-1 * (2 * phi + 2 * gamma) / 2.0) expected.p(phi, qr2[0]) expected.p(gamma, qr2[2]) expected.cx(qr2[0], qr2[1]) expected.cx(qr2[2], qr2[3]) expected.p(phi, qr2[1]) expected.p(gamma, qr2[3]) self.assertEqual(circuit_to_dag(expected), out_dag)
def test_unrolling_parameterized_composite_gates(self): """Verify unrolling circuits with parameterized composite gates.""" mock_sel = EquivalenceLibrary(base=std_eqlib) qr1 = QuantumRegister(2) subqc = QuantumCircuit(qr1) theta = Parameter('theta') subqc.rz(theta, qr1[0]) subqc.cx(qr1[0], qr1[1]) subqc.rz(theta, qr1[1]) # Expanding across register with shared parameter qr2 = QuantumRegister(4) qc = QuantumCircuit(qr2) sub_instr = circuit_to_instruction(subqc, equivalence_library=mock_sel) qc.append(sub_instr, [qr2[0], qr2[1]]) qc.append(sub_instr, [qr2[2], qr2[3]]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(mock_sel, ['u1', 'cx']) dag = pass_.run(dag) out_dag = BasisTranslator(mock_sel, ['u1', 'cx']).run(dag) expected = QuantumCircuit(qr2) expected.u1(theta, qr2[0]) expected.u1(theta, qr2[2]) expected.cx(qr2[0], qr2[1]) expected.cx(qr2[2], qr2[3]) expected.u1(theta, qr2[1]) expected.u1(theta, qr2[3]) self.assertEqual(circuit_to_dag(expected), out_dag) # Expanding across register with shared parameter qc = QuantumCircuit(qr2) phi = Parameter('phi') gamma = Parameter('gamma') sub_instr = circuit_to_instruction(subqc, {theta: phi}, mock_sel) qc.append(sub_instr, [qr2[0], qr2[1]]) sub_instr = circuit_to_instruction(subqc, {theta: gamma}, mock_sel) qc.append(sub_instr, [qr2[2], qr2[3]]) dag = circuit_to_dag(qc) pass_ = UnrollCustomDefinitions(mock_sel, ['u1', 'cx']) dag = pass_.run(dag) out_dag = BasisTranslator(mock_sel, ['u1', 'cx']).run(dag) expected = QuantumCircuit(qr2) expected.u1(phi, qr2[0]) expected.u1(gamma, qr2[2]) expected.cx(qr2[0], qr2[1]) expected.cx(qr2[2], qr2[3]) expected.u1(phi, qr2[1]) expected.u1(gamma, qr2[3]) self.assertEqual(circuit_to_dag(expected), out_dag)
def test_unroll_all_instructions(self): """Test unrolling a circuit containing all standard instructions. """ qr = QuantumRegister(3, 'qr') cr = ClassicalRegister(3, 'cr') circuit = QuantumCircuit(qr, cr) circuit.crx(0.5, qr[1], qr[2]) circuit.cry(0.5, qr[1], qr[2]) circuit.ccx(qr[0], qr[1], qr[2]) circuit.ch(qr[0], qr[2]) circuit.crz(0.5, qr[1], qr[2]) circuit.cswap(qr[1], qr[0], qr[2]) circuit.append(CU1Gate(0.1), [qr[0], qr[2]]) circuit.append(CU3Gate(0.2, 0.1, 0.0), [qr[1], qr[2]]) circuit.cx(qr[1], qr[0]) circuit.cy(qr[1], qr[2]) circuit.cz(qr[2], qr[0]) circuit.h(qr[1]) circuit.i(qr[0]) circuit.rx(0.1, qr[0]) circuit.ry(0.2, qr[1]) circuit.rz(0.3, qr[2]) circuit.rzz(0.6, qr[1], qr[0]) circuit.s(qr[0]) circuit.sdg(qr[1]) circuit.swap(qr[1], qr[2]) circuit.t(qr[2]) circuit.tdg(qr[0]) circuit.append(U1Gate(0.1), [qr[1]]) circuit.append(U2Gate(0.2, -0.1), [qr[0]]) circuit.append(U3Gate(0.3, 0.0, -0.1), [qr[2]]) circuit.x(qr[2]) circuit.y(qr[1]) circuit.z(qr[0]) # circuit.snapshot('0') # circuit.measure(qr, cr) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ['u3', 'cx', 'id']) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ['u3', 'cx', 'id']) unrolled_dag = pass_.run(dag) ref_circuit = QuantumCircuit(qr, cr) ref_circuit.append(U3Gate(0, 0, pi / 2), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(-0.25, 0, 0), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0.25, -pi / 2, 0), [qr[2]]) ref_circuit.append(U3Gate(0.25, 0, 0), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(-0.25, 0, 0), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[1]]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.cx(qr[0], qr[1]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[0]]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[1]]) ref_circuit.cx(qr[0], qr[1]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.append(U3Gate(0, 0, pi / 2), [qr[2]]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[2]]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.append(U3Gate(0, 0, -pi / 2), [qr[2]]) ref_circuit.append(U3Gate(0, 0, 0.25), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0, 0, -0.25), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[0]]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[0]]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[1]]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.append(U3Gate(0, 0, 0.05), [qr[1]]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[2]]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.append(U3Gate(0, 0, 0.05), [qr[0]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, -0.05), [qr[2]]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.append(U3Gate(0, 0, 0.05), [qr[2]]) ref_circuit.append(U3Gate(0, 0, -0.05), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(-0.1, 0, -0.05), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[0]]) ref_circuit.append(U3Gate(0.1, 0.1, 0), [qr[2]]) ref_circuit.append(U3Gate(0, 0, -pi / 2), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[1]]) ref_circuit.append(U3Gate(0.2, 0, 0), [qr[1]]) ref_circuit.append(U3Gate(0, 0, pi / 2), [qr[2]]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.append(U3Gate(pi / 2, 0, pi), [qr[0]]) ref_circuit.i(qr[0]) ref_circuit.append(U3Gate(0.1, -pi / 2, pi / 2), [qr[0]]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.append(U3Gate(0, 0, 0.6), [qr[0]]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.append(U3Gate(0, 0, pi / 2), [qr[0]]) ref_circuit.append(U3Gate(0, 0, -pi / 4), [qr[0]]) ref_circuit.append(U3Gate(pi / 2, 0.2, -0.1), [qr[0]]) ref_circuit.append(U3Gate(0, 0, pi), [qr[0]]) ref_circuit.append(U3Gate(0, 0, -pi / 2), [qr[1]]) ref_circuit.append(U3Gate(0, 0, 0.3), [qr[2]]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[2], qr[1]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.append(U3Gate(0, 0, 0.1), [qr[1]]) ref_circuit.append(U3Gate(pi, pi / 2, pi / 2), [qr[1]]) ref_circuit.append(U3Gate(0, 0, pi / 4), [qr[2]]) ref_circuit.append(U3Gate(0.3, 0.0, -0.1), [qr[2]]) ref_circuit.append(U3Gate(pi, 0, pi), [qr[2]]) # ref_circuit.snapshot('0') # ref_circuit.measure(qr, cr) # ref_dag = circuit_to_dag(ref_circuit) self.assertTrue( Operator(dag_to_circuit(unrolled_dag)).equiv(ref_circuit))
def test_unroll_all_instructions(self): """Test unrolling a circuit containing all standard instructions. """ qr = QuantumRegister(3, 'qr') cr = ClassicalRegister(3, 'cr') circuit = QuantumCircuit(qr, cr) circuit.crx(0.5, qr[1], qr[2]) circuit.cry(0.5, qr[1], qr[2]) circuit.ccx(qr[0], qr[1], qr[2]) circuit.ch(qr[0], qr[2]) circuit.crz(0.5, qr[1], qr[2]) circuit.cswap(qr[1], qr[0], qr[2]) circuit.cu1(0.1, qr[0], qr[2]) circuit.cu3(0.2, 0.1, 0.0, qr[1], qr[2]) circuit.cx(qr[1], qr[0]) circuit.cy(qr[1], qr[2]) circuit.cz(qr[2], qr[0]) circuit.h(qr[1]) circuit.i(qr[0]) circuit.rx(0.1, qr[0]) circuit.ry(0.2, qr[1]) circuit.rz(0.3, qr[2]) circuit.rzz(0.6, qr[1], qr[0]) circuit.s(qr[0]) circuit.sdg(qr[1]) circuit.swap(qr[1], qr[2]) circuit.t(qr[2]) circuit.tdg(qr[0]) circuit.u1(0.1, qr[1]) circuit.u2(0.2, -0.1, qr[0]) circuit.u3(0.3, 0.0, -0.1, qr[2]) circuit.x(qr[2]) circuit.y(qr[1]) circuit.z(qr[0]) circuit.snapshot('0') circuit.measure(qr, cr) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ['u3', 'cx', 'id']) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ['u3', 'cx', 'id']) unrolled_dag = pass_.run(dag) ref_circuit = QuantumCircuit(qr, cr) ref_circuit.u3(0, 0, pi / 2, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(-0.25, 0, 0, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0.25, -pi / 2, 0, qr[2]) ref_circuit.u3(0.25, 0, 0, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(-0.25, 0, 0, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0, 0, -pi / 4, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0, 0, pi / 4, qr[1]) ref_circuit.u3(0, 0, -pi / 4, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.cx(qr[0], qr[1]) ref_circuit.u3(0, 0, pi / 4, qr[0]) ref_circuit.u3(0, 0, -pi / 4, qr[1]) ref_circuit.cx(qr[0], qr[1]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.u3(0, 0, pi / 2, qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, -pi / 4, qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.u3(0, 0, -pi / 2, qr[2]) ref_circuit.u3(0, 0, 0.25, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0, 0, -0.25, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, -pi / 4, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, pi / 4, qr[0]) ref_circuit.u3(0, 0, -pi / 4, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.u3(0, 0, -pi / 4, qr[0]) ref_circuit.u3(0, 0, pi / 4, qr[1]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.u3(0, 0, 0.05, qr[1]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[2]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.u3(0, 0, 0.05, qr[0]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, -0.05, qr[2]) ref_circuit.cx(qr[0], qr[2]) ref_circuit.u3(0, 0, 0.05, qr[2]) ref_circuit.u3(0, 0, -0.05, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(-0.1, 0, -0.05, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.u3(pi / 2, 0, pi, qr[0]) ref_circuit.u3(0.1, 0.1, 0, qr[2]) ref_circuit.u3(0, 0, -pi / 2, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(pi / 2, 0, pi, qr[1]) ref_circuit.u3(0.2, 0, 0, qr[1]) ref_circuit.u3(0, 0, pi / 2, qr[2]) ref_circuit.cx(qr[2], qr[0]) ref_circuit.u3(pi / 2, 0, pi, qr[0]) ref_circuit.i(qr[0]) ref_circuit.u3(0.1, -pi / 2, pi / 2, qr[0]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.u3(0, 0, 0.6, qr[0]) ref_circuit.cx(qr[1], qr[0]) ref_circuit.u3(0, 0, pi / 2, qr[0]) ref_circuit.u3(0, 0, -pi / 4, qr[0]) ref_circuit.u3(pi / 2, 0.2, -0.1, qr[0]) ref_circuit.u3(0, 0, pi, qr[0]) ref_circuit.u3(0, 0, -pi / 2, qr[1]) ref_circuit.u3(0, 0, 0.3, qr[2]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.cx(qr[2], qr[1]) ref_circuit.cx(qr[1], qr[2]) ref_circuit.u3(0, 0, 0.1, qr[1]) ref_circuit.u3(pi, pi / 2, pi / 2, qr[1]) ref_circuit.u3(0, 0, pi / 4, qr[2]) ref_circuit.u3(0.3, 0.0, -0.1, qr[2]) ref_circuit.u3(pi, 0, pi, qr[2]) ref_circuit.snapshot('0') ref_circuit.measure(qr, cr) ref_dag = circuit_to_dag(ref_circuit) self.assertEqual(unrolled_dag, ref_dag)
def test_unroll_1q_chain_conditional(self): """Test unroll chain of 1-qubit gates interrupted by conditional.""" # ┌───┐┌─────┐┌───┐┌───┐┌─────────┐┌─────────┐┌─────────┐┌─┐ ┌───┐ ┌───┐ » # qr: ┤ H ├┤ Tdg ├┤ Z ├┤ T ├┤ Ry(0.5) ├┤ Rz(0.3) ├┤ Rx(0.1) ├┤M├─┤ X ├──┤ Y ├─» # └───┘└─────┘└───┘└───┘└─────────┘└─────────┘└─────────┘└╥┘ └─╥─┘ └─╥─┘ » # ║ ┌──╨──┐┌──╨──┐» # cr: 1/══════════════════════════════════════════════════════╩═╡ 0x1 ╞╡ 0x1 ╞» # 0 └─────┘└─────┘» # « ┌───┐ # « qr: ─┤ Z ├─ # « └─╥─┘ # « ┌──╨──┐ # «cr: 1/╡ 0x1 ╞ # « └─────┘ qr = QuantumRegister(1, "qr") cr = ClassicalRegister(1, "cr") circuit = QuantumCircuit(qr, cr) circuit.h(qr) circuit.tdg(qr) circuit.z(qr) circuit.t(qr) circuit.ry(0.5, qr) circuit.rz(0.3, qr) circuit.rx(0.1, qr) circuit.measure(qr, cr) circuit.x(qr).c_if(cr, 1) circuit.y(qr).c_if(cr, 1) circuit.z(qr).c_if(cr, 1) dag = circuit_to_dag(circuit) pass_ = UnrollCustomDefinitions(std_eqlib, ["u1", "u2", "u3"]) dag = pass_.run(dag) pass_ = BasisTranslator(std_eqlib, ["u1", "u2", "u3"]) unrolled_dag = pass_.run(dag) # Pick up -1 * 0.3 / 2 global phase for one RZ -> U1. # # global phase: 6.1332 # ┌─────────┐┌──────────┐┌───────┐┌─────────┐┌─────────────┐┌─────────┐» # qr: ┤ U2(0,π) ├┤ U1(-π/4) ├┤ U1(π) ├┤ U1(π/4) ├┤ U3(0.5,0,0) ├┤ U1(0.3) ├» # └─────────┘└──────────┘└───────┘└─────────┘└─────────────┘└─────────┘» # cr: 1/═══════════════════════════════════════════════════════════════════» # » # « ┌──────────────────┐┌─┐┌───────────┐┌───────────────┐┌───────┐ # « qr: ┤ U3(0.1,-π/2,π/2) ├┤M├┤ U3(π,0,π) ├┤ U3(π,π/2,π/2) ├┤ U1(π) ├ # « └──────────────────┘└╥┘└─────╥─────┘└───────╥───────┘└───╥───┘ # « ║ ┌──╨──┐ ┌──╨──┐ ┌──╨──┐ # «cr: 1/═════════════════════╩════╡ 0x1 ╞════════╡ 0x1 ╞══════╡ 0x1 ╞═ # « 0 └─────┘ └─────┘ └─────┘ ref_circuit = QuantumCircuit(qr, cr, global_phase=-0.3 / 2) ref_circuit.append(U2Gate(0, pi), [qr[0]]) ref_circuit.append(U1Gate(-pi / 4), [qr[0]]) ref_circuit.append(U1Gate(pi), [qr[0]]) ref_circuit.append(U1Gate(pi / 4), [qr[0]]) ref_circuit.append(U3Gate(0.5, 0, 0), [qr[0]]) ref_circuit.append(U1Gate(0.3), [qr[0]]) ref_circuit.append(U3Gate(0.1, -pi / 2, pi / 2), [qr[0]]) ref_circuit.measure(qr[0], cr[0]) ref_circuit.append(U3Gate(pi, 0, pi), [qr[0]]).c_if(cr, 1) ref_circuit.append(U3Gate(pi, pi / 2, pi / 2), [qr[0]]).c_if(cr, 1) ref_circuit.append(U1Gate(pi), [qr[0]]).c_if(cr, 1) ref_dag = circuit_to_dag(ref_circuit) self.assertEqual(unrolled_dag, ref_dag)