def test_apply_operation_back_conditional_measure(self): """Test consistency of apply_operation_back for conditional measure.""" # Measure targeting a clbit which is not a member of the conditional # register. qc.measure(qr[0], cr[0]).c_if(cr2, 0) new_creg = ClassicalRegister(1, 'cr2') self.dag.add_creg(new_creg) meas_gate = Measure() meas_gate.condition = (new_creg, 0) meas_node = self.dag.apply_operation_back(meas_gate, [self.qubit0], [self.clbit0], meas_gate.condition) self.assertEqual(meas_node.qargs, [self.qubit0]) self.assertEqual(meas_node.cargs, [self.clbit0]) self.assertEqual(meas_node.condition, meas_gate.condition) self.assertEqual( sorted(self.dag._multi_graph.in_edges(meas_node, data=True)), sorted([ (self.dag.input_map[self.qubit0], meas_node, { 'wire': self.qubit0, 'name': 'qr[0]' }), (self.dag.input_map[self.clbit0], meas_node, { 'wire': self.clbit0, 'name': 'cr[0]' }), (self.dag.input_map[new_creg[0]], meas_node, { 'wire': Clbit(new_creg, 0), 'name': 'cr2[0]' }), ])) self.assertEqual( sorted(self.dag._multi_graph.out_edges(meas_node, data=True)), sorted([ (meas_node, self.dag.output_map[self.qubit0], { 'wire': self.qubit0, 'name': 'qr[0]' }), (meas_node, self.dag.output_map[self.clbit0], { 'wire': self.clbit0, 'name': 'cr[0]' }), (meas_node, self.dag.output_map[new_creg[0]], { 'wire': Clbit(new_creg, 0), 'name': 'cr2[0]' }), ])) self.assertTrue(nx.is_directed_acyclic_graph(self.dag._multi_graph))
def test_registerless_one_bit(self): """Text circuit with one-bit registers and registerless bits.""" filename = self._get_resource_path( "test_latex_registerless_one_bit.tex") qrx = QuantumRegister(2, "qrx") qry = QuantumRegister(1, "qry") crx = ClassicalRegister(2, "crx") circuit = QuantumCircuit(qrx, [Qubit(), Qubit()], qry, [Clbit(), Clbit()], crx) circuit_drawer(circuit, filename=filename, output="latex_source") self.assertEqualToReference(filename)
def test_conditions_with_bits_reverse(self): """Test that gates with conditions and measures work with bits reversed""" filename = self._get_resource_path("test_latex_cond_reverse.tex") bits = [Qubit(), Qubit(), Clbit(), Clbit()] cr = ClassicalRegister(2, "cr") crx = ClassicalRegister(3, "cs") circuit = QuantumCircuit(bits, cr, [Clbit()], crx) circuit.x(0).c_if(bits[3], 0) circuit_drawer( circuit, cregbundle=False, reverse_bits=True, filename=filename, output="latex_source" ) self.assertEqualToReference(filename)
def test_apply_operation_back_conditional_measure_to_self(self): """Test consistency of apply_operation_back for measure onto conditioning bit.""" # Measure targeting a clbit which _is_ a member of the conditional # register. qc.measure(qr[0], cr[0]).c_if(cr, 3) meas_gate = Measure() meas_gate.control = self.condition meas_node = self.dag.apply_operation_back(meas_gate, [self.qubit1], [self.clbit1], self.condition) self.assertEqual(meas_node.qargs, [self.qubit1]) self.assertEqual(meas_node.cargs, [self.clbit1]) self.assertEqual(meas_node.condition, meas_gate.control) self.assertEqual( sorted(self.dag._multi_graph.in_edges(meas_node, data=True)), sorted([ (self.dag.input_map[self.qubit1], meas_node, { 'wire': Qubit(*self.qubit1), 'name': 'qr[1]' }), (self.dag.input_map[self.clbit0], meas_node, { 'wire': Clbit(*self.clbit0), 'name': 'cr[0]' }), (self.dag.input_map[self.clbit1], meas_node, { 'wire': Clbit(*self.clbit1), 'name': 'cr[1]' }), ])) self.assertEqual( sorted(self.dag._multi_graph.out_edges(meas_node, data=True)), sorted([ (meas_node, self.dag.output_map[self.qubit1], { 'wire': Qubit(*self.qubit1), 'name': 'qr[1]' }), (meas_node, self.dag.output_map[self.clbit0], { 'wire': Clbit(*self.clbit0), 'name': 'cr[0]' }), (meas_node, self.dag.output_map[self.clbit1], { 'wire': Clbit(*self.clbit1), 'name': 'cr[1]' }), ])) self.assertTrue(nx.is_directed_acyclic_graph(self.dag._multi_graph))
def test_conditions_measures_with_bits(self): """Test that gates with conditions and measures work with bits""" bits = [Qubit(), Qubit(), Clbit(), Clbit()] cr = ClassicalRegister(2, "cr") crx = ClassicalRegister(3, "cs") circuit = QuantumCircuit(bits, cr, [Clbit()], crx) circuit.x(0).c_if(crx[1], 0) circuit.measure(0, bits[3]) self.circuit_drawer(circuit, cregbundle=False, filename="measure_cond_bits_false.png") self.circuit_drawer(circuit, cregbundle=True, filename="measure_cond_bits_true.png")
def test_measures_with_conditions_with_bits(self): """Condition and measure on single bits cregbundle true""" filename1 = self._get_resource_path("test_latex_meas_cond_bits_false.tex") filename2 = self._get_resource_path("test_latex_meas_cond_bits_true.tex") bits = [Qubit(), Qubit(), Clbit(), Clbit()] cr = ClassicalRegister(2, "cr") crx = ClassicalRegister(3, "cs") circuit = QuantumCircuit(bits, cr, [Clbit()], crx) circuit.x(0).c_if(crx[1], 0) circuit.measure(0, bits[3]) circuit_drawer(circuit, cregbundle=False, filename=filename1, output="latex_source") circuit_drawer(circuit, cregbundle=True, filename=filename2, output="latex_source") self.assertEqualToReference(filename1) self.assertEqualToReference(filename2)
def test_apply_operation_back_conditional(self): """Test consistency of apply_operation_back with condition set.""" # Single qubit gate conditional: qc.h(qr[2]).c_if(cr, 3) h_gate = HGate() h_gate.control = self.condition h_node = self.dag.apply_operation_back(h_gate, [self.qubit2], [], h_gate.control) self.assertEqual(h_node.qargs, [self.qubit2]) self.assertEqual(h_node.cargs, []) self.assertEqual(h_node.condition, h_gate.control) self.assertEqual( sorted(self.dag._multi_graph.in_edges(h_node, data=True)), sorted([ (self.dag.input_map[self.qubit2], h_node, { 'wire': Qubit(*self.qubit2), 'name': 'qr[2]' }), (self.dag.input_map[self.clbit0], h_node, { 'wire': Clbit(*self.clbit0), 'name': 'cr[0]' }), (self.dag.input_map[self.clbit1], h_node, { 'wire': Clbit(*self.clbit1), 'name': 'cr[1]' }), ])) self.assertEqual( sorted(self.dag._multi_graph.out_edges(h_node, data=True)), sorted([ (h_node, self.dag.output_map[self.qubit2], { 'wire': Qubit(*self.qubit2), 'name': 'qr[2]' }), (h_node, self.dag.output_map[self.clbit0], { 'wire': Clbit(*self.clbit0), 'name': 'cr[0]' }), (h_node, self.dag.output_map[self.clbit1], { 'wire': Clbit(*self.clbit1), 'name': 'cr[1]' }), ])) self.assertTrue(nx.is_directed_acyclic_graph(self.dag._multi_graph))
def test_instructionset_c_if_with_no_requester(self): """Test that using a raw :obj:`.InstructionSet` with no classical-resource resoluer accepts arbitrary :obj:`.Clbit` and `:obj:`.ClassicalRegister` instances, but rejects integers.""" with self.subTest("accepts arbitrary register"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) register = ClassicalRegister(2) instructions.c_if(register, 0) self.assertIs(instruction.condition[0], register) with self.subTest("accepts arbitrary bit"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) bit = Clbit() instructions.c_if(bit, 0) self.assertIs(instruction.condition[0], bit) with self.subTest("rejects index"): instruction = HGate() instructions = InstructionSet() instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, r"Cannot pass an index as a condition .*"): instructions.c_if(0, 0)
def test_if_else_invalid_params_setter(self): """Verify we catch invalid param settings for IfElseOp.""" condition = (Clbit(), True) true_body = QuantumCircuit(3, 1) false_body = QuantumCircuit(3, 1) op = IfElseOp(condition, true_body, false_body) with self.assertRaisesRegex( CircuitError, r"true_body parameter of type QuantumCircuit"): op.params = [XGate(), None] with self.assertRaisesRegex( CircuitError, r"false_body parameter of type QuantumCircuit"): op.params = [true_body, XGate()] bad_body = QuantumCircuit(4, 2) with self.assertRaisesRegex( CircuitError, r"num_clbits different than that of the IfElseOp"): op.params = [true_body, bad_body] with self.assertRaisesRegex( CircuitError, r"num_clbits different than that of the IfElseOp"): op.params = [bad_body, false_body] with self.assertRaisesRegex( CircuitError, r"num_clbits different than that of the IfElseOp"): op.params = [bad_body, bad_body]
def test_if_else_invalid_instantiation(self): """Verify we catch invalid instantiations of IfElseOp.""" condition = (Clbit(), True) true_body = QuantumCircuit(3, 1) false_body = QuantumCircuit(3, 1) with self.assertRaisesRegex( CircuitError, r"A classical condition should be a 2-tuple"): _ = IfElseOp(1, true_body, false_body) with self.assertRaisesRegex( CircuitError, r"A classical condition should be a 2-tuple"): _ = IfElseOp((1, 2), true_body, false_body) with self.assertRaisesRegex( CircuitError, r"true_body parameter of type QuantumCircuit"): _ = IfElseOp(condition, XGate()) with self.assertRaisesRegex( CircuitError, r"false_body parameter of type QuantumCircuit"): _ = IfElseOp(condition, true_body, XGate()) bad_body = QuantumCircuit(4, 2) with self.assertRaisesRegex( CircuitError, r"num_clbits different than that of the IfElseOp"): _ = IfElseOp(condition, true_body, bad_body)
def test_instructionset_c_if_rejects_invalid_specifiers(self): """Test that calling the :meth:`.InstructionSet.c_if` method on instructions added to a circuit raises a suitable exception if an invalid specifier is passed to it.""" qreg = QuantumRegister(1) creg = ClassicalRegister(2) def case(specifier, message): qc = QuantumCircuit(qreg, creg) instruction = qc.x(0) with self.assertRaisesRegex(CircuitError, message): instruction.c_if(specifier, 0) with self.subTest("absent bit"): case(Clbit(), r"Clbit .* is not present in this circuit\.") with self.subTest("absent register"): case(ClassicalRegister(2), r"Register .* is not present in this circuit\.") with self.subTest("index out of range"): case(2, r"Classical bit index .* is out-of-range\.") with self.subTest("list of bits"): case(list(creg), r"Unknown classical resource specifier: .*") with self.subTest("tuple of bits"): case(tuple(creg), r"Unknown classical resource specifier: .*") with self.subTest("float"): case(1.0, r"Unknown classical resource specifier: .*")
def test_circuit_qasm_with_registerless_bits(self): """Test that registerless bits do not have naming collisions in their registers.""" initial_registers = [QuantumRegister(2), ClassicalRegister(2)] qc = QuantumCircuit(*initial_registers, [Qubit(), Clbit()]) # Match a 'qreg identifier[3];'-like QASM register declaration. register_regex = re.compile(r"\s*[cq]reg\s+(\w+)\s*\[\d+\]\s*", re.M) qasm_register_names = set() for statement in qc.qasm().split(";"): match = register_regex.match(statement) if match: qasm_register_names.add(match.group(1)) self.assertEqual(len(qasm_register_names), 4) # Check that no additional registers were added to the circuit. self.assertEqual(len(qc.qregs), 1) self.assertEqual(len(qc.cregs), 1) # Check that the registerless-register names are recalculated after adding more registers, # to avoid naming clashes in this case. generated_names = qasm_register_names - { register.name for register in initial_registers } for generated_name in generated_names: qc.add_register(QuantumRegister(1, name=generated_name)) qasm_register_names = set() for statement in qc.qasm().split(";"): match = register_regex.match(statement) if match: qasm_register_names.add(match.group(1)) self.assertEqual(len(qasm_register_names), 6)
def test_get_layered_instructions_right_justification_less_simple(self): """ Test _get_layered_instructions right justification less simple example since #2802 ┌────────────┐┌───┐┌────────────┐┌─┐┌────────────┐┌───┐┌────────────┐ q_0: |0>┤ U2(0,pi/1) ├┤ X ├┤ U2(0,pi/1) ├┤M├┤ U2(0,pi/1) ├┤ X ├┤ U2(0,pi/1) ├ ├────────────┤└─┬─┘├────────────┤└╥┘├────────────┤└─┬─┘├────────────┤ q_1: |0>┤ U2(0,pi/1) ├──■──┤ U2(0,pi/1) ├─╫─┤ U2(0,pi/1) ├──■──┤ U2(0,pi/1) ├ └────────────┘ └────────────┘ ║ └────────────┘ └────────────┘ q_2: |0>──────────────────────────────────╫────────────────────────────────── ║ q_3: |0>──────────────────────────────────╫────────────────────────────────── ║ q_4: |0>──────────────────────────────────╫────────────────────────────────── ║ c1_0: 0 ══════════════════════════════════╩══════════════════════════════════ """ qasm = """ OPENQASM 2.0; include "qelib1.inc"; qreg q[5]; creg c1[1]; u2(0,3.14159265358979) q[0]; u2(0,3.14159265358979) q[1]; cx q[1],q[0]; u2(0,3.14159265358979) q[0]; u2(0,3.14159265358979) q[1]; u2(0,3.14159265358979) q[1]; measure q[0] -> c1[0]; u2(0,3.14159265358979) q[0]; cx q[1],q[0]; u2(0,3.14159265358979) q[0]; u2(0,3.14159265358979) q[1]; """ qc = QuantumCircuit.from_qasm_str(qasm) (_, _, layered_ops) = utils._get_layered_instructions(qc, justify='right') r_exp = [[('u2', [Qubit(QuantumRegister(5, 'q'), 0)], []), ('u2', [Qubit(QuantumRegister(5, 'q'), 1)], [])], [('cx', [ Qubit(QuantumRegister(5, 'q'), 1), Qubit(QuantumRegister(5, 'q'), 0) ], [])], [('u2', [Qubit(QuantumRegister(5, 'q'), 0)], []), ('u2', [Qubit(QuantumRegister(5, 'q'), 1)], [])], [('measure', [Qubit(QuantumRegister(5, 'q'), 0)], [Clbit(ClassicalRegister(1, 'c1'), 0)])], [('u2', [Qubit(QuantumRegister(5, 'q'), 0)], []), ('u2', [Qubit(QuantumRegister(5, 'q'), 1)], [])], [('cx', [ Qubit(QuantumRegister(5, 'q'), 1), Qubit(QuantumRegister(5, 'q'), 0) ], [])], [('u2', [Qubit(QuantumRegister(5, 'q'), 0)], []), ('u2', [Qubit(QuantumRegister(5, 'q'), 1)], [])]] self.assertEqual(r_exp, [[(op.name, op.qargs, op.cargs) for op in ops] for ops in layered_ops])
def test_add_registerless_bits(self): """Verify we can add are retrieve bits without an associated register.""" qubits = [Qubit() for _ in range(5)] clbits = [Clbit() for _ in range(3)] dag = DAGDependency() dag.add_qubits(qubits) dag.add_clbits(clbits) self.assertEqual(dag.qubits, qubits) self.assertEqual(dag.clbits, clbits)
def test_instructionset_c_if_direct_resource(self): """Test that using :meth:`.InstructionSet.c_if` with an exact classical resource always works, and produces the expected condition.""" cr1 = ClassicalRegister(3) qubits = [Qubit()] loose_clbits = [Clbit(), Clbit(), Clbit()] # These bits are going into registers which overlap. register_clbits = [Clbit(), Clbit(), Clbit()] cr2 = ClassicalRegister(bits=register_clbits[:2]) cr3 = ClassicalRegister(bits=register_clbits[1:]) def case(resource): qc = QuantumCircuit(cr1, qubits, loose_clbits, cr2, cr3) qc.x(0).c_if(resource, 0) c_if_resource = qc.data[0].operation.condition[0] self.assertIs(c_if_resource, resource) with self.subTest("classical register"): case(cr1) with self.subTest("bit from classical register"): case(cr1[0]) with self.subTest("loose bit"): case(loose_clbits[0]) with self.subTest("overlapping register left"): case(cr2) with self.subTest("overlapping register right"): case(cr3) with self.subTest("bit in two different registers"): case(register_clbits[1])
def test_if_else_simple(self): """Test a simple if-else statement unrolls correctly.""" qubits = [Qubit(), Qubit()] clbits = [Clbit(), Clbit()] qc = QuantumCircuit(qubits, clbits) qc.h(0) qc.measure(0, 0) with qc.if_test((clbits[0], 0)) as else_: qc.x(0) with else_: qc.z(0) qc.h(0) qc.measure(0, 1) with qc.if_test((clbits[1], 0)) as else_: qc.h(1) qc.cx(1, 0) with else_: qc.h(0) qc.cx(0, 1) dag = circuit_to_dag(qc) unrolled_dag = Unroller(["u", "cx"]).run(dag) expected = QuantumCircuit(qubits, clbits) expected.u(pi / 2, 0, pi, 0) expected.measure(0, 0) with expected.if_test((clbits[0], 0)) as else_: expected.u(pi, 0, pi, 0) with else_: expected.u(0, 0, pi, 0) expected.u(pi / 2, 0, pi, 0) expected.measure(0, 1) with expected.if_test((clbits[1], 0)) as else_: expected.u(pi / 2, 0, pi, 1) expected.cx(1, 0) with else_: expected.u(pi / 2, 0, pi, 0) expected.cx(0, 1) expected_dag = circuit_to_dag(expected) self.assertEqual(unrolled_dag, expected_dag)
def test_add_duplicate_registerless_bits(self): """Verify we raise when adding a bit already present in the circuit.""" qubits = [Qubit() for _ in range(5)] clbits = [Clbit() for _ in range(3)] dag = DAGDependency() dag.add_qubits(qubits) dag.add_clbits(clbits) with self.assertRaisesRegex(DAGDependencyError, r"duplicate qubits"): dag.add_qubits(qubits[:1]) with self.assertRaisesRegex(DAGDependencyError, r"duplicate clbits"): dag.add_clbits(clbits[:1])
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)
def test_instructionset_c_if_no_classical_registers(self): """Test that using :meth:`.InstructionSet.c_if` works if there are no classical registers defined on the circuit. Regression test for gh-7250.""" bits = [Qubit(), Clbit()] qc = QuantumCircuit(bits) with self.subTest("by value"): qc.x(0).c_if(bits[1], 0) self.assertIs(qc.data[-1].operation.condition[0], bits[1]) with self.subTest("by index"): qc.x(0).c_if(0, 0) self.assertIs(qc.data[-1].operation.condition[0], bits[1])
def test_flatten_circuit_registerless(self): """Test that the conversion works when the given circuit has bits that are not contained in any register.""" qr1 = QuantumRegister(2) qubits = [Qubit(), Qubit(), Qubit()] qr2 = QuantumRegister(3) cr1 = ClassicalRegister(2) clbits = [Clbit(), Clbit(), Clbit()] cr2 = ClassicalRegister(3) circ = QuantumCircuit(qr1, qubits, qr2, cr1, clbits, cr2) circ.cx(3, 5) circ.measure(4, 4) inst = circuit_to_instruction(circ) self.assertEqual(inst.num_qubits, len(qr1) + len(qubits) + len(qr2)) self.assertEqual(inst.num_clbits, len(cr1) + len(clbits) + len(cr2)) inst_definition = inst.definition _, cx_qargs, cx_cargs = inst_definition.data[0] _, measure_qargs, measure_cargs = inst_definition.data[1] self.assertEqual(cx_qargs, [inst_definition.qubits[3], inst_definition.qubits[5]]) self.assertEqual(cx_cargs, []) self.assertEqual(measure_qargs, [inst_definition.qubits[4]]) self.assertEqual(measure_cargs, [inst_definition.clbits[4]])
def test_dag_drawer_no_register(self): """Test dag visualization with a circuit with no registers.""" qubit = Qubit() clbit = Clbit() qc = QuantumCircuit([qubit, clbit]) qc.h(0) qc.measure(0, 0) dag = circuit_to_dag(qc) with tempfile.TemporaryDirectory() as tmpdirname: tmp_path = os.path.join(tmpdirname, "dag.png") dag_drawer(dag, filename=tmp_path) image_ref = path_to_diagram_reference("dag_no_reg.png") image = Image.open(tmp_path) self.assertImagesAreEqual(image, image_ref, 0.2)
def test_condition_mapping_whileloopop(self): """Test that the condition in a `WhileLoopOp` is correctly mapped to a new set of bits and registers.""" base_loose = Clbit() base_creg = ClassicalRegister(2) base_qreg = QuantumRegister(1) base = QuantumCircuit(base_qreg, [base_loose], base_creg) with base.while_loop((base_loose, True)): base.x(0) with base.while_loop((base_creg, 3)): base.x(0) test_loose = Clbit() test_creg = ClassicalRegister(2) test_qreg = QuantumRegister(1) test = QuantumCircuit(test_qreg, [test_loose], test_creg).compose(base) bit_instruction = test.data[0].operation reg_instruction = test.data[1].operation self.assertIs(bit_instruction.condition[0], test_loose) self.assertEqual(bit_instruction.condition, (test_loose, True)) self.assertIs(reg_instruction.condition[0], test_creg) self.assertEqual(reg_instruction.condition, (test_creg, 3))
def test_circuit_constructor_on_bits(self): """Verify we can add bits directly to a circuit.""" qubits = [Qubit(), Qubit()] clbits = [Clbit()] ancillas = [AncillaQubit(), AncillaQubit()] qc = QuantumCircuit(qubits, clbits, ancillas) self.assertEqual(qc.qubits, qubits + ancillas) self.assertEqual(qc.clbits, clbits) self.assertEqual(qc.ancillas, ancillas) self.assertEqual(qc.qregs, []) self.assertEqual(qc.cregs, [])
def test_get_layered_instructions_op_with_cargs(self): """Test _get_layered_instructions op with cargs right of measure ┌───┐┌─┐ q_0: |0>┤ H ├┤M├───────────── └───┘└╥┘┌───────────┐ q_1: |0>──────╫─┤0 ├ ║ │ add_circ │ c_0: 0 ══════╩═╡0 ╞ └───────────┘ c_1: 0 ═════════════════════ """ qc = QuantumCircuit(2, 2) qc.h(0) qc.measure(0, 0) qc_2 = QuantumCircuit(1, 1, name="add_circ") qc_2.h(0).c_if(qc_2.cregs[0], 1) qc_2.measure(0, 0) qc.append(qc_2, [1], [0]) (_, _, layered_ops) = utils._get_layered_instructions(qc) expected = [ [("h", [Qubit(QuantumRegister(2, "q"), 0)], [])], [( "measure", [Qubit(QuantumRegister(2, "q"), 0)], [Clbit(ClassicalRegister(2, "c"), 0)], )], [( "add_circ", [Qubit(QuantumRegister(2, "q"), 1)], [Clbit(ClassicalRegister(2, "c"), 0)], )], ] self.assertEqual(expected, [[(op.name, op.qargs, op.cargs) for op in ops] for ops in layered_ops])
def test_while_loop_invalid_instantiation(self): """Verify we catch invalid instantiations of WhileLoopOp.""" body = QuantumCircuit(3, 1) condition = (body.clbits[0], True) with self.assertRaisesRegex( CircuitError, r"A classical condition should be a 2-tuple"): _ = WhileLoopOp(0, body) with self.assertRaisesRegex( CircuitError, r"A classical condition should be a 2-tuple"): _ = WhileLoopOp((Clbit(), None), body) with self.assertRaisesRegex(CircuitError, r"of type QuantumCircuit"): _ = WhileLoopOp(condition, XGate())
def test_registerless_classical_bits(self): """Test that conditions on registerless classical bits can be handled during the conversion. Regression test of gh-7394.""" expected = QuantumCircuit([Qubit(), Clbit()]) expected.h(0).c_if(expected.clbits[0], 0) test = circuit_to_instruction(expected) self.assertIsInstance(test, Instruction) self.assertIsInstance(test.definition, QuantumCircuit) self.assertEqual(len(test.definition.data), 1) test_instruction, _, _ = test.definition.data[0] expected_instruction, _, _ = expected.data[0] self.assertIs(type(test_instruction), type(expected_instruction)) self.assertEqual(test_instruction.condition, (test.definition.clbits[0], 0))
def test_transpile_optional_registers(self, optimization_level): """Verify transpile accepts circuits without registers end-to-end.""" qubits = [Qubit() for _ in range(3)] clbits = [Clbit() for _ in range(3)] qc = QuantumCircuit(qubits, clbits) qc.h(0) qc.cx(0, 1) qc.cx(1, 2) qc.measure(qubits, clbits) out = transpile(qc, FakeAlmaden(), optimization_level=optimization_level) self.assertEqual(len(out.qubits), FakeAlmaden().configuration().num_qubits) self.assertEqual(out.clbits, clbits)
def test_flatten_circuit_overlapping_registers(self): """Test that the conversion works when the given circuit has bits that are contained in more than one register.""" qubits = [Qubit() for _ in [None] * 10] qr1 = QuantumRegister(bits=qubits[:6]) qr2 = QuantumRegister(bits=qubits[4:]) clbits = [Clbit() for _ in [None] * 10] cr1 = ClassicalRegister(bits=clbits[:6]) cr2 = ClassicalRegister(bits=clbits[4:]) circ = QuantumCircuit(qubits, clbits, qr1, qr2, cr1, cr2) circ.cx(3, 5) circ.measure(4, 4) inst = circuit_to_instruction(circ) self.assertEqual(inst.num_qubits, len(qubits)) self.assertEqual(inst.num_clbits, len(clbits)) inst_definition = inst.definition _, cx_qargs, cx_cargs = inst_definition.data[0] _, measure_qargs, measure_cargs = inst_definition.data[1] self.assertEqual(cx_qargs, [inst_definition.qubits[3], inst_definition.qubits[5]]) self.assertEqual(cx_cargs, []) self.assertEqual(measure_qargs, [inst_definition.qubits[4]]) self.assertEqual(measure_cargs, [inst_definition.clbits[4]])
def test_instructionset_c_if_indexing(self): """Test that using :meth:`.InstructionSet.c_if` with an index for the classical resource resolves to the same value that :obj:`.QuantumCircuit` would resolve it to. Regression test for gh-7246.""" cr1 = ClassicalRegister(3) qubits = [Qubit()] loose_clbits = [Clbit(), Clbit(), Clbit()] # These bits are going into registers which overlap. register_clbits = [Clbit(), Clbit(), Clbit()] cr2 = ClassicalRegister(bits=register_clbits[:2]) cr3 = ClassicalRegister(bits=register_clbits[1:]) qc = QuantumCircuit(cr1, qubits, loose_clbits, cr2, cr3) for index, clbit in enumerate(qc.clbits): with self.subTest(index=index): qc.x(0).c_if(index, 0) qc.measure(0, index) from_c_if = qc.data[-2].operation.condition[0] from_measure = qc.data[-1].clbits[0] self.assertIs(from_c_if, from_measure) # Sanity check that the bit is also the one we expected. self.assertIs(from_c_if, clbit)
def test_instructionset_c_if_deprecated_resolution(self): r"""Test that the deprecated path of passing an iterable of :obj:`.ClassicalRegister`\ s to :obj:`.InstructionSet` works, issues a deprecation warning, and resolves indices in the simple cases it was meant to handle.""" # The deprecated path can only cope with non-overlapping classical registers, with no loose # clbits in the mix. registers = [ ClassicalRegister(2), ClassicalRegister(3), ClassicalRegister(1) ] bits = [bit for register in registers for bit in register] deprecated_regex = r"The 'circuit_cregs' argument to 'InstructionSet' is deprecated .*" def dummy_requester(specifier): """A dummy requester that technically fulfills the spec.""" raise CircuitError with self.subTest("cannot pass both registers and requester"): with self.assertRaisesRegex( CircuitError, r"Cannot pass both 'circuit_cregs' and 'resource_requester'\." ): InstructionSet(registers, resource_requester=dummy_requester) with self.subTest("classical register"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(registers[0], 0) self.assertIs(instruction.condition[0], registers[0]) with self.subTest("classical bit"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(registers[0][1], 0) self.assertIs(instruction.condition[0], registers[0][1]) for i, bit in enumerate(bits): with self.subTest("bit index", index=i): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) instructions.c_if(i, 0) self.assertIs(instruction.condition[0], bit) with self.subTest("raises on bad register"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, r"Condition register .* is not one of the registers known here: .*" ): instructions.c_if(ClassicalRegister(2), 0) with self.subTest("raises on bad bit"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex( CircuitError, "Condition bit .* is not in the registers known here: .*"): instructions.c_if(Clbit(), 0) with self.subTest("raises on bad index"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex(CircuitError, r"Bit index .* is out-of-range\."): instructions.c_if(len(bits), 0) with self.subTest("raises on bad type"): instruction = HGate() with self.assertWarnsRegex(DeprecationWarning, deprecated_regex): instructions = InstructionSet(registers) instructions.add(instruction, [Qubit()], []) with self.assertRaisesRegex(CircuitError, r"Invalid classical condition\. .*"): instructions.c_if([0], 0)