-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
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 ParameterExpression
s, 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 ParameterExpression
s 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.