Skip to content

Commit

Permalink
Fix loose-bit handling in QPY (Qiskit#8928)
Browse files Browse the repository at this point in the history
A typo in clbit-reconstruction was generating the incorrect number of
loose clbits in circuits that contained registers and loose bits, and
had more qubits than clbits.  A bug elsewhere in the code caused
circuits with _no_ registers to be deserialised as containing registers,
since the `QuantumCircuit(int, int)` constructor actually does produce
two registers (slightly surprisingly, perhaps).
  • Loading branch information
jakelishman authored and ajavadia committed Oct 18, 2022
1 parent 6684fd5 commit 65e09bb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
6 changes: 3 additions & 3 deletions qiskit/qpy/binary_io/circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,12 +950,12 @@ def read_circuit(file_obj, version, metadata_deserializer=None):
qubits = [Qubit() for _ in range(num_qubits - len(circ.qubits))]
circ.add_bits(qubits)
if len(circ.clbits) < num_clbits:
clbits = [Clbit() for _ in range(num_qubits - len(circ.clbits))]
clbits = [Clbit() for _ in range(num_clbits - len(circ.clbits))]
circ.add_bits(clbits)
else:
circ = QuantumCircuit(
num_qubits,
num_clbits,
[Qubit() for _ in [None] * num_qubits],
[Clbit() for _ in [None] * num_clbits],
name=name,
global_phase=global_phase,
metadata=metadata,
Expand Down
9 changes: 9 additions & 0 deletions releasenotes/notes/fix-qpy-loose-bits-5283dc4ad3823ce3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
QPY deserialisation will no longer add extra :class:`.Clbit` instances to the
circuit if there are both loose :class:`.Clbit`\ s in the circuit and more
:class:`.Qubit`\ s than :class:`.Clbit`\ s.
- |
QPY deserialisation will no longer add registers named `q` and `c` if the
input circuit contained only loose bits.
20 changes: 20 additions & 0 deletions test/python/circuit/test_circuit_load_from_qpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1054,3 +1054,23 @@ def test_standard_control_gates(self):
qpy_file.seek(0)
new_circuit = load(qpy_file)[0]
self.assertEqual(qc, new_circuit)

def test_load_with_loose_bits(self):
"""Test that loading from a circuit with loose bits works."""
qc = QuantumCircuit([Qubit(), Qubit(), Clbit()])
qpy_file = io.BytesIO()
dump(qc, qpy_file)
qpy_file.seek(0)
new_circuit = load(qpy_file)[0]
self.assertEqual(tuple(new_circuit.qregs), ())
self.assertEqual(tuple(new_circuit.cregs), ())
self.assertEqual(qc, new_circuit)

def test_load_with_loose_bits_and_registers(self):
"""Test that loading from a circuit with loose bits and registers works."""
qc = QuantumCircuit(QuantumRegister(3), ClassicalRegister(1), [Clbit()])
qpy_file = io.BytesIO()
dump(qc, qpy_file)
qpy_file.seek(0)
new_circuit = load(qpy_file)[0]
self.assertEqual(qc, new_circuit)

0 comments on commit 65e09bb

Please sign in to comment.