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

Introduce Pulse IR skeleton #11767

Merged
merged 4 commits into from
Feb 14, 2024
Merged

Conversation

TsafrirA
Copy link
Collaborator

Summary

This PR continues the work on the new Pulse Compiler and IR (RFC) by introducing a skeleton for the IR representation.

Details and comments

The implementation follows the form first presented in #11234. Only basic functionalities were introduced at this point, because #11726 is still pending, and the work on the compiler (following #11743) will better reveal what functionality is missing.

@TsafrirA TsafrirA requested review from eggerdj, wshanks and a team as code owners February 11, 2024 23:43
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core
  • @nkanazawa1989

@nkanazawa1989 nkanazawa1989 added experimental Experimental feature without API stability guarantee mod: pulse Related to the Pulse module labels Feb 12, 2024
@nkanazawa1989 nkanazawa1989 changed the title [pulse branch] Introduce Pulse IR skeleton Introduce Pulse IR skeleton Feb 12, 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.

Thanks @TsafrirA this is great starting point of discussion. I like the use of composite pattern. This really fits in with our pulse model. However, I prefer simpler implementation and want to delegate all complexity to passes unless the method is used by multiple passes (so I prefer starting with minimum implementation and add methods later if we find it's necessary).

qiskit/pulse/ir/ir.py Outdated Show resolved Hide resolved
qiskit/pulse/ir/ir.py Outdated Show resolved Hide resolved
pass

@abstractmethod
def shift_initial_time(self, value: int):
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this must be implemented by a pass.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Let's leave it in at the moment, and remove it later if we decide it's better to have it as a pass. I think during scheduling this is something we might have to do often, so it might make sense to have it as a method.

qiskit/pulse/ir/ir.py Show resolved Hide resolved
qiskit/pulse/ir/ir.py Outdated Show resolved Hide resolved
@property
def initial_time(self) -> int | None:
"""Return the initial time ``initial_time`` of the object"""
elements_initial_times = [element.initial_time for element in self._elements]
Copy link
Contributor

Choose a reason for hiding this comment

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

This is O(N) lookup and expensive. I'd prefer turning the data structure into (rustworkx based) DAG and then return the first node to calculate the initial time. Alternatively we can use dict keyed on the initial time, but this doesn't work because None shouldn't be a key.

@property
def final_time(self) -> int | None:
"""Return the final time of the ``IrBlock``object"""
elements_final_times = [element.final_time for element in self._elements]
Copy link
Contributor

Choose a reason for hiding this comment

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

With the same reason I prefer DAG.

qiskit/pulse/ir/ir.py Outdated Show resolved Hide resolved
qiskit/pulse/ir/ir.py Outdated Show resolved Hide resolved
"""Return the length of the IR, defined as the number of elements in it"""
return len(self._elements)

def __repr__(self) -> str:
Copy link
Contributor

@nkanazawa1989 nkanazawa1989 Feb 12, 2024

Choose a reason for hiding this comment

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

In my experience repr for sequence (e.g. ScheduleBlock) is not really useful, because it's super lengthy. If we prefer LLVM IR like, probably we can support .dump method that generates parsable code. This also helps debugging (unittest); i.e. the reference is always text, which is very robust.

Copy link
Contributor

@nkanazawa1989 nkanazawa1989 Feb 12, 2024

Choose a reason for hiding this comment

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

(note that I don't suggest implementing the code in this PR, since you need to start from defining AST...)

@nkanazawa1989 nkanazawa1989 linked an issue Feb 12, 2024 that may be closed by this pull request
9 tasks
@nkanazawa1989 nkanazawa1989 mentioned this pull request Feb 12, 2024
9 tasks
@TsafrirA
Copy link
Collaborator Author

Thanks @nkanazawa1989 for the quick review.
As we discussed offline, we both think it's reasonable to continue with the list representation of the elements for now. Conversion to DAG is not trivial, and might require an extra conversion step (ScheduleBlock->IR1->IR2?).

With the exception of shift_initial_time, I removed all methods which are arguably a pass. I think shift_initial_time is something we'll need to do often, and should live in the IR level.

About initial_time, I don't think O(N) is terrible here. But if we don't go in the DAG direction, we can later optimize this - Tracking initial time instead of calculating it? (will require initial_time setting to go through the block). Using the list structure to only examine some of the elements?

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.

Let's merge the PR as a skeleton. I'll do some followup for internal machinery.

@nkanazawa1989 nkanazawa1989 merged commit f385aec into Qiskit:feature/pulse-ir Feb 14, 2024
10 checks passed
@TsafrirA TsafrirA deleted the PulseIR3 branch February 14, 2024 20:40
@TsafrirA TsafrirA mentioned this pull request Mar 6, 2024
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