From d39c7c3ad5573925c8767c2421ac5605a7293c69 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Sat, 18 Nov 2023 02:11:22 +0000 Subject: [PATCH] Fix `QuantumCircuit.barrier` argument conversion (#11272) (#11273) * Fix `QuantumCircuit.barrier` argument conversion The manual argument conversion within `QuantumCircuit.barrier` made it inconsistent with the rest of the circuit methods, and it would silently generate invalid circuit output when given iterables outside an expected set. This switches the method to use the standard argument conversion, bringing it inline with the rest of the circuit methods. * Include link to issue Co-authored-by: Matthew Treinish --------- Co-authored-by: Matthew Treinish (cherry picked from commit 252dbd5c86de44b96f99ec2b2f3ae2d871921a4d) Co-authored-by: Jake Lishman --- qiskit/circuit/quantumcircuit.py | 23 +++++-------------- .../fix-circuit-barrier-c696eabae1dcc6c2.yaml | 7 ++++++ .../python/circuit/test_circuit_operations.py | 21 +++++++++++++++++ 3 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 releasenotes/notes/fix-circuit-barrier-c696eabae1dcc6c2.yaml diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index 16ec9da9f91c..1f741280fb47 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -2850,23 +2850,12 @@ def barrier(self, *qargs: QubitSpecifier, label=None) -> InstructionSet: """ from .barrier import Barrier - qubits: list[QubitSpecifier] = [] - - if not qargs: # None - qubits.extend(self.qubits) - - for qarg in qargs: - if isinstance(qarg, QuantumRegister): - qubits.extend([qarg[j] for j in range(qarg.size)]) - elif isinstance(qarg, list): - qubits.extend(qarg) - elif isinstance(qarg, range): - qubits.extend(list(qarg)) - elif isinstance(qarg, slice): - qubits.extend(self.qubits[qarg]) - else: - qubits.append(qarg) - + qubits = ( + # This uses a `dict` not a `set` to guarantee a deterministic order to the arguments. + list({q: None for qarg in qargs for q in self.qbit_argument_conversion(qarg)}) + if qargs + else self.qubits.copy() + ) return self.append(Barrier(len(qubits), label=label), qubits, []) def delay( diff --git a/releasenotes/notes/fix-circuit-barrier-c696eabae1dcc6c2.yaml b/releasenotes/notes/fix-circuit-barrier-c696eabae1dcc6c2.yaml new file mode 100644 index 000000000000..b16792f8fb3f --- /dev/null +++ b/releasenotes/notes/fix-circuit-barrier-c696eabae1dcc6c2.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + :meth:`.QuantumCircuit.barrier` will now generate correct output when given a :class:`set` as + one of its inputs. Previously, it would append an invalid operation onto the circuit, though in + practice this usually would not cause observable problems. + Fixed `#11208 `__ diff --git a/test/python/circuit/test_circuit_operations.py b/test/python/circuit/test_circuit_operations.py index 11770d896bc6..3f773fb09abc 100644 --- a/test/python/circuit/test_circuit_operations.py +++ b/test/python/circuit/test_circuit_operations.py @@ -420,6 +420,27 @@ def test_clear_circuit(self): self.assertEqual(len(qc.data), 0) self.assertEqual(len(qc._parameter_table), 0) + def test_barrier(self): + """Test multiple argument forms of barrier.""" + qr1, qr2 = QuantumRegister(3, "qr1"), QuantumRegister(4, "qr2") + qc = QuantumCircuit(qr1, qr2) + qc.barrier() # All qubits. + qc.barrier(0, 1) + qc.barrier([4, 2]) + qc.barrier(qr1) + qc.barrier(slice(3, 5)) + qc.barrier({1, 4, 2}, range(5, 7)) + + expected = QuantumCircuit(qr1, qr2) + expected.append(Barrier(expected.num_qubits), expected.qubits.copy(), []) + expected.append(Barrier(2), [expected.qubits[0], expected.qubits[1]], []) + expected.append(Barrier(2), [expected.qubits[2], expected.qubits[4]], []) + expected.append(Barrier(3), expected.qubits[0:3], []) + expected.append(Barrier(2), [expected.qubits[3], expected.qubits[4]], []) + expected.append(Barrier(5), [expected.qubits[x] for x in [1, 2, 4, 5, 6]], []) + + self.assertEqual(qc, expected) + def test_measure_active(self): """Test measure_active Applies measurements only to non-idle qubits. Creates a ClassicalRegister of size equal to