Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b566c21
✨ Add quaternion rotation merging pass with core algorithm
J4MMlE Dec 28, 2025
34a9e7c
✅ Add tests for quaternion merging and simplify pattern matching
J4MMlE Jan 15, 2026
6749f3c
🐛 Fix u-gate combination and improve test infrastructure
J4MMlE Jan 22, 2026
f8aaa9d
♻️ Refine pass implementation, error handling, and documentation
J4MMlE Jan 22, 2026
44c3c62
🐛 Handle gimbal lock and add edge case tests
J4MMlE Jan 23, 2026
aa8caf4
♻️ Final improvements: type checks, parameter ordering, pipeline test
J4MMlE Feb 4, 2026
9f468aa
Merge branch 'main' into merge-main
MatthiasReumann Mar 10, 2026
f75edf8
Fix compiler pipeline test
MatthiasReumann Mar 10, 2026
cfe9eda
Add RotationGateMergingPass test
MatthiasReumann Mar 10, 2026
1a22b2b
Fix test
MatthiasReumann Mar 10, 2026
54e612b
🔀 Merge with main
burgholzer Mar 12, 2026
c11e856
📝 Split off merge-rotation-gates pass changelog entry
burgholzer Mar 12, 2026
05d5fdc
✅ refine compiler pipeline test
burgholzer Mar 12, 2026
22d17ad
🚨 fix clang-tidy warning
burgholzer Mar 12, 2026
1ee703b
🎨 remove most of the redundant `mlir::` namespace specifiers
burgholzer Mar 12, 2026
fb0d8cb
✏️ Fix typo in changelog entry
burgholzer Mar 12, 2026
abdacce
🚨 Use `OpType::create` methods
burgholzer Mar 12, 2026
b267779
♻️ Rename compiler flag and clean up docstrings
J4MMlE Mar 17, 2026
409f94d
♻️ Remove single-use constraint on rotation gate
J4MMlE Mar 17, 2026
e707dc5
♻️ Refactor operation replacement
J4MMlE Mar 18, 2026
e506cec
♻️ Consolidate constants into shared Constants struc
J4MMlE Mar 18, 2026
7e6299b
🔀 Merge with main
J4MMlE Mar 21, 2026
40b697d
✨ Add support for POp, ROp, U2Op
J4MMlE Mar 19, 2026
7198eb3
🐛 Normalize UOp alpha/gamma angles after quaternion-to-Euler conversion
J4MMlE Mar 19, 2026
e7b8da6
♻️ Refactor from pairwise to chain-based merging
J4MMlE Mar 21, 2026
e16f12d
🔀 Merge with main
J4MMlE Mar 21, 2026
b2a7d4b
🐛 fix collectChain UB, linter warnings, and inaccurate test and comment
J4MMlE Mar 21, 2026
f889a11
🔥 remove dead pairwise gate merge
J4MMlE Mar 22, 2026
114392b
🚨 fix linter warnings
J4MMlE Mar 22, 2026
3bf55ff
🩹 fix linter warnings and emit merged op at chain tail
J4MMlE Mar 22, 2026
212605a
📝 add note for discarding of global phase
J4MMlE Mar 22, 2026
0fbd0d8
🔀 Merge with main
J4MMlE Apr 4, 2026
64f7efa
🚨 Fix NOLINT code
J4MMlE Apr 4, 2026
01c4bc2
📝 Update doc strings
J4MMlE Apr 4, 2026
308c45a
♻️ Emit UOp inside matchAndRewrite
J4MMlE Apr 4, 2026
2b26336
♻️ Simplify merge condition
J4MMlE Apr 4, 2026
5a46fdc
✨ Add global phase tracking
J4MMlE Apr 4, 2026
14b2855
♻️ Use modulus based normalization
J4MMlE Apr 4, 2026
e7b4fc7
♻️ Simpler chain collect loop
J4MMlE Apr 4, 2026
4fe98af
♻️ Stricter gate types for conversion functions
J4MMlE Apr 4, 2026
0d67494
🚚 Naming consistency
J4MMlE Apr 4, 2026
4566735
✨ Enable merge pass by default
J4MMlE Apr 5, 2026
a2adde2
✅ Add global phase checks to tests
J4MMlE Apr 5, 2026
deda0b9
📝 Fix Documentation
J4MMlE Apr 5, 2026
ae434e4
Merge branch 'main' into quaternion-rotation-merging
denialhaag Apr 15, 2026
2784094
Remove faulty test
denialhaag Apr 15, 2026
324f8db
Remove outdated comment
denialhaag Apr 15, 2026
b42f9f7
Address the Rabbit's comment
denialhaag Apr 15, 2026
e873baa
Simplify diff
denialhaag Apr 15, 2026
a02e8c7
Improve pass description
denialhaag Apr 15, 2026
e75c5b6
Fix linter errors
denialhaag Apr 15, 2026
83f36d0
Improve some docstrings
denialhaag Apr 15, 2026
ba641ad
Remove unneeded operations immediately
denialhaag Apr 15, 2026
61a6cf2
Reduce test duplication
denialhaag Apr 16, 2026
7f36f92
Streamline tests
denialhaag Apr 20, 2026
e842ef6
Merge branch 'main' into quaternion-rotation-merging
denialhaag Apr 20, 2026
e777252
✅ add SymPy reference script
J4MMlE Apr 20, 2026
7daba0f
♻️ consistent format for floating point constants
J4MMlE Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Added

- ✨ Add a `merge-single-qubit-rotation-gates` pass for merging consecutive rotation gates using quaternions ([#1407]) ([**@J4MMlE**])
- ✨ Add Sampler and Estimator Primitives to the QDMI-Qiskit Interface ([#1507]) ([**@marcelwa**])
- ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637]) ([**@denialhaag**])
- ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588]) ([**@MatthiasReumann**])
Expand Down Expand Up @@ -395,6 +396,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
[#1413]: https://github.com/munich-quantum-toolkit/core/pull/1413
[#1412]: https://github.com/munich-quantum-toolkit/core/pull/1412
[#1411]: https://github.com/munich-quantum-toolkit/core/pull/1411
[#1407]: https://github.com/munich-quantum-toolkit/core/pull/1407
[#1406]: https://github.com/munich-quantum-toolkit/core/pull/1406
[#1403]: https://github.com/munich-quantum-toolkit/core/pull/1403
[#1402]: https://github.com/munich-quantum-toolkit/core/pull/1402
Expand Down Expand Up @@ -551,6 +553,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
[**@lirem101**]: https://github.com/lirem101
[**@Ectras**]: https://github.com/Ectras
[**@simon1hofmann**]: https://github.com/simon1hofmann
[**@J4MMlE**]: https://github.com/J4MMlE

<!-- General links -->

Expand Down
3 changes: 3 additions & 0 deletions mlir/include/mlir/Compiler/CompilerPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ struct QuantumCompilerConfig {

/// Print IR after each stage
bool printIRAfterAllStages = false;

/// Disable quaternion-based single-qubit rotation gate merging
bool disableMergeSingleQubitRotationGates = false;
};

/**
Expand Down
5 changes: 0 additions & 5 deletions mlir/include/mlir/Dialect/QCO/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ namespace mlir::qco {
#define GEN_PASS_DECL
#include "mlir/Dialect/QCO/Transforms/Passes.h.inc" // IWYU pragma: export

//===----------------------------------------------------------------------===//
// Registration
//===----------------------------------------------------------------------===//

/// Generate the code for registering passes.
#define GEN_PASS_REGISTRATION
#include "mlir/Dialect/QCO/Transforms/Passes.h.inc" // IWYU pragma: export

Expand Down
37 changes: 37 additions & 0 deletions mlir/include/mlir/Dialect/QCO/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,43 @@

include "mlir/Pass/PassBase.td"

def MergeSingleQubitRotationGates
: Pass<"merge-single-qubit-rotation-gates", "mlir::ModuleOp"> {
let dependentDialects = ["mlir::qco::QCODialect",
"::mlir::arith::ArithDialect",
"::mlir::math::MathDialect"];
let summary = "Merge rotation gates using quaternion-based fusion";
let description = [{
Merges consecutive single-qubit rotation gates acting on the same qubit into
a single equivalent U gate, reducing circuit depth and gate count.

Supported gate types: `rx`, `ry`, `rz`, `p`, `r`, `u2`, `u`.

The pass greedily collects the longest possible chain of consecutive
mergeable gates. Each gate is converted to a unit quaternion:

- `rx`, `ry`, `rz`, `p`: single-axis rotations via half-angle formulas.
- `r(theta, phi)`: rotation by `theta` around axis `(cos(phi), sin(phi), 0)`.
- `u2(phi, lambda) = u(pi/2, phi, lambda)`.
- `u(theta, phi, lambda)`: ZYZ decomposition `rz(phi)*ry(theta)*rz(lambda)`,
each factor converted to a quaternion and merged via the Hamilton product.

The gates are then folded one by one via the Hamilton product into a single
quaternion, which is decomposed back into ZYZ Euler angles and emitted as a
single `UOp`, representing the same rotation as the chain of single gates.
The global phase of each gate is tracked alongside and combined together.

The U gate which is emitted is defined as:
U = e^{i(phi+lambda)/2} RZ(phi) RY(theta) RZ(lambda)
Each merge emits a `GPhaseOp` carrying the accumulated input phase
of the chain. Because the synthesized `UOp`
introduces an additional intrinsic phase of (phi+lambda)/2, the `GPhaseOp`
must compensate for it. This applies even to chains composed entirely of
SU(2) gates (`rx`, `ry`, `rz`, `r`), because the synthesis into a `UOp`
still produces the intrinsic phase term.
}];
Comment thread
J4MMlE marked this conversation as resolved.
}

//===----------------------------------------------------------------------===//
// Transpilation Passes
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Compiler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ add_mlir_library(
MLIRQCToQCO
MLIRQCOToQC
MLIRQCToQIR
MLIRQCOTransforms
MQT::MLIRSupport)

mqt_mlir_target_use_project_options(MQTCompilerPipeline)
Expand Down
10 changes: 7 additions & 3 deletions mlir/lib/Compiler/CompilerPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "mlir/Conversion/QCOToQC/QCOToQC.h"
#include "mlir/Conversion/QCToQCO/QCToQCO.h"
#include "mlir/Conversion/QCToQIR/QCToQIR.h"
#include "mlir/Dialect/QCO/Transforms/Passes.h"
#include "mlir/Support/Passes.h"
#include "mlir/Support/PrettyPrinting.h"

Expand Down Expand Up @@ -136,9 +137,12 @@ QuantumCompilerPipeline::runPipeline(ModuleOp module,
}
}
// Stage 5: Optimization passes
// TODO: Add optimization passes
if (failed(
runStage([&](PassManager& pm) { populateQCOCleanupPipeline(pm); }))) {
if (failed(runStage([&](PassManager& pm) {
if (!config_.disableMergeSingleQubitRotationGates) {
pm.addPass(qco::createMergeSingleQubitRotationGates());
populateQCOCleanupPipeline(pm);
}
}))) {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
burgholzer marked this conversation as resolved.
return failure();
}
if (record != nullptr && config_.recordIntermediates) {
Expand Down
2 changes: 2 additions & 0 deletions mlir/lib/Dialect/QCO/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ add_mlir_library(
PRIVATE
MLIRQCODialect
MLIRQCOUtils
MLIRArithDialect
MLIRMathDialect
DEPENDS
MLIRQCOTransformsIncGen)

Expand Down
Loading
Loading