Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -16,17 +16,13 @@
#include <cstdint>
#include <llvm/ADT/DenseSet.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/StringRef.h>
#include <memory>
#include <string>
#include <string_view>

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 +106,6 @@ class Architecture {
/**
* @brief Get architecture by its name.
*/
std::unique_ptr<Architecture> getArchitecture(const ArchitectureName& name);
std::unique_ptr<Architecture> getArchitecture(llvm::StringRef name);

}; // namespace mqt::ir::opt
71 changes: 59 additions & 12 deletions mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <cstddef>
#include <cstdint>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/StringRef.h>
#include <memory>
#include <stdexcept>
#include <string>
Expand Down Expand Up @@ -84,23 +85,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

const Architecture::CouplingSet couplingMap{
std::unique_ptr<Architecture> getArchitecture(const llvm::StringRef name) {
if (name == "MQTTest") {
static const Architecture::CouplingSet COUPLING{
{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);
return std::make_unique<Architecture>("MQT-Test", 6, COUPLING);
}

if (name == "IBMFalcon") {
static const Architecture::CouplingSet COUPLING{
{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, COUPLING);
}

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,19 @@ 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 '" << archName << "'";
signalPassFailure();
return;
}

const auto placer = getPlacer(*arch);

if (PlacementContext ctx(*arch, *placer);
Expand All @@ -447,14 +460,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,27 @@ 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 '" << archName << "'";
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 +534,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,24 @@ 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 '" << archName << "'";
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 +279,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