-
Notifications
You must be signed in to change notification settings - Fork 643
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
Adding a user-friendly qml.transform.decompose
function
#6334
Conversation
Hi @lillian542 & @albi3ro, Would appreciate any comments on the implementation and whether or not I have the right idea for what's required. I'm working on tests now but I figured I would get it out to you ASAP 😄. |
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.
Looks like great progress, @andrijapau 🚀 I left a few thoughts on the implementation so far, let me know if you have any questions!
Wrt names, one suggestion could be to rename the other function to device_decompose
(that would probably require a deprecation cycle), and then call this something like apply_decomposition
. I think that would make it fairly clear that one is intended for the preprocess
of a device, and the other is just a user applying a decomposition they want to specify.
Hi @lillian542 & @albi3ro, Thank you for your input, I've implemented the suggestions into the newest commit. 😄 Notable changes:
Open to feedback! |
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.
Looking good! I left a few more comments/questions :)
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.
Looking good! If you feel it's ready, you could switch this from a draft to ready-for-review now. Then CI will run and you will see any CodeCov warnings if there are any lines missing test coverage 😅
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6334 +/- ##
==========================================
- Coverage 99.71% 99.39% -0.32%
==========================================
Files 447 448 +1
Lines 42365 42464 +99
==========================================
- Hits 42244 42209 -35
- Misses 121 255 +134 ☔ View full report in Codecov by Sentry. |
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.
Left some comments about documentation, this one is very user-facing, so being extra careful 🚀
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.
❤️ No more concerns from my side. So happy to be getting this in :)
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.
Looks great, thanks @andrijapau!
**Context:** Users often want to inspect and transform quantum circuits at different stages of decomposition. This feature will allow them to gain a better understanding for the decomposition and to think about algorithms at different layers of abstraction. Prior to this feature, users only had access to `qml.devices.preprocess.decompose`- a function focused on device preprocessing. Over time, it became apparent that this function is developer focused, making use of hard-coded error messages / exceptions as well as non-intuitive stopping conditions. This led to some frustrations where users were trying to explore abstract decompositions (such as counting the number of CNOTs in a multi-controlled gate). For now, this function will serve to call the `qml.devices.preprocess.decompose` function and prune any developer-focused features. This feature should accomplish the following, 1. Decomposition of circuits into a desired gate set. 2. Decomposition of circuits into gate sets defined by a `Callable[Operator, bool]` (e.g. `lambda op: len(op.wires) <= 2`). 3. Decomposition of circuits in stages to understand the process. This can be done by adjusting the `max_expansion` kwarg. **Description of the Change:** The goal of this feature is to create a user-facing function that enables intuitive decomposition in a less restrictive manner. Examples: ```python >>> @partial(decompose, gate_set={qml.Toffoli, "RX", "RZ"}) >>> @qml.qnode(dev) >>> def circuit(): >>> qml.Hadamard(wires=[0]) >>> qml.Toffoli(wires=[0,1,2]) >>> return qml.expval(qml.Z(0)) >>> >>> print(qml.draw(circuit)()) 0: ──RZ(1.57)──RX(1.57)──RZ(1.57)─╭●─┤ <Z> 1: ───────────────────────────────├●─┤ 2: ───────────────────────────────╰X─┤ >>> @partial(decompose, gate_set=lambda op: len(op.wires) <= 2) >>> @qml.qnode(dev) >>> def circuit(): >>> qml.Hadamard(wires=[0]) >>> qml.Toffoli(wires=[0,1,2]) >>> return qml.expval(qml.Z(0)) >>> >>> print(qml.draw(circuit)()) 0: ──H────────╭●───────────╭●────╭●──T──╭●─┤ <Z> 1: ────╭●─────│─────╭●─────│───T─╰X──T†─╰X─┤ 2: ──H─╰X──T†─╰X──T─╰X──T†─╰X──T──H────────┤ >>> tape = qml.tape.QuantumScript([qml.IsingXX(1.2, wires=(0,1))], [qml.expval(qml.Z(0))]) >>> batch, fn = qml.transforms.decompose(tape, gate_set={"CNOT", "RX", "RZ"}) >>> batch[0].circuit [CNOT(wires=[0, 1]), RX(1.2, wires=[0]), CNOT(wires=[0, 1]), expval(Z(0))] ``` **Benefits:** Users can explore quantum circuit decomposition in a more abstract sense without having to rely on specific device architectures. **Possible Drawbacks:** None that I am aware of (yet 😄). **Related Shortcut Story:** [sc-51282]
**Context:** Users often want to inspect and transform quantum circuits at different stages of decomposition. This feature will allow them to gain a better understanding for the decomposition and to think about algorithms at different layers of abstraction. Prior to this feature, users only had access to `qml.devices.preprocess.decompose`- a function focused on device preprocessing. Over time, it became apparent that this function is developer focused, making use of hard-coded error messages / exceptions as well as non-intuitive stopping conditions. This led to some frustrations where users were trying to explore abstract decompositions (such as counting the number of CNOTs in a multi-controlled gate). For now, this function will serve to call the `qml.devices.preprocess.decompose` function and prune any developer-focused features. This feature should accomplish the following, 1. Decomposition of circuits into a desired gate set. 2. Decomposition of circuits into gate sets defined by a `Callable[Operator, bool]` (e.g. `lambda op: len(op.wires) <= 2`). 3. Decomposition of circuits in stages to understand the process. This can be done by adjusting the `max_expansion` kwarg. **Description of the Change:** The goal of this feature is to create a user-facing function that enables intuitive decomposition in a less restrictive manner. Examples: ```python >>> @partial(decompose, gate_set={qml.Toffoli, "RX", "RZ"}) >>> @qml.qnode(dev) >>> def circuit(): >>> qml.Hadamard(wires=[0]) >>> qml.Toffoli(wires=[0,1,2]) >>> return qml.expval(qml.Z(0)) >>> >>> print(qml.draw(circuit)()) 0: ──RZ(1.57)──RX(1.57)──RZ(1.57)─╭●─┤ <Z> 1: ───────────────────────────────├●─┤ 2: ───────────────────────────────╰X─┤ >>> @partial(decompose, gate_set=lambda op: len(op.wires) <= 2) >>> @qml.qnode(dev) >>> def circuit(): >>> qml.Hadamard(wires=[0]) >>> qml.Toffoli(wires=[0,1,2]) >>> return qml.expval(qml.Z(0)) >>> >>> print(qml.draw(circuit)()) 0: ──H────────╭●───────────╭●────╭●──T──╭●─┤ <Z> 1: ────╭●─────│─────╭●─────│───T─╰X──T†─╰X─┤ 2: ──H─╰X──T†─╰X──T─╰X──T†─╰X──T──H────────┤ >>> tape = qml.tape.QuantumScript([qml.IsingXX(1.2, wires=(0,1))], [qml.expval(qml.Z(0))]) >>> batch, fn = qml.transforms.decompose(tape, gate_set={"CNOT", "RX", "RZ"}) >>> batch[0].circuit [CNOT(wires=[0, 1]), RX(1.2, wires=[0]), CNOT(wires=[0, 1]), expval(Z(0))] ``` **Benefits:** Users can explore quantum circuit decomposition in a more abstract sense without having to rely on specific device architectures. **Possible Drawbacks:** None that I am aware of (yet 😄). **Related Shortcut Story:** [sc-51282]
Context:
Users often want to inspect and transform quantum circuits at different stages of decomposition. This feature will allow them to gain a better understanding for the decomposition and to think about algorithms at different layers of abstraction.
Prior to this feature, users only had access to
qml.devices.preprocess.decompose
- a function focused on device preprocessing. Over time, it became apparent that this function is developer focused, making use of hard-coded error messages / exceptions as well as non-intuitive stopping conditions. This led to some frustrations where users were trying to explore abstract decompositions (such as counting the number of CNOTs in a multi-controlled gate). For now, this function will serve to call theqml.devices.preprocess.decompose
function and prune any developer-focused features. This feature should accomplish the following,Callable[Operator, bool]
(e.g.lambda op: len(op.wires) <= 2
).max_expansion
kwarg.Description of the Change:
The goal of this feature is to create a user-facing function that enables intuitive decomposition in a less restrictive manner.
Examples:
Benefits:
Users can explore quantum circuit decomposition in a more abstract sense without having to rely on specific device architectures.
Possible Drawbacks:
None that I am aware of (yet 😄).
Related Shortcut Story:
[sc-51282]