Skip to content

Commit bd76813

Browse files
committed
✨ Implement controlled swap reconstruction MLIR pass (#1158)
1 parent f252c67 commit bd76813

File tree

5 files changed

+720
-0
lines changed

5 files changed

+720
-0
lines changed

mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace mqt::ir::opt {
2828
void populateGateEliminationPatterns(mlir::RewritePatternSet& patterns);
2929
void populateMergeRotationGatesPatterns(mlir::RewritePatternSet& patterns);
3030
void populateElidePermutationsPatterns(mlir::RewritePatternSet& patterns);
31+
void populateSwapReconstructionPatterns(mlir::RewritePatternSet& patterns);
3132
void populateQuantumSinkShiftPatterns(mlir::RewritePatternSet& patterns);
3233
void populateQuantumSinkPushPatterns(mlir::RewritePatternSet& patterns);
3334
void populateToQuantumComputationPatterns(mlir::RewritePatternSet& patterns,

mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.td

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,34 @@ def ElidePermutations : Pass<"elide-permutations", "mlir::ModuleOp"> {
6464
}];
6565
}
6666

67+
def SwapReconstruction : Pass<"swap-reconstruction", "mlir::ModuleOp"> {
68+
let summary = "This pass searches for CNOTs that can be merged into a SWAP.";
69+
let description = [{
70+
Three CNOTs that are equivalent to a SWAP are directly replaced with a (potentially controlled) SWAP gate.
71+
72+
For swap reconstructions with just two CNOTs (utilizing an insertion of two self-cancelling CNOTs), only non-controlled SWAP gates are inserted.
73+
74+
Examples of swap reconstructions:
75+
76+
```
77+
┌───┐ ┌───┐
78+
──■──┤ X ├ ──■──┤ X ├──■────■── ──╳────■──
79+
┌─┴─┐└─┬─┘ => ┌─┴─┐└─┬─┘┌─┴─┐┌─┴─┐ => | ┌─┴─┐
80+
┤ X ├──■── ┤ X ├──■──┤ X ├┤ X ├ ──╳──┤ X ├
81+
└───┘ └───┘ └───┘└───┘ └───┘
82+
```
83+
84+
```
85+
──■────■────■── ──■──
86+
| ┌─┴─┐ | |
87+
──■──┤ X ├──■── => ──╳──
88+
┌─┴─┐└─┬─┘┌─┴─┐ |
89+
┤ X ├──■──┤ X ├ ──╳──
90+
└───┘ └───┘
91+
```
92+
}];
93+
}
94+
6795
def QuantumSinkPass : Pass<"quantum-sink", "mlir::ModuleOp"> {
6896
let summary = "This pass attempts to push down operations into branches for possible optimizations.";
6997
let description = [{
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2023 - 2025 Chair for Design Automation, TUM
3+
* Copyright (c) 2025 Munich Quantum Software Company GmbH
4+
* All rights reserved.
5+
*
6+
* SPDX-License-Identifier: MIT
7+
*
8+
* Licensed under the MIT License
9+
*/
10+
11+
#include "mlir/Dialect/Common/Compat.h"
12+
#include "mlir/Dialect/MQTOpt/Transforms/Passes.h"
13+
14+
#include <mlir/IR/PatternMatch.h>
15+
#include <mlir/Support/LLVM.h>
16+
#include <utility>
17+
18+
namespace mqt::ir::opt {
19+
20+
#define GEN_PASS_DEF_SWAPRECONSTRUCTION
21+
#include "mlir/Dialect/MQTOpt/Transforms/Passes.h.inc"
22+
23+
/**
24+
* @brief This pass uses the swap reconstruction patterns to replace according
25+
* CNOT patterns with SWAP gates.
26+
*/
27+
struct SwapReconstruction final
28+
: impl::SwapReconstructionBase<SwapReconstruction> {
29+
30+
void runOnOperation() override {
31+
// Get the current operation being operated on.
32+
auto op = getOperation();
33+
auto* ctx = &getContext();
34+
35+
// Define the set of patterns to use.
36+
mlir::RewritePatternSet patterns(ctx);
37+
populateSwapReconstructionPatterns(patterns);
38+
39+
// Apply patterns in an iterative and greedy manner.
40+
if (mlir::failed(APPLY_PATTERNS_GREEDILY(op, std::move(patterns)))) {
41+
signalPassFailure();
42+
}
43+
}
44+
};
45+
46+
} // namespace mqt::ir::opt

0 commit comments

Comments
 (0)