From c38c99cf3a8974abf1b8967bb94648f2e49e2271 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Wed, 9 Sep 2026 10:08:50 +0000 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Simplify=20routing=20s?= =?UTF-8?q?tate=20and=20layout=20repair?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip graph construction for equal layouts, remove duplicate routing state and unused graph APIs, and diagnose unsupported mapping inputs. Preserve routing heuristics and document the dense temporary workspace. Add boundary regression tests and reproducible before/after benchmarks with mapped-output checks and plots. Assisted-by: GPT-6 via Codex --- .agent/benchmarks/routing/README.md | 79 ++ .agent/benchmarks/routing/before-after.png | Bin 0 -> 181607 bytes .agent/benchmarks/routing/collect.py | 41 + .agent/benchmarks/routing/plot.py | 78 ++ .agent/benchmarks/routing/results.csv | 811 ++++++++++++++++++ .agent/plans/routing-simplification.md | 37 + .../mlir/Dialect/QCO/Transforms/Passes.td | 7 +- mlir/include/mlir/Dialect/QCO/Utils/Graph.h | 53 +- .../QCO/Transforms/Mapping/Mapping.cpp | 122 ++- mlir/lib/Dialect/QCO/Utils/Graph.cpp | 41 +- .../QCO/Transforms/Mapping/CMakeLists.txt | 5 + .../Transforms/Mapping/benchmark_mapping.cpp | 166 ++++ .../QCO/Transforms/Mapping/test_mapping.cpp | 114 ++- 13 files changed, 1395 insertions(+), 159 deletions(-) create mode 100644 .agent/benchmarks/routing/README.md create mode 100644 .agent/benchmarks/routing/before-after.png create mode 100644 .agent/benchmarks/routing/collect.py create mode 100644 .agent/benchmarks/routing/plot.py create mode 100644 .agent/benchmarks/routing/results.csv create mode 100644 .agent/plans/routing-simplification.md create mode 100644 mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp diff --git a/.agent/benchmarks/routing/README.md b/.agent/benchmarks/routing/README.md new file mode 100644 index 0000000000..4853878728 --- /dev/null +++ b/.agent/benchmarks/routing/README.md @@ -0,0 +1,79 @@ +# Routing cleanup benchmarks + +Compare upstream main `91a9e0ba514af938680cdd394d6d63195872dc9a` with the +routing changes in this PR. The same benchmark source and build settings were +used for both executables. + +![Before and after routing cleanup](before-after.png) + +| Workload | Size | Before (ms) | After (ms) | +| ------------------- | ------------: | ----------: | ---------: | +| Unchanged branches | 16 sites | 1.320 | 0.845 | +| Unchanged branches | 64 sites | 3.545 | 2.053 | +| Unchanged branches | 256 sites | 13.208 | 7.266 | +| Routing | 16 sites | 0.737 | 0.733 | +| Routing | 64 sites | 2.140 | 2.146 | +| Routing | 256 sites | 23.783 | 23.259 | +| Graph, 100 searches | 128 vertices | 1.044 | 0.587 | +| Graph, 100 searches | 512 vertices | 7.967 | 2.766 | +| Graph, 100 searches | 2048 vertices | 64.042 | 13.656 | + +Unchanged branches are 1.56–1.82 times faster. Routing times differ by less than +3%; this experiment does not establish an improvement for that workload. + +## Workloads and limits + +- **Unchanged branch layouts:** two active qubits, one measurement, and 32 + dynamic conditionals containing X gates, on square targets with 16, 64, and + 256 sites. No SWAPs are required. This isolates unchanged region boundaries; + it is not representative of every adaptive program. +- **Circuits that need routing:** eight active qubits and 64 CX gates with + varying partners on the same target sizes. The mapper emits 39, 50, and 53 + SWAPs respectively. This checks for a cost change when branch repair is + absent. +- **Graph traversal:** 100 cycle searches on an acyclic star with 128, 512, or + 2048 vertices. This exposes repeated adjacency copying at high degree. It is a + synthetic helper benchmark, not a mapper speedup on a typical coupling graph. + +The mapping interval includes `PassManager::run`, including its verifier. Input +construction, cloning, output verification, SWAP counting, and printing are +outside the interval. Each process discards one warmup per workload and records +five samples. Nine process pairs alternate execution order. The figure shows +medians and interquartile ranges over the 45 samples per variant and workload; +these are sample spread, not confidence intervals or 45 independent processes. +All mapped-IR hashes and SWAP counts match across variants and repetitions. The +mapper uses seed 42, one trial, one refinement iteration, and its default +lookahead and cost weights. MLIR multithreading is disabled in the benchmark. + +Measured on DGX Spark (ARM64), pinned to CPU 0, GCC 13.3.0, LLVM/MLIR 23.1.0, +release preset with IPO disabled. This is local evidence, not hosted CI or a +claim about all CPUs or circuits. Build and lint processes were stopped before +the recorded measurement run. + +## Reproduce + +The optional executable lives under +`mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp`. It is +excluded from the default build and from CTest. + +Create a detached checkout at the baseline and copy only the benchmark source +and its CMake target into that checkout. Configure both checkouts with the same +compiler and dependency versions: + +```sh +cmake --preset release -DBUILD_MQT_CORE_MLIR=ON -DBUILD_MQT_CORE_TESTS=ON \ + -DBUILD_MQT_CORE_BINDINGS=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF +cmake --build --preset release --target mqt-core-mlir-benchmark-mapping +``` + +Copy the resulting executables to distinct paths before rebuilding either +checkout. From this directory, collect and render the results: + +```sh +taskset -c 0 python3 collect.py /path/to/before-binary /path/to/after-binary +uv run plot.py +``` + +`collect.py` checks output equivalence before replacing `results.csv`. `plot.py` +declares its plotting dependency through uv script metadata. Plotting adds no +project dependency. `results.csv` preserves every recorded sample. diff --git a/.agent/benchmarks/routing/before-after.png b/.agent/benchmarks/routing/before-after.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6f0ba2cb287aa782a3b957677a2736f98f1f1b GIT binary patch literal 181607 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

?xd7!Ak3IvI>Lt2 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 M#@*l2uNgf1KR{K#EdT%j literal 0 HcmV?d00001 diff --git a/.agent/benchmarks/routing/collect.py b/.agent/benchmarks/routing/collect.py new file mode 100644 index 0000000000..e9e4ac5693 --- /dev/null +++ b/.agent/benchmarks/routing/collect.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +# /// script +# dependencies = [] +# /// +"""Collect alternating runs: python collect.py BEFORE_BINARY AFTER_BINARY.""" + +import csv +import io +import subprocess +import sys +from pathlib import Path + +before, after = sys.argv[1:] +rows = [] +for pair in range(9): + variants = (("before", before), ("after", after)) + if pair % 2: + variants = variants[::-1] + for variant, binary in variants: + # Execute the benchmark binaries explicitly selected by the caller. + result = subprocess.run([binary], check=True, capture_output=True, text=True) # ruff: ignore[subprocess-without-shell-equals-true] + rows.extend({"variant": variant, "pair": pair, **row} for row in csv.DictReader(io.StringIO(result.stdout))) + +for workload, size in sorted({(row["workload"], row["size"]) for row in rows}): + group = [row for row in rows if (row["workload"], row["size"]) == (workload, size)] + if len({(row["swaps"], row["hash"]) for row in group}) != 1: + msg = f"Mapped output changed for {workload}, size {size}" + raise RuntimeError(msg) + + +with Path(__file__).with_name("results.csv").open("w", newline="") as stream: + writer = csv.DictWriter(stream, fieldnames=list(rows[0]), lineterminator="\n") + writer.writeheader() + writer.writerows(rows) diff --git a/.agent/benchmarks/routing/plot.py b/.agent/benchmarks/routing/plot.py new file mode 100644 index 0000000000..acdfa3ec17 --- /dev/null +++ b/.agent/benchmarks/routing/plot.py @@ -0,0 +1,78 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +# /// script +# dependencies = ["matplotlib==3.10.8"] +# /// +"""Render the recorded routing benchmarks: uv run plot.py.""" + +import csv +import statistics +from pathlib import Path + +import matplotlib.pyplot as plt + +ROOT = Path(__file__).resolve().parent +with (ROOT / "results.csv").open() as stream: + rows = list(csv.DictReader(stream)) + +plt.rcParams.update({"font.family": "DejaVu Sans", "font.size": 11}) +fig, axes = plt.subplots(1, 3, figsize=(15, 5.2), layout="constrained") +fig.set_facecolor("#f6f8fc") +colors = {"before": "#75859c", "after": "#007f83"} +for ax, workload, title, subtitle in zip( + axes, + ("conditional", "routing", "graph"), + ("Unchanged branch layouts", "Circuits that need routing", "Graph traversal"), + ("2 qubits · 32 dynamic branches", "8 qubits · 64 CX gates", "Acyclic star · 100 traversals"), + strict=False, +): + sizes = sorted({int(row["size"]) for row in rows if row["workload"] == workload}) + for variant, offset in (("before", -0.19), ("after", 0.19)): + groups = [ + [ + float(r["milliseconds"]) + for r in rows + if r["workload"] == workload and int(r["size"]) == size and r["variant"] == variant + ] + for size in sizes + ] + values = [statistics.median(group) for group in groups] + quartiles = [statistics.quantiles(group, n=4) for group in groups] + bars = ax.bar( + [i + offset for i in range(len(sizes))], + values, + 0.34, + color=colors[variant], + label=variant.title(), + yerr=[ + [v - q[0] for v, q in zip(values, quartiles, strict=False)], + [q[2] - v for v, q in zip(values, quartiles, strict=False)], + ], + capsize=3, + error_kw={"linewidth": 1, "ecolor": "#263449"}, + ) + ax.bar_label(bars, labels=[f"{v:.2f}" for v in values], padding=5, fontsize=9) + ax.set_title(f"{title}\n{subtitle}", loc="left", fontsize=12, pad=16) + ax.set_xticks(range(len(sizes)), [str(size) for size in sizes]) + ax.set_xlabel("Graph vertices" if workload == "graph" else "Target sites") + ax.set_ylabel("Time (ms) · lower is better") + ax.set_ylim(0, ax.get_ylim()[1] * 1.17) + ax.spines[["top", "right", "left"]].set_visible(False) + ax.grid(axis="y", alpha=0.18) + ax.set_axisbelow(True) + ax.tick_params(axis="y", length=0) +axes[0].legend(frameon=False, loc="upper left") +fig.suptitle("Routing cleanup · before / after", fontsize=22, fontweight="bold", color="#18334a") +fig.supxlabel( + "Median and interquartile range · 9 alternating process pairs x 5 samples · fixed CPU, seed 42\n" + "Mapped IR hashes and SWAP counts match. Graph case is synthetic; it is not a mapper speedup.", + fontsize=10, + color="#405268", +) +fig.savefig(ROOT / "before-after.png", dpi=180, facecolor=fig.get_facecolor()) diff --git a/.agent/benchmarks/routing/results.csv b/.agent/benchmarks/routing/results.csv new file mode 100644 index 0000000000..498c221f97 --- /dev/null +++ b/.agent/benchmarks/routing/results.csv @@ -0,0 +1,811 @@ +variant,pair,workload,size,sample,milliseconds,swaps,hash +before,0,conditional,16,1,1.340152e+00,0,17189890484463169050 +before,0,conditional,16,2,1.309480e+00,0,17189890484463169050 +before,0,conditional,16,3,1.309864e+00,0,17189890484463169050 +before,0,conditional,16,4,1.297352e+00,0,17189890484463169050 +before,0,conditional,16,5,1.312072e+00,0,17189890484463169050 +before,0,conditional,64,1,3.498725e+00,0,5534067803201244807 +before,0,conditional,64,2,3.467797e+00,0,5534067803201244807 +before,0,conditional,64,3,3.476853e+00,0,5534067803201244807 +before,0,conditional,64,4,3.447252e+00,0,5534067803201244807 +before,0,conditional,64,5,3.467621e+00,0,5534067803201244807 +before,0,conditional,256,1,1.300168e+01,0,12517723600315101147 +before,0,conditional,256,2,1.306860e+01,0,12517723600315101147 +before,0,conditional,256,3,1.298821e+01,0,12517723600315101147 +before,0,conditional,256,4,1.299526e+01,0,12517723600315101147 +before,0,conditional,256,5,1.299230e+01,0,12517723600315101147 +before,0,routing,16,1,7.393330e-01,39,16070625545712530677 +before,0,routing,16,2,7.372200e-01,39,16070625545712530677 +before,0,routing,16,3,7.326120e-01,39,16070625545712530677 +before,0,routing,16,4,7.292360e-01,39,16070625545712530677 +before,0,routing,16,5,7.333650e-01,39,16070625545712530677 +before,0,routing,64,1,2.170077e+00,50,6989942321493789781 +before,0,routing,64,2,2.168333e+00,50,6989942321493789781 +before,0,routing,64,3,2.155997e+00,50,6989942321493789781 +before,0,routing,64,4,2.191133e+00,50,6989942321493789781 +before,0,routing,64,5,2.136844e+00,50,6989942321493789781 +before,0,routing,256,1,2.293703e+01,53,4706122369782581589 +before,0,routing,256,2,2.258450e+01,53,4706122369782581589 +before,0,routing,256,3,2.301279e+01,53,4706122369782581589 +before,0,routing,256,4,2.376637e+01,53,4706122369782581589 +before,0,routing,256,5,2.286207e+01,53,4706122369782581589 +before,0,graph,128,1,1.036630e+00,0,0 +before,0,graph,128,2,1.040214e+00,0,0 +before,0,graph,128,3,1.035238e+00,0,0 +before,0,graph,128,4,1.045575e+00,0,0 +before,0,graph,128,5,1.038102e+00,0,0 +before,0,graph,512,1,8.083504e+00,0,0 +before,0,graph,512,2,8.028000e+00,0,0 +before,0,graph,512,3,8.055024e+00,0,0 +before,0,graph,512,4,8.051743e+00,0,0 +before,0,graph,512,5,8.042048e+00,0,0 +before,0,graph,2048,1,6.366003e+01,0,0 +before,0,graph,2048,2,6.376060e+01,0,0 +before,0,graph,2048,3,6.382811e+01,0,0 +before,0,graph,2048,4,6.379993e+01,0,0 +before,0,graph,2048,5,6.353734e+01,0,0 +after,0,conditional,16,1,8.492370e-01,0,17189890484463169050 +after,0,conditional,16,2,8.341010e-01,0,17189890484463169050 +after,0,conditional,16,3,8.352530e-01,0,17189890484463169050 +after,0,conditional,16,4,8.308050e-01,0,17189890484463169050 +after,0,conditional,16,5,8.391410e-01,0,17189890484463169050 +after,0,conditional,64,1,1.976347e+00,0,5534067803201244807 +after,0,conditional,64,2,1.968828e+00,0,5534067803201244807 +after,0,conditional,64,3,1.969867e+00,0,5534067803201244807 +after,0,conditional,64,4,1.994732e+00,0,5534067803201244807 +after,0,conditional,64,5,1.980699e+00,0,5534067803201244807 +after,0,conditional,256,1,6.987273e+00,0,12517723600315101147 +after,0,conditional,256,2,7.012041e+00,0,12517723600315101147 +after,0,conditional,256,3,7.055402e+00,0,12517723600315101147 +after,0,conditional,256,4,7.008361e+00,0,12517723600315101147 +after,0,conditional,256,5,7.039673e+00,0,12517723600315101147 +after,0,routing,16,1,7.288680e-01,39,16070625545712530677 +after,0,routing,16,2,7.402280e-01,39,16070625545712530677 +after,0,routing,16,3,7.227410e-01,39,16070625545712530677 +after,0,routing,16,4,7.330770e-01,39,16070625545712530677 +after,0,routing,16,5,7.225000e-01,39,16070625545712530677 +after,0,routing,64,1,2.123469e+00,50,6989942321493789781 +after,0,routing,64,2,2.120861e+00,50,6989942321493789781 +after,0,routing,64,3,2.173549e+00,50,6989942321493789781 +after,0,routing,64,4,2.103932e+00,50,6989942321493789781 +after,0,routing,64,5,2.156060e+00,50,6989942321493789781 +after,0,routing,256,1,2.242804e+01,53,4706122369782581589 +after,0,routing,256,2,2.229767e+01,53,4706122369782581589 +after,0,routing,256,3,2.248303e+01,53,4706122369782581589 +after,0,routing,256,4,2.323459e+01,53,4706122369782581589 +after,0,routing,256,5,2.367284e+01,53,4706122369782581589 +after,0,graph,128,1,5.821630e-01,0,0 +after,0,graph,128,2,5.786430e-01,0,0 +after,0,graph,128,3,5.805320e-01,0,0 +after,0,graph,128,4,5.784350e-01,0,0 +after,0,graph,128,5,5.817800e-01,0,0 +after,0,graph,512,1,2.772368e+00,0,0 +after,0,graph,512,2,2.764177e+00,0,0 +after,0,graph,512,3,2.775392e+00,0,0 +after,0,graph,512,4,2.768817e+00,0,0 +after,0,graph,512,5,2.766752e+00,0,0 +after,0,graph,2048,1,1.371373e+01,0,0 +after,0,graph,2048,2,1.367303e+01,0,0 +after,0,graph,2048,3,1.370754e+01,0,0 +after,0,graph,2048,4,1.375866e+01,0,0 +after,0,graph,2048,5,1.366269e+01,0,0 +after,1,conditional,16,1,8.501330e-01,0,17189890484463169050 +after,1,conditional,16,2,8.312530e-01,0,17189890484463169050 +after,1,conditional,16,3,8.363880e-01,0,17189890484463169050 +after,1,conditional,16,4,8.287570e-01,0,17189890484463169050 +after,1,conditional,16,5,8.335410e-01,0,17189890484463169050 +after,1,conditional,64,1,2.002300e+00,0,5534067803201244807 +after,1,conditional,64,2,2.070285e+00,0,5534067803201244807 +after,1,conditional,64,3,2.020908e+00,0,5534067803201244807 +after,1,conditional,64,4,2.021980e+00,0,5534067803201244807 +after,1,conditional,64,5,1.975564e+00,0,5534067803201244807 +after,1,conditional,256,1,7.035418e+00,0,12517723600315101147 +after,1,conditional,256,2,6.993065e+00,0,12517723600315101147 +after,1,conditional,256,3,7.057946e+00,0,12517723600315101147 +after,1,conditional,256,4,7.010585e+00,0,12517723600315101147 +after,1,conditional,256,5,7.052362e+00,0,12517723600315101147 +after,1,routing,16,1,7.360360e-01,39,16070625545712530677 +after,1,routing,16,2,7.335880e-01,39,16070625545712530677 +after,1,routing,16,3,7.254280e-01,39,16070625545712530677 +after,1,routing,16,4,7.264210e-01,39,16070625545712530677 +after,1,routing,16,5,7.153000e-01,39,16070625545712530677 +after,1,routing,64,1,2.142973e+00,50,6989942321493789781 +after,1,routing,64,2,2.133773e+00,50,6989942321493789781 +after,1,routing,64,3,2.148109e+00,50,6989942321493789781 +after,1,routing,64,4,2.133356e+00,50,6989942321493789781 +after,1,routing,64,5,2.152956e+00,50,6989942321493789781 +after,1,routing,256,1,2.250031e+01,53,4706122369782581589 +after,1,routing,256,2,2.255482e+01,53,4706122369782581589 +after,1,routing,256,3,2.264930e+01,53,4706122369782581589 +after,1,routing,256,4,2.272969e+01,53,4706122369782581589 +after,1,routing,256,5,2.285335e+01,53,4706122369782581589 +after,1,graph,128,1,5.830910e-01,0,0 +after,1,graph,128,2,5.833000e-01,0,0 +after,1,graph,128,3,5.797950e-01,0,0 +after,1,graph,128,4,5.831230e-01,0,0 +after,1,graph,128,5,5.816040e-01,0,0 +after,1,graph,512,1,2.764384e+00,0,0 +after,1,graph,512,2,2.760673e+00,0,0 +after,1,graph,512,3,2.755760e+00,0,0 +after,1,graph,512,4,2.755777e+00,0,0 +after,1,graph,512,5,2.754896e+00,0,0 +after,1,graph,2048,1,1.367094e+01,0,0 +after,1,graph,2048,2,1.363071e+01,0,0 +after,1,graph,2048,3,1.361744e+01,0,0 +after,1,graph,2048,4,1.367384e+01,0,0 +after,1,graph,2048,5,1.363570e+01,0,0 +before,1,conditional,16,1,1.320584e+00,0,17189890484463169050 +before,1,conditional,16,2,1.312600e+00,0,17189890484463169050 +before,1,conditional,16,3,1.335272e+00,0,17189890484463169050 +before,1,conditional,16,4,1.299064e+00,0,17189890484463169050 +before,1,conditional,16,5,1.299000e+00,0,17189890484463169050 +before,1,conditional,64,1,3.460100e+00,0,5534067803201244807 +before,1,conditional,64,2,3.472293e+00,0,5534067803201244807 +before,1,conditional,64,3,3.464997e+00,0,5534067803201244807 +before,1,conditional,64,4,3.491061e+00,0,5534067803201244807 +before,1,conditional,64,5,3.488709e+00,0,5534067803201244807 +before,1,conditional,256,1,1.304128e+01,0,12517723600315101147 +before,1,conditional,256,2,1.298134e+01,0,12517723600315101147 +before,1,conditional,256,3,1.295209e+01,0,12517723600315101147 +before,1,conditional,256,4,1.292459e+01,0,12517723600315101147 +before,1,conditional,256,5,1.296627e+01,0,12517723600315101147 +before,1,routing,16,1,7.548520e-01,39,16070625545712530677 +before,1,routing,16,2,7.355240e-01,39,16070625545712530677 +before,1,routing,16,3,7.311090e-01,39,16070625545712530677 +before,1,routing,16,4,7.602280e-01,39,16070625545712530677 +before,1,routing,16,5,7.298280e-01,39,16070625545712530677 +before,1,routing,64,1,2.123021e+00,50,6989942321493789781 +before,1,routing,64,2,2.140061e+00,50,6989942321493789781 +before,1,routing,64,3,2.128540e+00,50,6989942321493789781 +before,1,routing,64,4,2.127500e+00,50,6989942321493789781 +before,1,routing,64,5,2.183181e+00,50,6989942321493789781 +before,1,routing,256,1,2.271334e+01,53,4706122369782581589 +before,1,routing,256,2,2.268252e+01,53,4706122369782581589 +before,1,routing,256,3,2.257965e+01,53,4706122369782581589 +before,1,routing,256,4,2.254996e+01,53,4706122369782581589 +before,1,routing,256,5,2.262577e+01,53,4706122369782581589 +before,1,graph,128,1,1.055271e+00,0,0 +before,1,graph,128,2,1.055574e+00,0,0 +before,1,graph,128,3,1.055542e+00,0,0 +before,1,graph,128,4,1.056822e+00,0,0 +before,1,graph,128,5,1.063623e+00,0,0 +before,1,graph,512,1,8.025839e+00,0,0 +before,1,graph,512,2,8.012272e+00,0,0 +before,1,graph,512,3,8.020752e+00,0,0 +before,1,graph,512,4,8.013183e+00,0,0 +before,1,graph,512,5,8.011600e+00,0,0 +before,1,graph,2048,1,6.381551e+01,0,0 +before,1,graph,2048,2,6.374425e+01,0,0 +before,1,graph,2048,3,6.383209e+01,0,0 +before,1,graph,2048,4,6.398310e+01,0,0 +before,1,graph,2048,5,6.356123e+01,0,0 +before,2,conditional,16,1,1.311368e+00,0,17189890484463169050 +before,2,conditional,16,2,1.308216e+00,0,17189890484463169050 +before,2,conditional,16,3,1.298376e+00,0,17189890484463169050 +before,2,conditional,16,4,1.292280e+00,0,17189890484463169050 +before,2,conditional,16,5,1.315927e+00,0,17189890484463169050 +before,2,conditional,64,1,3.516133e+00,0,5534067803201244807 +before,2,conditional,64,2,3.463557e+00,0,5534067803201244807 +before,2,conditional,64,3,3.467364e+00,0,5534067803201244807 +before,2,conditional,64,4,3.465428e+00,0,5534067803201244807 +before,2,conditional,64,5,3.457972e+00,0,5534067803201244807 +before,2,conditional,256,1,1.292595e+01,0,12517723600315101147 +before,2,conditional,256,2,1.313766e+01,0,12517723600315101147 +before,2,conditional,256,3,1.329158e+01,0,12517723600315101147 +before,2,conditional,256,4,1.316542e+01,0,12517723600315101147 +before,2,conditional,256,5,1.318270e+01,0,12517723600315101147 +before,2,routing,16,1,7.600210e-01,39,16070625545712530677 +before,2,routing,16,2,7.410450e-01,39,16070625545712530677 +before,2,routing,16,3,7.357490e-01,39,16070625545712530677 +before,2,routing,16,4,7.395890e-01,39,16070625545712530677 +before,2,routing,16,5,7.460210e-01,39,16070625545712530677 +before,2,routing,64,1,2.110636e+00,50,6989942321493789781 +before,2,routing,64,2,2.156813e+00,50,6989942321493789781 +before,2,routing,64,3,2.122141e+00,50,6989942321493789781 +before,2,routing,64,4,2.121805e+00,50,6989942321493789781 +before,2,routing,64,5,2.142317e+00,50,6989942321493789781 +before,2,routing,256,1,2.378334e+01,53,4706122369782581589 +before,2,routing,256,2,2.423226e+01,53,4706122369782581589 +before,2,routing,256,3,2.421312e+01,53,4706122369782581589 +before,2,routing,256,4,2.329428e+01,53,4706122369782581589 +before,2,routing,256,5,2.381953e+01,53,4706122369782581589 +before,2,graph,128,1,1.047526e+00,0,0 +before,2,graph,128,2,1.047398e+00,0,0 +before,2,graph,128,3,1.047974e+00,0,0 +before,2,graph,128,4,1.046886e+00,0,0 +before,2,graph,128,5,1.047398e+00,0,0 +before,2,graph,512,1,7.407964e+00,0,0 +before,2,graph,512,2,7.354556e+00,0,0 +before,2,graph,512,3,7.355772e+00,0,0 +before,2,graph,512,4,7.353163e+00,0,0 +before,2,graph,512,5,7.357116e+00,0,0 +before,2,graph,2048,1,6.340330e+01,0,0 +before,2,graph,2048,2,6.339636e+01,0,0 +before,2,graph,2048,3,6.325388e+01,0,0 +before,2,graph,2048,4,6.324548e+01,0,0 +before,2,graph,2048,5,6.330438e+01,0,0 +after,2,conditional,16,1,8.750770e-01,0,17189890484463169050 +after,2,conditional,16,2,8.446610e-01,0,17189890484463169050 +after,2,conditional,16,3,8.595090e-01,0,17189890484463169050 +after,2,conditional,16,4,8.445010e-01,0,17189890484463169050 +after,2,conditional,16,5,8.446130e-01,0,17189890484463169050 +after,2,conditional,64,1,2.040076e+00,0,5534067803201244807 +after,2,conditional,64,2,2.049916e+00,0,5534067803201244807 +after,2,conditional,64,3,2.050620e+00,0,5534067803201244807 +after,2,conditional,64,4,2.073117e+00,0,5534067803201244807 +after,2,conditional,64,5,2.060972e+00,0,5534067803201244807 +after,2,conditional,256,1,7.200747e+00,0,12517723600315101147 +after,2,conditional,256,2,7.319788e+00,0,12517723600315101147 +after,2,conditional,256,3,7.299260e+00,0,12517723600315101147 +after,2,conditional,256,4,7.339387e+00,0,12517723600315101147 +after,2,conditional,256,5,7.366859e+00,0,12517723600315101147 +after,2,routing,16,1,7.799250e-01,39,16070625545712530677 +after,2,routing,16,2,7.323400e-01,39,16070625545712530677 +after,2,routing,16,3,7.374290e-01,39,16070625545712530677 +after,2,routing,16,4,7.230600e-01,39,16070625545712530677 +after,2,routing,16,5,7.264680e-01,39,16070625545712530677 +after,2,routing,64,1,2.146940e+00,50,6989942321493789781 +after,2,routing,64,2,2.128189e+00,50,6989942321493789781 +after,2,routing,64,3,2.118253e+00,50,6989942321493789781 +after,2,routing,64,4,2.123805e+00,50,6989942321493789781 +after,2,routing,64,5,2.117869e+00,50,6989942321493789781 +after,2,routing,256,1,2.415886e+01,53,4706122369782581589 +after,2,routing,256,2,2.370486e+01,53,4706122369782581589 +after,2,routing,256,3,2.302529e+01,53,4706122369782581589 +after,2,routing,256,4,2.440581e+01,53,4706122369782581589 +after,2,routing,256,5,2.404581e+01,53,4706122369782581589 +after,2,graph,128,1,5.877950e-01,0,0 +after,2,graph,128,2,5.834760e-01,0,0 +after,2,graph,128,3,5.800990e-01,0,0 +after,2,graph,128,4,5.840200e-01,0,0 +after,2,graph,128,5,5.796510e-01,0,0 +after,2,graph,512,1,2.772305e+00,0,0 +after,2,graph,512,2,2.770672e+00,0,0 +after,2,graph,512,3,2.772849e+00,0,0 +after,2,graph,512,4,2.771152e+00,0,0 +after,2,graph,512,5,2.771681e+00,0,0 +after,2,graph,2048,1,1.370909e+01,0,0 +after,2,graph,2048,2,1.367920e+01,0,0 +after,2,graph,2048,3,1.363290e+01,0,0 +after,2,graph,2048,4,1.362663e+01,0,0 +after,2,graph,2048,5,1.361746e+01,0,0 +after,3,conditional,16,1,8.766130e-01,0,17189890484463169050 +after,3,conditional,16,2,8.632690e-01,0,17189890484463169050 +after,3,conditional,16,3,8.558610e-01,0,17189890484463169050 +after,3,conditional,16,4,8.536690e-01,0,17189890484463169050 +after,3,conditional,16,5,8.426610e-01,0,17189890484463169050 +after,3,conditional,64,1,2.044637e+00,0,5534067803201244807 +after,3,conditional,64,2,2.073117e+00,0,5534067803201244807 +after,3,conditional,64,3,2.065277e+00,0,5534067803201244807 +after,3,conditional,64,4,2.091404e+00,0,5534067803201244807 +after,3,conditional,64,5,2.080893e+00,0,5534067803201244807 +after,3,conditional,256,1,7.206523e+00,0,12517723600315101147 +after,3,conditional,256,2,7.355676e+00,0,12517723600315101147 +after,3,conditional,256,3,7.347259e+00,0,12517723600315101147 +after,3,conditional,256,4,7.336476e+00,0,12517723600315101147 +after,3,conditional,256,5,7.348956e+00,0,12517723600315101147 +after,3,routing,16,1,7.604680e-01,39,16070625545712530677 +after,3,routing,16,2,7.608520e-01,39,16070625545712530677 +after,3,routing,16,3,7.440360e-01,39,16070625545712530677 +after,3,routing,16,4,7.372520e-01,39,16070625545712530677 +after,3,routing,16,5,7.330130e-01,39,16070625545712530677 +after,3,routing,64,1,2.171756e+00,50,6989942321493789781 +after,3,routing,64,2,2.162509e+00,50,6989942321493789781 +after,3,routing,64,3,2.172205e+00,50,6989942321493789781 +after,3,routing,64,4,2.182989e+00,50,6989942321493789781 +after,3,routing,64,5,2.140717e+00,50,6989942321493789781 +after,3,routing,256,1,2.386401e+01,53,4706122369782581589 +after,3,routing,256,2,2.368848e+01,53,4706122369782581589 +after,3,routing,256,3,2.387113e+01,53,4706122369782581589 +after,3,routing,256,4,2.393414e+01,53,4706122369782581589 +after,3,routing,256,5,2.401158e+01,53,4706122369782581589 +after,3,graph,128,1,5.897480e-01,0,0 +after,3,graph,128,2,5.873470e-01,0,0 +after,3,graph,128,3,5.897800e-01,0,0 +after,3,graph,128,4,5.869310e-01,0,0 +after,3,graph,128,5,5.897480e-01,0,0 +after,3,graph,512,1,2.766832e+00,0,0 +after,3,graph,512,2,2.781857e+00,0,0 +after,3,graph,512,3,2.771856e+00,0,0 +after,3,graph,512,4,2.768688e+00,0,0 +after,3,graph,512,5,2.768177e+00,0,0 +after,3,graph,2048,1,1.365733e+01,0,0 +after,3,graph,2048,2,1.362589e+01,0,0 +after,3,graph,2048,3,1.361638e+01,0,0 +after,3,graph,2048,4,1.359496e+01,0,0 +after,3,graph,2048,5,1.359997e+01,0,0 +before,3,conditional,16,1,1.337976e+00,0,17189890484463169050 +before,3,conditional,16,2,1.327864e+00,0,17189890484463169050 +before,3,conditional,16,3,1.306328e+00,0,17189890484463169050 +before,3,conditional,16,4,1.306951e+00,0,17189890484463169050 +before,3,conditional,16,5,1.309528e+00,0,17189890484463169050 +before,3,conditional,64,1,3.544629e+00,0,5534067803201244807 +before,3,conditional,64,2,3.544485e+00,0,5534067803201244807 +before,3,conditional,64,3,3.545286e+00,0,5534067803201244807 +before,3,conditional,64,4,3.557797e+00,0,5534067803201244807 +before,3,conditional,64,5,3.559877e+00,0,5534067803201244807 +before,3,conditional,256,1,1.314952e+01,0,12517723600315101147 +before,3,conditional,256,2,1.321421e+01,0,12517723600315101147 +before,3,conditional,256,3,1.323603e+01,0,12517723600315101147 +before,3,conditional,256,4,1.333650e+01,0,12517723600315101147 +before,3,conditional,256,5,1.332938e+01,0,12517723600315101147 +before,3,routing,16,1,7.513490e-01,39,16070625545712530677 +before,3,routing,16,2,7.467410e-01,39,16070625545712530677 +before,3,routing,16,3,7.327240e-01,39,16070625545712530677 +before,3,routing,16,4,7.402280e-01,39,16070625545712530677 +before,3,routing,16,5,7.210600e-01,39,16070625545712530677 +before,3,routing,64,1,2.195373e+00,50,6989942321493789781 +before,3,routing,64,2,2.168733e+00,50,6989942321493789781 +before,3,routing,64,3,2.167965e+00,50,6989942321493789781 +before,3,routing,64,4,2.132412e+00,50,6989942321493789781 +before,3,routing,64,5,2.142125e+00,50,6989942321493789781 +before,3,routing,256,1,2.440355e+01,53,4706122369782581589 +before,3,routing,256,2,2.449149e+01,53,4706122369782581589 +before,3,routing,256,3,2.452525e+01,53,4706122369782581589 +before,3,routing,256,4,2.438827e+01,53,4706122369782581589 +before,3,routing,256,5,2.383254e+01,53,4706122369782581589 +before,3,graph,128,1,1.055254e+00,0,0 +before,3,graph,128,2,1.041798e+00,0,0 +before,3,graph,128,3,1.042599e+00,0,0 +before,3,graph,128,4,1.042150e+00,0,0 +before,3,graph,128,5,1.041894e+00,0,0 +before,3,graph,512,1,7.735166e+00,0,0 +before,3,graph,512,2,7.797071e+00,0,0 +before,3,graph,512,3,7.745502e+00,0,0 +before,3,graph,512,4,7.745854e+00,0,0 +before,3,graph,512,5,7.747550e+00,0,0 +before,3,graph,2048,1,6.411347e+01,0,0 +before,3,graph,2048,2,6.414308e+01,0,0 +before,3,graph,2048,3,6.415128e+01,0,0 +before,3,graph,2048,4,6.421011e+01,0,0 +before,3,graph,2048,5,6.423814e+01,0,0 +before,4,conditional,16,1,1.353432e+00,0,17189890484463169050 +before,4,conditional,16,2,1.324040e+00,0,17189890484463169050 +before,4,conditional,16,3,1.316776e+00,0,17189890484463169050 +before,4,conditional,16,4,1.325463e+00,0,17189890484463169050 +before,4,conditional,16,5,1.318903e+00,0,17189890484463169050 +before,4,conditional,64,1,3.609478e+00,0,5534067803201244807 +before,4,conditional,64,2,3.575269e+00,0,5534067803201244807 +before,4,conditional,64,3,3.585493e+00,0,5534067803201244807 +before,4,conditional,64,4,3.580262e+00,0,5534067803201244807 +before,4,conditional,64,5,3.583973e+00,0,5534067803201244807 +before,4,conditional,256,1,1.323616e+01,0,12517723600315101147 +before,4,conditional,256,2,1.321696e+01,0,12517723600315101147 +before,4,conditional,256,3,1.326536e+01,0,12517723600315101147 +before,4,conditional,256,4,1.330144e+01,0,12517723600315101147 +before,4,conditional,256,5,1.326805e+01,0,12517723600315101147 +before,4,routing,16,1,7.509800e-01,39,16070625545712530677 +before,4,routing,16,2,7.514610e-01,39,16070625545712530677 +before,4,routing,16,3,7.296360e-01,39,16070625545712530677 +before,4,routing,16,4,7.306280e-01,39,16070625545712530677 +before,4,routing,16,5,7.242120e-01,39,16070625545712530677 +before,4,routing,64,1,2.171469e+00,50,6989942321493789781 +before,4,routing,64,2,2.138300e+00,50,6989942321493789781 +before,4,routing,64,3,2.134589e+00,50,6989942321493789781 +before,4,routing,64,4,2.137069e+00,50,6989942321493789781 +before,4,routing,64,5,2.136845e+00,50,6989942321493789781 +before,4,routing,256,1,2.423846e+01,53,4706122369782581589 +before,4,routing,256,2,2.354486e+01,53,4706122369782581589 +before,4,routing,256,3,2.335681e+01,53,4706122369782581589 +before,4,routing,256,4,2.361737e+01,53,4706122369782581589 +before,4,routing,256,5,2.404003e+01,53,4706122369782581589 +before,4,graph,128,1,1.043687e+00,0,0 +before,4,graph,128,2,1.039062e+00,0,0 +before,4,graph,128,3,1.039766e+00,0,0 +before,4,graph,128,4,1.038070e+00,0,0 +before,4,graph,128,5,1.038070e+00,0,0 +before,4,graph,512,1,8.069872e+00,0,0 +before,4,graph,512,2,8.067455e+00,0,0 +before,4,graph,512,3,8.064000e+00,0,0 +before,4,graph,512,4,8.073328e+00,0,0 +before,4,graph,512,5,8.057408e+00,0,0 +before,4,graph,2048,1,6.399382e+01,0,0 +before,4,graph,2048,2,6.407520e+01,0,0 +before,4,graph,2048,3,6.400340e+01,0,0 +before,4,graph,2048,4,6.404246e+01,0,0 +before,4,graph,2048,5,6.407012e+01,0,0 +after,4,conditional,16,1,8.792530e-01,0,17189890484463169050 +after,4,conditional,16,2,8.467730e-01,0,17189890484463169050 +after,4,conditional,16,3,8.522770e-01,0,17189890484463169050 +after,4,conditional,16,4,8.458450e-01,0,17189890484463169050 +after,4,conditional,16,5,8.366930e-01,0,17189890484463169050 +after,4,conditional,64,1,2.002476e+00,0,5534067803201244807 +after,4,conditional,64,2,2.021100e+00,0,5534067803201244807 +after,4,conditional,64,3,2.013500e+00,0,5534067803201244807 +after,4,conditional,64,4,2.025164e+00,0,5534067803201244807 +after,4,conditional,64,5,2.070668e+00,0,5534067803201244807 +after,4,conditional,256,1,7.214539e+00,0,12517723600315101147 +after,4,conditional,256,2,7.301131e+00,0,12517723600315101147 +after,4,conditional,256,3,7.315995e+00,0,12517723600315101147 +after,4,conditional,256,4,7.355772e+00,0,12517723600315101147 +after,4,conditional,256,5,7.340908e+00,0,12517723600315101147 +after,4,routing,16,1,7.540850e-01,39,16070625545712530677 +after,4,routing,16,2,7.307090e-01,39,16070625545712530677 +after,4,routing,16,3,7.324850e-01,39,16070625545712530677 +after,4,routing,16,4,7.206920e-01,39,16070625545712530677 +after,4,routing,16,5,7.388520e-01,39,16070625545712530677 +after,4,routing,64,1,2.154604e+00,50,6989942321493789781 +after,4,routing,64,2,2.149197e+00,50,6989942321493789781 +after,4,routing,64,3,2.169244e+00,50,6989942321493789781 +after,4,routing,64,4,2.149453e+00,50,6989942321493789781 +after,4,routing,64,5,2.134828e+00,50,6989942321493789781 +after,4,routing,256,1,2.373843e+01,53,4706122369782581589 +after,4,routing,256,2,2.308863e+01,53,4706122369782581589 +after,4,routing,256,3,2.353313e+01,53,4706122369782581589 +after,4,routing,256,4,2.307047e+01,53,4706122369782581589 +after,4,routing,256,5,2.295367e+01,53,4706122369782581589 +after,4,graph,128,1,5.915070e-01,0,0 +after,4,graph,128,2,5.985960e-01,0,0 +after,4,graph,128,3,5.836030e-01,0,0 +after,4,graph,128,4,5.857800e-01,0,0 +after,4,graph,128,5,5.817630e-01,0,0 +after,4,graph,512,1,2.763777e+00,0,0 +after,4,graph,512,2,2.755904e+00,0,0 +after,4,graph,512,3,2.755024e+00,0,0 +after,4,graph,512,4,2.752545e+00,0,0 +after,4,graph,512,5,2.757216e+00,0,0 +after,4,graph,2048,1,1.360366e+01,0,0 +after,4,graph,2048,2,1.356762e+01,0,0 +after,4,graph,2048,3,1.355797e+01,0,0 +after,4,graph,2048,4,1.355790e+01,0,0 +after,4,graph,2048,5,1.356413e+01,0,0 +after,5,conditional,16,1,8.710930e-01,0,17189890484463169050 +after,5,conditional,16,2,8.566290e-01,0,17189890484463169050 +after,5,conditional,16,3,8.389970e-01,0,17189890484463169050 +after,5,conditional,16,4,8.403250e-01,0,17189890484463169050 +after,5,conditional,16,5,8.478610e-01,0,17189890484463169050 +after,5,conditional,64,1,2.052780e+00,0,5534067803201244807 +after,5,conditional,64,2,2.094765e+00,0,5534067803201244807 +after,5,conditional,64,3,2.096108e+00,0,5534067803201244807 +after,5,conditional,64,4,2.076653e+00,0,5534067803201244807 +after,5,conditional,64,5,2.057564e+00,0,5534067803201244807 +after,5,conditional,256,1,7.150043e+00,0,12517723600315101147 +after,5,conditional,256,2,7.354348e+00,0,12517723600315101147 +after,5,conditional,256,3,7.337691e+00,0,12517723600315101147 +after,5,conditional,256,4,7.352988e+00,0,12517723600315101147 +after,5,conditional,256,5,7.398604e+00,0,12517723600315101147 +after,5,routing,16,1,7.551090e-01,39,16070625545712530677 +after,5,routing,16,2,7.472050e-01,39,16070625545712530677 +after,5,routing,16,3,7.321330e-01,39,16070625545712530677 +after,5,routing,16,4,7.410450e-01,39,16070625545712530677 +after,5,routing,16,5,7.256840e-01,39,16070625545712530677 +after,5,routing,64,1,2.178445e+00,50,6989942321493789781 +after,5,routing,64,2,2.145805e+00,50,6989942321493789781 +after,5,routing,64,3,2.136268e+00,50,6989942321493789781 +after,5,routing,64,4,2.118205e+00,50,6989942321493789781 +after,5,routing,64,5,2.131693e+00,50,6989942321493789781 +after,5,routing,256,1,2.291348e+01,53,4706122369782581589 +after,5,routing,256,2,2.251340e+01,53,4706122369782581589 +after,5,routing,256,3,2.356123e+01,53,4706122369782581589 +after,5,routing,256,4,2.325862e+01,53,4706122369782581589 +after,5,routing,256,5,2.316215e+01,53,4706122369782581589 +after,5,graph,128,1,5.846760e-01,0,0 +after,5,graph,128,2,5.865950e-01,0,0 +after,5,graph,128,3,6.014920e-01,0,0 +after,5,graph,128,4,5.827870e-01,0,0 +after,5,graph,128,5,5.929800e-01,0,0 +after,5,graph,512,1,2.760928e+00,0,0 +after,5,graph,512,2,2.762065e+00,0,0 +after,5,graph,512,3,2.761168e+00,0,0 +after,5,graph,512,4,2.761904e+00,0,0 +after,5,graph,512,5,2.757841e+00,0,0 +after,5,graph,2048,1,1.376055e+01,0,0 +after,5,graph,2048,2,1.376827e+01,0,0 +after,5,graph,2048,3,1.374362e+01,0,0 +after,5,graph,2048,4,1.379226e+01,0,0 +after,5,graph,2048,5,1.373298e+01,0,0 +before,5,conditional,16,1,1.337656e+00,0,17189890484463169050 +before,5,conditional,16,2,1.321448e+00,0,17189890484463169050 +before,5,conditional,16,3,1.321576e+00,0,17189890484463169050 +before,5,conditional,16,4,1.311784e+00,0,17189890484463169050 +before,5,conditional,16,5,1.347112e+00,0,17189890484463169050 +before,5,conditional,64,1,3.602133e+00,0,5534067803201244807 +before,5,conditional,64,2,3.567445e+00,0,5534067803201244807 +before,5,conditional,64,3,3.550325e+00,0,5534067803201244807 +before,5,conditional,64,4,3.572677e+00,0,5534067803201244807 +before,5,conditional,64,5,3.585141e+00,0,5534067803201244807 +before,5,conditional,256,1,1.325883e+01,0,12517723600315101147 +before,5,conditional,256,2,1.321573e+01,0,12517723600315101147 +before,5,conditional,256,3,1.326851e+01,0,12517723600315101147 +before,5,conditional,256,4,1.320801e+01,0,12517723600315101147 +before,5,conditional,256,5,1.320579e+01,0,12517723600315101147 +before,5,routing,16,1,7.616850e-01,39,16070625545712530677 +before,5,routing,16,2,7.428840e-01,39,16070625545712530677 +before,5,routing,16,3,7.432520e-01,39,16070625545712530677 +before,5,routing,16,4,7.355720e-01,39,16070625545712530677 +before,5,routing,16,5,7.242600e-01,39,16070625545712530677 +before,5,routing,64,1,2.129101e+00,50,6989942321493789781 +before,5,routing,64,2,2.153756e+00,50,6989942321493789781 +before,5,routing,64,3,2.135004e+00,50,6989942321493789781 +before,5,routing,64,4,2.113261e+00,50,6989942321493789781 +before,5,routing,64,5,2.164141e+00,50,6989942321493789781 +before,5,routing,256,1,2.425051e+01,53,4706122369782581589 +before,5,routing,256,2,2.375843e+01,53,4706122369782581589 +before,5,routing,256,3,2.412704e+01,53,4706122369782581589 +before,5,routing,256,4,2.349067e+01,53,4706122369782581589 +before,5,routing,256,5,2.371611e+01,53,4706122369782581589 +before,5,graph,128,1,1.050647e+00,0,0 +before,5,graph,128,2,1.061654e+00,0,0 +before,5,graph,128,3,1.048742e+00,0,0 +before,5,graph,128,4,1.049110e+00,0,0 +before,5,graph,128,5,1.050231e+00,0,0 +before,5,graph,512,1,7.980127e+00,0,0 +before,5,graph,512,2,7.967791e+00,0,0 +before,5,graph,512,3,7.954784e+00,0,0 +before,5,graph,512,4,7.967167e+00,0,0 +before,5,graph,512,5,7.964623e+00,0,0 +before,5,graph,2048,1,6.765680e+01,0,0 +before,5,graph,2048,2,6.764138e+01,0,0 +before,5,graph,2048,3,6.762527e+01,0,0 +before,5,graph,2048,4,6.753306e+01,0,0 +before,5,graph,2048,5,6.764018e+01,0,0 +before,6,conditional,16,1,1.340424e+00,0,17189890484463169050 +before,6,conditional,16,2,1.324472e+00,0,17189890484463169050 +before,6,conditional,16,3,1.342264e+00,0,17189890484463169050 +before,6,conditional,16,4,1.311784e+00,0,17189890484463169050 +before,6,conditional,16,5,1.303320e+00,0,17189890484463169050 +before,6,conditional,64,1,3.558021e+00,0,5534067803201244807 +before,6,conditional,64,2,3.558261e+00,0,5534067803201244807 +before,6,conditional,64,3,3.598693e+00,0,5534067803201244807 +before,6,conditional,64,4,3.573894e+00,0,5534067803201244807 +before,6,conditional,64,5,3.578597e+00,0,5534067803201244807 +before,6,conditional,256,1,1.313899e+01,0,12517723600315101147 +before,6,conditional,256,2,1.316576e+01,0,12517723600315101147 +before,6,conditional,256,3,1.320525e+01,0,12517723600315101147 +before,6,conditional,256,4,1.335163e+01,0,12517723600315101147 +before,6,conditional,256,5,1.326822e+01,0,12517723600315101147 +before,6,routing,16,1,7.531080e-01,39,16070625545712530677 +before,6,routing,16,2,7.426120e-01,39,16070625545712530677 +before,6,routing,16,3,7.383240e-01,39,16070625545712530677 +before,6,routing,16,4,7.240850e-01,39,16070625545712530677 +before,6,routing,16,5,7.395240e-01,39,16070625545712530677 +before,6,routing,64,1,2.135421e+00,50,6989942321493789781 +before,6,routing,64,2,2.113997e+00,50,6989942321493789781 +before,6,routing,64,3,2.162253e+00,50,6989942321493789781 +before,6,routing,64,4,2.120476e+00,50,6989942321493789781 +before,6,routing,64,5,2.129197e+00,50,6989942321493789781 +before,6,routing,256,1,2.410171e+01,53,4706122369782581589 +before,6,routing,256,2,2.337457e+01,53,4706122369782581589 +before,6,routing,256,3,2.428805e+01,53,4706122369782581589 +before,6,routing,256,4,2.329342e+01,53,4706122369782581589 +before,6,routing,256,5,2.399003e+01,53,4706122369782581589 +before,6,graph,128,1,1.056326e+00,0,0 +before,6,graph,128,2,1.038054e+00,0,0 +before,6,graph,128,3,1.035623e+00,0,0 +before,6,graph,128,4,1.036742e+00,0,0 +before,6,graph,128,5,1.035334e+00,0,0 +before,6,graph,512,1,8.069440e+00,0,0 +before,6,graph,512,2,8.069280e+00,0,0 +before,6,graph,512,3,8.060112e+00,0,0 +before,6,graph,512,4,8.073504e+00,0,0 +before,6,graph,512,5,8.066336e+00,0,0 +before,6,graph,2048,1,6.772909e+01,0,0 +before,6,graph,2048,2,6.769915e+01,0,0 +before,6,graph,2048,3,6.771519e+01,0,0 +before,6,graph,2048,4,6.780418e+01,0,0 +before,6,graph,2048,5,6.760221e+01,0,0 +after,6,conditional,16,1,8.664210e-01,0,17189890484463169050 +after,6,conditional,16,2,8.560050e-01,0,17189890484463169050 +after,6,conditional,16,3,8.332850e-01,0,17189890484463169050 +after,6,conditional,16,4,8.301970e-01,0,17189890484463169050 +after,6,conditional,16,5,8.354130e-01,0,17189890484463169050 +after,6,conditional,64,1,2.045260e+00,0,5534067803201244807 +after,6,conditional,64,2,2.052204e+00,0,5534067803201244807 +after,6,conditional,64,3,2.064684e+00,0,5534067803201244807 +after,6,conditional,64,4,2.062621e+00,0,5534067803201244807 +after,6,conditional,64,5,2.082876e+00,0,5534067803201244807 +after,6,conditional,256,1,7.126186e+00,0,12517723600315101147 +after,6,conditional,256,2,7.224683e+00,0,12517723600315101147 +after,6,conditional,256,3,7.265771e+00,0,12517723600315101147 +after,6,conditional,256,4,7.315915e+00,0,12517723600315101147 +after,6,conditional,256,5,7.270587e+00,0,12517723600315101147 +after,6,routing,16,1,7.433480e-01,39,16070625545712530677 +after,6,routing,16,2,7.257480e-01,39,16070625545712530677 +after,6,routing,16,3,7.321330e-01,39,16070625545712530677 +after,6,routing,16,4,7.130120e-01,39,16070625545712530677 +after,6,routing,16,5,7.223720e-01,39,16070625545712530677 +after,6,routing,64,1,2.114717e+00,50,6989942321493789781 +after,6,routing,64,2,2.124205e+00,50,6989942321493789781 +after,6,routing,64,3,2.123021e+00,50,6989942321493789781 +after,6,routing,64,4,2.133085e+00,50,6989942321493789781 +after,6,routing,64,5,2.113501e+00,50,6989942321493789781 +after,6,routing,256,1,2.316545e+01,53,4706122369782581589 +after,6,routing,256,2,2.306028e+01,53,4706122369782581589 +after,6,routing,256,3,2.332209e+01,53,4706122369782581589 +after,6,routing,256,4,2.277548e+01,53,4706122369782581589 +after,6,routing,256,5,2.318337e+01,53,4706122369782581589 +after,6,graph,128,1,6.036840e-01,0,0 +after,6,graph,128,2,5.995880e-01,0,0 +after,6,graph,128,3,6.025790e-01,0,0 +after,6,graph,128,4,6.024520e-01,0,0 +after,6,graph,128,5,6.000990e-01,0,0 +after,6,graph,512,1,2.772641e+00,0,0 +after,6,graph,512,2,2.769904e+00,0,0 +after,6,graph,512,3,2.765137e+00,0,0 +after,6,graph,512,4,2.768416e+00,0,0 +after,6,graph,512,5,2.781473e+00,0,0 +after,6,graph,2048,1,1.374325e+01,0,0 +after,6,graph,2048,2,1.373176e+01,0,0 +after,6,graph,2048,3,1.371941e+01,0,0 +after,6,graph,2048,4,1.372325e+01,0,0 +after,6,graph,2048,5,1.370938e+01,0,0 +after,7,conditional,16,1,8.550770e-01,0,17189890484463169050 +after,7,conditional,16,2,8.425330e-01,0,17189890484463169050 +after,7,conditional,16,3,8.384050e-01,0,17189890484463169050 +after,7,conditional,16,4,8.403730e-01,0,17189890484463169050 +after,7,conditional,16,5,8.297810e-01,0,17189890484463169050 +after,7,conditional,64,1,2.110892e+00,0,5534067803201244807 +after,7,conditional,64,2,2.047244e+00,0,5534067803201244807 +after,7,conditional,64,3,2.035708e+00,0,5534067803201244807 +after,7,conditional,64,4,2.035372e+00,0,5534067803201244807 +after,7,conditional,64,5,2.062652e+00,0,5534067803201244807 +after,7,conditional,256,1,7.193354e+00,0,12517723600315101147 +after,7,conditional,256,2,7.167771e+00,0,12517723600315101147 +after,7,conditional,256,3,7.203355e+00,0,12517723600315101147 +after,7,conditional,256,4,7.171851e+00,0,12517723600315101147 +after,7,conditional,256,5,7.199547e+00,0,12517723600315101147 +after,7,routing,16,1,7.493480e-01,39,16070625545712530677 +after,7,routing,16,2,7.537960e-01,39,16070625545712530677 +after,7,routing,16,3,7.389640e-01,39,16070625545712530677 +after,7,routing,16,4,7.432040e-01,39,16070625545712530677 +after,7,routing,16,5,7.317160e-01,39,16070625545712530677 +after,7,routing,64,1,2.128236e+00,50,6989942321493789781 +after,7,routing,64,2,2.146493e+00,50,6989942321493789781 +after,7,routing,64,3,2.181421e+00,50,6989942321493789781 +after,7,routing,64,4,2.153389e+00,50,6989942321493789781 +after,7,routing,64,5,2.156653e+00,50,6989942321493789781 +after,7,routing,256,1,2.358542e+01,53,4706122369782581589 +after,7,routing,256,2,2.372440e+01,53,4706122369782581589 +after,7,routing,256,3,2.354459e+01,53,4706122369782581589 +after,7,routing,256,4,2.401120e+01,53,4706122369782581589 +after,7,routing,256,5,2.449391e+01,53,4706122369782581589 +after,7,graph,128,1,5.876200e-01,0,0 +after,7,graph,128,2,5.853470e-01,0,0 +after,7,graph,128,3,5.881640e-01,0,0 +after,7,graph,128,4,5.852350e-01,0,0 +after,7,graph,128,5,5.884840e-01,0,0 +after,7,graph,512,1,2.783408e+00,0,0 +after,7,graph,512,2,2.750353e+00,0,0 +after,7,graph,512,3,2.751056e+00,0,0 +after,7,graph,512,4,2.751921e+00,0,0 +after,7,graph,512,5,2.751344e+00,0,0 +after,7,graph,2048,1,1.364688e+01,0,0 +after,7,graph,2048,2,1.364687e+01,0,0 +after,7,graph,2048,3,1.363078e+01,0,0 +after,7,graph,2048,4,1.360966e+01,0,0 +after,7,graph,2048,5,1.360384e+01,0,0 +before,7,conditional,16,1,1.336760e+00,0,17189890484463169050 +before,7,conditional,16,2,1.330008e+00,0,17189890484463169050 +before,7,conditional,16,3,1.336680e+00,0,17189890484463169050 +before,7,conditional,16,4,1.307879e+00,0,17189890484463169050 +before,7,conditional,16,5,1.307784e+00,0,17189890484463169050 +before,7,conditional,64,1,3.578981e+00,0,5534067803201244807 +before,7,conditional,64,2,3.554853e+00,0,5534067803201244807 +before,7,conditional,64,3,3.583926e+00,0,5534067803201244807 +before,7,conditional,64,4,3.576581e+00,0,5534067803201244807 +before,7,conditional,64,5,3.580422e+00,0,5534067803201244807 +before,7,conditional,256,1,1.336214e+01,0,12517723600315101147 +before,7,conditional,256,2,1.337782e+01,0,12517723600315101147 +before,7,conditional,256,3,1.343814e+01,0,12517723600315101147 +before,7,conditional,256,4,1.331555e+01,0,12517723600315101147 +before,7,conditional,256,5,1.339382e+01,0,12517723600315101147 +before,7,routing,16,1,7.686450e-01,39,16070625545712530677 +before,7,routing,16,2,7.381810e-01,39,16070625545712530677 +before,7,routing,16,3,7.359090e-01,39,16070625545712530677 +before,7,routing,16,4,7.320530e-01,39,16070625545712530677 +before,7,routing,16,5,7.367880e-01,39,16070625545712530677 +before,7,routing,64,1,2.179917e+00,50,6989942321493789781 +before,7,routing,64,2,2.161869e+00,50,6989942321493789781 +before,7,routing,64,3,2.175853e+00,50,6989942321493789781 +before,7,routing,64,4,2.186781e+00,50,6989942321493789781 +before,7,routing,64,5,2.173324e+00,50,6989942321493789781 +before,7,routing,256,1,2.389361e+01,53,4706122369782581589 +before,7,routing,256,2,2.458610e+01,53,4706122369782581589 +before,7,routing,256,3,2.411501e+01,53,4706122369782581589 +before,7,routing,256,4,2.306423e+01,53,4706122369782581589 +before,7,routing,256,5,2.425037e+01,53,4706122369782581589 +before,7,graph,128,1,1.045222e+00,0,0 +before,7,graph,128,2,1.041478e+00,0,0 +before,7,graph,128,3,1.044374e+00,0,0 +before,7,graph,128,4,1.048342e+00,0,0 +before,7,graph,128,5,1.043895e+00,0,0 +before,7,graph,512,1,7.107051e+00,0,0 +before,7,graph,512,2,7.142826e+00,0,0 +before,7,graph,512,3,7.102298e+00,0,0 +before,7,graph,512,4,7.106810e+00,0,0 +before,7,graph,512,5,7.100379e+00,0,0 +before,7,graph,2048,1,6.331751e+01,0,0 +before,7,graph,2048,2,6.327890e+01,0,0 +before,7,graph,2048,3,6.338170e+01,0,0 +before,7,graph,2048,4,6.319262e+01,0,0 +before,7,graph,2048,5,6.322039e+01,0,0 +before,8,conditional,16,1,1.325432e+00,0,17189890484463169050 +before,8,conditional,16,2,1.319976e+00,0,17189890484463169050 +before,8,conditional,16,3,1.331464e+00,0,17189890484463169050 +before,8,conditional,16,4,1.350024e+00,0,17189890484463169050 +before,8,conditional,16,5,1.326280e+00,0,17189890484463169050 +before,8,conditional,64,1,3.526005e+00,0,5534067803201244807 +before,8,conditional,64,2,3.515940e+00,0,5534067803201244807 +before,8,conditional,64,3,3.544918e+00,0,5534067803201244807 +before,8,conditional,64,4,3.523893e+00,0,5534067803201244807 +before,8,conditional,64,5,3.523397e+00,0,5534067803201244807 +before,8,conditional,256,1,1.310019e+01,0,12517723600315101147 +before,8,conditional,256,2,1.314395e+01,0,12517723600315101147 +before,8,conditional,256,3,1.324213e+01,0,12517723600315101147 +before,8,conditional,256,4,1.323078e+01,0,12517723600315101147 +before,8,conditional,256,5,1.307152e+01,0,12517723600315101147 +before,8,routing,16,1,7.357960e-01,39,16070625545712530677 +before,8,routing,16,2,7.810450e-01,39,16070625545712530677 +before,8,routing,16,3,7.175400e-01,39,16070625545712530677 +before,8,routing,16,4,7.343090e-01,39,16070625545712530677 +before,8,routing,16,5,7.218600e-01,39,16070625545712530677 +before,8,routing,64,1,2.155852e+00,50,6989942321493789781 +before,8,routing,64,2,2.121820e+00,50,6989942321493789781 +before,8,routing,64,3,2.156828e+00,50,6989942321493789781 +before,8,routing,64,4,2.136557e+00,50,6989942321493789781 +before,8,routing,64,5,2.132749e+00,50,6989942321493789781 +before,8,routing,256,1,2.358275e+01,53,4706122369782581589 +before,8,routing,256,2,2.404870e+01,53,4706122369782581589 +before,8,routing,256,3,2.455579e+01,53,4706122369782581589 +before,8,routing,256,4,2.359651e+01,53,4706122369782581589 +before,8,routing,256,5,2.382635e+01,53,4706122369782581589 +before,8,graph,128,1,1.044566e+00,0,0 +before,8,graph,128,2,1.035222e+00,0,0 +before,8,graph,128,3,1.037622e+00,0,0 +before,8,graph,128,4,1.034390e+00,0,0 +before,8,graph,128,5,1.035030e+00,0,0 +before,8,graph,512,1,7.824175e+00,0,0 +before,8,graph,512,2,7.796750e+00,0,0 +before,8,graph,512,3,7.782062e+00,0,0 +before,8,graph,512,4,7.773886e+00,0,0 +before,8,graph,512,5,7.771518e+00,0,0 +before,8,graph,2048,1,6.798407e+01,0,0 +before,8,graph,2048,2,6.799344e+01,0,0 +before,8,graph,2048,3,6.796472e+01,0,0 +before,8,graph,2048,4,6.796799e+01,0,0 +before,8,graph,2048,5,6.782314e+01,0,0 +after,8,conditional,16,1,8.749010e-01,0,17189890484463169050 +after,8,conditional,16,2,8.521330e-01,0,17189890484463169050 +after,8,conditional,16,3,8.483090e-01,0,17189890484463169050 +after,8,conditional,16,4,8.729490e-01,0,17189890484463169050 +after,8,conditional,16,5,8.291250e-01,0,17189890484463169050 +after,8,conditional,64,1,2.077420e+00,0,5534067803201244807 +after,8,conditional,64,2,2.064381e+00,0,5534067803201244807 +after,8,conditional,64,3,2.054332e+00,0,5534067803201244807 +after,8,conditional,64,4,2.075437e+00,0,5534067803201244807 +after,8,conditional,64,5,2.076652e+00,0,5534067803201244807 +after,8,conditional,256,1,7.217819e+00,0,12517723600315101147 +after,8,conditional,256,2,7.324252e+00,0,12517723600315101147 +after,8,conditional,256,3,7.407388e+00,0,12517723600315101147 +after,8,conditional,256,4,7.342475e+00,0,12517723600315101147 +after,8,conditional,256,5,7.406444e+00,0,12517723600315101147 +after,8,routing,16,1,7.636040e-01,39,16070625545712530677 +after,8,routing,16,2,7.383880e-01,39,16070625545712530677 +after,8,routing,16,3,7.427400e-01,39,16070625545712530677 +after,8,routing,16,4,7.276360e-01,39,16070625545712530677 +after,8,routing,16,5,7.305810e-01,39,16070625545712530677 +after,8,routing,64,1,2.178556e+00,50,6989942321493789781 +after,8,routing,64,2,2.168125e+00,50,6989942321493789781 +after,8,routing,64,3,2.159869e+00,50,6989942321493789781 +after,8,routing,64,4,2.150061e+00,50,6989942321493789781 +after,8,routing,64,5,2.143261e+00,50,6989942321493789781 +after,8,routing,256,1,2.341676e+01,53,4706122369782581589 +after,8,routing,256,2,2.385213e+01,53,4706122369782581589 +after,8,routing,256,3,2.318926e+01,53,4706122369782581589 +after,8,routing,256,4,2.270564e+01,53,4706122369782581589 +after,8,routing,256,5,2.383584e+01,53,4706122369782581589 +after,8,graph,128,1,5.929310e-01,0,0 +after,8,graph,128,2,5.868030e-01,0,0 +after,8,graph,128,3,5.916360e-01,0,0 +after,8,graph,128,4,5.886270e-01,0,0 +after,8,graph,128,5,5.856840e-01,0,0 +after,8,graph,512,1,2.795873e+00,0,0 +after,8,graph,512,2,2.769696e+00,0,0 +after,8,graph,512,3,2.762881e+00,0,0 +after,8,graph,512,4,2.765712e+00,0,0 +after,8,graph,512,5,2.765537e+00,0,0 +after,8,graph,2048,1,1.366250e+01,0,0 +after,8,graph,2048,2,1.362906e+01,0,0 +after,8,graph,2048,3,1.365571e+01,0,0 +after,8,graph,2048,4,1.366805e+01,0,0 +after,8,graph,2048,5,1.361725e+01,0,0 diff --git a/.agent/plans/routing-simplification.md b/.agent/plans/routing-simplification.md new file mode 100644 index 0000000000..31ffc0c428 --- /dev/null +++ b/.agent/plans/routing-simplification.md @@ -0,0 +1,37 @@ +# Simplify routing without changing its heuristics + +Status: complete. + +## Outcome and decisions + +Mapping skips repair for equal layouts and updates RoutingBundle directly. +WireInfos derives membership from its inverse vectors. Graph traversal borrows +adjacency lists; unused distance-matrix and graph APIs are removed. The mapping +boundary diagnoses qubit-carrying calls, multi-block entry functions, and +invalid options. Classical calls remain supported. Documentation describes the +dense temporary workspace and its later cleanup. + +Branch convergence, voting, A* ordering, and traversal semantics are unchanged. +Payload control-flow legalization remains owned by #2162. Supported structured +regions already have single-block verifiers; the entry-function restriction is +checked by mapping. No payload capability checks were duplicated. + +The optional mapping benchmark and its data, figure, and reproduction steps are +in `.agent/benchmarks/routing/README.md`. Identical mapped-IR hashes and SWAP +counts accompany a 1.56–1.82 times speedup for unchanged branch layouts. The +routing workload is essentially unchanged. Graph measurements are synthetic. + +## Validation + +Release builds passed 104 mapping tests, 192 QCO utility tests, and 182 compiler +tests. `uvx nox -s lint` passed. Full changed-file C++ lint passed with +`uvx nox -s cpp-lint -- 91a9e0ba514af938680cdd394d6d63195872dc9a`. + +A disposable combination with #2162 at `1c5d4cc66` applied cleanly using +three-way patch application. All 100 existing mapping tests passed there. The +combined compiler suite passed 193 of 195 tests. Its two failing tests, +`PayloadControlRejectsLinearStateInGenericSCFControl` and +`PayloadControlRejectsUnstructuredCFG`, fail during parsing because they +allocate qubits outside the entry block. Both failures were reproduced with the +routing changes removed, before the mapping pass runs. Updating those #2162 +inputs is outside this PR's scope. diff --git a/mlir/include/mlir/Dialect/QCO/Transforms/Passes.td b/mlir/include/mlir/Dialect/QCO/Transforms/Passes.td index 10e9f66175..5b457f23aa 100644 --- a/mlir/include/mlir/Dialect/QCO/Transforms/Passes.td +++ b/mlir/include/mlir/Dialect/QCO/Transforms/Passes.td @@ -132,8 +132,9 @@ def MappingPass : Pass<"place-and-route", "mlir::ModuleOp"> { 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. 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 + complete target. The pass materializes all target sites as routing workspace + and carries them through structured control flow. Cleanup after mapping + removes unused sites. 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. @@ -168,7 +169,7 @@ def MappingPass : Pass<"place-and-route", "mlir::ModuleOp"> { let options = [Option<"nlookahead", "nlookahead", "std::size_t", "1", "The number of lookahead steps.">, Option<"alpha", "alpha", "float", "1.0F", - "The alpha factor in the cost function. Must be > 0.">, + "The alpha cost factor. Must be finite and > 0.">, Option<"lambda", "lambda", "float", "0.5F", "The lambda factor in the cost function.">, Option<"niterations", "niterations", "std::size_t", "1", diff --git a/mlir/include/mlir/Dialect/QCO/Utils/Graph.h b/mlir/include/mlir/Dialect/QCO/Utils/Graph.h index 6cd25c8144..6de747b660 100644 --- a/mlir/include/mlir/Dialect/QCO/Utils/Graph.h +++ b/mlir/include/mlir/Dialect/QCO/Utils/Graph.h @@ -11,13 +11,11 @@ #pragma once #include -#include +#include +#include #include -#include -#include #include -#include #include #include #include @@ -27,40 +25,11 @@ namespace mlir::qco { /// A directed graph. class Graph { public: - class DistanceMatrix { - SmallVector data_; - size_t n_{}; - - public: - /// Initialize distance matrix, where all entries are filled with `v`. - explicit DistanceMatrix(size_t n, size_t v) : n_(n), data_(n * n, v) {} - - /// Return the i-th row. - MutableArrayRef operator[](size_t i) { - assert(i < n_ && "row index out of bounds"); - return MutableArrayRef(data_).slice(i * n_, n_); - } - - /// Return the i-th row. - ArrayRef operator[](size_t i) const { - assert(i < n_ && "row index out of bounds"); - return ArrayRef(data_).slice(i * n_, n_); - } - }; - - /// Construct an empty graph. - Graph() = default; - /// Construct graph from node identifiers. explicit Graph(ArrayRef nodes) { for_each(nodes, [this](const auto u) { std::ignore = adj_[u]; }); } - /// Construct graph from edge set. - explicit Graph(const llvm::DenseSet>& edges) { - for_each(edges, [this](const auto& e) { addEdge(e.first, e.second); }); - } - /// Add a directed edge to the internal representation of the graph. /// Implicitly adds nodes. void addEdge(size_t u, size_t v); @@ -71,32 +40,14 @@ class Graph { /// Return the nodes. [[nodiscard]] SmallVector getNodes() const; - /// Return the number of nodes. - [[nodiscard]] size_t getNumNodes() const { return adj_.size(); } - /// Return the degree of a node. [[nodiscard]] size_t getDegree(const size_t id) const { return adj_.at(id).size(); } - /// Return the max degree of the graph. - [[nodiscard]] size_t getMaxDegree() const; - - /// Return true if the graph has no nodes and edges. - [[nodiscard]] bool empty() const { return adj_.empty(); } - - /// Clear the graph. - void clear() { adj_.clear(); } - /// Remove the edges from the graph. Keep the nodes. void clearEdges(); - /// Return the minimum distance matrix of the graph by implementing the - /// Floyd-Warshall Algorithm - /// (https://en.wikipedia.org/wiki/Floyd–Warshall_algorithm) where dist[i][j] - /// denotes the distance between i and j. - [[nodiscard]] Graph::DistanceMatrix getDistMatrix() const; - /// Return cycle in graph or `std::nullopt` if none exists. /// Implements an iterative depth-first search inspired by LLVM's SCC /// utilities. For a cycle [A, B, C, A], the function returns [A, B, C]. diff --git a/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp b/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp index 5a07f6378e..ce982f0988 100644 --- a/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp +++ b/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp @@ -18,6 +18,7 @@ #include "mlir/Dialect/QCO/IR/QCODialect.h" #include "mlir/Dialect/QCO/IR/QCOInterfaces.h" #include "mlir/Dialect/QCO/IR/QCOOps.h" +#include "mlir/Dialect/QCO/QCOUtils.h" #include "mlir/Dialect/QCO/Transforms/Passes.h" #include "mlir/Dialect/QCO/Utils/Drivers.h" #include "mlir/Dialect/QCO/Utils/Graph.h" @@ -50,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -94,7 +97,7 @@ struct WireInfos { } /// Bidirectionally map a wire index to a program index. - /// Overwrites existing mappings. + /// Callers preserve a one-to-one mapping and append wire indices densely. void insertOrUpdate(const size_t index, const size_t prog) { if (index >= indexToProgram_.size()) { indexToProgram_.resize(index + 1); @@ -104,12 +107,12 @@ struct WireInfos { } indexToProgram_[index] = prog; programToIndex_[prog] = index; - programs_.insert(prog); } /// Return whether a program index has a corresponding wire. [[nodiscard]] bool containsProgram(const size_t prog) const { - return programs_.contains(prog); + return prog < programToIndex_.size() && + indexToProgram_[programToIndex_[prog]] == prog; } /// Swap two program indices. @@ -128,8 +131,6 @@ struct WireInfos { SmallVector indexToProgram_; /// Maps a program index to the i-th wire index. SmallVector programToIndex_; - /// Program indices that have corresponding wires. - DenseSet programs_; }; struct TensorAllocation { @@ -146,17 +147,29 @@ struct Computation { } // namespace -/// Verify that every non-barrier unitary can be routed by the mapping pass. +/// Check the structural input contract before traversing qubit wires. static LogicalResult validateRoutingOperations(func::FuncOp func) { + if (!llvm::hasSingleElement(func.getBody())) { + return func.emitError("mapping requires a single-block entry function"); + } const auto result = - func.walk([](UnitaryOpInterface unitary) { - if (isa(unitary) || unitary.getNumQubits() <= 2) { - return WalkResult::advance(); + func.walk([](Operation* operation) { + if (isa(operation) && + (llvm::any_of(operation->getOperandTypes(), isLinearQubitType) || + llvm::any_of(operation->getResultTypes(), isLinearQubitType))) { + operation->emitError("inline calls that carry qubits before mapping"); + return WalkResult::interrupt(); } - unitary.emitError() - << "cannot route an operation acting on " << unitary.getNumQubits() - << " qubits; decompose it to one- and two-qubit operations first"; - return WalkResult::interrupt(); + if (auto unitary = dyn_cast(operation); + unitary && !isa(operation) && + unitary.getNumQubits() > 2) { + unitary.emitError() + << "cannot route an operation acting on " + << unitary.getNumQubits() + << " qubits; decompose it to one- and two-qubit operations first"; + return WalkResult::interrupt(); + } + return WalkResult::advance(); }); return result.wasInterrupted() ? failure() : success(); } @@ -385,30 +398,11 @@ struct MappingPass : impl::MappingPassBase { float lambda; }; - /// Utility-struct for routing functions. + /// State shared by traversal and routing. struct RoutingBundle { Wires wires; WireInfos infos; Layout layout; - - struct Patch { - std::optional layout; - std::optional infos; - std::optional wires; - }; - - void applyPatch(Patch&& patch) { - Patch p = std::move(patch); - if (p.layout) { - layout = std::move(*p.layout); - } - if (p.infos) { - infos = std::move(*p.infos); - } - if (p.wires) { - wires = std::move(*p.wires); - } - } }; /// Describes a node in the A* search graph. @@ -561,11 +555,14 @@ struct MappingPass : impl::MappingPassBase { protected: void runOnOperation() override { - assert(alpha > 0 && "expected alpha > 0"); - assert(niterations > 0 && "expected niterations > 0"); - assert(ntrials > 0 && "expected ntrials > 0"); - auto moduleOp = getOperation(); + if (!std::isfinite(alpha) || alpha <= 0 || niterations == 0 || + ntrials == 0) { + moduleOp.emitError("mapping requires finite alpha > 0, niterations > 0, " + "and ntrials > 0"); + signalPassFailure(); + return; + } if (failed(mqt::verifyQuantumAllocations(moduleOp))) { signalPassFailure(); return; @@ -954,6 +951,9 @@ struct MappingPass : impl::MappingPassBase { /// Implements the 4-Approximation algorithm described in arXiv:1602.05150v3. [[nodiscard]] SmallVector restore(const Layout& from, const Layout& to) const { + if (from == to) { + return {}; + } Layout curr(from); FGraph f(*target); SmallVector swaps; @@ -993,6 +993,9 @@ struct MappingPass : impl::MappingPassBase { [[nodiscard]] std::tuple, SmallVector> converge(const Layout& lhs, const Layout& rhs) const { + if (lhs == rhs) { + return {lhs, {}, {}}; + } std::array layouts{Layout(lhs), Layout(rhs)}; std::array graphs{FGraph(*target), FGraph(*target)}; std::array, 2> swaps{}; @@ -1379,12 +1382,10 @@ struct MappingPass : impl::MappingPassBase { } /// Extends the composite unitary's operation to cover all target qubits by - /// adding operands for indices not in the composite's index set. Returns a - /// patch with the updated wire mapping which preserves the parent's wire - /// infos and layout. - RoutingBundle::Patch place(CompositeUnitary& composite, - const RoutingBundle& parent, - IRRewriter& rewriter) { + /// adding operands for indices not in the composite's index set. Updates + /// the parent's wires while preserving its wire information and layout. + void place(CompositeUnitary& composite, RoutingBundle& parent, + IRRewriter& rewriter) { DenseSet included; // Already included indices. included.reserve(composite.indices.size()); @@ -1435,11 +1436,7 @@ struct MappingPass : impl::MappingPassBase { return it.operation() == composite.op; })); - return RoutingBundle::Patch{ - .layout = std::nullopt, - .infos = std::nullopt, - .wires = std::move(wires), - }; + parent.wires = std::move(wires); } /// Return `values` with only the qubit entries realigned according to the @@ -1467,14 +1464,13 @@ struct MappingPass : impl::MappingPassBase { } /// Processes the composite unitary by routing the nested operation and - /// inserting a SWAP appendix. Returns a pair of the patch to apply to the - /// parent bundle and the accumulated statistics, or `failure` if routing - /// fails. + /// inserting epilogue SWAPs. Updates the parent bundle and returns the + /// accumulated statistics, or `failure` if routing fails. template requires(Mode != RoutingMode::Hot || Direction == WireDirection::Forward) - FailureOr> - dispatch(const CompositeUnitary& composite, const RoutingBundle& parent, - IRRewriter* rewriter = nullptr) { + FailureOr dispatch(const CompositeUnitary& composite, + RoutingBundle& parent, + IRRewriter* rewriter = nullptr) { const auto& [op, indices] = composite; SmallVector permutation(indices.size()); @@ -1706,19 +1702,19 @@ struct MappingPass : impl::MappingPassBase { // layout and index-to-program mapping. if (isa(op)) { - return std::make_pair(RoutingBundle::Patch{}, totalStats); + return totalStats; } - RoutingBundle::Patch patch{.layout = std::nullopt, .infos = WireInfos{}}; + WireInfos updatedInfos; for (size_t i = 0; i < parent.wires.size(); ++i) { const auto oldProg = parent.infos.lookupProgram(i); const auto oldHw = parent.layout.getHardwareIndex(oldProg); const auto newProg = exit.getProgramIndex(oldHw); - patch.infos->insertOrUpdate(i, newProg); + updatedInfos.insertOrUpdate(i, newProg); } - patch.layout = std::move(exit); - - return std::make_pair(std::move(patch), totalStats); + parent.infos = std::move(updatedInfos); + parent.layout = std::move(exit); + return totalStats; } /// Iterates over a dynamically computed window of layers and uses A* search @@ -1743,8 +1739,7 @@ struct MappingPass : impl::MappingPassBase { for (auto& composite : composites) { if constexpr (Mode == RoutingMode::Hot) { - auto patch = place(composite, bundle, *rewriter); - bundle.applyPatch(std::move(patch)); + place(composite, bundle, *rewriter); } auto res = dispatch(composite, bundle, rewriter); @@ -1752,8 +1747,7 @@ struct MappingPass : impl::MappingPassBase { return failure(); } - bundle.applyPatch(std::move(res->first)); - stats.merge(res->second); + stats.merge(*res); // Once the composite is mapped, move past this op by incrementing // the respective wires. diff --git a/mlir/lib/Dialect/QCO/Utils/Graph.cpp b/mlir/lib/Dialect/QCO/Utils/Graph.cpp index 5e3de25add..2c074abd44 100644 --- a/mlir/lib/Dialect/QCO/Utils/Graph.cpp +++ b/mlir/lib/Dialect/QCO/Utils/Graph.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -33,48 +32,10 @@ ArrayRef Graph::getNeighbours(size_t id) const { return adj_.at(id); } SmallVector Graph::getNodes() const { return to_vector(adj_.keys()); } -size_t Graph::getMaxDegree() const { - size_t deg = 0; - for (const auto& [u, nbrs] : adj_) { - deg = std::ranges::max(deg, nbrs.size()); - } - return deg; -} - void Graph::clearEdges() { for_each(adj_, [](auto& kv) { kv.second.clear(); }); } -Graph::DistanceMatrix Graph::getDistMatrix() const { - const auto n = getNumNodes(); - - Graph::DistanceMatrix dist(n, std::numeric_limits::max()); - for (const auto& [u, nbrs] : adj_) { - for (const auto& v : nbrs) { - dist[u][v] = 1; - } - } - for (size_t v = 0; v < n; ++v) { - dist[v][v] = 0; - } - - for (size_t k = 0; k < n; ++k) { - for (size_t i = 0; i < n; ++i) { - for (size_t j = 0; j < n; ++j) { - if (dist[i][k] == std::numeric_limits::max() || - dist[k][j] == std::numeric_limits::max()) { - continue; // Avoid overflow with "infinite" distances. - } - - const size_t sum = dist[i][k] + dist[k][j]; - dist[i][j] = std::min(dist[i][j], sum); - } - } - } - - return dist; -} - std::optional> Graph::findCycle() const { enum struct State : uint8_t { Unseen, Seen, Finished }; @@ -108,7 +69,7 @@ std::optional> Graph::findCycle() const { auto it = adj_.find(top.id); assert(it != adj_.end() && "expected node id in adjacency map"); - const auto nbrs = it->getSecond(); + const auto& nbrs = it->getSecond(); // Once all neighbours have been visited (indicated by the index // exceeding the number of neighbours - 1), set the frame on node to diff --git a/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt b/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt index 49b90f6ac3..0644063de5 100644 --- a/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt +++ b/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt @@ -23,3 +23,8 @@ target_link_libraries( mqt_mlir_configure_unittest_target(${target_name}) gtest_discover_tests(${target_name} PROPERTIES LABELS mqt-mlir-unittests DISCOVERY_TIMEOUT 60) + +add_executable(mqt-core-mlir-benchmark-mapping EXCLUDE_FROM_ALL benchmark_mapping.cpp) +target_link_libraries(mqt-core-mlir-benchmark-mapping PRIVATE MLIRQCOProgramBuilder + MLIRQCOTransforms MQTCompilerTarget) +mqt_mlir_configure_unittest_target(mqt-core-mlir-benchmark-mapping) diff --git a/mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp b/mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp new file mode 100644 index 0000000000..619aaae700 --- /dev/null +++ b/mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM + * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH + * All rights reserved. + * + * SPDX-License-Identifier: MIT + * + * Licensed under the MIT License + */ + +#include "mlir/Compiler/Target.h" +#include "mlir/Compiler/TargetEnvironment.h" +#include "mlir/Dialect/MQT/IR/MQTDialect.h" +#include "mlir/Dialect/QCO/Builder/QCOProgramBuilder.h" +#include "mlir/Dialect/QCO/IR/QCODialect.h" +#include "mlir/Dialect/QCO/IR/QCOOps.h" +#include "mlir/Dialect/QCO/Transforms/Mapping/Mapping.h" +#include "mlir/Dialect/QCO/Utils/Graph.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace mlir; +using namespace mlir::qco; +using Clock = std::chrono::steady_clock; + +static CompilerTarget grid(size_t side) { + std::vector edges; + for (size_t row = 0; row < side; ++row) { + for (size_t col = 0; col < side; ++col) { + const auto vertex = row * side + col; + if (col + 1 < side) { + edges.emplace_back(vertex, vertex + 1); + } + if (row + 1 < side) { + edges.emplace_back(vertex, vertex + side); + } + } + } + return llvm::cantFail(CompilerTarget::create( + side * side, CompilerTarget::Connectivity::fromCouplings(edges), + CompilerTarget::NativeOperations::unrestricted())); +} + +static OwningOpRef circuit(MLIRContext& context, bool conditional) { + QCOProgramBuilder builder(&context); + builder.initialize(); + SmallVector qubits; + for (size_t i = 0; i < (conditional ? 2U : 8U); ++i) { + qubits.push_back(builder.allocQubit()); + } + if (conditional) { + auto [qubit, condition] = builder.measure(qubits[0]); + qubits[0] = qubit; + for (size_t i = 0; i < 32; ++i) { + qubits[1] = builder.qcoIf(condition, qubits[1], + [&](Value arg) { return builder.x(arg); }); + } + } else { + for (size_t layer = 0; layer < 8; ++layer) { + for (size_t i = 0; i < qubits.size(); ++i) { + const auto j = (i + 1 + layer % 3) % qubits.size(); + std::tie(qubits[i], qubits[j]) = builder.cx(qubits[i], qubits[j]); + } + } + } + for (Value qubit : qubits) { + builder.sink(qubit); + } + return builder.finalize(); +} + +/// CSV times cover only pass execution; cloning, printing, and verification +/// are outside the timed interval. Every run reports a deterministic IR hash. +int main() { + MLIRContext context; + context.disableMultithreading(); + context.loadDialect(); + PayloadFormat format; + format.id = "benchmark.payload"; + format.version = "1.0.0"; + const auto payload = + llvm::cantFail(PayloadSpecification::create(std::move(format))); + llvm::outs() << "workload,size,sample,milliseconds,swaps,hash\n"; + for (bool conditional : {true, false}) { + for (size_t side : {4U, 8U, 16U}) { + auto input = circuit(context, conditional); + attachTargetEnvironment(*input, TargetEnvironment(grid(side), payload)); + if (failed(verify(*input))) { + return 1; + } + for (size_t sample = 0; sample < 6; ++sample) { + OwningOpRef moduleOp(input->clone()); + PassManager pm(&context); + pm.addPass(createMappingPass( + MappingPassOptions{.niterations = 1, .ntrials = 1, .seed = 42})); + const auto start = Clock::now(); + const auto result = pm.run(*moduleOp); + const auto elapsed = + std::chrono::duration(Clock::now() - start) + .count(); + if (failed(result) || failed(verify(*moduleOp))) { + return 1; + } + size_t swaps = 0; + moduleOp->walk([&](SWAPOp) { ++swaps; }); + std::string ir; + llvm::raw_string_ostream stream(ir); + moduleOp->print(stream); + /// Discard the first run for each workload as a warmup. + if (sample != 0) { + llvm::outs() << (conditional ? "conditional" : "routing") << ',' + << side * side << ',' << sample << ',' << elapsed << ',' + << swaps << ',' << llvm::xxh3_64bits(ir) << '\n'; + } + } + } + } + for (size_t size : {128U, 512U, 2048U}) { + SmallVector nodes; + for (size_t i = 0; i < size; ++i) { + nodes.push_back(i); + } + Graph graph(nodes); + for (size_t i = 1; i < size; ++i) { + graph.addEdge(0, i); + } + for (size_t sample = 0; sample < 6; ++sample) { + const auto start = Clock::now(); + for (size_t iteration = 0; iteration < 100; ++iteration) { + if (graph.findCycle()) { + return 1; + } + } + const auto elapsed = + std::chrono::duration(Clock::now() - start) + .count(); + if (sample != 0) { + llvm::outs() << "graph," << size << ',' << sample << ',' << elapsed + << ",0,0\n"; + } + } + } +} diff --git a/mlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cpp b/mlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cpp index 3ad277a997..9cd618ad60 100644 --- a/mlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cpp +++ b/mlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -323,7 +325,7 @@ class MappingPassFixture : public testing::Test { DialectRegistry registry; registry.insert(); + func::FuncDialect, cf::ControlFlowDialect>(); context = std::make_unique(); context->appendDialectRegistry(registry); context->loadAllAvailableDialects(); @@ -2500,3 +2502,113 @@ INSTANTIATE_TEST_SUITE_P(FourByFourSquareGrid, MappingPassTest, testing::Values(getSquareGridTarget(4))); INSTANTIATE_TEST_SUITE_P(TenByTenSquareGrid, MappingPassTest, testing::Values(getSquareGridTarget(10))); + +TEST_F(MappingPassFixture, RejectQuantumCallsBeforeMutation) { + auto moduleOp = parseSourceString(R"mlir( + module { + func.func private @helper(!qco.qubit) -> !qco.qubit + func.func @main() attributes {mqt.entry_point} { + %q = qco.alloc : !qco.qubit + %r = func.call @helper(%q) : (!qco.qubit) -> !qco.qubit + qco.sink %r : !qco.qubit + return + } + })mlir", + context.get()); + ASSERT_TRUE(moduleOp); + ASSERT_TRUE(succeeded(verify(*moduleOp))); + const auto target = getSquareGridTarget(2); + attachTestEnvironment(*moduleOp, target); + const auto before = printModule(*moduleOp); + std::string diagnostics; + ScopedDiagnosticHandler handler(context.get(), [&](Diagnostic& diagnostic) { + diagnostics += diagnostic.str(); + return success(); + }); + EXPECT_TRUE(failed(runPass(*moduleOp, target, MappingPassOptions{}))); + EXPECT_NE(diagnostics.find("inline calls that carry qubits before mapping"), + std::string::npos) + << diagnostics; + EXPECT_EQ(printModule(*moduleOp), before); +} + +TEST_F(MappingPassFixture, RejectEntryControlFlowBeforeMutation) { + auto moduleOp = parseSourceString(R"mlir( + module { + func.func @main() attributes {mqt.entry_point} { + %q = qco.alloc : !qco.qubit + cf.br ^exit(%q : !qco.qubit) + ^exit(%r : !qco.qubit): + qco.sink %r : !qco.qubit + return + } + })mlir", + context.get()); + ASSERT_TRUE(moduleOp); + ASSERT_TRUE(succeeded(verify(*moduleOp))); + const auto target = getSquareGridTarget(2); + attachTestEnvironment(*moduleOp, target); + const auto before = printModule(*moduleOp); + std::string diagnostics; + ScopedDiagnosticHandler handler(context.get(), [&](Diagnostic& diagnostic) { + diagnostics += diagnostic.str(); + return success(); + }); + EXPECT_TRUE(failed(runPass(*moduleOp, target, MappingPassOptions{}))); + EXPECT_NE(diagnostics.find("mapping requires a single-block entry function"), + std::string::npos) + << diagnostics; + EXPECT_EQ(printModule(*moduleOp), before); +} + +TEST_F(MappingPassFixture, RejectInvalidOptionsBeforeMutation) { + const auto target = getSquareGridTarget(2); + for (const auto& options : { + MappingPassOptions{.ntrials = 0}, + MappingPassOptions{.niterations = 0}, + MappingPassOptions{.alpha = 0}, + MappingPassOptions{.alpha = -1}, + MappingPassOptions{.alpha = std::numeric_limits::infinity()}, + MappingPassOptions{.alpha = std::numeric_limits::quiet_NaN()}, + }) { + QCOProgramBuilder builder(context.get()); + builder.initialize(); + builder.sink(builder.allocQubit()); + auto moduleOp = builder.finalize(); + ASSERT_TRUE(succeeded(verify(*moduleOp))); + attachTestEnvironment(*moduleOp, target); + const auto before = printModule(*moduleOp); + std::string diagnostics; + ScopedDiagnosticHandler handler(context.get(), [&](Diagnostic& diagnostic) { + diagnostics += diagnostic.str(); + return success(); + }); + EXPECT_TRUE(failed(runPass(*moduleOp, target, options))); + EXPECT_NE(diagnostics.find("mapping requires finite alpha > 0"), + std::string::npos) + << diagnostics; + EXPECT_EQ(printModule(*moduleOp), before); + } +} + +TEST_F(MappingPassFixture, PreserveClassicalCalls) { + auto moduleOp = parseSourceString(R"mlir( + module { + func.func private @classical() + func.func @main() attributes {mqt.entry_point} { + %q = qco.alloc : !qco.qubit + func.call @classical() : () -> () + qco.sink %q : !qco.qubit + return + } + })mlir", + context.get()); + ASSERT_TRUE(moduleOp); + ASSERT_TRUE(succeeded(verify(*moduleOp))); + ASSERT_TRUE(succeeded(runPass(*moduleOp, getSquareGridTarget(2), + MappingPassOptions{.ntrials = 1}))); + EXPECT_TRUE(succeeded(verify(*moduleOp))); + size_t calls = 0; + moduleOp->walk([&](func::CallOp) { ++calls; }); + EXPECT_EQ(calls, 1); +} From 0d763c5063a5202d1cdcda2bbb016f633b72c612 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Wed, 9 Sep 2026 10:19:00 +0000 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20Read=20the=20mapping=20optio?= =?UTF-8?q?n=20before=20checking=20finiteness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSVC's isfinite overload otherwise tries to copy the non-copyable MLIR option wrapper. Pass its stored float value explicitly. Assisted-by: GPT-6 via Codex --- mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp b/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp index ce982f0988..0da5bdc514 100644 --- a/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp +++ b/mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp @@ -556,7 +556,7 @@ struct MappingPass : impl::MappingPassBase { protected: void runOnOperation() override { auto moduleOp = getOperation(); - if (!std::isfinite(alpha) || alpha <= 0 || niterations == 0 || + if (!std::isfinite(alpha.getValue()) || alpha <= 0 || niterations == 0 || ntrials == 0) { moduleOp.emitError("mapping requires finite alpha > 0, niterations > 0, " "and ntrials > 0"); From 579af778afa7b95ef1271d735a35f3b4b6893c42 Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Wed, 9 Sep 2026 12:37:32 +0000 Subject: [PATCH 3/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Keep=20benchmark=20exp?= =?UTF-8?q?eriments=20self-contained?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the routing harness, build hook, data, and plots into .agents/benchmarks/routing. Build against selected checkouts without adding benchmark targets to the production or test source trees. Define shared benchmark evidence and reproduction rules in AGENTS.md and link them from the planning and audit guides. Assisted-by: GPT-6 via Codex --- .agent/AUDITS.md | 7 ++++ .agent/PLANS.md | 8 ++++ .agent/plans/routing-simplification.md | 11 +++++- .../benchmarks/routing/README.md | 32 ++++++++++------ .../benchmarks/routing/before-after.png | Bin .../benchmarks/routing}/benchmark_mapping.cpp | 28 +++++++------- .../benchmarks/routing/collect.py | 0 .agents/benchmarks/routing/enable.cmake | 23 ++++++++++++ .../benchmarks/routing/plot.py | 0 .../benchmarks/routing/results.csv | 0 AGENTS.md | 35 ++++++++++++++++++ .../QCO/Transforms/Mapping/CMakeLists.txt | 5 --- 12 files changed, 119 insertions(+), 30 deletions(-) rename {.agent => .agents}/benchmarks/routing/README.md (71%) rename {.agent => .agents}/benchmarks/routing/before-after.png (100%) rename {mlir/unittests/Dialect/QCO/Transforms/Mapping => .agents/benchmarks/routing}/benchmark_mapping.cpp (90%) rename {.agent => .agents}/benchmarks/routing/collect.py (100%) create mode 100644 .agents/benchmarks/routing/enable.cmake rename {.agent => .agents}/benchmarks/routing/plot.py (100%) rename {.agent => .agents}/benchmarks/routing/results.csv (100%) diff --git a/.agent/AUDITS.md b/.agent/AUDITS.md index 25b67599b4..a4b12e2640 100644 --- a/.agent/AUDITS.md +++ b/.agent/AUDITS.md @@ -79,6 +79,13 @@ changes. Serialize experiments that share a checkout or build directory. A read-only investigation does not require aborting merely because unrelated user edits exist. +For performance experiments, follow the +[benchmark experiment rules](../AGENTS.md#benchmark-experiments). Keep the +harness, raw data, plots, and reproduction steps in +`.agents/benchmarks//` and link them from the finding. Record neutral +results and regressions; an untested optimization remains a candidate, not a +measured finding. + ### What an experiment proves - A behavior-preserving variation that breaks an assertion shows a possible diff --git a/.agent/PLANS.md b/.agent/PLANS.md index 49e396203d..9100663cf6 100644 --- a/.agent/PLANS.md +++ b/.agent/PLANS.md @@ -79,6 +79,14 @@ that an old API still exists or a follow-up was resolved. Reconcile remote status only when it matters to the task; do not turn document cleanup into CI monitoring. +## Performance evidence + +For a performance change, identify the workload, baseline, correctness checks, +and relevant quality measures before implementation. Follow the +[benchmark experiment rules](../AGENTS.md#benchmark-experiments), and link the +self-contained `.agents/benchmarks//` record from the plan. Keep the +measured result and its limits in the completed decision record. + ## Validation Use repository build and test entry points. Record the focused command, the diff --git a/.agent/plans/routing-simplification.md b/.agent/plans/routing-simplification.md index 31ffc0c428..df64c07f6a 100644 --- a/.agent/plans/routing-simplification.md +++ b/.agent/plans/routing-simplification.md @@ -17,7 +17,7 @@ regions already have single-block verifiers; the entry-function restriction is checked by mapping. No payload capability checks were duplicated. The optional mapping benchmark and its data, figure, and reproduction steps are -in `.agent/benchmarks/routing/README.md`. Identical mapped-IR hashes and SWAP +in `.agents/benchmarks/routing/README.md`. Identical mapped-IR hashes and SWAP counts accompany a 1.56–1.82 times speedup for unchanged branch layouts. The routing workload is essentially unchanged. Graph measurements are synthetic. @@ -35,3 +35,12 @@ combined compiler suite passed 193 of 195 tests. Its two failing tests, allocate qubits outside the entry block. Both failures were reproduced with the routing changes removed, before the mapping pass runs. Updating those #2162 inputs is outside this PR's scope. + +The benchmark is self-contained under `.agents/benchmarks/routing/`, including +an explicit CMake hook. It builds against baseline and candidate checkouts +without source-tree edits or test targets. Relocation checks matched all 45 +outputs per revision to the recorded hashes and SWAP counts; a candidate build +with tests disabled and a normal build without the benchmark target verified +isolation. The collection and plotting scripts were exercised separately from +the preserved historical timing data. Shared benchmark rules live in +`AGENTS.md`, with links from the plan and audit guides. diff --git a/.agent/benchmarks/routing/README.md b/.agents/benchmarks/routing/README.md similarity index 71% rename from .agent/benchmarks/routing/README.md rename to .agents/benchmarks/routing/README.md index 4853878728..e9860765f7 100644 --- a/.agent/benchmarks/routing/README.md +++ b/.agents/benchmarks/routing/README.md @@ -1,8 +1,10 @@ # Routing cleanup benchmarks Compare upstream main `91a9e0ba514af938680cdd394d6d63195872dc9a` with the -routing changes in this PR. The same benchmark source and build settings were -used for both executables. +routing changes at `c38c99cf3a8974abf1b8967bb94648f2e49e2271`. The same +benchmark source and build settings were used for both executables. The recorded +results predate the relocation of this harness; relocation validation checks +output equivalence without replacing those timing samples. ![Before and after routing cleanup](before-after.png) @@ -52,20 +54,28 @@ the recorded measurement run. ## Reproduce -The optional executable lives under -`mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp`. It is -excluded from the default build and from CTest. +All benchmark source, build integration, scripts, raw samples, and plots live in +this directory. The CMake top-level include adds the optional target after MQT +Core defines its libraries. Normal builds and CTest do not include it. No +source-tree edits or benchmark copies into the baseline are needed. -Create a detached checkout at the baseline and copy only the benchmark source -and its CMake target into that checkout. Configure both checkouts with the same -compiler and dependency versions: +Create separate checkouts for the baseline and candidate. For each checkout, +configure an isolated build directory with the same compiler and dependencies. +Use the **same absolute path** to this benchmark's `enable.cmake` for both: ```sh -cmake --preset release -DBUILD_MQT_CORE_MLIR=ON -DBUILD_MQT_CORE_TESTS=ON \ - -DBUILD_MQT_CORE_BINDINGS=OFF -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF -cmake --build --preset release --target mqt-core-mlir-benchmark-mapping +cmake -S /path/to/checkout -B /path/to/build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release -DENABLE_IPO=OFF \ + -DBUILD_MQT_CORE_MLIR=ON -DBUILD_MQT_CORE_TESTS=OFF \ + -DBUILD_MQT_CORE_BINDINGS=OFF \ + -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=/absolute/path/to/.agents/benchmarks/routing/enable.cmake +cmake --build /path/to/build --target mqt-core-mlir-benchmark-mapping ``` +The executable is +`/path/to/build/routing-benchmark/mqt-core-mlir-benchmark-mapping` (on +multi-configuration generators, also select and use the Release directory). + Copy the resulting executables to distinct paths before rebuilding either checkout. From this directory, collect and render the results: diff --git a/.agent/benchmarks/routing/before-after.png b/.agents/benchmarks/routing/before-after.png similarity index 100% rename from .agent/benchmarks/routing/before-after.png rename to .agents/benchmarks/routing/before-after.png diff --git a/mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp b/.agents/benchmarks/routing/benchmark_mapping.cpp similarity index 90% rename from mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp rename to .agents/benchmarks/routing/benchmark_mapping.cpp index 619aaae700..0b2cc50d48 100644 --- a/mlir/unittests/Dialect/QCO/Transforms/Mapping/benchmark_mapping.cpp +++ b/.agents/benchmarks/routing/benchmark_mapping.cpp @@ -14,14 +14,14 @@ #include "mlir/Dialect/QCO/Builder/QCOProgramBuilder.h" #include "mlir/Dialect/QCO/IR/QCODialect.h" #include "mlir/Dialect/QCO/IR/QCOOps.h" -#include "mlir/Dialect/QCO/Transforms/Mapping/Mapping.h" +#include "mlir/Dialect/QCO/Transforms/Passes.h" #include "mlir/Dialect/QCO/Utils/Graph.h" #include #include +#include #include #include -#include #include #include #include @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -45,11 +45,13 @@ using namespace mlir; using namespace mlir::qco; using Clock = std::chrono::steady_clock; -static CompilerTarget grid(size_t side) { +namespace { + +CompilerTarget grid(size_t side) { std::vector edges; for (size_t row = 0; row < side; ++row) { for (size_t col = 0; col < side; ++col) { - const auto vertex = row * side + col; + const auto vertex = (row * side) + col; if (col + 1 < side) { edges.emplace_back(vertex, vertex + 1); } @@ -63,7 +65,7 @@ static CompilerTarget grid(size_t side) { CompilerTarget::NativeOperations::unrestricted())); } -static OwningOpRef circuit(MLIRContext& context, bool conditional) { +OwningOpRef circuit(MLIRContext& context, bool conditional) { QCOProgramBuilder builder(&context); builder.initialize(); SmallVector qubits; @@ -80,17 +82,17 @@ static OwningOpRef circuit(MLIRContext& context, bool conditional) { } else { for (size_t layer = 0; layer < 8; ++layer) { for (size_t i = 0; i < qubits.size(); ++i) { - const auto j = (i + 1 + layer % 3) % qubits.size(); + const auto j = (i + 1 + (layer % 3)) % qubits.size(); std::tie(qubits[i], qubits[j]) = builder.cx(qubits[i], qubits[j]); } } } - for (Value qubit : qubits) { - builder.sink(qubit); - } + llvm::for_each(qubits, [&](Value qubit) { builder.sink(qubit); }); return builder.finalize(); } +} // namespace + /// CSV times cover only pass execution; cloning, printing, and verification /// are outside the timed interval. Every run reports a deterministic IR hash. int main() { @@ -104,8 +106,8 @@ int main() { const auto payload = llvm::cantFail(PayloadSpecification::create(std::move(format))); llvm::outs() << "workload,size,sample,milliseconds,swaps,hash\n"; - for (bool conditional : {true, false}) { - for (size_t side : {4U, 8U, 16U}) { + for (const bool conditional : {true, false}) { + for (const size_t side : {4U, 8U, 16U}) { auto input = circuit(context, conditional); attachTargetEnvironment(*input, TargetEnvironment(grid(side), payload)); if (failed(verify(*input))) { @@ -138,7 +140,7 @@ int main() { } } } - for (size_t size : {128U, 512U, 2048U}) { + for (const size_t size : {128U, 512U, 2048U}) { SmallVector nodes; for (size_t i = 0; i < size; ++i) { nodes.push_back(i); diff --git a/.agent/benchmarks/routing/collect.py b/.agents/benchmarks/routing/collect.py similarity index 100% rename from .agent/benchmarks/routing/collect.py rename to .agents/benchmarks/routing/collect.py diff --git a/.agents/benchmarks/routing/enable.cmake b/.agents/benchmarks/routing/enable.cmake new file mode 100644 index 0000000000..53dc47ffec --- /dev/null +++ b/.agents/benchmarks/routing/enable.cmake @@ -0,0 +1,23 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +include_guard(GLOBAL) + +# Add the benchmark after MQT Core has defined its libraries and build options. +function(add_routing_benchmark) + add_executable(mqt-core-mlir-benchmark-mapping EXCLUDE_FROM_ALL + "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/benchmark_mapping.cpp") + target_link_libraries(mqt-core-mlir-benchmark-mapping PRIVATE MLIRQCOProgramBuilder + MLIRQCOTransforms MQTCompilerTarget) + mqt_mlir_target_use_project_options(mqt-core-mlir-benchmark-mapping) + + set_target_properties(mqt-core-mlir-benchmark-mapping + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/routing-benchmark") +endfunction() + +cmake_language(DEFER CALL add_routing_benchmark) diff --git a/.agent/benchmarks/routing/plot.py b/.agents/benchmarks/routing/plot.py similarity index 100% rename from .agent/benchmarks/routing/plot.py rename to .agents/benchmarks/routing/plot.py diff --git a/.agent/benchmarks/routing/results.csv b/.agents/benchmarks/routing/results.csv similarity index 100% rename from .agent/benchmarks/routing/results.csv rename to .agents/benchmarks/routing/results.csv diff --git a/AGENTS.md b/AGENTS.md index 893b991e54..4cd19f3365 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -205,6 +205,41 @@ Use Google-style Python docstrings. Prefer fixing diagnostics from `ruff` and pass. Rerun affected checks and required gates, then stop unless a concrete remaining risk warrants broader validation. +## Benchmark experiments + +Keep task-specific and one-off benchmarks self-contained under +`.agents/benchmarks//`. Do not put their harnesses in production or test +source trees, add them to normal build or test targets, or add project-wide +runtime dependencies solely for an experiment. Use an explicit build entry point +that can target a selected checkout without editing that checkout. Durable +regression tests still belong in the corresponding test tree. + +Each benchmark folder must contain: + +- A `README.md` with the question, workload definitions, exact baseline and + candidate revisions, environment, build settings, commands, results, and + limits. +- The harness and scripts needed to build, run, compare, and plot the + experiment. +- Raw measurements in a machine-readable format and plots generated from those + measurements. Keep generated binaries and build output under ignored `build/` + directories, not in the committed benchmark folder. + +Run the benchmarks before making a performance claim. Compare the same harness +and inputs under matched build and runtime settings. Record units, timed scope, +seeds, threading, warmups, repetitions, and aggregation. Alternate before/after +runs when practical, avoid concurrent builds or tests, and show sample spread. +Check correctness and relevant quality measures alongside time or memory; for +routing, this includes mapped output and SWAP counts. A faster incorrect result +or a changed heuristic is not a behavior-preserving optimization. + +Report regressions and neutral results as well as improvements. Distinguish +synthetic helper measurements from end-to-end workloads, and do not generalize +beyond the measured cases. Include readable before/after plots and reproduction +links in performance PRs. Preserve revision attribution when moving or updating +a harness; label old measurements as historical and rerun affected measurements +before attributing them to changed code. + ## ExecPlans When writing complex features or significant refactors, use an ExecPlan (as diff --git a/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt b/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt index 0644063de5..49b90f6ac3 100644 --- a/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt +++ b/mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt @@ -23,8 +23,3 @@ target_link_libraries( mqt_mlir_configure_unittest_target(${target_name}) gtest_discover_tests(${target_name} PROPERTIES LABELS mqt-mlir-unittests DISCOVERY_TIMEOUT 60) - -add_executable(mqt-core-mlir-benchmark-mapping EXCLUDE_FROM_ALL benchmark_mapping.cpp) -target_link_libraries(mqt-core-mlir-benchmark-mapping PRIVATE MLIRQCOProgramBuilder - MLIRQCOTransforms MQTCompilerTarget) -mqt_mlir_configure_unittest_target(mqt-core-mlir-benchmark-mapping) From 4d5bbebe845e3a4ca8c1aae65ead91cb034e86aa Mon Sep 17 00:00:00 2001 From: Lukas Burgholzer Date: Wed, 9 Sep 2026 12:47:57 +0000 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=A7=B9=20Keep=20benchmark=20guidance?= =?UTF-8?q?=20and=20checks=20focused?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Condense the benchmark rules and exclude one-off experiments from routine pre-commit, Python, and local and hosted C++ lint checks. Validate benchmark execution explicitly instead. Assisted-by: GPT-6 via Codex --- .github/workflows/ci.yml | 2 +- .pre-commit-config.yaml | 2 ++ AGENTS.md | 40 ++++++++-------------------------------- noxfile.py | 2 +- pyproject.toml | 2 ++ 5 files changed, 14 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f4c5f2248..7f39398cc1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: cpp-linter-extra-args: "-std=c++20 -Wunused-template" # Vendored third-party headers are checked upstream and are not maintained # according to MQT Core's clang-tidy configuration. - cpp-linter-ignore-extra: "vendor/**" + cpp-linter-ignore-extra: "vendor/**|.agents/benchmarks/**" setup-mlir: true llvm-version: 23.1.0 permissions: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eb4c958f26..68b7fce5dc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,8 @@ ci: autofix_commit_msg: "🎨 pre-commit fixes" skip: [ty] +exclude: ^\.agents/benchmarks/ + repos: ## Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/AGENTS.md b/AGENTS.md index 4cd19f3365..64f5fd1129 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -207,38 +207,14 @@ Use Google-style Python docstrings. Prefer fixing diagnostics from `ruff` and ## Benchmark experiments -Keep task-specific and one-off benchmarks self-contained under -`.agents/benchmarks//`. Do not put their harnesses in production or test -source trees, add them to normal build or test targets, or add project-wide -runtime dependencies solely for an experiment. Use an explicit build entry point -that can target a selected checkout without editing that checkout. Durable -regression tests still belong in the corresponding test tree. - -Each benchmark folder must contain: - -- A `README.md` with the question, workload definitions, exact baseline and - candidate revisions, environment, build settings, commands, results, and - limits. -- The harness and scripts needed to build, run, compare, and plot the - experiment. -- Raw measurements in a machine-readable format and plots generated from those - measurements. Keep generated binaries and build output under ignored `build/` - directories, not in the committed benchmark folder. - -Run the benchmarks before making a performance claim. Compare the same harness -and inputs under matched build and runtime settings. Record units, timed scope, -seeds, threading, warmups, repetitions, and aggregation. Alternate before/after -runs when practical, avoid concurrent builds or tests, and show sample spread. -Check correctness and relevant quality measures alongside time or memory; for -routing, this includes mapped output and SWAP counts. A faster incorrect result -or a changed heuristic is not a behavior-preserving optimization. - -Report regressions and neutral results as well as improvements. Distinguish -synthetic helper measurements from end-to-end workloads, and do not generalize -beyond the measured cases. Include readable before/after plots and reproduction -links in performance PRs. Preserve revision attribution when moving or updating -a harness; label old measurements as historical and rerun affected measurements -before attributing them to changed code. +Keep one-off benchmarks in `.agents/benchmarks//`, outside normal build +and test targets. Include the harness, reproduction commands, exact revisions, +environment, raw measurements, and generated before/after plots. + +Run matched comparisons; check correctness and output quality alongside speed. +Report sample spread, regressions, and limits. Keep old results tied to their +measured revisions. Exclude these folders from routine lint; validate +experiments explicitly. Durable regression tests belong in the test tree. ## ExecPlans diff --git a/noxfile.py b/noxfile.py index 010e3d68e5..c435f4b4d3 100755 --- a/noxfile.py +++ b/noxfile.py @@ -111,7 +111,7 @@ def cpp_lint(session: nox.Session) -> None: "--style=", "--tidy-checks=", f"--version={llvm_bin}", - "--ignore=build|!build/mlir/**|**/include|include|vendor/**", + "--ignore=build|!build/mlir/**|**/include|include|vendor/**|.agents/benchmarks/**", "--thread-comments=false", "--step-summary=false", "--database=build/cpp-lint", diff --git a/pyproject.toml b/pyproject.toml index e53f23369a..6702d22d56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -295,6 +295,7 @@ test-sources = [] line-length = 120 namespace-packages = [ "mqt" ] src = [ "python" ] +extend-exclude = [ ".agents/benchmarks/**" ] preview = true fix = true unsafe-fixes = true @@ -391,6 +392,7 @@ olt = "olt" [tool.ty.src] exclude = [ + ".agents/benchmarks/**", "docs/**", "mlir/**", ]