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

Pulse Compiler - Scheduling pass #11981

Merged
merged 27 commits into from
Mar 14, 2024

Conversation

TsafrirA
Copy link
Collaborator

Summary

A scheduling pass is introduced. This PR depends on #11980.

Details and comments

The Scheduling Pass is introduced in a similar way to the SetSequence pass of #11980. Scheduling logic is added to the AlignmentKind classes.

Some tests which depended on scheduling and were commented out before are restored.

@TsafrirA TsafrirA requested review from eggerdj, wshanks and a team as code owners March 10, 2024 13:35
@qiskit-bot
Copy link
Collaborator

One or more of the the following people are requested to review this:

  • @Qiskit/terra-core
  • @nkanazawa1989

@TsafrirA TsafrirA added mod: pulse Related to the Pulse module experimental Experimental feature without API stability guarantee labels Mar 10, 2024
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

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

This is very quick review. I'll review this again after #11980 is merged.

qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
qiskit/pulse/transforms/alignments.py Outdated Show resolved Hide resolved
qiskit/pulse/transforms/alignments.py Outdated Show resolved Hide resolved
@nkanazawa1989 nkanazawa1989 linked an issue Mar 11, 2024 that may be closed by this pull request
9 tasks
@nkanazawa1989 nkanazawa1989 mentioned this pull request Mar 11, 2024
9 tasks
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

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

Thanks. Overall this looks good to me :)

qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
qiskit/pulse/compiler/passes/schedule.py Outdated Show resolved Hide resolved
@@ -77,6 +77,11 @@ def sequence(self) -> PyDAG:
"""Return the DAG sequence of the SequenceIR"""
return self._sequence

@property
def time_table(self) -> defaultdict:
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious why this needs to be a defaultdict? Since the scheduler logic naively assumes all previous nodes are scheduled, it's safer to raise a key error (or particular compiler error) instead of silently substituting t0=0.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the _time_table attribute is a defaultdict because we use it for initial_time, duration etc.

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 Mar 13, 2024

Choose a reason for hiding this comment

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

Can we use internal _time_table for them and typecast to dict when the property returns?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If you meant to do return dict(self._time_table) - that would return a different object and make _time_table it hard to mutate the base line dictionary. Did you have something else in mind?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's good point. Let's return same object as is.

@@ -217,11 +222,19 @@ def _draw_nodes(n):
def flatten(self, inplace: bool = False) -> SequenceIR:
"""Recursively flatten the SequenceIR.

The flattening process includes breaking up nested IRs until only instructions remain.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we provide this functionality as a pass? Seems like no existing pass requires flatten. I'm okey with visualizing a graph with nested (unflatten) sequences, if this is only for visualization purpose. Some target might require flatten if it doesn't have notion of context, so having the flatten pass still makes sense to me.

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 Mar 13, 2024

Choose a reason for hiding this comment

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

For the visualization purpose we can add a dedicated visualization function to the qiskit.visualization module, and call the flatten pass internally depending on the argument, e.g.

def visualize_sequence_ir(sequence_ir: SequenceIR, flat_nested: bool = True):

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not sure if this is something that should be a pass or a built-in method. I tend towards the latter because that's an operation which would probably be a stand alone - you want to visualize, or you want to flatten before sending to the backend. I don't think the user\developer should bother with a pass manager for something like that.

In other words - if the most likely scenario is a pass manager with only one pass, I think that's a good indication that it shouldn't be a pass.

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 Mar 13, 2024

Choose a reason for hiding this comment

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

In case you submit the IR to backend, you know target code and whether flatten is required or not. For example, if you output Schedule like payload flatten is required, but something like qe-compiler Dialect or OpenPulse code, they have context and we can keep nested context. In this sense, a pass for flatten seems reasonable to me.

In my thoughts, only Transform pass can touch the graph structure. IR should NOT modify the structure of IR itself. Having this method obscures the responsibility, i.e. SRP

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That makes sense as well. I will split flatten out in a separate PR. (It wasn't introduced in this PR - only its tests)

test/python/pulse/compiler_passes/test_schedule.py Outdated Show resolved Hide resolved
test/python/pulse/compiler_passes/test_schedule.py Outdated Show resolved Hide resolved
test/python/pulse/compiler_passes/test_schedule.py Outdated Show resolved Hide resolved
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 left a comment

Choose a reason for hiding this comment

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

LGTM thanks!

@nkanazawa1989 nkanazawa1989 merged commit f424a3a into Qiskit:feature/pulse-ir Mar 14, 2024
10 checks passed
@TsafrirA TsafrirA deleted the SchedulingPass branch March 14, 2024 21:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental Experimental feature without API stability guarantee mod: pulse Related to the Pulse module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pulse Compiler and IR
3 participants