Skip to content

Support decomposition to/from Adjoint Ops to the GraphSolver#3001

Open
maliasadi wants to merge 10 commits into
mainfrom
graph-solver/adjoint-op
Open

Support decomposition to/from Adjoint Ops to the GraphSolver#3001
maliasadi wants to merge 10 commits into
mainfrom
graph-solver/adjoint-op

Conversation

@maliasadi

@maliasadi maliasadi commented Jul 8, 2026

Copy link
Copy Markdown
Member

Context:
The decomposition graph solver could not decompose Adjoint ops. This PR adds this support to the graph solver to handle them, mirroring the two decomposition families used by PL:

  1. Decompose Adjoint(Op) directly: Rules registered against the adjoint operator itself: self_adjoint and adjoint_rotation funcs in PL. and other custom rules like _adjoint_rot, etc. These were already supported by the graph. A RuleNode whose output has adjoint = true is registered and solved like any other rule; so no new logic was needed to the solver; they just need to be provided as rules. I'll take care of this in a follow-up PR to integrate the support with the graph-decomposition pass.

  2. Decompose Op, then adjoint each produced gate: From each base rule Op, the graph builder should synthesize Adjoint(Op) with the same multiplicities. I assumed that gate-order reversal doesn't affect resources, so the graph only needs the Adjoint(Op) counts; the actual reversal happens in the follow-up PR when integrating with the pass.

Both pathways coexist in the graph, and the solver picks the cheapest decomp pathway! 🎉

Benefits:

  • Supporting Adjoint(Op) decomposition and resource estimation

Possible Drawbacks:

  • For circuits with many Adjoints, the size of the graph will be doubled as we need to add mirrored rules for each Adjoint(Op) and track them all throughout multiple decomp pathways.
  • I'm using explicit rules for self-adjoint gates! This can be further optimized later after integration with the graph-decomposition pass.

Related GitHub Issues:
[sc-125400]

@maliasadi
maliasadi requested review from astralcai and kipawaa July 8, 2026 21:25
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.99%. Comparing base (292e3f4) to head (9a5f1e4).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3001   +/-   ##
=======================================
  Coverage   96.99%   96.99%           
=======================================
  Files         165      165           
  Lines       19091    19091           
  Branches     1816     1816           
=======================================
  Hits        18518    18518           
  Misses        420      420           
  Partials      153      153           

☔ 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.

* - AdjointGenerated: A rule synthesized by adjointing a base decomposition rule.
*/
enum class RuleOrigin : uint8_t { Default = 0, Fixed = 1, Alternative = 2 };
enum class RuleOrigin : uint8_t { Default = 0, Fixed = 1, Alternative = 2, AdjointGenerated = 3 };

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.

Should we differentiate between adjoint genereated from default, adjoint generated from fixed and adjoint generated from alternative?

{
RuleNode adj;
adj.name = base.name + "_adjoint";
adj.output = makeAdjoint(base.output);

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.

Do we have to worry about this in-place mutating base.output?

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