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

Better MCX Decomposition with logarithmic Toffoli Depth #7028

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

patelvyom
Copy link

Context:
The recent paper Rise of conditionally clean ancillae for optimizing quantum circuits presents an improved decomposition of MCX gates using conditionally clean ancilla qubits. The proposed method achieves the following trade-offs in terms of Toffoli gate count and circuit depth:

  • 2n − 3 Toffoli and O(n) depth using 1 clean ancilla
  • 2n − 3 Toffoli and O(log(n)) depth using 2 clean ancilla
  • 4n − 8 Toffoli and O(n) depth using 1 dirty ancilla
  • 4n - 8 Toffoli and O(log(n)) depth using 2 dirty ancilla

This approach is currently optimal regarding Toffoli count (for 1 and 2 ancillae) and significantly improves circuit depth.

Description of the Change:
Added _decompose_mcx_with_two_workers and _decompose_mcx_with_one_worker_kg24 decompositions.

Benefits:
Extend support to:

  • len(work_wires) == 2, enabling a more efficient decomposition
  • Improved decomposition for len(work_wires) == 1, reducing circuit depth.

Related GitHub Issues:
Implements #6997

@patelvyom
Copy link
Author

@albi3ro I have a draft ready and am currently working on the tests. The implementation for dirty and clean only differs in terms of uncomputing certain gates.

Long term, it would be great to have the compiler find dirty wires and call the appropriate decomposition function because finding clean wires is much stricter condition than reusing other wires of larger circuit as dirty wires.

@Jaybsoni Jaybsoni self-requested a review February 28, 2025 21:21
@albi3ro
Copy link
Contributor

albi3ro commented Feb 28, 2025

Thanks for opening this @patelvyom 👍 I'll try and take a look at it on Monday.

@patelvyom
Copy link
Author

This pull request is nearly ready to merge. The main open question is whether decompose_mcx should assume it is always called within a qml.tape context. Currently, it returns a List[Operation], but if operations are expected to be taped, additional conditional logic (if qml.QueuingManager.recording()) will be needed in both functions.

Summary of Changes:

  • Implemented two new decomposition functions, along with helper functions, based on the referenced paper.
  • Added four test cases for each new decomposition function.
  • Introduced a new argument to decompose_mcx(): work_wire_type: Literal["clean", "dirty"].
  • Updated decompose_mcx to select the decomposition method in order: many_workers, two_workers, one_worker based on no. of available work wires.
  • Ensured _decompose_recursive sets work_wire_type="dirty" when called recursively, aligning with the assumptions of the cited lemma.
  • Renamed _decompose_mcx_with_one_worker to _decompose_mcx_with_one_worker_b95.

@patelvyom patelvyom marked this pull request as ready for review March 2, 2025 20:37
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.

2 participants