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
476 changes: 476 additions & 0 deletions .agent/plans/1687-map-01-target-mapping.md

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ releases may include breaking changes.
- ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637],
[#1676], [#1706], [#1776], [#1836], [#1934]) ([**@denialhaag**],
[**@burgholzer**])
- ✨ Add a `place-and-route` pass for mapping circuits to architectures with
restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588],
[#1600], [#1664], [#1709], [#1716], [#1748], [#1805], [#1870], [#1904],
[#1911], [#1951]) ([**@MatthiasReumann**], [**@burgholzer**])
- ✨ Add a `place-and-route` pass for mapping scalar- and tensor-allocated
circuits to compiler-target topologies while preserving provider site IDs and
materializing routing workspace on demand ([#1537], [#1547], [#1568], [#1581],
[#1583], [#1588], [#1600], [#1664], [#1709], [#1716], [#1748], [#1805],
[#1870], [#1904], [#1911], [#1951], [#1997]) ([**@MatthiasReumann**],
[**@burgholzer**])
- ✨ Add a pass for qubit reuse in quantum programs, as well as related
auxiliary passes and patterns ([#1705], [#1755], [#1756], [#1923], [#1924])
([**@DRovara**], [**@burgholzer**])
Expand Down Expand Up @@ -707,6 +709,7 @@ for previous changelogs._

<!-- PR links -->

[#1997]: https://github.com/munich-quantum-toolkit/core/pull/1997
[#1992]: https://github.com/munich-quantum-toolkit/core/pull/1992
[#1986]: https://github.com/munich-quantum-toolkit/core/pull/1986
[#1984]: https://github.com/munich-quantum-toolkit/core/pull/1984
Expand Down
18 changes: 10 additions & 8 deletions mlir/include/mlir/Dialect/QCO/Transforms/Mapping/Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@

#include "mlir/Dialect/QCO/Transforms/Passes.h"

#include <llvm/Support/LogicalResult.h>
#include <mlir/IR/Region.h>
#include <mlir/Pass/Pass.h>

#include <memory>

namespace mlir::qco {
namespace mlir {

class CompilerTarget;

namespace qco {

/**
* @brief Create a mapping pass instance with the given target architecture.
* @brief Create a mapping pass instance for a compiler target.
* @returns a pass object.
*/
std::unique_ptr<Pass>
createMappingPass(const llvm::DenseSet<std::pair<size_t, size_t>>&,
MappingPassOptions);
std::unique_ptr<Pass> createMappingPass(const CompilerTarget& target,
MappingPassOptions options);

} // namespace mlir::qco
} // namespace qco
} // namespace mlir
17 changes: 12 additions & 5 deletions mlir/include/mlir/Dialect/QCO/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,20 @@ def MappingPass : Pass<"place-and-route", "mlir::ModuleOp"> {
let summary = "This pass ensures that a program meets the connectivity "
"constraints of a target architecture.";
let description = [{
This pass maps the dynamically allocated qubits in a quantum program to the static qubits of a target architecture.
The pass performs both placement and routing of the qubits to ensure that all two-qubit operations in the program
can be executed on the target architecture.
This pass maps top-level scalar and tensor-backed dynamically allocated
qubits in a quantum program to the static sites of a `CompilerTarget`. It
uses only the target's undirected coupling topology: arbitrary one-qubit
operations pass through, and every two-qubit operation is routed to adjacent
target vertices. Higher-arity unitaries must be decomposed before mapping.
Provider-defined site identifiers are retained in the resulting
`qco.static` operations.

First, the pass assigns static qubits to the dynamically allocated ones by creating an initial dynamic-to-static
mapping, which is referred to as the initial layout. Then, it traverses the circuit and inserts `SWAP` operations to
ensure that all two-qubit operations are executable on the target architecture, a process known as routing.
mapping, which is referred to as the initial layout. The layout covers the
complete target virtually, while only program qubits and vacant sites used
as routing workspace are materialized. Then, the pass traverses the circuit
and inserts `qco.swap` operations to ensure that all two-qubit operations
are executable on the target architecture, a process known as routing.

For routing, the pass first divides the circuit into layers. A layer is a set of independently executable (sequences
or blocks of) two-qubit operations. Subsequently, the pass performs an A* search for each layer to find and insert a
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 @@ -50,6 +50,7 @@ add_mlir_library(
MLIRTargetLLVMIRExport
MLIRBuiltinToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
MQTCompilerTarget
MQT::MLIRSupport)

mqt_mlir_target_use_project_options(MQTCompilerPipeline)
Expand Down
38 changes: 34 additions & 4 deletions mlir/lib/Compiler/Programs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "mlir/Compiler/Programs.h"

#include "ir/QuantumComputation.hpp"
#include "mlir/Compiler/Target.h"
#include "mlir/Conversion/JeffToQCO/JeffToQCO.h"
#include "mlir/Conversion/QCOToJeff/QCOToJeff.h"
#include "mlir/Conversion/QCOToQC/QCOToQC.h"
Expand Down Expand Up @@ -58,16 +59,19 @@
#include <mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h>
#include <mlir/Target/LLVMIR/ModuleTranslation.h>

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <ios>
#include <limits>
#include <memory>
#include <optional>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
Expand Down Expand Up @@ -417,8 +421,34 @@ bool QCOProgram::placeAndRoute(
const std::size_t nlookahead, const float alpha, const float lambda,
const std::size_t niterations, const std::size_t ntrials,
const std::size_t seed) {
DenseSet<std::pair<std::size_t, std::size_t>> couplingSet;
couplingSet.insert(coupling.begin(), coupling.end());
std::vector<CompilerTarget::SiteId> siteIds;
siteIds.reserve(coupling.size() * 2);
std::vector<CompilerTarget::Coupling> couplings;
couplings.reserve(coupling.size());
for (const auto [source, target] : coupling) {
if (source > static_cast<std::size_t>(
std::numeric_limits<CompilerTarget::SiteId>::max()) ||
target > static_cast<std::size_t>(
std::numeric_limits<CompilerTarget::SiteId>::max())) {
throw std::invalid_argument(
"Coupling site ID exceeds the nonnegative i64 domain");
}
const auto sourceId = static_cast<CompilerTarget::SiteId>(source);
const auto targetId = static_cast<CompilerTarget::SiteId>(target);
siteIds.emplace_back(sourceId);
siteIds.emplace_back(targetId);
couplings.emplace_back(sourceId, targetId);
}
std::ranges::sort(siteIds);
const auto [duplicates, end] = std::ranges::unique(siteIds);
siteIds.erase(duplicates, end);
std::vector<CompilerTarget::Site> sites;
sites.reserve(siteIds.size());
for (const auto site : siteIds) {
sites.emplace_back(site);
}
const CompilerTarget target(std::move(sites), std::move(couplings));

qco::MappingPassOptions options;
options.nlookahead = nlookahead;
options.alpha = alpha;
Expand All @@ -428,8 +458,8 @@ bool QCOProgram::placeAndRoute(
options.seed = seed;
return succeeded(runPasses(
mod(),
[&couplingSet, &options](OpPassManager& pm) {
pm.addPass(qco::createMappingPass(couplingSet, options));
[&target, &options](OpPassManager& pm) {
pm.addPass(qco::createMappingPass(target, options));
},
"failed to place and route the QCO program"));
}
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Dialect/QCO/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_mlir_library(
${PASSES_SOURCES}
LINK_LIBS
PRIVATE
MQTCompilerTarget
MLIRQCODialect
MLIRQCOUtils
MLIRQTensorUtils
Expand Down
Loading
Loading