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

[RFC] Qiskit Pulse: Relative timing for Schedules #16

Conversation

lcapelluto
Copy link

Add an RFC proposing an implementation for relatively-timed instructions in pulse Schedules within Qiskit Pulse

@lcapelluto lcapelluto force-pushed the terra-3749-relatively-timed-pulse-schedules branch from 96d81f7 to 3cdf72f Compare February 21, 2020 21:21
@lcapelluto lcapelluto force-pushed the terra-3749-relatively-timed-pulse-schedules branch from 3cdf72f to 9876d18 Compare February 21, 2020 21:23
@lcapelluto lcapelluto force-pushed the terra-3749-relatively-timed-pulse-schedules branch from 39d6653 to 95ccc84 Compare February 21, 2020 21:30
0000-qiskit-pulse-schedule-relative-timing.md Show resolved Hide resolved
0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved


## Summary
Update the internal structure of `Schedule`s to track instructions sequentially. `Instruction`s will not be played at an explicit time; rather, they will begin immediately after the last is done. To schedule idle time between instructions, `Delay` instructions must be used.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Update the internal structure of `Schedule`s to track instructions sequentially. `Instruction`s will not be played at an explicit time; rather, they will begin immediately after the last is done. To schedule idle time between instructions, `Delay` instructions must be used.
Update the internal structure of `Schedule`s to track instructions sequentially. `Instruction`s will not be scheduled to be played at an explicit timestamp; rather, they will begin immediately after all channels on which the instruction effects are idle, ie., when instruction scheduling will be determined by the instruction dependency graph across channels. To schedule idle time between instructions, `Delay` instructions must be used.

0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
| Method | Runtime | Change |
|---------------|----------------|------------------|
| `append(self, schedule)` | O(\|N<sub>new</sub>\|) | |
|`insert(self, time, schedule)`| O(\|N<sub>new</sub>\| * \|N<sub>C</sub>\|) | |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you expect inserting in the middle of a schedule work? Verify that delays are present for all insertion locations?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. it's not great, since delays are supposed to be blocking, but I don't think there's any other way to do this


## Questions

1. Should we create `insert(self, index, channel)`?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this handled by the normal insert, I don't see what is different about this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the normal insert takes time, this takes index. I don't really see how this index method would be useful myself

0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
@taalexander taalexander changed the title Qiskit Pulse: Relative timing for Schedules [WIP][RFC] Qiskit Pulse: Relative timing for Schedules Feb 26, 2020
@taalexander taalexander changed the title [WIP][RFC] Qiskit Pulse: Relative timing for Schedules [WIP] [RFC] Qiskit Pulse: Relative timing for Schedules Feb 26, 2020
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

lcapelluto and others added 5 commits March 11, 2020 15:29
Co-Authored-By: Thomas Alexander <thomasalexander2718@gmail.com>
…com:lcapelluto/rfcs into terra-3749-relatively-timed-pulse-schedules
@lcapelluto lcapelluto marked this pull request as ready for review March 11, 2020 19:40
@lcapelluto lcapelluto changed the title [WIP] [RFC] Qiskit Pulse: Relative timing for Schedules [RFC] Qiskit Pulse: Relative timing for Schedules Mar 11, 2020
@itoko
Copy link
Contributor

itoko commented Mar 25, 2020

I realized we are using "relative time/timing" in the two meanings: "timing by channels (by-channels)" and "no start_time, no t=0", i.e. "absolute time/timing" means "timing across channels (across-channels)" and "having start_time from t=0".
For example,

`Instruction`s will not be played at an explicit time; rather, they will begin immediately after the last is done. 

is talking about "timing by channels", while

explicit timing of instructions will become confusing with the introduction of control-flow to quantum programs as it would become difficult to program experiments containing loops that are not unrollable.

is talking about "no start_time". These two points may be considered independently.

Regarding "by-/across-channels",
I think we have two options:

  • Build and save with "time counting by channels" (as of the current RFC)
  • Build with "across-channels" and save with "by-channels"

I guess we are heading to "by-channels" because real devices do not support communication among channels (right?). That makes "timing across channels" too much for real device.
So I don't disagree with heading "timing by channels" for Schedule (as a data class to be passed to backend) if communication among channels would never be supported, but I think we need to be careful when thinking about schedule builder (as a class for users to build pulse schedule). At the time building schedules, we (often?) want to do insert(time, instruction). So we may need to have intermediate (mutable) class to build schedule supporting insert(time, instruction).
IMO, current Schedule class is doing two things, building and storing, as like QuantumCircuit. While QuantumCircuit perform well because it's mutable, it is difficult for Schedule to perform well because it's immutable. I thought that's why we're going to introduce "builder class" for Schedule as like "StringBuilder" and "String" class in Java. Am I misunderstanding schedule builder?

Regarding "start_time from t=0" considering control-flow,
we can think of another option (I don't say better option).
What if we introduce a kind of "(control-flow) block" and "no t=0" among blocks but having "t=0" for each block?

0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
| `append(self, schedule)` | O(\|N<sub>new</sub>\|) | |
|`insert(self, time, schedule)`| O(\|N<sub>new</sub>\| * \|N<sub>C</sub>\|) | |
| `append(self, schedule)` | O(\|C\|) | Previously, `append` would add `schedule` to `self` with relative times preserved, at time set by `self.duration({schedule.channels}.intersection({self.channels}))`. The new method will simply extend the instructions in `self` with those in `schedule` on a per channel basis. |
|`insert(self, time, schedule)`| O(N<sub>new</sub> * N<sub>C</sub>) | This will be slow generally, but it can be implemented with the same runtime as `append` when the `time` is greater than `self.duration(schedule.channels)`. |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should have both an insert_at_time and an insert (as the actual argument position in the schedule data structure) to properly differentiate these two operations?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good to me

0000-qiskit-pulse-schedule-relative-timing.md Show resolved Hide resolved
@lcapelluto
Copy link
Author

@itoko I don't understand your comment; I don't understand what you mean by "cross channels"

0000-qiskit-pulse-schedule-relative-timing.md Outdated Show resolved Hide resolved
Comment on lines +61 to +72
{
DriveChannel(0):
('instructions'=[Delay(duration=10, ...),
Play(duration=100, ...),
Play(duration=20, ...)],
'duration'=130),
DriveChannel(1):
('instructions'=[Delay(duration=110, ...),
Play(duration=20, ...)],
'duration'=130),
...
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be the main takeaway of this RFC, so we should settle on it.

So the 130 number is here for performance right? Even though it could be computed by summing all durations on that channel. I'm good with that.

However, we should think about what a conditional will look like. If I don't know an instruction's delay, due to a branch or conditional, how does this datastructure work?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Schedule is a "basic block", so conditionals should live on top of this. An alt approach (which I should list in this RFC) would be to make this explicit and allow absolute timing within a basic block even when we have control flow. I find that misleading (too "special case"-y), but, at the heart of it, they're equivalent.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Thomas' new RFC touches on this

@ajavadia
Copy link
Member

ajavadia commented Apr 2, 2020

I'm not totally clear on this justification. Can you clarify the complexity of union with absolute and relative datastructures? I don't think it's different with the currently proposed structure, but I could be wrong.

It also encourages inefficient operations such as taking the union of two schedules. At first glance this operation should be efficient since all one needs to do is specifying the starting time of the instructions, but this requires verification that no instructions overlap in time in the two schedules resulting in expensive checks. The requirement for such a check to merge two schedules is obvious within the relatively schedules model, as one must look to make sure a delay exists in the first schedule for all instructions of the second schedule to merge.

@ajavadia
Copy link
Member

ajavadia commented Apr 3, 2020 via email

@lcapelluto
Copy link
Author

@ajavadia I agree. I'll do that 👍

lcapelluto and others added 3 commits April 10, 2020 14:56
remove ref to removed section

Co-Authored-By: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
@ajavadia
Copy link
Member

Ok so it based on this, append and shift are faster in relative, insert faster in absolute?

If I compare this with #18 it seems the findings are different in the case of insert. Can we come to an agreement on this @lcapelluto @itoko? Because I think the timed circuit and pulse case should be pretty identical in terms of datastructure and manipulation runtime.

In any case I just wanted to make sure we are basing this on some concrete runtime analysis, which will also help in the implementation. I think it is clear that relative wins in terms of the most common operation which is append.

@lcapelluto lcapelluto closed this May 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants