Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QPY fails to load circuits whose first register qubit is after a loose bit #9094

Closed
jakelishman opened this issue Nov 7, 2022 · 0 comments · Fixed by #9095
Closed

QPY fails to load circuits whose first register qubit is after a loose bit #9094

jakelishman opened this issue Nov 7, 2022 · 0 comments · Fixed by #9095
Assignees
Labels
bug Something isn't working

Comments

@jakelishman
Copy link
Member

jakelishman commented Nov 7, 2022

Environment

  • Qiskit Terra version: 0.22.2
  • Python version: 3.10
  • Operating system: macOS

What is happening?

QPY fails to load a circuit that has registers, but bit index 0 isn't in a register or at least, isn't in the circuit by the time a later register is read.

How can we reproduce the issue?

import io

from qiskit.circuit import QuantumCircuit, Clbit, ClassicalRegister
from qiskit.qpy import load, dump

qc = QuantumCircuit()
qc.add_bits([Clbit()])
qc.add_register(ClassicalRegister(2))

with io.BytesIO() as f:
    dump(qc, f)
    f.seek(0)
    out, = load(f)

fails with

TypeError                                 Traceback (most recent call last)
<ipython-input-1-ddaf374c6759> in <module>
     11     dump(qc, f)
     12     f.seek(0)
---> 13     out, = load(f)
     14

~/code/qiskit/terra/qiskit/qpy/interface.py in load(file_obj, metadata_deserializer)
    269     for _ in range(data.num_programs):
    270         programs.append(
--> 271             loader(file_obj, data.qpy_version, metadata_deserializer=metadata_deserializer)
    272         )
    273     return programs

~/code/qiskit/terra/qiskit/qpy/binary_io/circuits.py in read_circuit(file_obj, version, metadata_deserializer)
    924                         if start > len(circ.qubits):
    925                             bits = [bit_type() for _ in range(start - bit_len)]
--> 926                             circ.add_bits(bit_len)
    927                         if in_circuit:
    928                             circ.add_register(reg)

~/code/qiskit/terra/qiskit/circuit/quantumcircuit.py in add_bits(self, bits)
   1394     def add_bits(self, bits: Iterable[Bit]) -> None:
   1395         """Add Bits to the circuit."""
-> 1396         duplicate_bits = set(self._qubit_indices).union(self._clbit_indices).intersection(bits)
   1397         if duplicate_bits:
   1398             raise CircuitError(f"Attempted to add bits found already in circuit: {duplicate_bits}")

TypeError: 'int' object is not iterable

What should happen?

Correct load from QPY.

Any suggestions?

qpy/binary_io/circuits.py:926 is obviously wrong: it's passing an int to QuantumCircuit.add_bits rather than the bits that it has defined right above. This isn't the only issue, though - the whole register reconstruction has an incorrect model of bit ownership and bit ordering, so a more complete example like

import io
from qiskit.circuit import QuantumCircuit, Qubit, Clbit, QuantumRegister, ClassicalRegister
from qiskit.qpy import dump, load

qc = QuantumCircuit()
qc.add_bits([Qubit(), Clbit()])
qc.add_register(QuantumRegister(2, name="q1"))
qc.add_register(ClassicalRegister(2, name="c1"))
with io.BytesIO() as fptr:
    dump(qc, fptr)
    fptr.seek(0)
    new_circuit = load(fptr)[0]
assert qc == new_circuit

fails, because in the output circuit, the clbits go [('c1', 0), ('c1', 1), Clbit()], whereas they should be [Clbit(), ('c1', 0), ('c1', 1)].

@jakelishman jakelishman added the bug Something isn't working label Nov 7, 2022
@jakelishman jakelishman self-assigned this Nov 7, 2022
@mergify mergify bot closed this as completed in #9095 Nov 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant