Skip to content

QPY serialization of ParameterExpression throws error #13879

@jlapeyre

Description

@jlapeyre
  • Qiskit version: 1.3.2
  • qiskit-ibm-runtime version: 0.36.1
  • Python version: 3.12

Certain ParameterExpressions cause QPY serialization v13 to throw. QPY v12 does not throw.

Note

After opening this issue I found the following much simpler script for triggering the bug:

from qiskit.circuit import Parameter, ParameterExpression
from qiskit import qpy

a = Parameter("a")
b = Parameter("b")
a1 = a * 2
a2 = a1.subs({a: 2 * b})

qpy.binary_io.value.dumps_value(a2, version=13);

There is no error with QPY version 12.

When running the script above, the error,

AttributeError: 'ParameterExpression' object has no attribute 'name'

is thrown here at line 40

def _write_parameter(file_obj, obj):
name_bytes = obj.name.encode(common.ENCODE)
file_obj.write(struct.pack(formats.PARAMETER_PACK, len(name_bytes), obj.uuid.bytes))
file_obj.write(name_bytes)

I tried to track down the problem, which is centered on _qpy_replay. But there are no documentation or comments describing _qpy_replay and several adjacent structures and functions.

Note

The following script is not a minimal description of the bug. But it is an example abstracted from using EstimatorQNN and NeuralNetworkClassifier from qiskit-machine-learning on a real IBM device (in this case, ibm_kyiv). It's unlikely that simple workflows involving EstimatorQNN will work when this bug is present.

Running this script will trigger the bug:

from qiskit.circuit.library import ZZFeatureMap, RealAmplitudes
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import fake_provider
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

def make_circuit():
    n_qubits = 2
    reps = 1
    feature_map = ZZFeatureMap(feature_dimension=n_qubits, reps=reps)
    ansatz = RealAmplitudes(num_qubits=n_qubits, reps=reps)
    qc = QuantumCircuit(n_qubits)
    qc.compose(feature_map, inplace=True)
    qc.compose(ansatz, inplace=True)
    backend = fake_provider.FakeKyiv()
    pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
    isa_qc = pm.run(qc)
    return isa_qc

from qiskit import qpy
isa_qc = make_circuit()
qpy.binary_io.value.dumps_value(isa_qc.global_phase, version=13);

If I replace versions=13 with version=12, I see no apparent problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions