Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.03k stars 2.32k forks source link

RZXCalibrationBuilder.rescale_cr_inst does not support instructions from GenericBackendV2 #12834

Open 1ucian0 opened 1 month ago

1ucian0 commented 1 month ago

Environment

What is happening?

While deprecating BackendV1, I noticed that test.python.transpiler.test_calibrationbuilder is hard to transition to BackendV2. The pulse name structure seems to be different (for example, in V2 the previously pulse called CR90p_u0 are now generically called pulse_2). Beyond those adaptations, the differences look even deeper.

How can we reproduce the issue?

This is a BackendV2 version of test.python.transpiler.test_calibrationbuilder.TestRZXCalibrationBuilder.test_rzx_calibration_cr_pulse_stretch:

from qiskit.pulse import builder, Play
from qiskit.transpiler.passes.calibration.builders import RZXCalibrationBuilder
from qiskit.providers.fake_provider import GenericBackendV2

def u0p_play(cr_schedule):
    def _filter_func(time_inst):
        return isinstance(time_inst[1], Play) and time_inst[1].pulse.name.startswith("pulse_2")

    return cr_schedule.filter(_filter_func).instructions[0][1]

inst_map = GenericBackendV2(
    num_qubits=27,
    calibrate_instructions=True,
    pulse_channels=True,
    seed=42,
).target.instruction_schedule_map()
cr_schedule = inst_map.get("cx", (0, 1))

with builder.build() as test_sched:
    RZXCalibrationBuilder.rescale_cr_inst(u0p_play(cr_schedule), 0.1)
[...]
    139 risefall_area = params["sigma"] * math.sqrt(2 * pi) * erf(risefall_sigma_ratio)

KeyError: 'duration'

Notice that calling RZXCalibrationBuilder.rescale_cr_inst with pulses coming from BackendV1 works:

from qiskit.providers.fake_provider import Fake27QPulseV1

def u0p_play(cr_schedule):
    def _filter_func(time_inst):
        return isinstance(time_inst[1], Play) and time_inst[1].pulse.name.startswith("CR90p_u")
    return cr_schedule.filter(_filter_func).instructions[0][1]

inst_map = Fake27QPulseV1().defaults().instruction_schedule_map
cr_schedule = inst_map.get("cx", (0, 1))
with builder.build() as test_sched:
    RZXCalibrationBuilder.rescale_cr_inst(u0p_play(cr_schedule), 0.1)

What should happen?

It should be possible to fully move test.python.transpiler.test_calibrationbuilder to BackendV2.

Any suggestions?

No response

1ucian0 commented 1 month ago

Maybe is a GenericBackendV2 problem, since a BackendV2 created via BackendV2Converter works:

from qiskit.providers.backend_compat import BackendV2Converter

def u0p_play(cr_schedule):
    def _filter_func(time_inst):
        return isinstance(time_inst[1], Play) and time_inst[1].pulse.name.startswith("CR90p_u")
    return cr_schedule.filter(_filter_func).instructions[0][1]

backendV1 = Fake27QPulseV1() 
backendV2 = BackendV2Converter(backendV1)
inst_map = backendV2.target.instruction_schedule_map()
cr_schedule = inst_map.get("cx", (0, 1))
with builder.build() as test_sched:
    RZXCalibrationBuilder.rescale_cr_inst(u0p_play(cr_schedule), 0.1)