Skip to content

Resource analysis - integrate graph solver - #3351

Open
hsajjad14 wants to merge 27 commits into
resource-analysis/expose-graph-solverfrom
resource-analysis/integrate-graph-solver-squashed
Open

hsajjad14 wants to merge 27 commits into
resource-analysis/expose-graph-solverfrom
resource-analysis/integrate-graph-solver-squashed

Conversation

@hsajjad14

@hsajjad14 hsajjad14 commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Context:

Made a new pass resource-estimate which uses resource-analysis and graph decomposition to project resources onto target gate sets.

Description of the Change:
Modified frontend from_plxpr.py, adding an additional parameter to _handle_decompose_transform which checks if the pass is resource-estimate for qp.estimate. In that case it makes a new transform setting up the graph-decomposition and resource-estimate inputs.

Modified GraphDecompositionPrep::prepareGraph call in graph_decomposition to fix CI.

Created a new resource-estimate pass which creates the graph via GraphDecompositionPrep::prepareGraph, then it solves it, then runs ResourceAnalysis to collect the IR's resources. Then prunes them according to the solution reported from the graph solver, such that the final resources (estimates) are in the target gate set.

Benefits:

Allows for qp.estimate, to estimate projected resources on a circuit without compilation.

Possible Drawbacks:

GraphDecompositionPrep and ResourceAnalysis are repeating work in building the GOIDs, I made https://app.shortcut.com/xanaduai/story/135442/remove-graphdecompprep to address this.

This resource-estimate pass currently modifies the IR due to graph decomposition adding rules to the IR, after they are moved to their own module/file, this will be a read-only pass.

Related GitHub Issues:

[sc-133131]

JukeBox review: If gate_set is None, handle_transform skips the gate-set handler and sends resource-estimate with no gate-set. The pass then aborts (exit 134). e7f066e

@hsajjad14 hsajjad14 changed the title Resource analysis/integrate graph solver Resource analysis/integrate graph solver (squashed) Oct 16, 2026
@hsajjad14 hsajjad14 changed the title Resource analysis/integrate graph solver (squashed) Resource analysis - integrate graph solver Oct 16, 2026
@hsajjad14
hsajjad14 marked this pull request as ready for review October 16, 2026 17:57
@hsajjad14
hsajjad14 requested review from a team, kipawaa and maliasadi October 16, 2026 17:58
@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.25%. Comparing base (e444f3f) to head (f346cb8).

Additional details and impacted files
@@                          Coverage Diff                           @@
##           resource-analysis/expose-graph-solver    #3351   +/-   ##
======================================================================
  Coverage                                  96.25%   96.25%           
======================================================================
  Files                                        177      177           
  Lines                                      21699    21715   +16     
  Branches                                    2162     2167    +5     
======================================================================
+ Hits                                       20886    20902   +16     
  Misses                                       629      629           
  Partials                                     184      184           

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

@yde773786
yde773786 force-pushed the resource-analysis/integrate-graph-solver-squashed branch from 7545818 to 18f4f55 Compare October 21, 2026 21:46
bound_pass = bound_transform(**bound_transform_params)

# Set resource analysis estimation options after graph_decomposition_setup_inputs.
if resource_analysis_for_estimate:

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.

We can have resource_analysis transform uses a custom resource_analysis_setup_inputs (which in turn uses graph_decomposition_setup_inputs for graph related configs) and then handles setup_inputs for the output_json/output_fname.

// CHECK: "-1"
// CHECK: "testRX": 3
// CHECK: "testRZ": 4
// CHECK-NOT: "testHadamard"

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.

@hsajjad14

I had to change testRX : 3 under -1 instead of testRX : 2 under -1 and testRX: 1 under 1.

c55bd08

This is expected behaviour since numWires will now always be -1 since we've severed any reference to parseOperator

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.

Yup, this is fine since we are removing use of parseOperator here. We won't be able to check if the op is in the gateset now, but either way it is the same.

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.

I have to admit adding graph into ResourceAnalysis breaks both the single-responsibility principle and pass semantics. With gate-set, this pass is no longer an analysis: loads rules into the module -> lowers modifiers -> solves the graph -> report estimated counts after decomp!! While previously, it was just a read-only counter! One pass now does two different jobs. but why?

My suggestion here is to break it into two:

  1. A new pass, resource-estimation (C++ ResourceEstimationPass), named after qp.estimate.

    • It takes the graph options
    • It runs prepareGraph -> solve the graph -> builds the ID map ...
    • But the pass will be declared as a pass that changes the IR (not read-only)
  2. resource-analysis goes back to what it was on main and the ResourceAnalysis class keeps its name and loses the graph types w/ replacing the GraphResult * parameter with a generic count-substitution map.

From frontend, we can add a catalyst.passes.resource_estimation transform with its own setup_inputs, which can call graph_decomposition_setup_inputs for the graph option. This will further remove the current pass_name == "resource-analysis" and gate_set is not None check, which changes what a pass does based on whether one kwarg is present!

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.

@maliasadi Good points here - I think I might have a solution 😄 I'm working on putting decomposition rules into a separate module, independent from the circuit. Since this pass doesn't need to re-write after solving the graph, it could read attributes and generate rule nodes from that module, without materializing any rules into the circuit. This will require delaying these changes a bit, but we should be able to return this pass to read-only (assuming we skip on-demand rules...). In a situation like this I think it would make sense to keep the shared behaviour.

@hsajjad14 hsajjad14 Oct 28, 2026 •

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.

@maliasadi @kipawaa Thanks for the feedback.
@yde773786 and I updated our branches, this and #3349, where it now uses a new resource-estimate pass, that calls GraphDecompositionPrep to make the graph, then ResourceAnalysis to collect the resources and GOIDs. It then does post-processing to the resources, to ensure the reported resources are in the target gate-set. Both passes will become read only when the changes to move decomposition rules into their own modules are in.

@yde773786 mentioned this in his PR #3349, there are currently two walks to collect the GOIDs, one in GraphDecompositionPrep and the other in ResourceAnalysis, this is due to graph-decomp collecting GOIDs slightly differently than ResourceAnalysis, where it ignores operators in decomp rules. We have a few options here, but I think it would be good to go with this for now. And after Decomposition rules have their own module is in main, we can look into removing GraphDecompositionPrep completely. I opened a story for this here.

hsajjad14 and others added 15 commits October 28, 2026 12:11
When a target gate set is given, resource-analysis builds and solves the
decomposition graph and counts ops outside the gate set by the basis counts
of their chosen decomposition rule.

Squash of resource-analysis/integrate-graph-solver.
Parts of this change were written with the help of an AI assistant.

Co-authored-by: Cursor <cursoragent@cursor.com>
… opNode is in the gateset (as the gateset searches by name of Op). Removed the graph from RA as its only needed to extract the gateset.
@hsajjad14
hsajjad14 force-pushed the resource-analysis/integrate-graph-solver-squashed branch from 446327b to 1276706 Compare October 28, 2026 16:36
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.

4 participants