Skip to content

Parameterized circuits can no longer be loaded with qpy. #13720

@Guillermo-Mijares-Vilarino

Description

Environment

  • Qiskit version: 1.3.2
  • Python version: 3.12.7
  • Operating system: macOS Sequoia 15.1.1

What is happening?

After upgrading qiskit from 1.2.4 to 1.3.2, qpy started failing to load parameterized circuits.

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[2], line 10
      7     qpy.dump(fm, file)
      9 with open(\"circuit.qpy\", \"rb\") as file:
---> 10     new_fm = qpy.load(file)[0]

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/interface.py:370, in load(file_obj, metadata_deserializer)
    367 programs = []
    368 for _ in range(data.num_programs):
    369     programs.append(
--> 370         loader(
    371             file_obj,
    372             data.qpy_version,
    373             metadata_deserializer=metadata_deserializer,
    374             use_symengine=use_symengine,
    375         )
    376     )
    377 return programs

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/circuits.py:1441, in read_circuit(file_obj, version, metadata_deserializer, use_symengine)
   1439 for declaration in var_segments[type_keys.ExprVarDeclaration.LOCAL]:
   1440     circ.add_uninitialized_var(declaration)
-> 1441 custom_operations = _read_custom_operations(file_obj, version, vectors)
   1442 for _instruction in range(num_instructions):
   1443     _read_instruction(
   1444         file_obj,
   1445         circ,
   (...)
   1451         standalone_var_indices,
   1452     )

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/circuits.py:617, in _read_custom_operations(file_obj, version, vectors)
    615 def_binary = file_obj.read(data.size)
    616 if version < 3 or not name.startswith(r\"###PauliEvolutionGate_\"):
--> 617     definition_circuit = common.data_from_binary(
    618         def_binary, read_circuit, version=version
    619     )
    620 elif name.startswith(r\"###PauliEvolutionGate_\"):
    621     definition_circuit = common.data_from_binary(
    622         def_binary, _read_pauli_evolution_gate, version=version, vectors=vectors
    623     )

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/common.py:267, in data_from_binary(binary_data, deserializer, **kwargs)
    265 with io.BytesIO(binary_data) as container:
    266     container.seek(0)
--> 267     obj = deserializer(container, **kwargs)
    268 return obj

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/circuits.py:1443, in read_circuit(file_obj, version, metadata_deserializer, use_symengine)
   1441 custom_operations = _read_custom_operations(file_obj, version, vectors)
   1442 for _instruction in range(num_instructions):
-> 1443     _read_instruction(
   1444         file_obj,
   1445         circ,
   1446         out_registers,
   1447         custom_operations,
   1448         version,
   1449         vectors,
   1450         use_symengine,
   1451         standalone_var_indices,
   1452     )
   1454 # Read calibrations
   1455 if version >= 5:

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/circuits.py:297, in _read_instruction(file_obj, circuit, registers, custom_operations, version, vectors, use_symengine, standalone_vars)
    295 for _param in range(instruction.num_parameters):
    296     type_key, data_bytes = common.read_generic_typed_data(file_obj)
--> 297     param = _loads_instruction_parameter(
    298         type_key,
    299         data_bytes,
    300         version,
    301         vectors,
    302         registers,
    303         circuit,
    304         use_symengine,
    305         standalone_vars,
    306     )
    307     params.append(param)
    309 # Load Gate object

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/circuits.py:201, in _loads_instruction_parameter(type_key, data_bytes, version, vectors, registers, circuit, use_symengine, standalone_vars)
    199 else:
    200     clbits = circuit.clbits if circuit is not None else ()
--> 201     param = value.loads_value(
    202         type_key,
    203         data_bytes,
    204         version,
    205         vectors,
    206         clbits=clbits,
    207         cregs=registers[\"c\"],
    208         use_symengine=use_symengine,
    209         standalone_vars=standalone_vars,
    210     )
    212 return param

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/value.py:971, in loads_value(type_key, binary_data, version, vectors, clbits, cregs, use_symengine, standalone_vars)
    964         return common.data_from_binary(
    965             binary_data,
    966             _read_parameter_expression_v3,
    967             vectors=vectors,
    968             use_symengine=use_symengine,
    969         )
    970     else:
--> 971         return common.data_from_binary(
    972             binary_data, _read_parameter_expression_v13, vectors=vectors, version=version
    973         )
    974 if type_key == type_keys.Value.EXPRESSION:
    975     return common.data_from_binary(
    976         binary_data,
    977         _read_expr,
   (...)
    980         standalone_vars=standalone_vars,
    981     )

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/common.py:267, in data_from_binary(binary_data, deserializer, **kwargs)
    265 with io.BytesIO(binary_data) as container:
    266     container.seek(0)
--> 267     obj = deserializer(container, **kwargs)
    268 return obj

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/value.py:518, in _read_parameter_expression_v13(file_obj, vectors, version)
    516     symbol = _read_parameter(file_obj)
    517 elif symbol_key == type_keys.Value.PARAMETER_VECTOR:
--> 518     symbol = _read_parameter_vec(file_obj, vectors)
    519 else:
    520     raise exceptions.QpyError(f\"Invalid parameter expression map type: {symbol_key}\")

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/qpy/binary_io/value.py:402, in _read_parameter_vec(file_obj, vectors)
    400     vectors[name] = (ParameterVector(name, data.vector_size), set())
    401 vector = vectors[name][0]
--> 402 if vector[data.index].uuid != param_uuid:
    403     vectors[name][1].add(data.index)
    404     vector._params[data.index] = ParameterVectorElement(vector, data.index, uuid=param_uuid)

File ~/miniconda3/envs/pqf_function/lib/python3.12/site-packages/qiskit/circuit/parametervector.py:78, in ParameterVector.__getitem__(self, key)
     77 def __getitem__(self, key):
---> 78     return self.params[key]

IndexError: list index out of range

How can we reproduce the issue?

from qiskit import qpy
from qiskit.circuit.library import PauliFeatureMap

qc = PauliFeatureMap(feature_dimension=5, reps=1)

with open("circuit.qpy", "wb") as fd:
    qpy.dump(qc, fd)

with open("circuit.qpy", "rb") as fd:
    new_qc = qpy.load(fd)[0]

What should happen?

The circuit should be loaded without raising an error, as in qiskit<1.3.0.

Any suggestions?

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions