✨ Add fuse-two-qubit-unitary-runs pass - #1865
Conversation
Add a `fuse-two-qubit-unitary-runs` MLIR pass that fuses compile-time two-qubit unitary windows and resynthesizes them to a native gateset via Weyl/KAK decomposition. Includes the pass definition, implementation, unit tests, and CMake wiring. Also add the `isEquivalentUpToGlobalPhase` matrix helper used by the new tests to compare unitaries up to a global phase. Assisted-by: Claude Opus 4.8 via Cursor Co-authored-by: Cursor <cursoragent@cursor.com>
…ry-runs` pass and remove outdated PR link
fuse-two-qubit-unitary-runs passfuse-two-qubit-unitary-runs pass
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
… metadata management
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds an MLIR QCO pass that fuses two-qubit unitary runs, resynthesizes them to a native gateset, and validates the result. Compiler, CLI, and Python APIs, reusable single-qubit fusion wiring, tests, and changelog entries are also added. ChangesTwo-Qubit Unitary Fusion Pass
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@mlir/include/mlir/Dialect/QCO/Transforms/Passes.td`:
- Around line 88-89: The gate-set docs in Passes.td are advertising the
unsupported `p` alias even though `parseGateToken` only recognizes `rz`, so
update the `QCO` pass descriptions to match the parser by either adding `p`
handling in `parseGateToken` or removing `p` from the documented token list and
any related examples/comments. Make sure the wording around the gate tokens in
the pass definitions stays consistent with the actual accepted syntax.
In `@mlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cpp`:
- Around line 248-250: The comparison in the `FuseTwoQubitUnitaryRuns` scan is
unsafe because `uniqueUnitaryUser()` does not guarantee `nextOnA` and `nextOnB`
are in the same block, so `isBeforeInBlock` can trip MLIR preconditions when the
run spans blocks or regions. Update the logic around the `aSingle`/`bSingle`
check to first verify both successors are in the same block, and if not, stop
the scan before calling `isBeforeInBlock`; use the existing `nextOnA`,
`nextOnB`, and `sameOp` flow in `FuseTwoQubitUnitaryRuns.cpp` to place this
guard.
In `@mlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/CMakeLists.txt`:
- Around line 12-26: The NativeSynthesis test target is missing the MemRef
dialect dependency even though the test registers memref::MemRefDialect in the
related test source. Update the target_link_libraries list for the test target
to include MLIRMemRefDialect alongside the existing MLIR dialect libraries,
matching the pattern used by other QCO test targets such as test_qc_ir.cpp and
test_qc_to_qco.cpp.
In
`@mlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/test_fuse_two_qubit_unitary_runs.cpp`:
- Around line 388-390: The boundary comment in the test is stale and contradicts
the current pass behavior: in the scenario around the entangler and the
three-qubit gate, the wider gate should be described as stopping the run scan
and being left untouched, not “for the pass to reject.” Update the comment near
the affected test case in test_fuse_two_qubit_unitary_runs.cpp so it matches the
contract exercised by the surrounding test and the NativeSynthesis pass
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbd760f5-f291-4778-bbd7-825ed27db900
📒 Files selected for processing (11)
CHANGELOG.mdmlir/include/mlir/Dialect/QCO/Transforms/Decomposition/Euler.hmlir/include/mlir/Dialect/QCO/Transforms/Decomposition/NativeGateset.hmlir/include/mlir/Dialect/QCO/Transforms/Passes.tdmlir/lib/Dialect/QCO/Transforms/Decomposition/NativeGateset.cppmlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseSingleQubitUnitaryRuns.cppmlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cppmlir/unittests/Dialect/QCO/Transforms/CMakeLists.txtmlir/unittests/Dialect/QCO/Transforms/Decomposition/test_weyl_decomposition.cppmlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/CMakeLists.txtmlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/test_fuse_two_qubit_unitary_runs.cpp
|
@coderabbitai review |
✅ Action performedReview finished.
|
Co-authored-by: Cursor <cursoragent@cursor.com> Assisted-by: Cursor Grok 4.5 via Cursor
Assisted-by: GPT-5 via Codex
Assisted-by: GPT-5 via Codex
Move QCO cleanup ahead of explicit native synthesis so no later QCO transformation can reintroduce off-menu gates, and reject native-gate menus for raw QCO output where they cannot be applied. Add end-to-end driver regressions for both contracts. Assisted-by: GPT-5 via Codex
Assisted-by: GPT-5 via Codex
Assisted-by: GPT-5 via Codex
Assisted-by: GPT-5 via Codex
Assisted-by: GPT-5 via Codex
Match the --pass-pipeline guard so the option is not silently ignored when optimization is skipped.
Emit the off-gateset convergence error on the leftover operation and cover runtime-parameterized residuals with a unit test.
Use h+swap input and assert synthesized ctrl output rather than only single-qubit lowering.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mlir/include/mlir/Dialect/QCO/Transforms/Decomposition/NativeGateset.h (1)
70-78: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winDocument the exact
qco.ctrlshape accepted byallowsOp.
entanglerKindForrequires exactly one control, one target, and one body unitary, but this documentation only says “single-target.” Align it with the implementation and pass contract to avoid implying that multi-control shells are accepted.Proposed wording
- * and single-target `qco.ctrl` shells (with an `X`/`Z` body) are checked + * and single-control/single-target `qco.ctrl` shells with one `X`/`Z` body + * are checked🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@mlir/include/mlir/Dialect/QCO/Transforms/Decomposition/NativeGateset.h` around lines 70 - 78, Update the documentation for NativeGateset::allowsOp to state that accepted qco.ctrl shells have exactly one control, one target, and one body unitary, with the body restricted to X or Z; do not describe them only as “single-target,” which could imply multi-control shells are valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@mlir/tools/mqt-cc/mqt-cc.cpp`:
- Around line 397-403: Validate the trimmed native-gates value whenever
nativeGates was explicitly provided, rejecting empty values such as
--native-gates= or whitespace-only input before selecting the optimized-output
path. Reuse this same non-empty validation in the pass-construction logic near
the native-gates fusion handling so an empty menu cannot be skipped or treated
as successful synthesis.
---
Outside diff comments:
In `@mlir/include/mlir/Dialect/QCO/Transforms/Decomposition/NativeGateset.h`:
- Around line 70-78: Update the documentation for NativeGateset::allowsOp to
state that accepted qco.ctrl shells have exactly one control, one target, and
one body unitary, with the body restricted to X or Z; do not describe them only
as “single-target,” which could imply multi-control shells are valid.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 77c5595d-4693-45e3-a339-38f9eb1bae88
📒 Files selected for processing (20)
CHANGELOG.mdbindings/mlir/register_mlir.cppmlir/include/mlir/Compiler/Programs.hmlir/include/mlir/Dialect/QCO/Transforms/Decomposition/NativeGateset.hmlir/include/mlir/Dialect/QCO/Transforms/Passes.tdmlir/lib/Compiler/Programs.cppmlir/lib/Dialect/QCO/Transforms/Decomposition/NativeGateset.cppmlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseSingleQubitUnitaryRuns.cppmlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cppmlir/lib/Support/Passes.cppmlir/tools/mqt-cc/CMakeLists.txtmlir/tools/mqt-cc/mqt-cc.cppmlir/tools/mqt-cc/tests/check-native-gates-raw-qco.cmakemlir/tools/mqt-cc/tests/native-gates.qasmmlir/unittests/Compiler/test_compiler_pipeline.cppmlir/unittests/Dialect/QCO/Transforms/Decomposition/test_weyl_decomposition.cppmlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/CMakeLists.txtmlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/test_fuse_two_qubit_unitary_runs.cpppython/mqt/core/mlir.pyitest/python/test_mlir.py
|
@coderabbitai review |
✅ Action performedReview finished.
|
Exercise one- and two-qubit synthesis through the compiler API and rely on the dedicated native-synthesis suite for equivalence coverage. Assisted-by: GPT-5 via Codex
Document the pass scope, compile-time matrix requirement, and exact native controlled-gate shape. Assisted-by: GPT-5 via Codex
Description
Add a
fuse-two-qubit-unitary-runsMLIR pass that fuses compile-time two-qubit unitary windows and resynthesizes them to a native gateset via Weyl/KAK decomposition.AI Assistance
Used
Composer 2.5via Cursor for parts of this change. I reviewed the fulldiff and take responsibility for everything in this PR.
Checklist
If PR contains AI-assisted content:
Assisted-by: [Model Name] via [Tool Name]footer.