Skip to content

Commit 2e7cc39

Browse files
✨ Add --arch option to MLIR Routing Pass (#1279)
1 parent e9991b0 commit 2e7cc39

File tree

14 files changed

+203
-51
lines changed

14 files changed

+203
-51
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel
1111

1212
### Added
1313

14-
- ✨ Add A\*-search-based routing algorithm to MLIR transpilation routines ([#1237], [#1271]) ([**@MatthiasReumann**])
14+
- ✨ Add A\*-search-based routing algorithm to MLIR transpilation routines ([#1237], [#1271], [#1279]) ([**@MatthiasReumann**])
1515

1616
### Fixed
1717

@@ -220,6 +220,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
220220

221221
<!-- PR links -->
222222

223+
[#1279]: https://github.com/munich-quantum-toolkit/core/pull/1279
223224
[#1276]: https://github.com/munich-quantum-toolkit/core/pull/1276
224225
[#1271]: https://github.com/munich-quantum-toolkit/core/pull/1271
225226
[#1269]: https://github.com/munich-quantum-toolkit/core/pull/1269

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class RewritePatternSet;
2424
namespace mqt::ir::opt {
2525

2626
enum class PlacementStrategy : std::uint8_t { Random, Identity };
27-
2827
enum class RoutingMethod : std::uint8_t { Naive, AStar };
2928

3029
#define GEN_PASS_DECL

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ def PlacementPassSC : Pass<"placement-sc", "mlir::ModuleOp"> {
101101
Option<"strategy", "strategy", "PlacementStrategy", "PlacementStrategy::Random",
102102
"The initial placement strategy to use.", [{llvm::cl::values(
103103
clEnumValN(PlacementStrategy::Random, "random", "Random placement"),
104-
clEnumValN(PlacementStrategy::Identity, "identity", "Identity placement"))}]>
104+
clEnumValN(PlacementStrategy::Identity, "identity", "Identity placement"))}]>,
105+
Option<"archName", "arch", "std::string", "",
106+
"The name of the targeted architecture.">,
105107
];
106108
}
107109

@@ -115,6 +117,8 @@ def RoutingPassSC : Pass<"route-sc", "mlir::ModuleOp"> {
115117
"The routing method to use.", [{llvm::cl::values(
116118
clEnumValN(RoutingMethod::Naive, "naive", "Swap along shortest paths"),
117119
clEnumValN(RoutingMethod::AStar, "astar", "A*-search-based routing algorithm"))}]>,
120+
Option<"archName", "arch", "std::string", "",
121+
"The name of the targeted architecture.">,
118122
Option<"nlookahead", "nlookahead", "std::size_t", "1",
119123
"astar option: Number of lookahead steps (heuristic horizon)">,
120124
Option<"alpha", "alpha", "float", "1.0F",
@@ -132,6 +136,10 @@ def RoutingVerificationSCPass : Pass<"verify-routing-sc", "mlir::ModuleOp"> {
132136
let description = [{
133137
This pass ensures that all two-qubit gates are executable on the target's architecture.
134138
}];
139+
let options = [
140+
Option<"archName", "arch", "std::string", "",
141+
"The name of the targeted architecture.">
142+
];
135143
}
136144

137145
#endif // MQTO_PASSES

mlir/include/mlir/Dialect/MQTOpt/Transforms/Transpilation/Architecture.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@
1616
#include <cstdint>
1717
#include <llvm/ADT/DenseSet.h>
1818
#include <llvm/ADT/SmallVector.h>
19+
#include <llvm/ADT/StringRef.h>
1920
#include <memory>
2021
#include <string>
2122
#include <string_view>
2223

2324
namespace mqt::ir::opt {
2425

25-
/**
26-
* @brief Enumerates the available target architectures.
27-
*/
28-
enum class ArchitectureName : std::uint8_t { MQTTest };
29-
3026
/**
3127
* @brief A quantum accelerator's architecture.
3228
* @details Computes all-shortest paths at construction.
@@ -110,6 +106,6 @@ class Architecture {
110106
/**
111107
* @brief Get architecture by its name.
112108
*/
113-
std::unique_ptr<Architecture> getArchitecture(const ArchitectureName& name);
109+
std::unique_ptr<Architecture> getArchitecture(llvm::StringRef name);
114110

115111
}; // namespace mqt::ir::opt

mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/Architecture.cpp

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstddef>
1616
#include <cstdint>
1717
#include <llvm/ADT/SmallVector.h>
18+
#include <llvm/ADT/StringRef.h>
1819
#include <memory>
1920
#include <stdexcept>
2021
#include <string>
@@ -84,23 +85,69 @@ Architecture::neighboursOf(QubitIndex u) const {
8485
return neighbours_[u];
8586
}
8687

87-
std::unique_ptr<Architecture> getArchitecture(const ArchitectureName& name) {
88-
switch (name) {
89-
case ArchitectureName::MQTTest: {
90-
// 0 -- 1
91-
// | |
92-
// 2 -- 3
93-
// | |
94-
// 4 -- 5
95-
96-
const Architecture::CouplingSet couplingMap{
88+
std::unique_ptr<Architecture> getArchitecture(const llvm::StringRef name) {
89+
if (name == "MQTTest") {
90+
static const Architecture::CouplingSet COUPLING{
9791
{0, 1}, {1, 0}, {0, 2}, {2, 0}, {1, 3}, {3, 1}, {2, 3},
9892
{3, 2}, {2, 4}, {4, 2}, {3, 5}, {5, 3}, {4, 5}, {5, 4}};
9993

100-
return std::make_unique<Architecture>("MQT-Test", 6, couplingMap);
94+
return std::make_unique<Architecture>("MQT-Test", 6, COUPLING);
10195
}
96+
97+
if (name == "IBMFalcon") {
98+
static const Architecture::CouplingSet COUPLING{
99+
{0, 1}, {0, 14}, {1, 0}, {1, 2}, {2, 1}, {2, 3},
100+
{3, 2}, {3, 4}, {4, 3}, {4, 5}, {4, 15}, {5, 4},
101+
{5, 6}, {6, 5}, {6, 7}, {7, 6}, {7, 8}, {8, 7},
102+
{8, 16}, {9, 10}, {10, 9}, {10, 11}, {11, 10}, {11, 12},
103+
{12, 11}, {12, 13}, {12, 17}, {13, 12}, {14, 0}, {14, 18},
104+
{15, 4}, {15, 22}, {16, 8}, {16, 26}, {17, 12}, {17, 30},
105+
{18, 14}, {18, 19}, {19, 18}, {19, 20}, {20, 19}, {20, 21},
106+
{20, 33}, {21, 20}, {21, 22}, {22, 15}, {22, 21}, {22, 23},
107+
{23, 22}, {23, 24}, {24, 23}, {24, 25}, {24, 34}, {25, 24},
108+
{25, 26}, {26, 16}, {26, 25}, {26, 27}, {27, 26}, {27, 28},
109+
{28, 27}, {28, 29}, {28, 35}, {29, 28}, {29, 30}, {30, 17},
110+
{30, 29}, {30, 31}, {31, 30}, {31, 32}, {32, 31}, {32, 36},
111+
{33, 20}, {33, 39}, {34, 24}, {34, 43}, {35, 28}, {35, 47},
112+
{36, 32}, {36, 51}, {37, 38}, {37, 52}, {38, 37}, {38, 39},
113+
{39, 33}, {39, 38}, {39, 40}, {40, 39}, {40, 41}, {41, 40},
114+
{41, 42}, {41, 53}, {42, 41}, {42, 43}, {43, 34}, {43, 42},
115+
{43, 44}, {44, 43}, {44, 45}, {45, 44}, {45, 46}, {45, 54},
116+
{46, 45}, {46, 47}, {47, 35}, {47, 46}, {47, 48}, {48, 47},
117+
{48, 49}, {49, 48}, {49, 50}, {49, 55}, {50, 49}, {50, 51},
118+
{51, 36}, {51, 50}, {52, 37}, {52, 56}, {53, 41}, {53, 60},
119+
{54, 45}, {54, 64}, {55, 49}, {55, 68}, {56, 52}, {56, 57},
120+
{57, 56}, {57, 58}, {58, 57}, {58, 59}, {58, 71}, {59, 58},
121+
{59, 60}, {60, 53}, {60, 59}, {60, 61}, {61, 60}, {61, 62},
122+
{62, 61}, {62, 63}, {62, 72}, {63, 62}, {63, 64}, {64, 54},
123+
{64, 63}, {64, 65}, {65, 64}, {65, 66}, {66, 65}, {66, 67},
124+
{66, 73}, {67, 66}, {67, 68}, {68, 55}, {68, 67}, {68, 69},
125+
{69, 68}, {69, 70}, {70, 69}, {70, 74}, {71, 58}, {71, 77},
126+
{72, 62}, {72, 81}, {73, 66}, {73, 85}, {74, 70}, {74, 89},
127+
{75, 76}, {75, 90}, {76, 75}, {76, 77}, {77, 71}, {77, 76},
128+
{77, 78}, {78, 77}, {78, 79}, {79, 78}, {79, 80}, {79, 91},
129+
{80, 79}, {80, 81}, {81, 72}, {81, 80}, {81, 82}, {82, 81},
130+
{82, 83}, {83, 82}, {83, 84}, {83, 92}, {84, 83}, {84, 85},
131+
{85, 73}, {85, 84}, {85, 86}, {86, 85}, {86, 87}, {87, 86},
132+
{87, 88}, {87, 93}, {88, 87}, {88, 89}, {89, 74}, {89, 88},
133+
{90, 75}, {90, 94}, {91, 79}, {91, 98}, {92, 83}, {92, 102},
134+
{93, 87}, {93, 106}, {94, 90}, {94, 95}, {95, 94}, {95, 96},
135+
{96, 95}, {96, 97}, {96, 109}, {97, 96}, {97, 98}, {98, 91},
136+
{98, 97}, {98, 99}, {99, 98}, {99, 100}, {100, 99}, {100, 101},
137+
{100, 110}, {101, 100}, {101, 102}, {102, 92}, {102, 101}, {102, 103},
138+
{103, 102}, {103, 104}, {104, 103}, {104, 105}, {104, 111}, {105, 104},
139+
{105, 106}, {106, 93}, {106, 105}, {106, 107}, {107, 106}, {107, 108},
140+
{108, 107}, {108, 112}, {109, 96}, {110, 100}, {110, 118}, {111, 104},
141+
{111, 122}, {112, 108}, {112, 126}, {113, 114}, {114, 113}, {114, 115},
142+
{115, 114}, {115, 116}, {116, 115}, {116, 117}, {117, 116}, {117, 118},
143+
{118, 110}, {118, 117}, {118, 119}, {119, 118}, {119, 120}, {120, 119},
144+
{120, 121}, {121, 120}, {121, 122}, {122, 111}, {122, 121}, {122, 123},
145+
{123, 122}, {123, 124}, {124, 123}, {124, 125}, {125, 124}, {125, 126},
146+
{126, 112}, {126, 125}};
147+
148+
return std::make_unique<Architecture>("IBM-Falcon", 127, COUPLING);
102149
}
103150

104-
throw std::invalid_argument("Unsupported architecture.");
151+
return nullptr;
105152
}
106153
}; // namespace mqt::ir::opt

mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/sc/PlacementPass.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <mlir/IR/Builders.h>
3131
#include <mlir/IR/BuiltinAttributes.h>
3232
#include <mlir/IR/BuiltinOps.h>
33+
#include <mlir/IR/Diagnostics.h>
3334
#include <mlir/IR/MLIRContext.h>
3435
#include <mlir/IR/PatternMatch.h>
3536
#include <mlir/IR/Types.h>
@@ -427,7 +428,19 @@ struct PlacementPassSC final : impl::PlacementPassSCBase<PlacementPassSC> {
427428
using PlacementPassSCBase::PlacementPassSCBase;
428429

429430
void runOnOperation() override {
430-
const auto arch = getArchitecture(ArchitectureName::MQTTest);
431+
if (preflight().failed()) {
432+
signalPassFailure();
433+
return;
434+
}
435+
436+
const auto arch = getArchitecture(archName);
437+
if (!arch) {
438+
emitError(UnknownLoc::get(&getContext()))
439+
<< "unsupported architecture '" << archName << "'";
440+
signalPassFailure();
441+
return;
442+
}
443+
431444
const auto placer = getPlacer(*arch);
432445

433446
if (PlacementContext ctx(*arch, *placer);
@@ -447,14 +460,23 @@ struct PlacementPassSC final : impl::PlacementPassSCBase<PlacementPassSC> {
447460
std::random_device rd;
448461
const std::size_t seed = rd();
449462
LLVM_DEBUG({
450-
llvm::dbgs() << "getPlacer: random placement with seed = " << seed
463+
llvm::dbgs() << "getPlacer: random placement with seed =" << seed
451464
<< '\n';
452465
});
453466
return std::make_unique<RandomPlacer>(arch.nqubits(),
454467
std::mt19937_64(seed));
455468
}
456469
llvm_unreachable("Unknown strategy");
457470
}
471+
472+
LogicalResult preflight() {
473+
if (archName.empty()) {
474+
return emitError(UnknownLoc::get(&getContext()),
475+
"required option 'arch' not provided");
476+
}
477+
478+
return success();
479+
}
458480
};
459481
} // namespace
460482
} // namespace mqt::ir::opt

mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/sc/RoutingPass.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <mlir/IR/BuiltinAttributes.h>
3333
#include <mlir/IR/BuiltinOps.h>
3434
#include <mlir/IR/BuiltinTypes.h>
35+
#include <mlir/IR/Diagnostics.h>
3536
#include <mlir/IR/MLIRContext.h>
3637
#include <mlir/IR/Operation.h>
3738
#include <mlir/IR/PatternMatch.h>
@@ -497,17 +498,27 @@ struct RoutingPassSC final : impl::RoutingPassSCBase<RoutingPassSC> {
497498
using RoutingPassSCBase<RoutingPassSC>::RoutingPassSCBase;
498499

499500
void runOnOperation() override {
500-
Mapper mapper = getMapper();
501+
if (preflight().failed()) {
502+
signalPassFailure();
503+
return;
504+
}
505+
506+
auto arch = getArchitecture(archName);
507+
if (!arch) {
508+
emitError(UnknownLoc::get(&getContext()))
509+
<< "unsupported architecture '" << archName << "'";
510+
signalPassFailure();
511+
return;
512+
}
513+
514+
Mapper mapper = getMapper(std::move(arch));
501515
if (failed(route(getOperation(), &getContext(), mapper))) {
502516
signalPassFailure();
503517
}
504518
}
505519

506520
private:
507-
[[nodiscard]] Mapper getMapper() {
508-
/// TODO: Configurable Architecture.
509-
auto arch = getArchitecture(ArchitectureName::MQTTest);
510-
521+
[[nodiscard]] Mapper getMapper(std::unique_ptr<Architecture> arch) {
511522
switch (static_cast<RoutingMethod>(method)) {
512523
case RoutingMethod::Naive:
513524
LLVM_DEBUG({ llvm::dbgs() << "getRouter: method=naive\n"; });
@@ -523,6 +534,15 @@ struct RoutingPassSC final : impl::RoutingPassSCBase<RoutingPassSC> {
523534

524535
llvm_unreachable("Unknown method");
525536
}
537+
538+
LogicalResult preflight() {
539+
if (archName.empty()) {
540+
return emitError(UnknownLoc::get(&getContext()),
541+
"required option 'arch' not provided");
542+
}
543+
544+
return success();
545+
}
526546
};
527547

528548
} // namespace

mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/sc/RoutingVerificationPass.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
#include <cstddef>
2020
#include <llvm/ADT/STLExtras.h>
2121
#include <llvm/ADT/TypeSwitch.h>
22+
#include <memory>
2223
#include <mlir/Dialect/Func/IR/FuncOps.h>
2324
#include <mlir/Dialect/SCF/IR/SCF.h>
25+
#include <mlir/IR/Builders.h>
2426
#include <mlir/IR/BuiltinAttributes.h>
2527
#include <mlir/IR/BuiltinOps.h>
28+
#include <mlir/IR/Diagnostics.h>
2629
#include <mlir/IR/Value.h>
2730
#include <mlir/IR/Visitors.h>
2831
#include <mlir/Support/LLVM.h>
2932
#include <mlir/Support/WalkResult.h>
33+
#include <utility>
3034
#include <vector>
3135

3236
#define DEBUG_TYPE "routing-verification-sc"
@@ -43,9 +47,10 @@ using namespace mlir;
4347
* @brief The necessary datastructures for verification.
4448
*/
4549
struct VerificationContext {
46-
explicit VerificationContext(Architecture& arch) : arch(&arch) {}
50+
explicit VerificationContext(std::unique_ptr<Architecture> arch)
51+
: arch(std::move(arch)) {}
4752

48-
Architecture* arch;
53+
std::unique_ptr<Architecture> arch;
4954
LayoutStack<Layout> stack{};
5055
};
5156

@@ -219,10 +224,24 @@ WalkResult handleMeasure(MeasureOp op, VerificationContext& ctx) {
219224
*/
220225
struct RoutingVerificationPassSC final
221226
: impl::RoutingVerificationSCPassBase<RoutingVerificationPassSC> {
227+
using RoutingVerificationSCPassBase<
228+
RoutingVerificationPassSC>::RoutingVerificationSCPassBase;
229+
222230
void runOnOperation() override {
223-
const auto arch = getArchitecture(ArchitectureName::MQTTest);
224-
VerificationContext ctx(*arch);
231+
if (preflight().failed()) {
232+
signalPassFailure();
233+
return;
234+
}
235+
236+
auto arch = getArchitecture(archName);
237+
if (!arch) {
238+
emitError(UnknownLoc::get(&getContext()))
239+
<< "unsupported architecture '" << archName << "'";
240+
signalPassFailure();
241+
return;
242+
}
225243

244+
VerificationContext ctx(std::move(arch));
226245
const auto res =
227246
getOperation()->walk<WalkOrder::PreOrder>([&](Operation* op) {
228247
return TypeSwitch<Operation*, WalkResult>(op)
@@ -260,6 +279,16 @@ struct RoutingVerificationPassSC final
260279
signalPassFailure();
261280
}
262281
}
282+
283+
private:
284+
LogicalResult preflight() {
285+
if (archName.empty()) {
286+
return emitError(UnknownLoc::get(&getContext()),
287+
"required option 'arch' not provided");
288+
}
289+
290+
return success();
291+
}
263292
};
264293
} // namespace
265294
} // namespace mqt::ir::opt

0 commit comments

Comments
 (0)