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

Added loop boundary optimization #1476

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open

Conversation

sengthai
Copy link
Contributor

@sengthai sengthai commented Jan 20, 2025

Context:

The Loop Boundary Optimization identifies and optimizes redundant quantum operations that occur at loop iteration boundaries, where operations at iteration boundaries often cancel each other out.

This method is standalone pass but also integrated in merge rotation and cancel inverses pass.

It specifically targets:

  1. Pattern recognition: Identifies matching quantum operations at the beginning and end of loop iteration.
  2. Operation Hoisting:
    • Moves matching operations from loop boundaries to outside loop
    • Top-edge and operations are hoisted before the loop and after the loop, respectively.

Description of the Change:

  • Register new pass for loop boundary optimization
  • Implement to support this method on merge_rotation and cancel_inverses pass

Benefits:

  • Eliminates redundant operations that cancel each other between iterations
  • Reduces quantum circuit depth and gate count
  • Effective for compute/uncompute patters in loops

Limited Scope

  • Only works with perfectly matching operations
    • Support gates: Pauli gates, H gate, CNOT, and rotation gates.

Possible Drawbacks:

  • Increased compilation time

[sc-83037]

Copy link
Contributor

@dime10 dime10 left a comment

Choose a reason for hiding this comment

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

Nice work so far! I left a few comments regarding the foundations of the pass, but since it's still a work in progress I didn't look at the code too closely yet :)

@paul0403
Copy link
Contributor

Remember to link to the shortcut story! You can see how this is done on other PRs :D

@sengthai
Copy link
Contributor Author

Remember to link to the shortcut story! You can see how this is done on other PRs :D

Of course, will do. Thanks Paul!

Integrate with merge rotation and cancel inverse

Improve code dynamic
@sengthai sengthai changed the title [WIP] Added loop boundary optimization pass Added loop boundary optimization Feb 4, 2025
@sengthai sengthai marked this pull request as ready for review February 4, 2025 14:39
@sengthai sengthai added the enhancement New feature or request label Feb 4, 2025
@sengthai sengthai requested a review from dime10 February 4, 2025 21:03
@sengthai sengthai requested a review from a team February 4, 2025 21:05
Copy link
Contributor

@dime10 dime10 left a comment

Choose a reason for hiding this comment

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

Excellent work @sengthai, this is looking really good 💯

A couple of questions I still have:

return qml.expval(qml.Z(0))
```

Note that this pass works with perfectly matching operations such as Pauli gates, Hadamard gate, CNOT and rotations gates.
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean by perfectly matching operations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean operations that cancel each other out exactly when applied in sequence, like Hadamard followed by Hadamard. I'll update the documentation to be more explicit about this.

Comment on lines 53 to 58
RewritePatternSet patternsCanonicalization(&getContext());
scf::ForOp::getCanonicalizationPatterns(patternsCanonicalization, &getContext());

if (failed(applyPatternsAndFoldGreedily(module, std::move(patternsCanonicalization)))) {
return signalPassFailure();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious as to why you are running the for loop patterns here?

There is also the option to combine the patterns from the for loop and the loop boundary and run them together.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, you're right! If we were only using ForOp canonicalization patterns thinking they would help filter/dispatch ForOps to our pass, that's not necessary. Our LoopBoundaryPattern already specifically matches and handles ForOps.

Comment on lines 52 to 55
populateLoopBoundaryPatterns(patternsLoopBoundary);

if (failed(applyPatternsAndFoldGreedily(module, std::move(patternsLoopBoundary)))) {
return signalPassFailure();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this apply adjoint cancellation as well even though we are in the merge rotation pass?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's intentional. Loop boundary optimization can create more opportunities for rotation merging. However, I will combine merge rotation and and loop boundary instead of applying pattern individually.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that is the intention product had though. Applying the rotation merging pass should simply merge rotations (now including across boundaries), not cancel inverses. Interaction between those two passes can be benefitted from by introducing a better pass that combines multiple quantum optimization patterns, but that's out of scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You got the point. And yes, the loop boundary pass here takes action on both Rotation and Hermitian gates no matter where we called it. Example:

For _ in range(3)
   X -> Q0
   Rx(0.1) -> Q1
   CNOT -> Q0, Q1
   Rx(0.3) -> Q1
   X -> Q0

In here even we just apply merge_rotation, the pass will consider to optimize on X gate as well.

I agree with you that current merge_rotation with loop boundary do more than what it supposed to do.

Let's me check if we can control the loop boundary behavior when applying with merge_rotations and cancel_inverse

Comment on lines 180 to 181
// CHECK: [[reg:%.+]] = quantum.alloc( 1) : !quantum.reg
// CHECK: [[qubit_0:%.+]] = quantum.extract [[reg]][ 0] : !quantum.reg -> !quantum.bit
Copy link
Contributor

@dime10 dime10 Feb 7, 2025

Choose a reason for hiding this comment

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

I don't think this test checks anything meaningful, the added complexity comes into play when the register is a loop iter_arg no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point! test_loop_boundary_register_2 is indeed a better test case. This simpler one can stay for basic verification, but we should focus on more complex register iter_arg cases.

mlir/test/Quantum/LoopBoundaryOptimization.mlir Outdated Show resolved Hide resolved
Updated changelog

Remove unnecessary codes
Copy link

codecov bot commented Feb 7, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.90%. Comparing base (7ff763a) to head (ed3e9da).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1476      +/-   ##
==========================================
+ Coverage   90.90%   95.90%   +4.99%     
==========================================
  Files          21       80      +59     
  Lines        1485     8319    +6834     
  Branches        0      779     +779     
==========================================
+ Hits         1350     7978    +6628     
- Misses        135      286     +151     
- Partials        0       55      +55     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sengthai sengthai requested a review from dime10 February 13, 2025 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants