def test_custom_gate_with_params_bound_main_call(self): """Custom gate with unbound parameters that are bound in the main circuit""" parameter0 = Parameter("param_0") parameter1 = Parameter("param_1") custom = QuantumCircuit(2, name="custom") custom.rz(parameter0, 0) custom.rz(parameter1 / 2, 1) qr_q = QuantumRegister(3, "q") qr_r = QuantumRegister(3, "r") circuit = QuantumCircuit(qr_q, qr_r) circuit.append(custom.to_gate(), [qr_q[0], qr_r[0]]) circuit.assign_parameters({ parameter0: pi, parameter1: pi / 2 }, inplace=True) qubit_name = circuit.data[0][0].definition.qregs[0].name expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', f"gate custom(param_0, param_1) {qubit_name}_0, {qubit_name}_1 {{", f" rz(pi) {qubit_name}_0;", f" rz(pi/4) {qubit_name}_1;", "}", "qubit[6] _q;", "let q = _q[0] || _q[1] || _q[2];", "let r = _q[3] || _q[4] || _q[5];", "custom(pi, pi/2) q[0], r[0];", "", ]) self.assertEqual(Exporter().dumps(circuit), expected_qasm)
def test_regs_conds_qasm(self): """Test with registers and conditionals.""" qr1 = QuantumRegister(1, "qr1") qr2 = QuantumRegister(2, "qr2") cr = ClassicalRegister(3, "cr") qc = QuantumCircuit(qr1, qr2, cr) qc.measure(qr1[0], cr[0]) qc.measure(qr2[0], cr[1]) qc.measure(qr2[1], cr[2]) qc.x(qr2[1]).c_if(cr, 0) qc.y(qr1[0]).c_if(cr, 1) qc.z(qr1[0]).c_if(cr, 2) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "bit[3] cr;", "qubit[3] _q;", "let qr1 = _q[0];", "let qr2 = _q[1] || _q[2];", "cr[0] = measure qr1[0];", "cr[1] = measure qr2[0];", "cr[2] = measure qr2[1];", "if (cr == 0) {", " x qr2[1];", "}", "if (cr == 1) {", " y qr1[0];", "}", "if (cr == 2) {", " z qr1[0];", "}", "", ]) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_reused_custom_gate_parameter(self): """Test reused custom gate with parameter.""" parameter_a = Parameter("a") custom = QuantumCircuit(1) custom.rx(parameter_a, 0) circuit = QuantumCircuit(1) circuit.append( custom.bind_parameters({ parameter_a: 0.5 }).to_gate(), [0]) circuit.append(custom.bind_parameters({parameter_a: 1}).to_gate(), [0]) circuit_name_0 = circuit.data[0][0].definition.name circuit_name_1 = circuit.data[1][0].definition.name expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', f"gate {circuit_name_0} q_0 {{", " rx(0.5) q_0;", "}", f"gate {circuit_name_1} q_0 {{", " rx(1) q_0;", "}", "qubit[1] _q;", "let q = _q[0];", f"{circuit_name_0} q[0];", f"{circuit_name_1} q[0];", "", ]) self.assertEqual(Exporter().dumps(circuit), expected_qasm)
def test_custom_gate_with_bound_parameter(self): """Test custom gate with bound parameter.""" parameter_a = Parameter("a") custom = QuantumCircuit(1) custom.rx(parameter_a, 0) custom_gate = custom.bind_parameters({parameter_a: 0.5}).to_gate() custom_gate.name = "custom" circuit = QuantumCircuit(1) circuit.append(custom_gate, [0]) expected_qasm = "\n".join( [ "OPENQASM 3;", 'include "stdgates.inc";', "gate custom q_0 {", " rx(0.5) q_0;", "}", "qubit[1] _q;", "let q = _q[0];", "custom q[0];", "", ] ) self.assertEqual(Exporter().dumps(circuit), expected_qasm)
def test_teleportation(self): """Teleportation with physical qubits""" qc = QuantumCircuit(3, 2) qc.h(1) qc.cx(1, 2) qc.barrier() qc.cx(0, 1) qc.h(0) qc.barrier() qc.measure([0, 1], [0, 1]) qc.barrier() qc.x(2).c_if(qc.clbits[1], 1) qc.z(2).c_if(qc.clbits[0], 1) transpiled = transpile(qc, initial_layout=[0, 1, 2]) expected_qasm = "\n".join( [ "OPENQASM 3;", "gate cx c, t {", " ctrl @ U(pi, 0, pi) c, t;", "}", "gate u3(param_0, param_1, param_2) q_0 {", " U(pi/2, 0, pi) q_0;", "}", "gate u2(param_0, param_1) q_0 {", " u3(pi/2, 0, pi) q_0;", "}", "gate h q_0 {", " u2(0, pi) q_0;", "}", "gate x q_0 {", " u3(pi, 0, pi) q_0;", "}", "gate u1(param_0) q_0 {", " u3(0, 0, pi) q_0;", "}", "gate z q_0 {", " u1(pi) q_0;", "}", "bit[2] c;", "h $1;", "cx $1, $2;", "barrier $0, $1, $2;", "cx $0, $1;", "h $0;", "barrier $0, $1, $2;", "c[0] = measure $0;", "c[1] = measure $1;", "barrier $0, $1, $2;", "if (c[1] == 1) {", " x $2;", "}", "if (c[0] == 1) {", " z $2;", "}", "", ] ) self.assertEqual(Exporter(includes=[]).dumps(transpiled), expected_qasm)
def test_pi_disable_constants_true(self): """Test pi constant (disable_constants=True)""" circuit = QuantumCircuit(2) circuit.u(2 * pi, 3 * pi, -5 * pi, 0) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "qubit[2] _q;", "let q = _q[0] || _q[1];", "U(6.283185307179586, 9.42477796076938, -15.707963267948966) q[0];", "", ]) self.assertEqual( Exporter(disable_constants=True).dumps(circuit), expected_qasm)
def test_pi_disable_constants_false(self): """Test pi constant (disable_constants=False)""" circuit = QuantumCircuit(2) circuit.u(2 * pi, 3 * pi, -5 * pi, 0) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "qubit[2] _q;", "let q = _q[0] || _q[1];", "U(2*pi, 3*pi, -5*pi) q[0];", "", ]) self.assertEqual( Exporter(disable_constants=False).dumps(circuit), expected_qasm)
def test_unbound_circuit(self): """Test with unbound parameters (turning them into inputs).""" qc = QuantumCircuit(1) theta = Parameter("θ") qc.rz(theta, 0) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "input float[32] θ;", "qubit[1] _q;", "let q = _q[0];", "rz(θ) q[0];", "", ]) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_no_include(self): """Test explicit gate declaration (no include)""" q = QuantumRegister(2, "q") circuit = QuantumCircuit(q) circuit.rz(pi / 2, 0) circuit.sx(0) circuit.cx(0, 1) expected_qasm = "\n".join( [ "OPENQASM 3;", "gate cx c, t {", " ctrl @ U(pi, 0, pi) c, t;", "}", "gate u3(param_0, param_1, param_2) q_0 {", " U(0, 0, pi/2) q_0;", "}", "gate u1(param_0) q_0 {", " u3(0, 0, pi/2) q_0;", "}", "gate rz(param_0) q_0 {", " u1(pi/2) q_0;", "}", "gate sdg q_0 {", " u1(-pi/2) q_0;", "}", "gate u2(param_0, param_1) q_0 {", " u3(pi/2, 0, pi) q_0;", "}", "gate h q_0 {", " u2(0, pi) q_0;", "}", "gate sx q_0 {", " sdg q_0;", " h q_0;", " sdg q_0;", "}", "qubit[2] _q;", "let q = _q[0] || _q[1];", "rz(pi/2) q[0];", "sx q[0];", "cx q[0], q[1];", "", ] ) self.assertEqual(Exporter(includes=[]).dumps(circuit), expected_qasm)
def test_gate_qasm_with_ctrl_state(self): """Test with open controlled gate that has ctrl_state""" qc = QuantumCircuit(2) qc.ch(0, 1, ctrl_state=0) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "gate ch_o0 q_0, q_1 {", " x q_0;", " ch q_0, q_1;", " x q_0;", "}", "qubit[2] _q;", "let q = _q[0] || _q[1];", "ch_o0 q[0], q[1];", "", ]) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_composite_circuits_with_same_name(self): """Test when multiple composite circuit instructions same name and different implementation""" my_gate = QuantumCircuit(1, name="my_gate") my_gate.h(0) my_gate_inst1 = my_gate.to_instruction() my_gate = QuantumCircuit(1, name="my_gate") my_gate.x(0) my_gate_inst2 = my_gate.to_instruction() my_gate = QuantumCircuit(1, name="my_gate") my_gate.x(0) my_gate_inst3 = my_gate.to_instruction() qr = QuantumRegister(1, name="qr") circuit = QuantumCircuit(qr, name="circuit") circuit.append(my_gate_inst1, [qr[0]]) circuit.append(my_gate_inst2, [qr[0]]) my_gate_inst2_id = id(circuit.data[-1][0]) circuit.append(my_gate_inst3, [qr[0]]) my_gate_inst3_id = id(circuit.data[-1][0]) expected_qasm = "\n".join( [ "OPENQASM 3;", 'include "stdgates.inc";', "def my_gate(qubit q_0) {", " h q_0;", "}", f"def my_gate_{my_gate_inst2_id}(qubit q_0) {{", " x q_0;", "}", f"def my_gate_{my_gate_inst3_id}(qubit q_0) {{", " x q_0;", "}", "qubit[1] _q;", "let qr = _q[0];", "my_gate qr[0];", f"my_gate_{my_gate_inst2_id} qr[0];", f"my_gate_{my_gate_inst3_id} qr[0];", "", ] ) self.assertEqual(Exporter().dumps(circuit), expected_qasm)
def test_same_composite_circuits(self): """Test when a composite circuit is added to the circuit multiple times.""" composite_circ_qreg = QuantumRegister(2) composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ") composite_circ.h(0) composite_circ.x(1) composite_circ.cx(0, 1) composite_circ_instr = composite_circ.to_instruction() qr = QuantumRegister(2, "qr") cr = ClassicalRegister(2, "cr") qc = QuantumCircuit(qr, cr) qc.h(0) qc.cx(0, 1) qc.barrier() qc.append(composite_circ_instr, [0, 1]) qc.append(composite_circ_instr, [0, 1]) qc.measure([0, 1], [0, 1]) expected_qasm = "\n".join( [ "OPENQASM 3;", 'include "stdgates.inc";', "def composite_circ(qubit q_0, qubit q_1) {", " h q_0;", " x q_1;", " cx q_0, q_1;", "}", "bit[2] cr;", "qubit[2] _q;", "let qr = _q[0] || _q[1];", "h qr[0];", "cx qr[0], qr[1];", "barrier qr[0], qr[1];", "composite_circ qr[0], qr[1];", "composite_circ qr[0], qr[1];", "cr[0] = measure qr[0];", "cr[1] = measure qr[1];", "", ] ) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_custom_gate_collision_with_stdlib(self): """Test a custom gate with name collision with the standard library.""" custom = QuantumCircuit(2, name="cx") custom.cx(0, 1) custom_gate = custom.to_gate() qc = QuantumCircuit(2) qc.append(custom_gate, [0, 1]) custom_gate_id = id(qc.data[-1][0]) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', f"gate cx_{custom_gate_id} q_0, q_1 {{", " cx q_0, q_1;", "}", "qubit[2] _q;", "let q = _q[0] || _q[1];", f"cx_{custom_gate_id} q[0], q[1];", "", ]) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_custom_gate(self): """Test custom gates (via to_gate).""" composite_circ_qreg = QuantumRegister(2) composite_circ = QuantumCircuit(composite_circ_qreg, name="composite_circ") composite_circ.h(0) composite_circ.x(1) composite_circ.cx(0, 1) composite_circ_instr = composite_circ.to_gate() qr = QuantumRegister(2, "qr") cr = ClassicalRegister(2, "cr") qc = QuantumCircuit(qr, cr) qc.h(0) qc.cx(0, 1) qc.barrier() qc.append(composite_circ_instr, [0, 1]) qc.measure([0, 1], [0, 1]) expected_qasm = "\n".join( [ "OPENQASM 3;", 'include "stdgates.inc";', "gate composite_circ q_0, q_1 {", " h q_0;", " x q_1;", " cx q_0, q_1;", "}", "bit[2] cr;", "qubit[2] _q;", "let qr = _q[0] || _q[1];", "h qr[0];", "cx qr[0], qr[1];", "barrier qr[0], qr[1];", "composite_circ qr[0], qr[1];", "cr[0] = measure qr[0];", "cr[1] = measure qr[1];", "", ] ) self.assertEqual(Exporter().dumps(qc), expected_qasm)
def test_reset_statement(self): """Test that a reset statement gets output into valid QASM 3. This includes tests of reset operations on single qubits and in nested scopes.""" inner = QuantumCircuit(1, name="inner_gate") inner.reset(0) qreg = QuantumRegister(2, "qr") qc = QuantumCircuit(qreg) qc.reset(0) qc.append(inner, [1], []) expected_qasm = "\n".join([ "OPENQASM 3;", "def inner_gate(qubit q_0) {", " reset q_0;", "}", "qubit[2] _q;", "let qr = _q[0] || _q[1];", "reset qr[0];", "inner_gate qr[1];", "", ]) self.assertEqual(Exporter(includes=[]).dumps(qc), expected_qasm)
def test_custom_gate_with_unbound_parameter(self): """Test custom gate with unbound parameter.""" parameter_a = Parameter("a") custom = QuantumCircuit(1, name="custom") custom.rx(parameter_a, 0) circuit = QuantumCircuit(1) circuit.append(custom.to_gate(), [0]) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "gate custom(a) q_0 {", " rx(a) q_0;", "}", "input float[32] a;", "qubit[1] _q;", "let q = _q[0];", "custom(a) q[0];", "", ]) self.assertEqual(Exporter().dumps(circuit), expected_qasm)