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
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_ = Unroller(basis=[]) with self.assertRaises(QiskitError): pass_.run(dag)
def _unroll_gate(operation, basis_gates): from qiskit.converters.dag_to_circuit import dag_to_circuit from qiskit.transpiler.passes import Unroller unroller = Unroller(basis_gates) dag = _gate_to_dag(operation) qc = dag_to_circuit(unroller.run(dag)) return qc.to_gate()
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)
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_ = Unroller(['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 get_controlled_circuit(circuit, ctl_qubit, tgt_circuit=None, use_basis_gates=True): """ Construct the controlled version of a given circuit. Args: circuit (QuantumCircuit) : the base circuit ctl_qubit (Qubit) : the control qubit to use tgt_circuit (QuantumCircuit) : the target controlled circuit to be modified in-place use_basis_gates (bool) : boolean flag to indicate whether or not only basis gates should be used Return: QuantumCircuit: a QuantumCircuit object with the base circuit being controlled by ctl_qubit Raises: RuntimeError: unexpected operation """ if tgt_circuit is not None: qc = tgt_circuit else: qc = QuantumCircuit() # get all the qubits and clbits qregs = circuit.qregs qubits = [] for qreg in qregs: if not qc.has_register(qreg): qc.add_register(qreg) qubits.extend(qreg) cregs = circuit.cregs clbits = [] for creg in cregs: if not qc.has_register(creg): qc.add_register(creg) clbits.extend(creg) # get all operations unroller = Unroller(basis=['u', 'p', 'cx']) ops = dag_to_circuit(unroller.run(circuit_to_dag(circuit))).data # process all basis gates to add control if not qc.has_register(ctl_qubit._register): qc.add_register(ctl_qubit._register) for op in ops: if op[0].name == 'id': apply_cu(qc, 0, 0, 0, ctl_qubit, op[1][0], use_basis_gates=use_basis_gates) elif op[0].name == 'p': apply_cp(qc, *op[0].params, ctl_qubit, op[1][0], use_basis_gates=use_basis_gates) elif op[0].name == 'u': apply_cu(qc, *op[0].params, ctl_qubit, op[1][0], use_basis_gates=use_basis_gates) elif op[0].name == 'cx': apply_ccx(qc, ctl_qubit, op[1][0], op[1][1], use_basis_gates=use_basis_gates) elif op[0].name == 'measure': qc.measure(op[1], op[2]) elif op[0].name == 'barrier': qc.barrier(op[1]) else: raise RuntimeError('Unexpected operation {}.'.format(op[0].name)) return qc
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.converters.instruction_to_gate import instruction_to_gate 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 instruction_to_gate(qc.to_instruction())
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_ = Unroller(["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_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_ = Unroller(['u2']) unrolled_dag = pass_.run(dag) op_nodes = unrolled_dag.op_nodes(data=True) self.assertEqual(len(op_nodes), 1) self.assertEqual(op_nodes[0][1]["op"].name, 'u2')
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_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_ = Unroller(["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_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
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_ = Unroller(['h', 't', 'tdg', 'cx']) unrolled_dag = pass_.run(dag) op_nodes = unrolled_dag.op_nodes(data=True) self.assertEqual(len(op_nodes), 15) for node in op_nodes: op = node[1]["op"] self.assertIn(op.name, ['h', 't', 'tdg', 'cx'])
def test_unroll_no_basis(self): """Test no-basis unrolls all the way to U, CX. """ qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.cx(qr[0], qr[1]) dag = circuit_to_dag(circuit) pass_ = Unroller() unrolled_dag = pass_.run(dag) op_nodes = unrolled_dag.op_nodes(data=True) self.assertEqual(len(op_nodes), 2) for node in op_nodes: op = node[1]["op"] self.assertIn(op.name, ['U', 'CX'])
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_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_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_ = Unroller(['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 convert_to_basis_gates(circuit): """ unroll the circuit using the basis ['u', 'cx'] """ unroller = Unroller(basis=['u', 'cx']) return dag_to_circuit(unroller.run(circuit_to_dag(circuit)))
class TestUnrollAllInstructions(QiskitTestCase): """Test unrolling a circuit containing all standard instructions.""" def setUp(self): super().setUp() qr = self.qr = QuantumRegister(3, "qr") cr = self.cr = ClassicalRegister(3, "cr") self.circuit = QuantumCircuit(qr, cr) self.ref_circuit = QuantumCircuit(qr, cr) self.pass_ = Unroller(basis=["u3", "cx", "id"]) def compare_dags(self): """compare dags in class tests""" dag = circuit_to_dag(self.circuit) unrolled_dag = self.pass_.run(dag) ref_dag = circuit_to_dag(self.ref_circuit) self.assertEqual(unrolled_dag, ref_dag) def test_unroll_crx(self): """test unroll crx""" # qr_1: ─────■───── qr_1: ─────────────────■─────────────────────■───────────────────── # ┌────┴────┐ = ┌─────────────┐┌─┴─┐┌───────────────┐┌─┴─┐┌─────────────────┐ # qr_2: ┤ Rx(0.5) ├ qr_2: ┤ U3(0,0,π/2) ├┤ X ├┤ U3(-0.25,0,0) ├┤ X ├┤ U3(0.25,-π/2,0) ├ # └─────────┘ └─────────────┘└───┘└───────────────┘└───┘└─────────────────┘ self.circuit.crx(0.5, 1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0.25, -pi / 2, 0), [2]) self.compare_dags() def test_unroll_cry(self): """test unroll cry""" # qr_1: ─────■───── qr_1: ──────────────────■─────────────────────■── # ┌────┴────┐ = ┌──────────────┐┌─┴─┐┌───────────────┐┌─┴─┐ # qr_2: ┤ Ry(0.5) ├ qr_2: ┤ U3(0.25,0,0) ├┤ X ├┤ U3(-0.25,0,0) ├┤ X ├ # └─────────┘ └──────────────┘└───┘└───────────────┘└───┘ self.circuit.cry(0.5, 1, 2) self.ref_circuit.append(U3Gate(0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_ccx(self): """test unroll ccx""" # qr_0: ──■── qr_0: ──────────────────────────────────────■──────────────────────» # │ │ » # qr_1: ──■── = qr_1: ─────────────────■────────────────────┼───────────────────■──» # ┌─┴─┐ ┌─────────────┐┌─┴─┐┌──────────────┐┌─┴─┐┌─────────────┐┌─┴─┐» # qr_2: ┤ X ├ qr_2: ┤ U3(π/2,0,π) ├┤ X ├┤ U3(0,0,-π/4) ├┤ X ├┤ U3(0,0,π/4) ├┤ X ├» # └───┘ └─────────────┘└───┘└──────────────┘└───┘└─────────────┘└───┘» # « ┌─────────────┐ # «qr_0: ──────────────────■─────────■───────┤ U3(0,0,π/4) ├───■── # « ┌─────────────┐ │ ┌─┴─┐ ├─────────────┴┐┌─┴─┐ # «qr_1: ┤ U3(0,0,π/4) ├───┼───────┤ X ├─────┤ U3(0,0,-π/4) ├┤ X ├ # « ├─────────────┴┐┌─┴─┐┌────┴───┴────┐├─────────────┬┘└───┘ # «qr_2: ┤ U3(0,0,-π/4) ├┤ X ├┤ U3(0,0,π/4) ├┤ U3(π/2,0,π) ├────── # « └──────────────┘└───┘└─────────────┘└─────────────┘ self.circuit.ccx(0, 1, 2) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [1]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.cx(0, 1) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [1]) self.ref_circuit.cx(0, 1) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.compare_dags() def test_unroll_ch(self): """test unroll ch""" # qr_0: ──■── qr_0: ───────────────────────────────────────────────■──────────────────» # ┌─┴─┐ = ┌─────────────┐┌─────────────┐┌─────────────┐┌─┴─┐┌──────────────┐» # qr_2: ┤ H ├ qr_2: ┤ U3(0,0,π/2) ├┤ U3(π/2,0,π) ├┤ U3(0,0,π/4) ├┤ X ├┤ U3(0,0,-π/4) ├» # └───┘ └─────────────┘└─────────────┘└─────────────┘└───┘└──────────────┘» # « # «qr_0: ─────────────────────────────── # « ┌─────────────┐┌──────────────┐ # «qr_2: ┤ U3(π/2,0,π) ├┤ U3(0,0,-π/2) ├ # « └─────────────┘└──────────────┘ self.circuit.ch(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [2]) self.compare_dags() def test_unroll_crz(self): """test unroll crz""" # qr_1: ─────■───── qr_1: ──────────────────■─────────────────────■── # ┌────┴────┐ = ┌──────────────┐┌─┴─┐┌───────────────┐┌─┴─┐ # qr_2: ┤ Rz(0.5) ├ qr_2: ┤ U3(0,0,0.25) ├┤ X ├┤ U3(0,0,-0.25) ├┤ X ├ # └─────────┘ └──────────────┘└───┘└───────────────┘└───┘ self.circuit.crz(0.5, 1, 2) self.ref_circuit.append(U3Gate(0, 0, 0.25), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, -0.25), [2]) self.ref_circuit.cx(1, 2) def test_unroll_cswap(self): """test unroll cswap""" # ┌───┐ » # qr_0: ─X─ qr_0: ┤ X ├─────────────────■────────────────────────────────────────■──» # │ └─┬─┘ │ │ » # qr_1: ─■─ = qr_1: ──┼───────────────────┼────────────────────■───────────────────┼──» # │ │ ┌─────────────┐┌─┴─┐┌──────────────┐┌─┴─┐┌─────────────┐┌─┴─┐» # qr_2: ─X─ qr_2: ──■──┤ U3(π/2,0,π) ├┤ X ├┤ U3(0,0,-π/4) ├┤ X ├┤ U3(0,0,π/4) ├┤ X ├» # └─────────────┘└───┘└──────────────┘└───┘└─────────────┘└───┘» # « ┌─────────────┐ ┌───┐ ┌──────────────┐┌───┐┌───┐ # «qr_0: ┤ U3(0,0,π/4) ├───────────┤ X ├─────┤ U3(0,0,-π/4) ├┤ X ├┤ X ├ # « └─────────────┘ └─┬─┘ ├─────────────┬┘└─┬─┘└─┬─┘ # «qr_1: ──────────────────■─────────■───────┤ U3(0,0,π/4) ├───■────┼── # « ┌──────────────┐┌─┴─┐┌─────────────┐├─────────────┤ │ # «qr_2: ┤ U3(0,0,-π/4) ├┤ X ├┤ U3(0,0,π/4) ├┤ U3(π/2,0,π) ├────────■── # « └──────────────┘└───┘└─────────────┘└─────────────┘ self.circuit.cswap(1, 0, 2) self.ref_circuit.cx(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [1]) self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(2, 0) self.compare_dags() def test_unroll_cu1(self): """test unroll cu1""" # ┌──────────────┐ # qr_0: ─■──────── qr_0: ┤ U3(0,0,0.05) ├──■─────────────────────■────────────────── # │U1(0.1) = └──────────────┘┌─┴─┐┌───────────────┐┌─┴─┐┌──────────────┐ # qr_2: ─■──────── qr_2: ────────────────┤ X ├┤ U3(0,0,-0.05) ├┤ X ├┤ U3(0,0,0.05) ├ # └───┘└───────────────┘└───┘└──────────────┘ self.circuit.append(CU1Gate(0.1), [0, 2]) self.ref_circuit.append(U3Gate(0, 0, 0.05), [0]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -0.05), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, 0.05), [2]) self.compare_dags() def test_unroll_cu3(self): """test unroll cu3""" # ┌──────────────┐ # q_1: ────────■──────── q_1: ─┤ U3(0,0,0.05) ├──■────────────────────────■─────────────────── # ┌───────┴───────┐ = ┌┴──────────────┤┌─┴─┐┌──────────────────┐┌─┴─┐┌───────────────┐ # q_2: ┤ U3(0.2,0.1,0) ├ q_2: ┤ U3(0,0,-0.05) ├┤ X ├┤ U3(-0.1,0,-0.05) ├┤ X ├┤ U3(0.1,0.1,0) ├ # └───────────────┘ └───────────────┘└───┘└──────────────────┘└───┘└───────────────┘ self.circuit.append(CU3Gate(0.2, 0.1, 0.0), [1, 2]) self.ref_circuit.append(U3Gate(0, 0, 0.05), [1]) self.ref_circuit.append(U3Gate(0, 0, -0.05), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.1, 0, -0.05), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0.1, 0.1, 0), [2]) self.compare_dags() def test_unroll_cx(self): """test unroll cx""" self.circuit.cx(1, 0) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_cy(self): """test unroll cy""" # qr_1: ──■── qr_1: ──────────────────■───────────────── # ┌─┴─┐ = ┌──────────────┐┌─┴─┐┌─────────────┐ # qr_2: ┤ Y ├ qr_2: ┤ U3(0,0,-π/2) ├┤ X ├┤ U3(0,0,π/2) ├ # └───┘ └──────────────┘└───┘└─────────────┘ self.circuit.cy(1, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.compare_dags() def test_unroll_cz(self): """test unroll cz""" # ┌─────────────┐┌───┐┌─────────────┐ # qr_0: ─■─ qr_0: ┤ U3(π/2,0,π) ├┤ X ├┤ U3(π/2,0,π) ├ # │ = └─────────────┘└─┬─┘└─────────────┘ # qr_2: ─■─ qr_2: ─────────────────■───────────────── self.circuit.cz(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [0]) self.ref_circuit.cx(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [0]) self.compare_dags() def test_unroll_h(self): """test unroll h""" self.circuit.h(1) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [1]) self.compare_dags() def test_unroll_i(self): """test unroll i""" self.circuit.i(0) self.ref_circuit.i(0) self.compare_dags() def test_unroll_rx(self): """test unroll rx""" self.circuit.rx(0.1, 0) self.ref_circuit.append(U3Gate(0.1, -pi / 2, pi / 2), [0]) self.compare_dags() def test_unroll_ry(self): """test unroll ry""" self.circuit.ry(0.2, 1) self.ref_circuit.append(U3Gate(0.2, 0, 0), [1]) self.compare_dags() def test_unroll_rz(self): """test unroll rz""" self.circuit.rz(0.3, 2) self.ref_circuit.global_phase = -1 * 0.3 / 2 self.ref_circuit.append(U3Gate(0, 0, 0.3), [2]) self.compare_dags() def test_unroll_rzz(self): """test unroll rzz""" # global phase: 5.9832 # ┌───┐┌─────────────┐┌───┐ # qr_0: ─■──────── qr_0: ┤ X ├┤ U3(0,0,0.6) ├┤ X ├ # │ZZ(0.6) = └─┬─┘└─────────────┘└─┬─┘ # qr_1: ─■──────── qr_1: ──■───────────────────■── self.circuit.rzz(0.6, 1, 0) self.ref_circuit.global_phase = -1 * 0.6 / 2 self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, 0.6), [0]) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_s(self): """test unroll s""" self.circuit.s(0) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [0]) self.compare_dags() def test_unroll_sdg(self): """test unroll sdg""" self.circuit.sdg(1) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [1]) self.compare_dags() def test_unroll_swap(self): """test unroll swap""" # ┌───┐ # qr_1: ─X─ qr_1: ──■──┤ X ├──■── # │ = ┌─┴─┐└─┬─┘┌─┴─┐ # qr_2: ─X─ qr_2: ┤ X ├──■──┤ X ├ # └───┘ └───┘ self.circuit.swap(1, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(2, 1) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_t(self): """test unroll t""" self.circuit.t(2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.compare_dags() def test_unroll_tdg(self): """test unroll tdg""" self.circuit.tdg(0) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [0]) self.compare_dags() def test_unroll_u1(self): """test unroll u1""" self.circuit.append(U1Gate(0.1), [1]) self.ref_circuit.append(U3Gate(0, 0, 0.1), [1]) self.compare_dags() def test_unroll_u2(self): """test unroll u2""" self.circuit.append(U2Gate(0.2, -0.1), [0]) self.ref_circuit.append(U3Gate(pi / 2, 0.2, -0.1), [0]) self.compare_dags() def test_unroll_u3(self): """test unroll u3""" self.circuit.append(U3Gate(0.3, 0.0, -0.1), [2]) self.ref_circuit.append(U3Gate(0.3, 0.0, -0.1), [2]) self.compare_dags() def test_unroll_x(self): """test unroll x""" self.circuit.x(2) self.ref_circuit.append(U3Gate(pi, 0, pi), [2]) self.compare_dags() def test_unroll_y(self): """test unroll y""" self.circuit.y(1) self.ref_circuit.append(U3Gate(pi, pi / 2, pi / 2), [1]) self.compare_dags() def test_unroll_z(self): """test unroll z""" self.circuit.z(0) self.ref_circuit.append(U3Gate(0, 0, pi), [0]) self.compare_dags() def test_unroll_snapshot(self): """test unroll snapshot""" num_qubits = self.circuit.num_qubits instr = Snapshot("0", num_qubits=num_qubits) self.circuit.append(instr, range(num_qubits)) self.ref_circuit.append(instr, range(num_qubits)) self.compare_dags() def test_unroll_measure(self): """test unroll measure""" self.circuit.measure(self.qr, self.cr) self.ref_circuit.measure(self.qr, self.cr) self.compare_dags()
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
class TestUnrollAllInstructions(QiskitTestCase): """Test unrolling a circuit containing all standard instructions.""" def setUp(self): qr = self.qr = QuantumRegister(3, 'qr') cr = self.cr = ClassicalRegister(3, 'cr') self.circuit = QuantumCircuit(qr, cr) self.ref_circuit = QuantumCircuit(qr, cr) self.pass_ = Unroller(basis=['u3', 'cx', 'id']) def compare_dags(self): """compare dags in class tests""" dag = circuit_to_dag(self.circuit) unrolled_dag = self.pass_.run(dag) ref_dag = circuit_to_dag(self.ref_circuit) self.assertEqual(unrolled_dag, ref_dag) def test_unroll_crx(self): """test unroll crx""" self.circuit.crx(0.5, 1, 2) self.ref_circuit.u3(0, 0, pi/2, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(-0.25, 0, 0, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0.25, -pi/2, 0, 2) self.compare_dags() def test_unroll_cry(self): """test unroll cry""" self.circuit.cry(0.5, 1, 2) self.ref_circuit.u3(0.25, 0, 0, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(-0.25, 0, 0, 2) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_ccx(self): """test unroll ccx""" self.circuit.ccx(0, 1, 2) self.ref_circuit.u3(pi/2, 0, pi, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0, 0, -pi/4, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, pi/4, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0, 0, pi/4, 1) self.ref_circuit.u3(0, 0, -pi/4, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.cx(0, 1) self.ref_circuit.u3(0, 0, pi/4, 0) self.ref_circuit.u3(0, 0, -pi/4, 1) self.ref_circuit.cx(0, 1) self.ref_circuit.u3(0, 0, pi/4, 2) self.ref_circuit.u3(pi/2, 0, pi, 2) self.compare_dags() def test_unroll_ch(self): """test unroll ch""" self.circuit.ch(0, 2) self.ref_circuit.u3(0, 0, pi/2, 2) self.ref_circuit.u3(pi/2, 0, pi, 2) self.ref_circuit.u3(0, 0, pi/4, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, -pi/4, 2) self.ref_circuit.u3(pi/2, 0, pi, 2) self.ref_circuit.u3(0, 0, -pi/2, 2) self.compare_dags() def test_unroll_crz(self): """test unroll crz""" self.circuit.crz(0.5, 1, 2) self.ref_circuit.u3(0, 0, 0.25, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0, 0, -0.25, 2) self.ref_circuit.cx(1, 2) def test_unroll_cswap(self): """test unroll cswap""" self.circuit.cswap(1, 0, 2) self.ref_circuit.cx(2, 0) self.ref_circuit.u3(pi/2, 0, pi, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, -pi/4, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0, 0, pi/4, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, pi/4, 0) self.ref_circuit.u3(0, 0, -pi/4, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(1, 0) self.ref_circuit.u3(0, 0, -pi/4, 0) self.ref_circuit.u3(0, 0, pi/4, 1) self.ref_circuit.cx(1, 0) self.ref_circuit.u3(0, 0, pi/4, 2) self.ref_circuit.u3(pi/2, 0, pi, 2) self.ref_circuit.cx(2, 0) self.compare_dags() def test_unroll_cu1(self): """test unroll cu1""" self.circuit.cu1(0.1, 0, 2) self.ref_circuit.u3(0, 0, 0.05, 0) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, -0.05, 2) self.ref_circuit.cx(0, 2) self.ref_circuit.u3(0, 0, 0.05, 2) self.compare_dags() def test_unroll_cu3(self): """test unroll cu3""" self.circuit.cu3(0.2, 0.1, 0.0, 1, 2) self.ref_circuit.u3(0, 0, 0.05, 1) self.ref_circuit.u3(0, 0, -0.05, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(-0.1, 0, -0.05, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0.1, 0.1, 0, 2) self.compare_dags() def test_unroll_cx(self): """test unroll cx""" self.circuit.cx(1, 0) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_cy(self): """test unroll cy""" self.circuit.cy(1, 2) self.ref_circuit.u3(0, 0, -pi/2, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.u3(0, 0, pi/2, 2) self.compare_dags() def test_unroll_cz(self): """test unroll cz""" self.circuit.cz(2, 0) self.ref_circuit.u3(pi/2, 0, pi, 0) self.ref_circuit.cx(2, 0) self.ref_circuit.u3(pi/2, 0, pi, 0) self.compare_dags() def test_unroll_h(self): """test unroll h""" self.circuit.h(1) self.ref_circuit.u3(pi/2, 0, pi, 1) self.compare_dags() def test_unroll_i(self): """test unroll i""" self.circuit.i(0) self.ref_circuit.i(0) self.compare_dags() def test_unroll_rx(self): """test unroll rx""" self.circuit.rx(0.1, 0) self.ref_circuit.u3(0.1, -pi/2, pi/2, 0) self.compare_dags() def test_unroll_ry(self): """test unroll ry""" self.circuit.ry(0.2, 1) self.ref_circuit.u3(0.2, 0, 0, 1) self.compare_dags() def test_unroll_rz(self): """test unroll rz""" self.circuit.rz(0.3, 2) self.ref_circuit.u3(0, 0, 0.3, 2) self.compare_dags() def test_unroll_rzz(self): """test unroll rzz""" self.circuit.rzz(0.6, 1, 0) self.ref_circuit.cx(1, 0) self.ref_circuit.u3(0, 0, 0.6, 0) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_s(self): """test unroll s""" self.circuit.s(0) self.ref_circuit.u3(0, 0, pi/2, 0) self.compare_dags() def test_unroll_sdg(self): """test unroll sdg""" self.circuit.sdg(1) self.ref_circuit.u3(0, 0, -pi/2, 1) self.compare_dags() def test_unroll_swap(self): """test unroll swap""" self.circuit.swap(1, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(2, 1) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_t(self): """test unroll t""" self.circuit.t(2) self.ref_circuit.u3(0, 0, pi/4, 2) self.compare_dags() def test_unroll_tdg(self): """test unroll tdg""" self.circuit.tdg(0) self.ref_circuit.u3(0, 0, -pi/4, 0) self.compare_dags() def test_unroll_u1(self): """test unroll u1""" self.circuit.u1(0.1, 1) self.ref_circuit.u3(0, 0, 0.1, 1) self.compare_dags() def test_unroll_u2(self): """test unroll u2""" self.circuit.u2(0.2, -0.1, 0) self.ref_circuit.u3(pi/2, 0.2, -0.1, 0) self.compare_dags() def test_unroll_u3(self): """test unroll u3""" self.circuit.u3(0.3, 0.0, -0.1, 2) self.ref_circuit.u3(0.3, 0.0, -0.1, 2) self.compare_dags() def test_unroll_x(self): """test unroll x""" self.circuit.x(2) self.ref_circuit.u3(pi, 0, pi, 2) self.compare_dags() def test_unroll_y(self): """test unroll y""" self.circuit.y(1) self.ref_circuit.u3(pi, pi/2, pi/2, 1) self.compare_dags() def test_unroll_z(self): """test unroll z""" self.circuit.z(0) self.ref_circuit.u3(0, 0, pi, 0) self.compare_dags() def test_unroll_snapshot(self): """test unroll snapshot""" self.circuit.snapshot('0') self.ref_circuit.snapshot('0') self.compare_dags() def test_unroll_measure(self): """test unroll measure""" self.circuit.measure(self.qr, self.cr) self.ref_circuit.measure(self.qr, self.cr) self.compare_dags()
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.iden(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_ = Unroller(basis=['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.iden(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 convert_to_basis_gates(circuit): """ unroll the circuit using the basis u1, u2, u3, cx gates """ unroller = Unroller(basis=['u1', 'u2', 'u3', 'cx']) return dag_to_circuit(unroller.run(circuit_to_dag(circuit)))
class TestUnrollAllInstructions(QiskitTestCase): """Test unrolling a circuit containing all standard instructions.""" def setUp(self): super().setUp() qr = self.qr = QuantumRegister(3, "qr") cr = self.cr = ClassicalRegister(3, "cr") self.circuit = QuantumCircuit(qr, cr) self.ref_circuit = QuantumCircuit(qr, cr) self.pass_ = Unroller(basis=["u3", "cx", "id"]) def compare_dags(self): """compare dags in class tests""" dag = circuit_to_dag(self.circuit) unrolled_dag = self.pass_.run(dag) ref_dag = circuit_to_dag(self.ref_circuit) self.assertEqual(unrolled_dag, ref_dag) def test_unroll_crx(self): """test unroll crx""" self.circuit.crx(0.5, 1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0.25, -pi / 2, 0), [2]) self.compare_dags() def test_unroll_cry(self): """test unroll cry""" self.circuit.cry(0.5, 1, 2) self.ref_circuit.append(U3Gate(0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.25, 0, 0), [2]) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_ccx(self): """test unroll ccx""" self.circuit.ccx(0, 1, 2) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [1]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.cx(0, 1) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [1]) self.ref_circuit.cx(0, 1) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.compare_dags() def test_unroll_ch(self): """test unroll ch""" self.circuit.ch(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [2]) self.compare_dags() def test_unroll_crz(self): """test unroll crz""" self.circuit.crz(0.5, 1, 2) self.ref_circuit.append(U3Gate(0, 0, 0.25), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, -0.25), [2]) self.ref_circuit.cx(1, 2) def test_unroll_cswap(self): """test unroll cswap""" self.circuit.cswap(1, 0, 2) self.ref_circuit.cx(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [0]) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [1]) self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [2]) self.ref_circuit.cx(2, 0) self.compare_dags() def test_unroll_cu1(self): """test unroll cu1""" self.circuit.append(CU1Gate(0.1), [0, 2]) self.ref_circuit.append(U3Gate(0, 0, 0.05), [0]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, -0.05), [2]) self.ref_circuit.cx(0, 2) self.ref_circuit.append(U3Gate(0, 0, 0.05), [2]) self.compare_dags() def test_unroll_cu3(self): """test unroll cu3""" self.circuit.append(CU3Gate(0.2, 0.1, 0.0), [1, 2]) self.ref_circuit.append(U3Gate(0, 0, 0.05), [1]) self.ref_circuit.append(U3Gate(0, 0, -0.05), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(-0.1, 0, -0.05), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0.1, 0.1, 0), [2]) self.compare_dags() def test_unroll_cx(self): """test unroll cx""" self.circuit.cx(1, 0) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_cy(self): """test unroll cy""" self.circuit.cy(1, 2) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [2]) self.ref_circuit.cx(1, 2) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [2]) self.compare_dags() def test_unroll_cz(self): """test unroll cz""" self.circuit.cz(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [0]) self.ref_circuit.cx(2, 0) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [0]) self.compare_dags() def test_unroll_h(self): """test unroll h""" self.circuit.h(1) self.ref_circuit.append(U3Gate(pi / 2, 0, pi), [1]) self.compare_dags() def test_unroll_i(self): """test unroll i""" self.circuit.i(0) self.ref_circuit.i(0) self.compare_dags() def test_unroll_rx(self): """test unroll rx""" self.circuit.rx(0.1, 0) self.ref_circuit.append(U3Gate(0.1, -pi / 2, pi / 2), [0]) self.compare_dags() def test_unroll_ry(self): """test unroll ry""" self.circuit.ry(0.2, 1) self.ref_circuit.append(U3Gate(0.2, 0, 0), [1]) self.compare_dags() def test_unroll_rz(self): """test unroll rz""" self.circuit.rz(0.3, 2) self.ref_circuit.global_phase = -1 * 0.3 / 2 self.ref_circuit.append(U3Gate(0, 0, 0.3), [2]) self.compare_dags() def test_unroll_rzz(self): """test unroll rzz""" self.circuit.rzz(0.6, 1, 0) self.ref_circuit.global_phase = -1 * 0.6 / 2 self.ref_circuit.cx(1, 0) self.ref_circuit.append(U3Gate(0, 0, 0.6), [0]) self.ref_circuit.cx(1, 0) self.compare_dags() def test_unroll_s(self): """test unroll s""" self.circuit.s(0) self.ref_circuit.append(U3Gate(0, 0, pi / 2), [0]) self.compare_dags() def test_unroll_sdg(self): """test unroll sdg""" self.circuit.sdg(1) self.ref_circuit.append(U3Gate(0, 0, -pi / 2), [1]) self.compare_dags() def test_unroll_swap(self): """test unroll swap""" self.circuit.swap(1, 2) self.ref_circuit.cx(1, 2) self.ref_circuit.cx(2, 1) self.ref_circuit.cx(1, 2) self.compare_dags() def test_unroll_t(self): """test unroll t""" self.circuit.t(2) self.ref_circuit.append(U3Gate(0, 0, pi / 4), [2]) self.compare_dags() def test_unroll_tdg(self): """test unroll tdg""" self.circuit.tdg(0) self.ref_circuit.append(U3Gate(0, 0, -pi / 4), [0]) self.compare_dags() def test_unroll_u1(self): """test unroll u1""" self.circuit.append(U1Gate(0.1), [1]) self.ref_circuit.append(U3Gate(0, 0, 0.1), [1]) self.compare_dags() def test_unroll_u2(self): """test unroll u2""" self.circuit.append(U2Gate(0.2, -0.1), [0]) self.ref_circuit.append(U3Gate(pi / 2, 0.2, -0.1), [0]) self.compare_dags() def test_unroll_u3(self): """test unroll u3""" self.circuit.append(U3Gate(0.3, 0.0, -0.1), [2]) self.ref_circuit.append(U3Gate(0.3, 0.0, -0.1), [2]) self.compare_dags() def test_unroll_x(self): """test unroll x""" self.circuit.x(2) self.ref_circuit.append(U3Gate(pi, 0, pi), [2]) self.compare_dags() def test_unroll_y(self): """test unroll y""" self.circuit.y(1) self.ref_circuit.append(U3Gate(pi, pi / 2, pi / 2), [1]) self.compare_dags() def test_unroll_z(self): """test unroll z""" self.circuit.z(0) self.ref_circuit.append(U3Gate(0, 0, pi), [0]) self.compare_dags() def test_unroll_snapshot(self): """test unroll snapshot""" num_qubits = self.circuit.num_qubits instr = Snapshot("0", num_qubits=num_qubits) self.circuit.append(instr, range(num_qubits)) self.ref_circuit.append(instr, range(num_qubits)) self.compare_dags() def test_unroll_measure(self): """test unroll measure""" self.circuit.measure(self.qr, self.cr) self.ref_circuit.measure(self.qr, self.cr) self.compare_dags()