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

Create a frontend UI for users to specify quantum compilation pipelines #1131

Merged
merged 45 commits into from
Sep 19, 2024

Conversation

paul0403
Copy link
Contributor

@paul0403 paul0403 commented Sep 11, 2024

Context:
We wish to create a frontend pipeline function for users to specify what circuit transformation passes to run in the dictionary form.
https://app.shortcut.com/xanaduai/epic/67492/p1-a-ui-is-available-for-users-to-specify-quantum-compilation-pipelines-from-python

Description of the Change:
A new API decorator function catalyst.passes.pipeline can be applied to qnodes. The decorator takes in a dictionary specifying what circuit transformation passes to run on the qnode with what options, and adds the passes to the transform_named_sequence.

In addition, qjit now takes in a kwarg circuit_transform_pipeline which expects the same pipeline dictionary. This will apply the pipeline to all qnodes in the qjit.

To test the pipeline, we added the boilerplate for a merge_rotation pass with a pass option. The pass is currently empty and does nothing. The merge_rotation boilerplate pass is not exposed as a user-facing API, and only exists for the purpose of testing the pipeline.

Benefits:
User can specify pass pipelines.

Possible Drawbacks:
There are two items of improvements possible:

  1. The target qnode of the pass is recorded by name. This is not optimal. The quantum scope work will likely put each qnode into a module instead of a func.func ... attributes {qnode}. When that is in place, the qnode's module can have a proper attribute (as opposed to discardable) that records its transform schedule, i.e.
module_with_transform @name_of_module {
  // transform schedule
} {
  // contents of the module
}

This eliminates the need for matching target functions by name.

  1. The number of qjit kwargs is maybe too many. As of now we implement the syntax specified by the epic, but there could be an alternate design.

[sc-67520]

@paul0403
Copy link
Contributor Author

paul0403 commented Sep 11, 2024

@rmoyard The epic description says the zne mitigation pass should go into the catalyst.passes module. I wanted to keep the old usage so in passes.py I just created a wrapper that calls the underlying mitigate_with_zne (the currently existing one).

The spirit of the epic is that the passes.py module should control what passes to run. Therefore I turned off lower-mitigation in the default pipeline and moved it into the apply-transform-sequence (see #911). The behavior is the same as before:

  • for functions not under mitigate_with_zne, nothing happens. Originally because the pass in the default pipeline ignores them, now because the pass is not run at all
  • for functions under mitigate_with_zne, the pass runs. Originally because the pass runs in the default pipeline, now because mitigate_with_zne registers the pass in the transform sequence.

Thoughts on this?

Update: we decided to exclude ZNE

@paul0403 paul0403 requested a review from a team September 13, 2024 19:24
@paul0403 paul0403 marked this pull request as ready for review September 13, 2024 19:25
@paul0403
Copy link
Contributor Author

paul0403 commented Sep 13, 2024

Marking ready for review to check CI.

Two remaining items:

  1. Do we really need to include ZNE? The pipeline was only meant for peephole circuit transformations We (@rmoyard and myself) decided to exclude ZNE @josh146
  2. Make local configurations override global configurations

frontend/catalyst/qfunc.py Outdated Show resolved Hide resolved
@mehrdad2m
Copy link
Contributor

I have some thoughts/questions about the design of the pipeline. Something that is worth clearing up is the definition of a "pass". My understanding of a compiler optimization pass is a transformation from one representation of the code to another without changing its functionality with hope that the transformed version is more optimized (runs faster, better memory usage, ...).
With this definition, I think there should be a distinction between things like cancel_inverses and mitigate_with_zne and only the former should be considered as a compiler optimization pass.
My question is then would the user want to run a performance related pipeline (that includes things like cancel_inverses) on individual functions within one qjit call?
My instinct is that the answer is mostly no in which case we can just tie the pipeline to the qjit (similar to how clang runs O2 or O3 on the whole module) instead which makes the implementation nicer and simpler. This would be something like the pipelines option of qjit except that instead of replacing the whole compilation pipeline, it modifies the list of QUANTUM_COMPILATION_PASS passes.
In some specific cases that we want a function to go through a certain optimization pass, we can still use the individual decorators that would work similar to pragma hints in c++. Any thoughts?

If the answer to the question is yes then ignore this comment :)

…fail by merging the `pass_pipeline` argument of QFunc.__call__ into its **kwargs
Copy link
Contributor

@mehrdad2m mehrdad2m left a comment

Choose a reason for hiding this comment

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

Very nice work 🚀

doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
frontend/catalyst/passes.py Show resolved Hide resolved
frontend/catalyst/passes.py Outdated Show resolved Hide resolved
@paul0403
Copy link
Contributor Author

paul0403 commented Sep 18, 2024

Summary of results from discussion:

  1. The current scope of the transform dialect is "function passes that need no processing in the frontend". This excludes ZNE.
    Note that the pipeline feature has no strict dependency on ZNE. We can merge in the pipeline; if we decide to include ZNE we can always add it later.

  2. (future work) Devices can have their own default pipeline, i.e. as a device implementor, I want to run pass X, Y, Z on programs that target my device. Users don't need to set it themselves neither on the qjit, nor qnode

  3. (future work) The quantum scope work will likely put each qnode into a module instead of a func.func ... attributes {qnode}. When that is in place, the qnode's module can have a proper attribute (as opposed to discardable) that records its transform schedule, i.e.

module_with_transform @name_of_module {
  // transform schedule
} {
  // contents of the module
}

This eliminates the need for matching target functions by name.

Copy link
Contributor

@rmoyard rmoyard left a comment

Choose a reason for hiding this comment

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

Thanks, here are some comments

doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
doc/releases/changelog-dev.md Outdated Show resolved Hide resolved
@@ -77,6 +77,10 @@ class CompileOptions:
experimental_capture (bool): If set to ``True``,
use PennyLane's experimental program capture capabilities
to capture the function for compilation.
circuit_transform_pipeline (Optional[dict[str, dict[str, str]]]):
Copy link
Contributor

Choose a reason for hiding this comment

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

No action here, but @josh146 @isaacdevlugt this will soon beat the number of qnode's arguments.

frontend/catalyst/jit.py Outdated Show resolved Hide resolved
@rmoyard rmoyard self-requested a review September 19, 2024 17:14
Copy link
Contributor

@rmoyard rmoyard left a comment

Choose a reason for hiding this comment

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

Great job @paul0403 ! Some UI to figure out but happy to approve as a first step 👍

@paul0403 paul0403 merged commit 5cf6bd4 into main Sep 19, 2024
41 of 42 checks passed
@paul0403 paul0403 deleted the pass_pipeline_UI branch September 19, 2024 17:48
rauletorresc pushed a commit that referenced this pull request Oct 9, 2024
…es (#1131)

**Context:**
We wish to create a frontend `pipeline` function for users to specify
what circuit transformation passes to run in the dictionary form:
https://app.shortcut.com/xanaduai/epic/67492/p1-a-ui-is-available-for-users-to-specify-quantum-compilation-pipelines-from-python

**Description of the Change:**
A new API decorator function `catalyst.passes.pipeline` can be applied
to qnodes. The decorator takes in a dictionary specifying what circuit
transformation passes to run on the qnode with what options, and adds
the passes to the `transform_named_sequence`.

In addition, `qjit` now takes in a kwarg `circuit_transform_pipeline`
which expects the same pipeline dictionary. This will apply the pipeline
to all qnodes in the qjit.

To test the pipeline, we added the boilerplate for a merge_rotation pass
with a pass option. The pass is currently empty and does nothing. The
merge_rotation boilerplate pass is not exposed as a user-facing API, and
only exists for the purpose of testing the pipeline.

**Benefits:**
User can specify pass pipelines.

**Possible Drawbacks:**
There are two items of improvements possible:
1. The target qnode of the pass is recorded by name. This is not
optimal. The quantum scope work will likely put each qnode into a module
instead of a `func.func ... attributes {qnode}` in mlir. When that is in place,
the qnode's module can have a proper attribute (as opposed to
discardable) that records its transform schedule, i.e.
```
module_with_transform @name_of_module {
  // transform schedule
} {
  // contents of the module
}
```
This eliminates the need for matching target functions by name.

2. The number of `qjit` kwargs is maybe too many. As of now we implement
the syntax specified by the epic, but there could be an alternate
design.

[sc-67520]
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.

6 participants