Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qpy serialization for pulse schedule #6923

Closed
nkanazawa1989 opened this issue Aug 17, 2021 · 5 comments · Fixed by #7821 or #7300
Closed

qpy serialization for pulse schedule #6923

nkanazawa1989 opened this issue Aug 17, 2021 · 5 comments · Fixed by #7821 or #7300
Assignees
Labels
mod: pulse Related to the Pulse module mod: qpy Related to QPY serialization type: feature request New feature or request
Milestone

Comments

@nkanazawa1989
Copy link
Contributor

What is the expected behavior?

Currently we are missing a serialization format for pulse schedule, and this is necessary for the calibration module in qiskit experiments. However implementation is not straightforward.

  1. No standard
    We don't have any de facto standard of schedule program representation. Currently we have two types of schedule representations Schedule and ScheduleBlock.
  • Schedule
    • Closer to hardware program representation. All instruction time is assigned, i.e. (t0, instruction).
    • Timing related parameters cannot be parametrized due to immediate timeslot evaluation (overlap constraint).
    • Still used in many community codebases (conventional representation).
    • Many util functions are supported (filter, pad, align_measure)
  • ScheduleBlock
    • Context rich representation of instruction timing, eg AlignLeft block, AlignRight block, etc...
    • We can stretch instruction duration. All instruction parameters can be parametrized with Parameter.
    • Used for the calibration module and the default output of pulse builder.
    • Need conversion to Schedule for execution.
  1. Still under (relatively) active development
    For example, we are trying to upgrade definition of channel with Support frames using signals #5977 . This PR can change the program representation. This means we need to pay a lot of effort for backward compatibility in serialization/deserialization logic.

  2. Subroutine support
    Schedule programs support Call instruction, which is one of schedule instructions but refers to another program defined outside the scope of current program, i.e. subroutine (in the current implementation the instruction just entirely copies the subroutine, thus it just looks like a nested program). If we support such data structure, the serialization logic could become complicated.

Regarding the point 1, I've tried to unify the Schedule and ScheduleBlock by allowing the block to take an instruction time t0 (kind of soft scheduling) in #6444 . Eventually we can deprecate Schedule with this approach, but currently the pros/cons of this attempt is not well discussed.

@nkanazawa1989 nkanazawa1989 added type: feature request New feature or request mod: pulse Related to the Pulse module labels Aug 17, 2021
@mtreinish
Copy link
Member

One thing we can do at least for calibrations (maybe not a good idea for standalone schedules) while the pulse api is finalized is to just leverage qobj. We can serialize the calibrartion schedules to qobj (without a backend set) and then embed that as a utf8 string in the calibrations field for a circuit. (we could also probably make some tweaks via the json encoder class for low hanging fruit changes to the serialization of numpy arrays and things which we couldn't do in qobj for real because it breaks the API schema). The only downside with this approach is we have to continue to support the qobj disassemble path in perpetuity then for backwards compatibility. Not necessarily as a public api but just being able to go from pulse qobj embedded in a qpy to pulse Schedule*.

@nkanazawa1989
Copy link
Contributor Author

Thank you Matthew for the advice. The assemble/disassemble only support Schedule, however, the calibration needs ScheduleBlock to keep the duration parametrized. This means we need to write serializer almost from scratch. In addition, the serialized data are planned to be stored in the remote database, so we cannot easily switch to new representation. So we are trying to use something much stable and easy to add a logic for backward compatibility (at least code version management).

For now this is not high priority (in the first product we can keep the template schedules in the codebase and only retrieve parameters from the database), but eventually we need to support arbitrary user provided schedules. So implementation of stable serialization format is still important issue to us.

@singular-value
Copy link

Hi folks, cc @nathanearnestnoble. We (cc @richrines1 @vtomole) noticed an issue with attempting to qpy-serialize a circuit that contains calibrations. Basically, circuit calibrations are lost in the process of qpy serialization:

image

I'm guessing that enabling qpy serialization for pulse schedules (i.e. solving this issue) would fix the problem? If not, let me know and I'll make a new issue.

-Pranav

P.S. Code snippet to reproduce:

import qiskit
import io

from qiskit.circuit import qpy_serialization
from qiskit.test.mock import FakeValencia

custom_gate = qiskit.circuit.Gate('my_custom_gate', 1, [])

in_qc = qiskit.QuantumCircuit(1)
in_qc.append(custom_gate, [0])
print(in_qc)

with qiskit.pulse.build(FakeValencia(), name='custom') as my_schedule:
    qiskit.pulse.play(
        qiskit.pulse.library.Gaussian(duration=64, amp=0.2, sigma=8),
        qiskit.pulse.drive_channel(0)
    )

in_qc.add_calibration('my_custom_gate', [0], my_schedule, [])

print(in_qc.calibrations)

buf = io.BytesIO()
qpy_serialization.dump(in_qc, buf)

buf = io.BytesIO(buf.getvalue())
out_qc = qpy_serialization.load(buf)[0]

print(out_qc)

print(out_qc.calibrations)

@mtreinish
Copy link
Member

Yeah, not preserving calibrations is a limitation with qpy currently, this is the tracking issue for it. To be able to serialize calibrations we need to have a representation for a pulse schedule. Once that exists preserving the calibrations should be trivial.

@mtreinish mtreinish added the mod: qpy Related to QPY serialization label Sep 10, 2021
@mtreinish mtreinish added this to the 0.20 milestone Mar 4, 2022
@mtreinish mtreinish modified the milestones: 0.20, 0.21 Mar 26, 2022
@kdk kdk linked a pull request Jun 14, 2022 that will close this issue
5 tasks
@mergify mergify bot closed this as completed in #7821 Jun 15, 2022
@mtreinish
Copy link
Member

This isn't closed yet, #7300 is needed before this is done.

@mtreinish mtreinish reopened this Jun 15, 2022
@mtreinish mtreinish linked a pull request Jun 22, 2022 that will close this issue
8 tasks
@mergify mergify bot closed this as completed in #7300 Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mod: pulse Related to the Pulse module mod: qpy Related to QPY serialization type: feature request New feature or request
Projects
None yet
3 participants