Skip to content

Track graph operation IDs in decomposition resource analysis - #3102

Open
sengthai wants to merge 34 commits into
ex-re/reshape-jsonfrom
add-graph-op-id
Open

Track graph operation IDs in decomposition resource analysis#3102
sengthai wants to merge 34 commits into
ex-re/reshape-jsonfrom
add-graph-op-id

Conversation

@sengthai

@sengthai sengthai commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Context:
Previously, ResourceAnalysis grouped quantum operations using only their name, wire(qubit) count, and parameter count, producing identifiers. Meanwhile graph-decompositions uses graphOpId, which also captures parameter types, wire structure, static data, and operator UIDs (some of these are part of Operator2).

This PR aligns resource generation with graphOpId by adding an optional detailed operation count used specifically by decomposition passes.

To use that, developer can toggle collectDetailedOperation when construct the analysis.

[sc-125008]

@sengthai sengthai changed the title add graph op id Add new field for quantum operation detailed in resource analysis for graph decomp Aug 5, 2026
@sengthai sengthai changed the title Add new field for quantum operation detailed in resource analysis for graph decomp Track graph operation IDs in decomposition resource analysis Aug 7, 2026
@sengthai
sengthai marked this pull request as ready for review August 7, 2026 19:55
@sengthai
sengthai requested review from jzaia18 and kipawaa August 7, 2026 19:55
Comment on lines 367 to +370
collectOperation(&op, result, isAdjoint);
if (collectDetailedOperations) {
collectDetailOperation(&op, result, isAdjoint);
}

@sengthai sengthai Aug 7, 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.

In ADR, we stated the mechanism that allow us to toggle between quantum_operation and quantum_operation_detailed, but in actual implementation, we still need to perform for quantum_operation by the way, because it needs to collect the function name for handling function call. Also, since buildResourceDict() serializes only detailOperations into MLIR attribute, we here just toggle only quantum_operation_detailed.

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.

If we needed to we could probably collect the function names using CollectDetailedOperation, but I think the current solution is fine, it shouldn't be much more expensive and saves us having 2 implementations.

@jzaia18 jzaia18 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.

Looks good so far, just a few comments

Comment thread mlir/include/Catalyst/Analysis/ResourceAnalysis.h Outdated
Comment thread mlir/include/Catalyst/Analysis/ResourceResult.h Outdated
Comment on lines 367 to +370
collectOperation(&op, result, isAdjoint);
if (collectDetailedOperations) {
collectDetailOperation(&op, result, isAdjoint);
}

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.

If we needed to we could probably collect the function names using CollectDetailedOperation, but I think the current solution is fine, it shouldn't be much more expensive and saves us having 2 implementations.

* @return DictionaryAttr representing the resource counts
*
*/
DictionaryAttr buildResourceDict(MLIRContext *ctx, const ResourceResult &result) {

@jzaia18 jzaia18 Aug 10, 2026

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.

Doesn't this method only work if we collect detailed operations now? What if the user didn't select this setting?

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.

If the user didn't enable collectDetailedOperaitons here.

ResourceAnalysis analysis(module, {}, /*collectDetailedOperations=*/true);

then, this return empty operations.

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.

But that's a bug, isn't it? If we leave collectDetailedOperations as false then the output JSON will be completely missing all operations data

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 can see that. Being empty when collectDetailedOperations is false seems incorrect interpretation. Okay, i will add an assert if in that function then.

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.

Comment thread mlir/test/Catalyst/RegisterDecompRuleResourceTest.mlir Outdated

@jzaia18 jzaia18 Aug 11, 2026

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 seems like we're replacing the existing unit tests with ones that check the detailed ops. I think we should instead add new unit tests -- we still want to test that the old pathway works as well

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.

what the old pathway you mention here? We actually replace the existing detailed ops fetching, completely.

// Rule with measure

// CHECK: resources = {measurements = {}, num_alloc_qubits = 1 : i64, num_arg_qubits = 0 : i64, num_qubits = 1 : i64, operations = {"Hadamard(1,0)" = 1 : i64, "MidCircuitMeasure(1,0)" = 1 : i64}}, target_gate = "gate"
// CHECK: resources = {measurements = {}, num_alloc_qubits = 1 : i64, num_arg_qubits = 0 : i64, num_qubits = 1 : i64, operations = {"Hadamard[][1]{}" = 1 : i64}}, target_gate = "gate"

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.

Why do we no longer expect the MCM to show?

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 include it in 0a277f1

Comment thread mlir/test/Catalyst/RegisterDecompRuleResourceTest.mlir Outdated
Comment thread mlir/test/Catalyst/RegisterDecompRuleResourceTest.mlir Outdated
sengthai and others added 3 commits August 11, 2026 10:30
Co-authored-by: Jake Zaia <23638795+jzaia18@users.noreply.github.com>
Fix missing adjoint in detailedOperaiton
std::string opId = inst.getGraphOpId();
if (auto resourceOp = dyn_cast<ResourceQuantumOpInterface>(op)) {
if (isAdjoint ^ resourceOp.getResourceAdjointFlag()) {
opId += "[adj]";

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.

Will this break anything for the actual decomposition graph IDs?

CC @kipawaa

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.

FYI, it should be like Rot[f64,f64,f64][2]{}[adj]

}
}
result.detailedOperations[opId] += 1;
}

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.

Don't forget to add an else-branch to catch cases when we don't have a graph operator ID

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 added another if-branch for handling the ResourceAnlaysis op type. 0a277f1

I'm sure how we handle unknown quantum ops here. So, i would leave that alone for unknown op as it can be classical ops as well.

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