Skip to content

Generalize python-decompositions#2983

Open
kipawaa wants to merge 49 commits into
mainfrom
decomp-interface
Open

Generalize python-decompositions#2983
kipawaa wants to merge 49 commits into
mainfrom
decomp-interface

Conversation

@kipawaa

@kipawaa kipawaa commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Context:
The initial implementation of python-decompositions was specialized to quantum.paulirot. This was done partly for simplicity, and partly due to a lack of consistency in op interfaces, which would have required bespoke solutions to parse dynamic data, static data etc for each quantum operation.

Description of the Change:
Introduces a generic DecomposableOpInterface interface for interacting with ops in the context of decomposition. This provides consistent methods for accessing dynamic data, static data, op graph IDs and more. This PR introduces the interface as a PoC for quantum.paulirot and quantum.operator, providing tests as a demonstration of the intended functionality. The intended result of this implementation will be to remove any op-specific logic from the graph-decomposition pass, instead using exclusively methods from the interface to improve generality and improve extensibility to other ops without altering core logic in the graph.

Benefits:
Enables consistent interfaces across all op types relevant to decomposition, reduces type-checking boilerplate and code duplication. This allows any op implementing the interface to use python-decompositions, and further simplifies the general graph infrastructure.

Possible Drawbacks:

Related GitHub Issues:

[sc-122013]
[sc-122018]

@kipawaa kipawaa changed the base branch from main to graph-decomp-rule-improvements June 30, 2026 15:54
@kipawaa kipawaa force-pushed the decomp-interface branch from 5a65616 to 3812a39 Compare June 30, 2026 18:05
@kipawaa kipawaa force-pushed the decomp-interface branch from 3812a39 to d46c6af Compare June 30, 2026 18:08

@dime10 dime10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is great thanks! Moving in a good direction :)

Comment thread mlir/include/Quantum/IR/QuantumInterfaces.td Outdated
Comment thread mlir/include/Quantum/IR/QuantumInterfaces.td Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md on your branch with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@kipawaa kipawaa changed the title Add DecomposableGate interface Generalize python-decompositions Jun 30, 2026

@maliasadi maliasadi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Happy to see this PR come through 🙌

Comment thread frontend/catalyst/device/python_decompositions.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We probably need to raise an error to guarantee the biggest constraint with the system which is if any rule for an op is present, all its rules need to be present. in other words, no support for user defined rules via add_decomps with python decomps.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think that it will be more appropriate to try to assert this once we have implemented the auto-tracing of decomposition rules with operators which will be future work for Operator2. Does that seem reasonable?

def circuit():
paulirot_subroutine(theta, wires)
for subroutine in subroutines:
subroutine(*[0.5 for _ in dynamic_shape], wires=wires)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pls add a TODO for 0.5. It's probably safe for all present ops/rules, but let's bring this up in the Op2 sync meeting to double-check with the rest of the team.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a placeholder for now, but I definitely agree that we should check in about this and what exactly might come through as dynamic data. I'll add the TODO and be sure to discuss this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added TODOs here: 0437262

];
}

def DecomposableGate : OpInterface<"DecomposableGate", [QuantumGate]> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it also meant to eventually replace the special-casing in getRuleNodes or basically name-handling (gphase -> GlobalPhase, which already has a "TODO: replace this with DecomposableGate interface")? If so, sketching that end state now would clarify whether the current method set is sufficient for use cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Definitely! My end goal is that any op that wants to participate in graph decomp should implement this interface, so that we can standardize how we identify which ops need decomposition and how to gather data from them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just to have all of the information in one place, we'll implement this interface for other ops in follow-up PRs. Once all of the core operations have implemented the interface, we can update the graph-decomposition pass to support the interface (and only the interface). I've improved the explanation of this in e3e6736

@kipawaa kipawaa marked this pull request as ready for review July 10, 2026 13:10
@kipawaa kipawaa requested review from dime10 and maliasadi July 10, 2026 14:47
Base automatically changed from graph-decomp-rule-improvements to main July 10, 2026 15:04
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.99%. Comparing base (e917017) to head (fde3c2e).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2983      +/-   ##
==========================================
+ Coverage   96.98%   96.99%   +0.01%     
==========================================
  Files         167      167              
  Lines       19390    19441      +51     
  Branches     1813     1817       +4     
==========================================
+ Hits        18805    18857      +52     
+ Misses        431      430       -1     
  Partials      154      154              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dime10 dime10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice work, this is coming together nicely 💯

return qp.capture.subroutine(decomp_rule)

# let this fail with the standard error message if the op is not found
op_class = getattr(qp, op_name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there any chance we could process operators that are not in the top-level pennylane namespace?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Perhaps it's possible to query the decomp rule registry with the name directly instead of the class, that would circumvent this problem (cc @astralcai).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good idea, we could probably remove this and just rely on list_decomps(op_name)? @astralcai does this seem like a reasonable approach? Since we intend to let this fail anyways if the op isn't found, that failure can be generated from the frontend graph, which allows a wider set of operators

Comment thread frontend/catalyst/device/python_decompositions.py
Comment thread frontend/catalyst/device/python_decompositions.py Outdated
Comment thread frontend/test/pytest/test_QPD.py Outdated
Comment thread mlir/include/Quantum/IR/QuantumInterfaces.td Outdated
Comment thread mlir/test/Quantum/DecomposeLoweringTest.mlir
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.

3 participants