Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Added

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

### Fixed

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

<!-- PR links -->

[#1279]: https://github.com/munich-quantum-toolkit/core/pull/1279
[#1276]: https://github.com/munich-quantum-toolkit/core/pull/1276
[#1271]: https://github.com/munich-quantum-toolkit/core/pull/1271
[#1269]: https://github.com/munich-quantum-toolkit/core/pull/1269
Expand Down
1 change: 0 additions & 1 deletion mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class RewritePatternSet;
namespace mqt::ir::opt {

enum class PlacementStrategy : std::uint8_t { Random, Identity };

enum class RoutingMethod : std::uint8_t { Naive, AStar };

#define GEN_PASS_DECL
Expand Down
10 changes: 9 additions & 1 deletion mlir/include/mlir/Dialect/MQTOpt/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ def PlacementPassSC : Pass<"placement-sc", "mlir::ModuleOp"> {
Option<"strategy", "strategy", "PlacementStrategy", "PlacementStrategy::Random",
"The initial placement strategy to use.", [{llvm::cl::values(
clEnumValN(PlacementStrategy::Random, "random", "Random placement"),
clEnumValN(PlacementStrategy::Identity, "identity", "Identity placement"))}]>
clEnumValN(PlacementStrategy::Identity, "identity", "Identity placement"))}]>,
Option<"archName", "arch", "std::string", "",
"The name of the targeted architecture.">,
];
}

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

#endif // MQTO_PASSES
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@

namespace mqt::ir::opt {

/**
* @brief Enumerates the available target architectures.
*/
enum class ArchitectureName : std::uint8_t { MQTTest };

/**
* @brief A quantum accelerator's architecture.
* @details Computes all-shortest paths at construction.
Expand Down Expand Up @@ -110,6 +105,6 @@ class Architecture {
/**
* @brief Get architecture by its name.
*/
std::unique_ptr<Architecture> getArchitecture(const ArchitectureName& name);
std::unique_ptr<Architecture> getArchitecture(const std::string& name);

}; // namespace mqt::ir::opt
66 changes: 56 additions & 10 deletions mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,69 @@ Architecture::neighboursOf(QubitIndex u) const {
return neighbours_[u];
}

std::unique_ptr<Architecture> getArchitecture(const ArchitectureName& name) {
switch (name) {
case ArchitectureName::MQTTest: {
// 0 -- 1
// | |
// 2 -- 3
// | |
// 4 -- 5

std::unique_ptr<Architecture> getArchitecture(const std::string& name) {
if (name == "MQTTest") {
const Architecture::CouplingSet couplingMap{
{0, 1}, {1, 0}, {0, 2}, {2, 0}, {1, 3}, {3, 1}, {2, 3},
{3, 2}, {2, 4}, {4, 2}, {3, 5}, {5, 3}, {4, 5}, {5, 4}};

return std::make_unique<Architecture>("MQT-Test", 6, couplingMap);
}

if (name == "IBMFalcon") {
const Architecture::CouplingSet couplingMap{
{0, 1}, {0, 14}, {1, 0}, {1, 2}, {2, 1}, {2, 3},
{3, 2}, {3, 4}, {4, 3}, {4, 5}, {4, 15}, {5, 4},
{5, 6}, {6, 5}, {6, 7}, {7, 6}, {7, 8}, {8, 7},
{8, 16}, {9, 10}, {10, 9}, {10, 11}, {11, 10}, {11, 12},
{12, 11}, {12, 13}, {12, 17}, {13, 12}, {14, 0}, {14, 18},
{15, 4}, {15, 22}, {16, 8}, {16, 26}, {17, 12}, {17, 30},
{18, 14}, {18, 19}, {19, 18}, {19, 20}, {20, 19}, {20, 21},
{20, 33}, {21, 20}, {21, 22}, {22, 15}, {22, 21}, {22, 23},
{23, 22}, {23, 24}, {24, 23}, {24, 25}, {24, 34}, {25, 24},
{25, 26}, {26, 16}, {26, 25}, {26, 27}, {27, 26}, {27, 28},
{28, 27}, {28, 29}, {28, 35}, {29, 28}, {29, 30}, {30, 17},
{30, 29}, {30, 31}, {31, 30}, {31, 32}, {32, 31}, {32, 36},
{33, 20}, {33, 39}, {34, 24}, {34, 43}, {35, 28}, {35, 47},
{36, 32}, {36, 51}, {37, 38}, {37, 52}, {38, 37}, {38, 39},
{39, 33}, {39, 38}, {39, 40}, {40, 39}, {40, 41}, {41, 40},
{41, 42}, {41, 53}, {42, 41}, {42, 43}, {43, 34}, {43, 42},
{43, 44}, {44, 43}, {44, 45}, {45, 44}, {45, 46}, {45, 54},
{46, 45}, {46, 47}, {47, 35}, {47, 46}, {47, 48}, {48, 47},
{48, 49}, {49, 48}, {49, 50}, {49, 55}, {50, 49}, {50, 51},
{51, 36}, {51, 50}, {52, 37}, {52, 56}, {53, 41}, {53, 60},
{54, 45}, {54, 64}, {55, 49}, {55, 68}, {56, 52}, {56, 57},
{57, 56}, {57, 58}, {58, 57}, {58, 59}, {58, 71}, {59, 58},
{59, 60}, {60, 53}, {60, 59}, {60, 61}, {61, 60}, {61, 62},
{62, 61}, {62, 63}, {62, 72}, {63, 62}, {63, 64}, {64, 54},
{64, 63}, {64, 65}, {65, 64}, {65, 66}, {66, 65}, {66, 67},
{66, 73}, {67, 66}, {67, 68}, {68, 55}, {68, 67}, {68, 69},
{69, 68}, {69, 70}, {70, 69}, {70, 74}, {71, 58}, {71, 77},
{72, 62}, {72, 81}, {73, 66}, {73, 85}, {74, 70}, {74, 89},
{75, 76}, {75, 90}, {76, 75}, {76, 77}, {77, 71}, {77, 76},
{77, 78}, {78, 77}, {78, 79}, {79, 78}, {79, 80}, {79, 91},
{80, 79}, {80, 81}, {81, 72}, {81, 80}, {81, 82}, {82, 81},
{82, 83}, {83, 82}, {83, 84}, {83, 92}, {84, 83}, {84, 85},
{85, 73}, {85, 84}, {85, 86}, {86, 85}, {86, 87}, {87, 86},
{87, 88}, {87, 93}, {88, 87}, {88, 89}, {89, 74}, {89, 88},
{90, 75}, {90, 94}, {91, 79}, {91, 98}, {92, 83}, {92, 102},
{93, 87}, {93, 106}, {94, 90}, {94, 95}, {95, 94}, {95, 96},
{96, 95}, {96, 97}, {96, 109}, {97, 96}, {97, 98}, {98, 91},
{98, 97}, {98, 99}, {99, 98}, {99, 100}, {100, 99}, {100, 101},
{100, 110}, {101, 100}, {101, 102}, {102, 92}, {102, 101}, {102, 103},
{103, 102}, {103, 104}, {104, 103}, {104, 105}, {104, 111}, {105, 104},
{105, 106}, {106, 93}, {106, 105}, {106, 107}, {107, 106}, {107, 108},
{108, 107}, {108, 112}, {109, 96}, {110, 100}, {110, 118}, {111, 104},
{111, 122}, {112, 108}, {112, 126}, {113, 114}, {114, 113}, {114, 115},
{115, 114}, {115, 116}, {116, 115}, {116, 117}, {117, 116}, {117, 118},
{118, 110}, {118, 117}, {118, 119}, {119, 118}, {119, 120}, {120, 119},
{120, 121}, {121, 120}, {121, 122}, {122, 111}, {122, 121}, {122, 123},
{123, 122}, {123, 124}, {124, 123}, {124, 125}, {125, 124}, {125, 126},
{126, 112}, {126, 125}};

return std::make_unique<Architecture>("IBM-Falcon", 127, couplingMap);
}

throw std::invalid_argument("Unsupported architecture.");
return nullptr;
}
}; // namespace mqt::ir::opt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/Diagnostics.h>
#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/PatternMatch.h>
#include <mlir/IR/Types.h>
Expand Down Expand Up @@ -427,7 +428,18 @@ struct PlacementPassSC final : impl::PlacementPassSCBase<PlacementPassSC> {
using PlacementPassSCBase::PlacementPassSCBase;

void runOnOperation() override {
const auto arch = getArchitecture(ArchitectureName::MQTTest);
if (preflight().failed()) {
signalPassFailure();
return;
}

const auto arch = getArchitecture(archName);
if (!arch) {
emitError(UnknownLoc::get(&getContext()), "Unsupported architecture.");
signalPassFailure();
return;
}

const auto placer = getPlacer(*arch);

if (PlacementContext ctx(*arch, *placer);
Expand All @@ -447,14 +459,23 @@ struct PlacementPassSC final : impl::PlacementPassSCBase<PlacementPassSC> {
std::random_device rd;
const std::size_t seed = rd();
LLVM_DEBUG({
llvm::dbgs() << "getPlacer: random placement with seed = " << seed
llvm::dbgs() << "getPlacer: random placement with seed =" << seed
<< '\n';
});
return std::make_unique<RandomPlacer>(arch.nqubits(),
std::mt19937_64(seed));
}
llvm_unreachable("Unknown strategy");
}

LogicalResult preflight() {
if (archName.empty()) {
return emitError(UnknownLoc::get(&getContext()),
"required option 'arch' not provided");
}

return success();
}
};
} // namespace
} // namespace mqt::ir::opt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/BuiltinTypes.h>
#include <mlir/IR/Diagnostics.h>
#include <mlir/IR/MLIRContext.h>
#include <mlir/IR/Operation.h>
#include <mlir/IR/PatternMatch.h>
Expand Down Expand Up @@ -497,17 +498,26 @@ struct RoutingPassSC final : impl::RoutingPassSCBase<RoutingPassSC> {
using RoutingPassSCBase<RoutingPassSC>::RoutingPassSCBase;

void runOnOperation() override {
Mapper mapper = getMapper();
if (preflight().failed()) {
signalPassFailure();
return;
}

auto arch = getArchitecture(archName);
if (!arch) {
emitError(UnknownLoc::get(&getContext()), "Unsupported architecture.");
signalPassFailure();
return;
}

Mapper mapper = getMapper(std::move(arch));
if (failed(route(getOperation(), &getContext(), mapper))) {
signalPassFailure();
}
}

private:
[[nodiscard]] Mapper getMapper() {
/// TODO: Configurable Architecture.
auto arch = getArchitecture(ArchitectureName::MQTTest);

[[nodiscard]] Mapper getMapper(std::unique_ptr<Architecture> arch) {
switch (static_cast<RoutingMethod>(method)) {
case RoutingMethod::Naive:
LLVM_DEBUG({ llvm::dbgs() << "getRouter: method=naive\n"; });
Expand All @@ -523,6 +533,15 @@ struct RoutingPassSC final : impl::RoutingPassSCBase<RoutingPassSC> {

llvm_unreachable("Unknown method");
}

LogicalResult preflight() {
if (archName.empty()) {
return emitError(UnknownLoc::get(&getContext()),
"required option 'arch' not provided");
}

return success();
}
};

} // namespace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@
#include <cstddef>
#include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/TypeSwitch.h>
#include <memory>
#include <mlir/Dialect/Func/IR/FuncOps.h>
#include <mlir/Dialect/SCF/IR/SCF.h>
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/Diagnostics.h>
#include <mlir/IR/Value.h>
#include <mlir/IR/Visitors.h>
#include <mlir/Support/LLVM.h>
#include <mlir/Support/WalkResult.h>
#include <utility>
#include <vector>

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

Architecture* arch;
std::unique_ptr<Architecture> arch;
LayoutStack<Layout> stack{};
};

Expand Down Expand Up @@ -219,10 +224,23 @@ WalkResult handleMeasure(MeasureOp op, VerificationContext& ctx) {
*/
struct RoutingVerificationPassSC final
: impl::RoutingVerificationSCPassBase<RoutingVerificationPassSC> {
using RoutingVerificationSCPassBase<
RoutingVerificationPassSC>::RoutingVerificationSCPassBase;

void runOnOperation() override {
const auto arch = getArchitecture(ArchitectureName::MQTTest);
VerificationContext ctx(*arch);
if (preflight().failed()) {
signalPassFailure();
return;
}

auto arch = getArchitecture(archName);
if (!arch) {
emitError(UnknownLoc::get(&getContext()), "Unsupported architecture.");
signalPassFailure();
return;
}

VerificationContext ctx(std::move(arch));
const auto res =
getOperation()->walk<WalkOrder::PreOrder>([&](Operation* op) {
return TypeSwitch<Operation*, WalkResult>(op)
Expand Down Expand Up @@ -260,6 +278,16 @@ struct RoutingVerificationPassSC final
signalPassFailure();
}
}

private:
LogicalResult preflight() {
if (archName.empty()) {
return emitError(UnknownLoc::get(&getContext()),
"required option 'arch' not provided");
}

return success();
}
};
} // namespace
} // namespace mqt::ir::opt
Loading
Loading