✨ Add decompose-multi-controlled pass for multi-controlled X/Z decomposition#1810
✨ Add decompose-multi-controlled pass for multi-controlled X/Z decomposition#1810simon1hofmann wants to merge 14 commits into
decompose-multi-controlled pass for multi-controlled X/Z decomposition#1810Conversation
…ontrolled X gates into one- and two-qubit gates.
…f multi-controlled Z gates.
…ted comments in McxSynthesis.cpp.
…criptions in test_multi_controlled_decomposition.cpp to reflect the one- vs two-ancilla boundary.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
@coderabbitai full review |
✅ Action performedFull review finished. |
📝 WalkthroughWalkthroughAdds a configurable pass that decomposes multi-controlled X/Z ChangesMulti-controlled gate decomposition pass
Sequence Diagram(s)sequenceDiagram
participant mqt-cc
participant QuantumCompilerConfig
participant QuantumCompilerPipeline as QuantumCompilerPipeline::runPipeline
participant DecomposeMultiControlled as DecomposeMultiControlled pass
participant synthesizeMcx
participant synthesizeMcz
mqt-cc->>QuantumCompilerConfig: set enableDecomposeMultiControlled and min-controls
QuantumCompilerPipeline->>QuantumCompilerConfig: validate min-controls >= 2
QuantumCompilerPipeline->>DecomposeMultiControlled: createDecomposeMultiControlled(options)
DecomposeMultiControlled->>synthesizeMcx: rewrite qco.ctrl with qco.x body
DecomposeMultiControlled->>synthesizeMcz: rewrite qco.ctrl with qco.z body
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)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 3
🤖 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/lib/Compiler/CompilerPipeline.cpp`:
- Around line 150-154: The `runPipeline` setup in `QuantumCompilerPipeline`
should validate `config_.decomposeMultiControlledMinControls` before any stages
mutate the module, instead of relying on `qco::createDecomposeMultiControlled`
to reject bad values later. Add an upfront config check alongside the other
early validations in `runPipeline`, using the `enableDecomposeMultiControlled` /
`decomposeMultiControlledMinControls` fields, and fail fast before Stage 1 if
the value is below 2.
In `@mlir/lib/Dialect/QCO/Transforms/Decomposition/McxSynthesis.cpp`:
- Around line 461-462: Clarify the one-dirty-ancilla branch in
McxSynthesis::decompose so the condition matches the comment’s “22+ controls”
wording and the parity-sensitive logic is unambiguous. Update the check on n to
explicitly reflect the intended control-count threshold in the dirty-ancilla
selection path, and keep the branch condition aligned with the surrounding
synthesis helpers so future cleanup does not invert the rule by mistake.
In `@mlir/unittests/Compiler/test_compiler_pipeline.cpp`:
- Around line 259-265: The CompilerPipelineTest end-to-end coverage only
exercises the X-path in DecomposeMultiControlledPass, so add a second
integration case for the Z-path using mlir::qc::multipleControlledZ. Update the
test fixture in test_compiler_pipeline.cpp by following the same pattern as the
existing runPipeline call and assert the MCZ pipeline behavior through the same
QCProgramBuilder::build and CompilationRecord flow. Keep the new case alongside
the current DecomposeMultiControlledPass coverage so both multipleControlledX
and multipleControlledZ are validated through the QC→QCO→optimization pipeline.
🪄 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: 83afc255-d120-40bc-8ed5-582fe1000e54
📒 Files selected for processing (12)
CHANGELOG.mdmlir/include/mlir/Compiler/CompilerPipeline.hmlir/include/mlir/Dialect/QCO/Transforms/Decomposition/MultiControlled.hmlir/include/mlir/Dialect/QCO/Transforms/Passes.tdmlir/lib/Compiler/CompilerPipeline.cppmlir/lib/Dialect/QCO/Transforms/Decomposition/DecomposeMultiControlled.cppmlir/lib/Dialect/QCO/Transforms/Decomposition/McxSynthesis.cppmlir/tools/mqt-cc/mqt-cc.cppmlir/unittests/Compiler/test_compiler_pipeline.cppmlir/unittests/Dialect/QCO/Transforms/Decomposition/CMakeLists.txtmlir/unittests/Dialect/QCO/Transforms/Decomposition/test_multi_controlled_decomposition.cpppyproject.toml
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mlir/unittests/Compiler/test_compiler_pipeline.cpp (1)
259-281: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDisable unrelated Stage 5 passes in these decomposition checks.
Both tests treat any
afterQCOCanon != afterOptimizationdiff as proof that multi-controlled decomposition ran, butrunPipeline(..., false, false, false, true, ...)still leavesMergeSingleQubitRotationGatesenabled. That means an unrelated Stage 5 change could keep these tests green even ifDecomposeMultiControlledregresses.Suggested fix
- runPipeline(module.get(), false, false, false, true, record); + runPipeline(module.get(), false, true, false, true, record);🤖 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/unittests/Compiler/test_compiler_pipeline.cpp` around lines 259 - 281, The decomposition tests in CompilerPipelineTest are currently too permissive because runPipeline still enables an unrelated Stage 5 pass, so a change in MergeSingleQubitRotationGates could make the afterQCOCanon versus afterOptimization comparison pass even if multi-controlled decomposition fails. Update DecomposeMultiControlledPass and DecomposeMultiControlledPassMcz to run with only the decomposition-relevant pipeline enabled, or otherwise disable the Stage 5 rotation-merge path in runPipeline for these checks, so the EXPECT_NE assertion specifically validates DecomposeMultiControlled and the multipleControlledX/multipleControlledZ cases.
🤖 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/unittests/Compiler/test_compiler_pipeline.cpp`:
- Around line 283-297: The test currently only checks that
QuantumCompilerPipeline::runPipeline fails, which still allows the rejection to
happen later in DecomposeMultiControlled after earlier stages have run. Update
CompilerPipelineTest.RejectsDecomposeMultiControlledMinControlsBelowTwo to also
assert that CompilationRecord::afterQCImport remains empty when
decomposeMultiControlledMinControls is below two, so the preflight validation is
enforced before Stage 1 or any intermediate records are produced.
In
`@mlir/unittests/Dialect/QCO/Transforms/Decomposition/test_multi_controlled_decomposition.cpp`:
- Around line 378-404: The two “untouched” tests only verify that one
multi-controlled op remains, so they can miss regressions where the surviving
operation changes kind; update McxDecompositionTest::LeavesMultiOpCtrlUntouched
and McxDecompositionTest::LeavesMultiControlledHUntouched to assert the
preserved op is still the expected CtrlOp/MCH form and that its body is
unchanged after runDecomposePass, using the existing QCOProgramBuilder setup and
countMultiControlledOps as a secondary check only.
---
Outside diff comments:
In `@mlir/unittests/Compiler/test_compiler_pipeline.cpp`:
- Around line 259-281: The decomposition tests in CompilerPipelineTest are
currently too permissive because runPipeline still enables an unrelated Stage 5
pass, so a change in MergeSingleQubitRotationGates could make the afterQCOCanon
versus afterOptimization comparison pass even if multi-controlled decomposition
fails. Update DecomposeMultiControlledPass and DecomposeMultiControlledPassMcz
to run with only the decomposition-relevant pipeline enabled, or otherwise
disable the Stage 5 rotation-merge path in runPipeline for these checks, so the
EXPECT_NE assertion specifically validates DecomposeMultiControlled and the
multipleControlledX/multipleControlledZ cases.
🪄 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: f9c18476-abd2-4d99-94d9-f4385100f19b
📒 Files selected for processing (5)
mlir/lib/Compiler/CompilerPipeline.cppmlir/lib/Dialect/QCO/Transforms/CMakeLists.txtmlir/lib/Dialect/QCO/Transforms/Decomposition/MultiControlled.cppmlir/unittests/Compiler/test_compiler_pipeline.cppmlir/unittests/Dialect/QCO/Transforms/Decomposition/test_multi_controlled_decomposition.cpp
|
@coderabbitai review |
✅ Action performedReview finished.
|
Signed-off-by: simon1hofmann <119581649+simon1hofmann@users.noreply.github.com>
Description
decompose-multi-controlledQCO pass that decomposes multi-controlled Pauli-X and Pauli-Z gates (qco.ctrlwith a singleqco.xorqco.zbody) intoh,t,tdg,p, andcxusing the Huang–Palsberg (PLDI 2024) no-ancilla algorithm (adapted from Qiskitsynth_mcx_noaux_hp24).MCZ = H·MCX·H, with redundant Hadamard bookends canceled for k ≥ 2).mqt-cc --decompose-multi-controlledandQuantumCompilerConfig::enableDecomposeMultiControlled(opt-in, default off).min-controlsoption (default2) keeps single-control gates (CX,CZ) intact; configurable viamqt-cc --decompose-multi-controlled-min-controls.Usage
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.