Skip to content

Commit

Permalink
Fix QuantumCircuit.barrier argument conversion (#11272)
Browse files Browse the repository at this point in the history
* 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 <mtreinish@kortar.org>

---------

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
(cherry picked from commit 252dbd5)
  • Loading branch information
jakelishman authored and mergify[bot] committed Nov 18, 2023
1 parent 4b1d392 commit 7882958
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 17 deletions.
23 changes: 6 additions & 17 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
7 changes: 7 additions & 0 deletions releasenotes/notes/fix-circuit-barrier-c696eabae1dcc6c2.yaml
Original file line number Diff line number Diff line change
@@ -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 <https://github.com/Qiskit/qiskit/issues/11208>`__
21 changes: 21 additions & 0 deletions test/python/circuit/test_circuit_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7882958

Please sign in to comment.