-
Notifications
You must be signed in to change notification settings - Fork 196
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
Demo about implementing Shor's algorithm with Catalyst #1010
base: master
Are you sure you want to change the base?
Conversation
# TODO: explain how the modular exponentiation circuits work (not sure yet how to | ||
# best include these, because some are quite large) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you don't want to go into too much detail here, there is an option to upload a .py and simply import the operator. However, I think it would be worth a small tutorial in the future. People would love it!
a positive step in this direction. In this demonstration we will show how | ||
Catalyst enables an implementation of Shor's factoring algorithm that is | ||
just-in-time compiled from end-to-end, classical control structure and all. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should recommend to the reader something about just-in-time since I think it is super important here and it is not a known term in quantum computing: "If you still don't know what this Jit thing is and the potential it has, I invite you to take a look to ..." or similar
# The quantum part | ||
# ^^^^^^^^^^^^^^^^ | ||
# | ||
# TODO: explain how the modular exponentiation circuits work (not sure yet how to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: pennylane now has qml.ModExp. So we can probably save the explanation here 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw! Are they qjit
compatible? There is a fair amount of customization in my implementation so I will probably still provide brief explanations, and the circuits, but only what's needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be, let me know if you have any problems :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious if this ended up working!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tried - I stayed with my own implementations because there are "higher-level" optimizations being applied (like removing entire QFTs, etc.).
…ociated diagrams.
Marking as ready-for-review to test the build (it worked locally). I'll tag people once a full first draft of all the text and code is finished. |
Thank you for opening this pull request. You can find the built site at this link. Deployment Info:
Note: It may take several minutes for updates to this pull request to be reflected on the deployed site. |
# - First, we randomly select a candidate integer, :math:`a`, between 2 and | ||
# :math:`N-1` (before proceeding, we double check that we did not get lucky and randomly select one of the true factors) | ||
# - Using our chosen a, we proceed to the quantum part of the algorithm: order-finding. | ||
# Quantum circuits are generated, and the circuit is executed on a device. The results | ||
# are used to make a guess for a non-trivial square root. | ||
# - If the square root is non-trivial, we test whether we found the factors. Otherwise, we try again | ||
# with more shots. Eventually, we try with a different value of a. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# - First, we randomly select a candidate integer, :math:`a`, between 2 and | |
# :math:`N-1` (before proceeding, we double check that we did not get lucky and randomly select one of the true factors) | |
# - Using our chosen a, we proceed to the quantum part of the algorithm: order-finding. | |
# Quantum circuits are generated, and the circuit is executed on a device. The results | |
# are used to make a guess for a non-trivial square root. | |
# - If the square root is non-trivial, we test whether we found the factors. Otherwise, we try again | |
# with more shots. Eventually, we try with a different value of a. | |
# - First, we randomly select a candidate integer, :math:`a`, between 2 and | |
# :math:`N-1` (before proceeding, we double check that we did not get lucky and randomly select one of the true factors) | |
# - Using our chosen a, we proceed to the quantum part of the algorithm: order-finding. | |
# Quantum circuits are generated, and the circuit is executed on a device. The results | |
# are used to make a guess for a non-trivial square root. | |
# - If the square root is non-trivial, we test whether we found the factors. Otherwise, we try again | |
# with more shots. Eventually, we try with a different value of a. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KetpuntoG @josh146 @dime10 At long last, here is a first draft for review. It's a long one, so please feel free to tag whoever has some bandwidth. I left some comments within. Two other top-level things:
- Most of the 90000 lines of this PR is SVG. The actual demo is ~1100
- The webpage does not seem to fully build. I can find the demo from the front, but most of the links give me XML access denied errors. I don't know if that's expected.
"previewImages": [ | ||
{ | ||
"type": "thumbnail", | ||
"uri": "/_static/demo_thumbnails/regular_demo_thumbnails/thumbnail_variationally_quantum_linear_solver.png" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just grabbed the thumbnail of another demo for now; many we can use a picture of one of the circuits, or a stylized picture of "N = p q" and a circuit?
.. meta:: | ||
:property="og:description": JIT compile Shor's algorithm from end-to-end with PennyLane and Catalyst. | ||
|
||
:property="og:image": https://pennylane.ai/qml/_static/demonstration_assets//fano.png |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to be updated with new image.
# that function. The next time that function is executed, the compiled version | ||
# can be reused, provided the structure of the inputs hasn't changed. | ||
# | ||
# .. figure:: ../_static/demonstration_assets/shor_catalyst/compilation_comparison.png |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be nice to include a graphic here, but consider this a placeholder (it's just a screenshot from a talk). Any suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this graphic fits quite nicely actually :)
# QJIT compiling Shor's algorithm | ||
# ------------------------------- | ||
# | ||
# Quantum subroutines |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is really long and detailed, but it also really helped my understanding to work through the circuits. Suggestions for trimming are welcome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will admit, at some point when I was deep into the explanation of the fourier addition and the subsequent optimization section, I started checking out trying to reason about all these circuits 😵💫 😅
The thing is, for someone looking to understand every piece of the algorithm this is actually an incredible resource! For a high-level read of the demo on the other hand it's possible to get lost in there.
Maybe we could have an appendix that explains how Fourier addition works, and the optimizations available there? In the main text we could then highlight two of the important optimizations like pre-computing the powers of a
, and the one estimation wire trick, which are already pretty neat :)
return num_to_return, denom_to_return | ||
|
||
|
||
def phase_to_order(phase, max_denominator): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dime10 is the author of a few of these functions - what's the best way to provide attribution?
N, pow_a, [control_wire, target_wires[n - i - 1]], aux_wires[:-1], aux_wires[-1] | ||
) | ||
|
||
qml.adjoint(QFT)(wires=aux_wires[:-1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functions like this one are the reason I'm not using PennyLane's modular arithmetic. They are heavily optimized to remove things like "outer" QFTs that are redundant, and they also implement the optimizations discussed in the circuit section.
# Performance and validation | ||
# ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
# | ||
# We will now verify that QJIT compilation is happening properly. We will run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestions welcome for what to show here. I'm hesitant to include the scaling plots (I prefer to save those for a more formal presentation). I also have not included resource counts because (as mentioned in the conclusion) actual quantum circuit optimization is not applied, so they look huge. Getting the resources also require an implementation in regular PennyLane so qml.specs
can be called.
plt.scatter(range(len(times)), times, c=[ex[0] for ex in execution_times]) | ||
plt.xticks(range(0, len(times), 2), labels=labels, rotation=80) | ||
plt.xlabel("N, a") | ||
plt.ylabel("Runtime (s)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't figure out how to suppress the text output of the plot. Adding a semicolon does not help. Also, would be great to get some feedback on clarity of the plot and whether it is effective in capturing the main points
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plot does show the lack of recompilation for different a
s and even N
s, but I think what might be missing is demonstrating why that is valuable to the user 🤔
What about comparing to the non-jitted version where re-computing and processing new circuits for each a
takes a lot of time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't figure out how to suppress the text output of the plot.
Have you tried this version?
plt.ylabel("Runtime (s)"); | |
plt.ylabel("Runtime (s)") | |
plt.show() |
# can automatically determine how subroutines can be simplified based on | ||
# classical information or on the input quantum superposition would be valuable | ||
# to develop, as they would enable co-optimization of the classical and quantum | ||
# parts of workflows. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestions welcome. Honestly this was so long in the making that I was at a loss for what to write here 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember you mentioning how great it was to be able to implement optimizations that are dependent on a
without any extra cost, maybe that is something we could highlight in the conclusion? :)
The fact that you can make all these really specific, a-dependent optimizations in the circuit, and it just works after the first run because of jit, is seriously amazing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, this is an incredible demo!! I'm amazed how well you explain and show the different pieces going in to this, must have been a lot work 😍 The introduction is also really nice :)
# Over the past year, PennyLane has been integrated with `Catalyst | ||
# <https://docs.pennylane.ai/projects/catalyst/en/latest/index.html>`_, allowing | ||
# for quantum just-in-time compilation of classical and quantum code | ||
# together. This demo leverages that integration to implement a version of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This statement confuses me a little bit, hasn't Catalyst been working with PennyLane ever since its release? Obviously features and usability have improved etc., but what did you want to express here?
# classical control structure and all. Even better, that compilation happens | ||
# only once per distinct bit-width of the integers being factored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😆 It's a good thing we're finally implementing qubit-number-independent compilation, which should make this sentence even more impactful.
# new program in assembly code; an assembler turns that into a | ||
# machine-executable program that is provided inputs and run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sentence ending in "... turns that into a program that is provided inputs and run[s?]" reads a bit odd to me, any chance we could rephrase it? :)
# To run the algorithm, we must randomly choose ``a``. In principle, we could | ||
# randomly generate ``a`` within the function above. However, this cannot | ||
# currently be QJITted. Passing ``n_bits`` as a static argument is also to work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh does this not work? Generating random numbers is possible with JAX, the main difference to numpy is that the PRNG state is explicit rather than implicit. We also use them in the MSD demo: https://docs.pennylane.ai/projects/catalyst/en/stable/demos/magic_distillation_demo.html#T-Type-Magic-States
from jax import random | ||
|
||
|
||
def factor_with_shor(N, n_shots=100): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm hesitant about the term shots here, since they could be confused with the concept of PennyLane/device shots. Should we just call these trials or similar?
# particularly valuable for large :math:`N`, where compilation time may become | ||
# long. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this saying that the JIT compilation time is long for large N or that "traditional" (e.g. PennyLane) circuit construction and processing becomes very expensive?
I think when I measured it the increase in JIT compilation time was relatively flat now.
# particularly valuable for large :math:`N`, where compilation time may become | |
# long. | |
# particularly valuable for large :math:`N`, where traditional circuit processing times can | |
# grow very large. |
plt.scatter(range(len(times)), times, c=[ex[0] for ex in execution_times]) | ||
plt.xticks(range(0, len(times), 2), labels=labels, rotation=80) | ||
plt.xlabel("N, a") | ||
plt.ylabel("Runtime (s)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plot does show the lack of recompilation for different a
s and even N
s, but I think what might be missing is demonstrating why that is valuable to the user 🤔
What about comparing to the non-jitted version where re-computing and processing new circuits for each a
takes a lot of time?
# can automatically determine how subroutines can be simplified based on | ||
# classical information or on the input quantum superposition would be valuable | ||
# to develop, as they would enable co-optimization of the classical and quantum | ||
# parts of workflows. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember you mentioning how great it was to be able to implement optimizations that are dependent on a
without any extra cost, maybe that is something we could highlight in the conclusion? :)
The fact that you can make all these really specific, a-dependent optimizations in the circuit, and it just works after the first run because of jit, is seriously amazing
Co-authored-by: David Ittah <dime10@users.noreply.github.com>
Title: JIT compiling Shor's algorithm with PennyLane and Catalyst
Summary: Over the past year, PennyLane has been integrated with Catalyst, allowing for quantum just-in-time compilation of classical and quantum code together. This demo leverages that integration to implement a version of Shor's factoring algorithm that is just-in-time compiled from end-to-end, classical control structure and all.
Relevant references: See within
Possible Drawbacks: As it stands, it's quite long (especially for the amount of actual output); I am not sure about the ending.
Related GitHub Issues: N/A
If you are writing a demonstration, please answer these questions to facilitate the marketing process.
Highlight PennyLane and Catalyst integration, and expose challenges (and opportunities) in scaling up quantum compilation pipelines.
Primarily people researchers and developers focused on quantum compilation.
quantum compilation; quantum circuits; quantum algorithms; Shor's algorithm
(more details here)