Skip to content

Calibrations involving bound parameters fail to roundtrip through QPY #9764

@jakelishman

Description

@jakelishman

Environment

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

What is happening?

Calibrations that are defined for gates whose parameters are precisely of type float seem to roundtrip through QPY just fine. However, if the calibration is made to a gate whose parameters are fully bound ParameterExpressions, then a QPY-roundtripped circuit doesn't seem to recognise the calibration any more.

How can we reproduce the issue?

import io
from qiskit import QuantumCircuit, transpile, qpy
from qiskit.circuit import ParameterVector
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import RZXCalibrationBuilder
from qiskit.providers.fake_provider import FakePerth

backend = FakePerth()
inst_sched_map = backend.instruction_schedule_map
channel_map = backend.channels_map

param_bind = [-1.7131982974314244]

qc1 = QuantumCircuit(2)
qc1.rzx(param_bind[0], 0, 1)
qc1.draw()

qc2 = QuantumCircuit(2)
thetas = ParameterVector('θ', 1)
qc2.rzx(thetas[0], 0, 1)

pm = PassManager(RZXCalibrationBuilder(inst_sched_map, channel_map))
qc1_t = transpile(pm.run(qc1), backend)
qc2_t = transpile(pm.run(qc2.assign_parameters(param_bind)), backend)

def roundtrip(qc):
    with io.BytesIO() as fptr:
        qpy.dump(qc, fptr)
        fptr.seek(0)
        return qpy.load(fptr)[0]

def check_calibration(qc):
    return qc.has_calibration_for(qc.data[0])

[check_calibration(x) for x in [qc1_t, qc2_t, roundtrip(qc1_t), roundtrip(qc2_t)]]

gives

[True, True, True, False]

Notably, roundtrip(qc2_t) still does appear to have the requisite calibration, it's just not quite recognised correctly:

>>> roundtrip(qc2_t).calibrations
{'rzx': {((0, 1), (-1.7131982974314244,)): ScheduleBlock(...)}}

What should happen?

The roundtripped circuit should still recognise that it has a calibration for that instruction.

Any suggestions?

I think what's happening is that the floating-point number in the ParameterExpression is changing by 1 ULP, which sounds suspiciously like there might be a dodgy float-to-str conversion happening somewhere in the ParameterExpression handling in QPY?

I mean, the underlying cause is another of these things where fully assigned ParameterExpressions not immediately becoming regular floats is causing problems. But either way, if it happens with bound ParameterExpression, I'm sure there'll be mechanisms to trigger it with bound ones as well, we just don't notice as much if they're like 1ULP differences in a random float coefficient in a mostly symbolic calculation.

See Qiskit/qiskit-ibm-runtime#666.

cc: @kt474, @nbronn.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmod: qpyRelated to QPY serialization

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions