Skip to content

✨ Add native gate synthesis MLIR pass and decomposition stack#1665

Draft
simon1hofmann wants to merge 55 commits into
mainfrom
native_gate_synthesis
Draft

✨ Add native gate synthesis MLIR pass and decomposition stack#1665
simon1hofmann wants to merge 55 commits into
mainfrom
native_gate_synthesis

Conversation

@simon1hofmann

Copy link
Copy Markdown
Contributor

Description

Introduces a native-gate-synthesis transform on QCO modules that lowers arbitrary supported unitaries to a comma-separated native gate menu, with scoring over two-qubit count, single-qubit count, and local depth.

User-visible behavior
--native-gates=<menu> on mqt-cc (empty menu = no-op), aligned with pass options documented in Passes.td (native-gates, score-weight-twoq, score-weight-oneq, score-weight-depth).

Fixes #(issue)

Checklist

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

If PR contains AI-assisted content:

  • I have disclosed the use of AI tools in the PR description as per our AI Usage Guidelines.
  • AI-assisted commits include an Assisted-by: [Model Name] via [Tool Name] footer.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

simon1hofmann and others added 13 commits April 22, 2026 16:04
…use `std::exp` for complex exponentiation instead of `std::polar`.
… basis decomposer, Euler decomposition, and associated helper functions. This update introduces new headers and source files for managing gate sequences, unitary matrices, and decomposition strategies, enhancing the framework's capabilities for quantum circuit transformations.

Co-authored-by: Tamino Bauknecht <dev@tb6.eu>
… and additional test cases for Euler and Weyl decompositions.
…, including new utility functions and validation for gate sequences.
@simon1hofmann simon1hofmann self-assigned this Apr 24, 2026
@simon1hofmann simon1hofmann added enhancement Improvement of existing feature MLIR Anything related to MLIR labels Apr 24, 2026
@simon1hofmann simon1hofmann added this to the MLIR Support milestone Apr 24, 2026
@codecov

codecov Bot commented Apr 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.47634% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
mlir/lib/Dialect/QCO/Utils/Matrix.cpp 97.5% 5 Missing ⚠️
mlir/unittests/TestCaseUtils.h 96.7% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@simon1hofmann

Copy link
Copy Markdown
Contributor Author

@burgholzer
I’m planning to split this branch into a stacked PR series to make review easier.

  1. PR1: Euler decomposition
  2. PR2: Weyl decomposition
  3. PR3: BasisDecomposer
  4. PR4: Single-qubit native synthesis
  5. PR5: Two-qubit native synthesis

Planned dependency chain: PR1 -> PR2 -> PR3 -> PR4 -> PR5 (each PR based on the previous one).

Does this split and order look good, or would you prefer a different grouping/order?

@burgholzer

Copy link
Copy Markdown
Member

@burgholzer I’m planning to split this branch into a stacked PR series to make review easier.

  1. PR1: Euler decomposition
  2. PR2: Weyl decomposition
  3. PR3: BasisDecomposer
  4. PR4: Single-qubit native synthesis
  5. PR5: Two-qubit native synthesis

Planned dependency chain: PR1 -> PR2 -> PR3 -> PR4 -> PR5 (each PR based on the previous one).

Does this split and order look good, or would you prefer a different grouping/order?

That order looks reasonable to me. If it can be split up like that, I would certainly appreciate it! 👍🏼

…::polar for complex exponentiation, improving numerical stability and readability.
@mergify mergify Bot added the conflict label Apr 29, 2026
Signed-off-by: simon1hofmann <119581649+simon1hofmann@users.noreply.github.com>
@mergify mergify Bot removed the conflict label Apr 29, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/include/mlir/Dialect/QCO/Transforms/Passes.h`:
- Around line 42-43: Add a Doxygen comment above the public factory declaration
createNativeGateSynthesisPass describing its purpose (what the pass does),
documenting the parameter `@param` options (type NativeGateSynthesisOptions) and
any important semantics of those options, and the return value via `@return` (a
std::unique_ptr<Pass> owning the created pass). Keep wording consistent with
surrounding pass factory comments (brief one-line summary plus `@param/`@return
tags) and place it immediately above the declaration for
createNativeGateSynthesisPass.
🪄 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: 468c7c0e-7e17-4ed8-8a53-dd3ca91801ad

📥 Commits

Reviewing files that changed from the base of the PR and between db83356 and 1af1116.

📒 Files selected for processing (4)
  • mlir/include/mlir/Dialect/QCO/Transforms/Passes.h
  • mlir/lib/Compiler/CompilerPipeline.cpp
  • mlir/lib/Dialect/QCO/IR/Operations/StandardGates/XXMinusYYOp.cpp
  • mlir/lib/Dialect/QCO/IR/Operations/StandardGates/XXPlusYYOp.cpp

Comment thread mlir/include/mlir/Dialect/QCO/Transforms/Passes.h Outdated
@simon1hofmann simon1hofmann marked this pull request as draft April 30, 2026 11:38
burgholzer added a commit that referenced this pull request Jun 17, 2026
…1672)

## Description
- Consolidate Euler decomposition into `Euler.h` / `Euler.cpp` (angle
extraction + `synthesizeUnitary1QEuler` IR emission), replacing the
previous `EulerDecomposition` / `GateSequence` / `Helpers` /
`UnitaryMatrices` split.
- Add the `fuse-single-qubit-unitary-runs` MLIR pass: fuse maximal runs
of constant single-qubit unitaries on a wire by composing 2×2 matrices
and resynthesizing in a configurable Euler basis (`zyz`, `zxz`, `xzx`,
`xyx`, `u`, `zsxx`), with `gphase` for exact global phase.

Split up and refactored from #1665.

## AI Assistance
Used Composer via Cursor for parts of this change. I reviewed the full
diff and take responsibility for everything in this PR.

## Checklist

<!---
This checklist serves as a reminder of a couple of things that ensure
your pull request will be merged swiftly.
-->

- [x] The pull request only contains commits that are focused and
relevant to this change.
- [x] I have added appropriate tests that cover the new/changed
functionality.
- [x] I have updated the documentation to reflect these changes.
- [x] I have added entries to the changelog for any noteworthy
additions, changes, fixes, or removals.
- [ ] I have added migration instructions to the upgrade guide (if
needed).
- [x] The changes follow the project's style guidelines and introduce no
new warnings.
- [x] The changes are fully tested and pass the CI checks.
- [x] I have reviewed my own code changes.

**If PR contains AI-assisted content:**

- [x] I have disclosed the use of AI tools in the PR description as per
our [AI Usage
Guidelines](https://github.com/munich-quantum-toolkit/core/blob/main/docs/ai_usage.md).
- [ ] AI-assisted commits include an `Assisted-by: [Model Name] via
[Tool Name]` footer.
- [x] I confirm that I have personally reviewed and understood all
AI-generated content, and accept full responsibility for it.

---------

Signed-off-by: simon1hofmann <119581649+simon1hofmann@users.noreply.github.com>
Signed-off-by: burgholzer <burgholzer@me.com>
Signed-off-by: Lukas Burgholzer <burgholzer@me.com>
Co-authored-by: Tamino Bauknecht <dev@tb6.eu>
Co-authored-by: Daniel Haag <121057143+denialhaag@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: burgholzer <burgholzer@me.com>
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-tidy (v22.1.8) reports: 14 concern(s)
  • mlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cpp:73:8: warning: [misc-use-internal-linkage]

    struct 'TwoQubitBlock' can be moved into an anonymous namespace to enforce internal linkage

       73 | struct TwoQubitBlock {
          |        ^
  • mlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cpp:85:8: warning: [misc-use-internal-linkage]

    struct 'TwoQubitWindowConsolidator' can be moved into an anonymous namespace to enforce internal linkage

       85 | struct TwoQubitWindowConsolidator {
          |        ^
  • mlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cpp:437:8: warning: [misc-use-internal-linkage]

    struct 'OneQubitRun' can be moved into an anonymous namespace to enforce internal linkage

      437 | struct OneQubitRun {
          |        ^
  • mlir/lib/Dialect/QCO/Transforms/NativeSynthesis/FuseTwoQubitUnitaryRuns.cpp:513:8: warning: [misc-use-internal-linkage]

    struct 'FuseTwoQubitUnitaryRunsPass' can be moved into an anonymous namespace to enforce internal linkage

      513 | struct FuseTwoQubitUnitaryRunsPass
          |        ^
  • mlir/unittests/Dialect/QCO/Transforms/Decomposition/test_weyl_decomposition.cpp:24:1: warning: [misc-include-cleaner]

    included header StringRef.h is not used directly

       24 | #include <llvm/ADT/StringRef.h>
          | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       25 | #include <llvm/Support/Casting.h>
  • mlir/unittests/Dialect/QCO/Transforms/Decomposition/test_weyl_decomposition.cpp:576:8: warning: [misc-use-internal-linkage]

    struct 'TwoQFuseFixture' can be moved into an anonymous namespace to enforce internal linkage

      576 | struct TwoQFuseFixture {
          |        ^
  • mlir/unittests/Dialect/QCO/Transforms/Decomposition/test_weyl_decomposition.cpp:603:53: warning: [misc-include-cleaner]

    no header providing "mlir::StringRef" is directly included

       36 | static LogicalResult runTwoQFuse(ModuleOp moduleOp, StringRef nativeGates) {
          |                                                     ^
  • mlir/unittests/Dialect/QCO/Transforms/NativeSynthesis/test_native_synthesis.cpp:440:8: warning: [misc-use-internal-linkage]

    struct 'NativeSynthMenuRow' can be moved into an anonymous namespace to enforce internal linkage

      440 | struct NativeSynthMenuRow {
          |        ^
  • mlir/unittests/TestCaseUtils.h:174:7: warning: [google-runtime-float]

    'long double' type from literal suffix 'L' is not portable and should not be used

      174 |       0.707106781186547524400844362104849039284835937688474036588L;
          |       ^
  • mlir/unittests/TestCaseUtils.h:175:37: warning: [readability-identifier-naming]

    invalid case style for static constant 'matrix'

      175 |   static const mlir::qco::Matrix2x2 matrix = mlir::qco::Matrix2x2::fromElements(
          |                                     ^~~~~~
          |                                     MATRIX
      176 |       frac1Sqrt2, frac1Sqrt2, frac1Sqrt2, -frac1Sqrt2);
      177 |   return matrix;
          |          ~~~~~~
          |          MATRIX
  • mlir/unittests/TestCaseUtils.h:207:18: warning: [readability-identifier-naming]

    invalid case style for global constant 'kSanityCheckPrecision'

      207 | constexpr double kSanityCheckPrecision = 1e-12;
          |                  ^~~~~~~~~~~~~~~~~~~~~
          |                  K_SANITY_CHECK_PRECISION
  • mlir/unittests/TestCaseUtils.h:263:37: warning: [readability-identifier-naming]

    invalid case style for static constant 'matrix'

      263 |   static const mlir::qco::Matrix4x4 matrix =
          |                                     ^~~~~~
          |                                     MATRIX
      264 |       mlir::qco::Matrix4x4::fromElements(1, 0, 0, 0, //
      265 |                                          0, 1, 0, 0, //
      266 |                                          0, 0, 0, 1, //
      267 |                                          0, 0, 1, 0);
      268 |   return matrix;
          |          ~~~~~~
          |          MATRIX
  • mlir/unittests/TestCaseUtils.h:272:37: warning: [readability-identifier-naming]

    invalid case style for static constant 'matrix'

      272 |   static const mlir::qco::Matrix4x4 matrix =
          |                                     ^~~~~~
          |                                     MATRIX
      273 |       mlir::qco::Matrix4x4::fromElements(1, 0, 0, 0, //
      274 |                                          0, 0, 0, 1, //
      275 |                                          0, 0, 1, 0, //
      276 |                                          0, 1, 0, 0);
      277 |   return matrix;
          |          ~~~~~~
          |          MATRIX
  • mlir/unittests/TestCaseUtils.h:281:37: warning: [readability-identifier-naming]

    invalid case style for static constant 'matrix'

      281 |   static const mlir::qco::Matrix4x4 matrix =
          |                                     ^~~~~~
          |                                     MATRIX
      282 |       mlir::qco::Matrix4x4::fromElements(1, 0, 0, 0, //
      283 |                                          0, 1, 0, 0, //
      284 |                                          0, 0, 1, 0, //
      285 |                                          0, 0, 0, -1);
      286 |   return matrix;
          |          ~~~~~~
          |          MATRIX

Have any feedback or feature suggestions? Share it here.

…qubit unitary windows via Weyl/KAK resynthesis. Update changelog and remove obsolete files related to two-qubit window consolidation.
@mergify mergify Bot added the conflict label Jun 18, 2026
@mergify mergify Bot removed the conflict label Jun 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants