Skip to content

Add a commutation aware rewriter/matcher and update quake-simplify to use - #5012

Open
taalexander wants to merge 29 commits into
NVIDIA:mainfrom
taalexander:feature/commutation-aware-rewrite-staged
Open

Add a commutation aware rewriter/matcher and update quake-simplify to use#5012
taalexander wants to merge 29 commits into
NVIDIA:mainfrom
taalexander:feature/commutation-aware-rewrite-staged

Conversation

@taalexander

@taalexander taalexander commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR is based on #4984 and should only be merged after. The LoC should go down significantly as those dependencies go in. This PR actually cuts ~200LoC from quake simplify with the majority of the logic being the rewriter/matcher.

Adds a block-local commutation-aware rewrite driver and uses it in
quake-simplify to cancel inverse gates and fold rotations across operations
proven to commute.

For example, this tested MLIR:

%first = arith.constant 0.125 : f64
%second = arith.constant 0.625 : f64
%q = quake.null_wire
%rz0 = quake.rz (%first) %q
    : (f64, !quake.wire) -> !quake.wire
%s = quake.s %rz0 : (!quake.wire) -> !quake.wire
%rz1 = quake.rz (%second) %s
    : (f64, !quake.wire) -> !quake.wire
quake.sink %rz1 : !quake.wire

is simplified to the equivalent form:

%sum = arith.constant 0.75 : f64
%q = quake.null_wire
%s = quake.s %q : (!quake.wire) -> !quake.wire
%rz = quake.rz (%sum) %s
    : (f64, !quake.wire) -> !quake.wire
quake.sink %rz : !quake.wire

Applicable IR

The matcher operates on block-local, value-semantics Quake with linear scalar
!quake.wire controls and targets. Endpoints must implement
OperatorInterface and preserve wire threading.

Measurement and reset operations may be crossed only for supported scalar-wire
forms and only when commutation is proven. Reusable controls, references,
aggregates, fanout, block edges, calls or regions touching the wire, unsupported
quantum effects, and unresolved identities are commutation boundaries
and the analysis would need to be extended to support if required
(I haven't seen much oppurtunity in this right now).

Pipelines can canonicalize to this form with:

factor-quantum-alloc, memtoreg, linear-ctrl-form

This is backward compatible with existing quake-simplify use.

Benchmarking

On a set of internal benchmarks this shows about ~0-20% circuit improvements in total gate counts on individual benchmarks with a mean of 6.6% improvement across the total gate count in the sampled benchmarks. A bit less than I was hoping for but it's pretty clear where the low hanging fruit in the follow on work is.

@github-actions github-actions Bot added runtime CUDA quantum runtime core compiler labels Jul 29, 2026
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown

CI Summary (push) — ✅ passed

Run #31525733618 · ✅ 6 · ⏩ 7 · ❌ 0 · ⛔ 0

Top-level jobs (13)
Job Result
binaries ⏩ skipped
build_and_test ✅ success
config_devdeps ✅ success
config_source_build ⏩ skipped
config_wheeldeps ✅ success
devdeps ✅ success
docker_image ⏩ skipped
gen_code_coverage ⏩ skipped
metadata ✅ success
python_metapackages ⏩ skipped
python_wheels ⏩ skipped
source_build ⏩ skipped
wheeldeps ✅ success
⏩ Skipped jobs (7) — intentionally skipped on PR builds; run on merge_group / workflow_dispatch
Job
binaries
config_source_build
docker_image
gen_code_coverage
python_metapackages
python_wheels
source_build
All sub-jobs (42) — every matrix leg, with links
Job Status Link
Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, gcc12, openmpi) / Dev environment (Python) ✅ success view
Build and test (amd64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, llvm, openmpi) / Dev environment (Python) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Python) ✅ success view
CI Summary ❔ in_progress view
Configure build (devdeps) ✅ success view
Configure build (source_build) ⏩ skipped view
Configure build (wheeldeps) ✅ success view
Create CUDA Quantum installer ⏩ skipped view
Create Docker images ⏩ skipped view
Create Python metapackages ⏩ skipped view
Create Python wheels ⏩ skipped view
Gen code coverage ⏩ skipped view
Load dependencies (amd64, gcc12) / Caching ✅ success view
Load dependencies (amd64, gcc12) / Finalize ✅ success view
Load dependencies (amd64, gcc12) / Metadata ✅ success view
Load dependencies (amd64, llvm) / Caching ✅ success view
Load dependencies (amd64, llvm) / Finalize ✅ success view
Load dependencies (amd64, llvm) / Metadata ✅ success view
Load dependencies (arm64, gcc12) / Caching ✅ success view
Load dependencies (arm64, gcc12) / Finalize ✅ success view
Load dependencies (arm64, gcc12) / Metadata ✅ success view
Load dependencies (arm64, llvm) / Caching ✅ success view
Load dependencies (arm64, llvm) / Finalize ✅ success view
Load dependencies (arm64, llvm) / Metadata ✅ success view
Load source build cache ⏩ skipped view
Load wheel dependencies (amd64, 12.6) / Caching ✅ success view
Load wheel dependencies (amd64, 12.6) / Finalize ✅ success view
Load wheel dependencies (amd64, 12.6) / Metadata ✅ success view
Load wheel dependencies (amd64, 13.0) / Caching ✅ success view
Load wheel dependencies (amd64, 13.0) / Finalize ✅ success view
Load wheel dependencies (amd64, 13.0) / Metadata ✅ success view
Load wheel dependencies (arm64, 12.6) / Caching ✅ success view
Load wheel dependencies (arm64, 12.6) / Finalize ✅ success view
Load wheel dependencies (arm64, 12.6) / Metadata ✅ success view
Load wheel dependencies (arm64, 13.0) / Caching ✅ success view
Load wheel dependencies (arm64, 13.0) / Finalize ✅ success view
Load wheel dependencies (arm64, 13.0) / Metadata ✅ success view
Prepare cache clean-up ✅ success view
Retrieve PR info ✅ success view
✅ Required checks (6/6) — declared in .github/required-checks.yml for push
Required check Status Link
Build and test (amd64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, llvm, openmpi) / Dev environment (Python) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Debug) ✅ success view
Build and test (arm64, llvm, openmpi) / Dev environment (Python) ✅ success view
Build and test (amd64, gcc12, openmpi) / Dev environment (Debug) ✅ success view
Build and test (amd64, gcc12, openmpi) / Dev environment (Python) ✅ success view

@taalexander
taalexander force-pushed the feature/commutation-aware-rewrite-staged branch from e618123 to e7f0900 Compare July 29, 2026 13:42
@github-actions github-actions Bot added the python-lang Anything related to the Python CUDA Quantum language implementation label Jul 29, 2026
@taalexander
taalexander force-pushed the feature/commutation-aware-rewrite-staged branch 2 times, most recently from 865bf96 to 5f5685c Compare August 6, 2026 02:40
@copy-pr-bot

copy-pr-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@taalexander
taalexander force-pushed the feature/commutation-aware-rewrite-staged branch 3 times, most recently from 473c7c4 to edc17bc Compare August 10, 2026 16:07
Provide a reusable read-only query for structural commutation between Quake operators in one value-form block. Keep the block-local qubit identity analysis as an internal, separately tested implementation dependency of the commutation analysis rather than publishing it as an independent review unit.

The rule set covers disjoint support, identical operations, diagonal and same-axis operators, Pauli parity, controlled-target compatibility, and mutually exclusive controls. Unsupported values and opaque shared-support semantics remain conservative.

The combined tree matches the previously tested identity and commutation PRs; the ownership comment now identifies CommutationAnalysis as the identity helper's consumer.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Limit block-local qubit identity and operation views to scalar wire controls and targets. Reusable controls and unsupported effects now remain conservative barriers while the public commutation query API and structural rules stay unchanged.

Keep control-then-target wire ordering in the shared Quake helper and cover canonical wire ordering plus valid reusable-control rejection in the focused analysis tests.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Recognize supported scalar-wire measurements, resets, and sinks without changing the public query shape or cache ownership. Preserve wire identity through measurement and reset results, prove only matching-basis measurement and reset-preserving unitary relations, and keep multi-target instruments and unsupported effects conservative.

Tests remain consolidated in the existing analysis fixtures and cover identity propagation, supported relations, sink behavior, and the multi-target boundary.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Centralize the conservative one-to-one scalar wire shape used by qubit identity propagation and the dependent rewrite matcher. The helper accepts only regionless, successorless, effect-free operator, measurement, and reset operations with ordered shape-matched wire inputs and results.

This preserves partial lane propagation while removing repeated operation dispatch. Verified with OptAnalysis and AnalysisPassUnitTests builds, the full 34-test analysis suite, and the focused 14-test commutation and identity suite.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Replace separate support, target, and control-polarity indexes with one typed per-qubit role index while retaining ordered control and target vectors for structural semantics.

The rule order and detailed reasons remain unchanged, and target overlap remains linear for large Pauli products. Verified by the complete and focused AnalysisPassUnitTests runs.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
@taalexander
taalexander force-pushed the feature/commutation-aware-rewrite-staged branch from edc17bc to a4558b4 Compare August 11, 2026 12:33
Update the commutation and qubit-identity parser fixtures to the current CC sequence and measurement-handle type spellings. This restores the tests after the stale stdvec and quake.measure names were removed from the dialect.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Add a block-local matcher and greedy rewrite driver that traverse only linear
scalar wire chains. Preserve deterministic endpoint selection, listener
forwarding, and incremental analysis maintenance while treating reusable
controls and unsupported quantum effects as lazy barriers.

Expose the driver to external pass plugins. Keep direct unit coverage to public
contracts that production pass output cannot isolate: backward traversal order,
listener forwarding, one-invocation lifetime, incremental maintenance, and
fallback invalidation. Production lit tests own rewrite behavior.

Verified with OptAnalysis, OptTransforms, cudaq-opt, CustomPassPlugin, the
direct custom-pass composition check, OptimizerUnitTests, and
AnalysisPassUnitTests.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Run quake-simplify through the shared rewrite driver so inverse wire-form gates can cancel across operations proven to commute. Preserve control order and polarity, adjoint handling, transposed adjacent Swap rewiring, existing local simplifications, and one-invocation greedy convergence.

Treat reusable controls and unsupported effects as lazy barriers. Remove dead reusable-control branches from adjacent patterns and cover canonical cancellation families, residual control form, barriers, deterministic output, circuit equivalence, and adjacent regressions.

Verified with OptTransforms, cudaq-opt, CustomPassPlugin, OptimizerUnitTests, AnalysisPassUnitTests, four focused lit tests, strict CircuitCheck, direct FileCheck runs, and byte-for-byte deterministic comparison.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Run factor-quantum-alloc before memtoreg and linear-ctrl-form immediately afterward in the first FTQC and NISQ benchmark simplification stages. This gives commutation-aware rewrites scalar wire controls and targets while leaving the post-mapping NISQ cleanup unchanged.

Keep the change limited to target placement and comments; the existing transform coverage continues to own linear-ctrl-form behavior.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Treat theta as the rotation angle and phi as the preserved axis parameter. Remove zero-theta operations regardless of phi, adjoint state, or control polarity, and combine adjacent operations only when phi matches exactly while applying adjoint signs only to theta.

Keep unequal axes and nonzero negative-control combinations conservative. Strict transform and CircuitCheck coverage isolates the corrected cases.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Extend the private scalar-wire cursor across analysis-approved measurement and reset operations while keeping anchors and endpoints unitary. Sink and unsupported effects remain lazy barriers, and the matcher continues to rely on CommutationAnalysis for the exact single-target effect contract.

Add one production Z-measurement-Z cancellation path and retain the existing unsupported measurement/reset barriers.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Fold matching S and T pairs through the commutation-aware matcher while preserving adjoint state, ordered action placement, and control polarity. Build the folded gate at the later endpoint and forward the anchor so crossed operations stay in place.

Keep opposite-adjoint cancellation under its existing patterns, retain ReduceYSX under current phase semantics, and note the explicit compensation needed when Quake models global phase.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Fold controlled and uncontrolled R1, Rx, Ry, and Rz pairs through the commutation-aware matcher with exact ordered placement and control polarity. Normalize adjoint signs at the later endpoint and cancel exact inverse angles before creating arithmetic.

Keep corrected PhasedRx behavior adjacent-only for its separate migration. Strict integration coverage exercises all four families, negative controls, endpoint dominance, zero identity, and exact cancellation.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Move the corrected PhasedRx rule onto the commutation-aware matcher while preserving exact phi, signed theta, endpoint placement, and control polarity. Keep unequal axes conservative and remove exact inverse pairs before materializing arithmetic.

Document the folding algebra beside the rule, use result-corresponding wire operands for zero-angle rewrites, and group the QuakeSimplify pattern registrations by purpose.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Define anchor, endpoint, crossed-operation, and consumer responsibilities in the public matcher documentation. Align the implementation and barrier fixtures with the supported scalar-wire traversal of measurements and resets while preserving conservative boundaries for other effects, regions, and reusable quantum values.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Accept an endpoint only when every anchor-wire cursor reaches that operation. This prevents identity-equivalent but differently threaded wire-set paths from being treated as one complete endpoint, while preserving block-order traversal of operations that touch only part of the anchor support.

Add matcher and pass-level regressions and document why identity equality alone is insufficient.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Open the scalar-wire frontier before constructing block analysis. Direct producer-consumer endpoints use exact ordered def-use threading and reject direct order or role mismatches locally; analysis is constructed only before crossing, where every crossed operation must have a commutation proof.

Document the proof boundary and cover unwrap-rooted Hadamard cancellation, numeric Rz folding, and direct role mismatch behavior.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Keep exact ordered producer-consumer threading allocation-free and classify reordered direct paths locally. Exact threading proves an empty crossing slice but not distinct logical operands, so require lazy normalized self-validity checks for multi-wire endpoints while retaining the analysis-free unary path.

Separate repeated SSA operands from aliased wire identities in focused fixtures and document the proof boundary beside the implementation and public matcher contract.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Restore per-lane identity propagation during initial block analysis so an unsupported scalar-wire input does not discard known identities on independent sibling lanes. Keep listener-driven incremental registration atomic, where accepting a partially mapped insertion would leave live cached analysis inconsistent.

Add a focused mixed-known-wire regression and clarify stale simplification and duplicate-role test comments found during final review.

Verified with AnalysisPassUnitTests, OptimizerUnitTests, six focused lit/plugin tests, clang-format, and git diff --check.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Carry the QuakeSimplify statistics added on upstream/main through the commutation-aware rewrite architecture. Each successful rewrite continues to update its original counter while preserving the downstream matcher, cancellation, rotation-folding, and barrier behavior.

Verified with the QuakeSimplify/statistics lit tests, optimizer and analysis unit tests, and independent stack-preservation review.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
The commutation-aware simplifier cancels the redundant middle X-control wrapper pair around the diagonal S block. Remove only those stale full-QIR expectations while retaining checks for the surviving outer wrappers and the controlled T and S operations.

Verified with the exact qir_profiles lit test, the QuakeSimplify/statistics lit set, and two independent semantic reviews.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Consolidate self-inverse and opposite-adjoint cancellation under one typed pattern policy, while retaining Swap's target handling and the existing statistics.

Reduce the local Y-S-X matcher to verifier-owned scalar-wire invariants and preserve the middle S adjoint. Add structural and CircuitCheck coverage for the adjoint identity.

Verified with the cudaq-opt target and focused QuakeSimplify lit tests using two parallel jobs.

Signed-off-by: Thomas Alexander <talexander@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core compiler python-lang Anything related to the Python CUDA Quantum language implementation runtime CUDA quantum runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant