Skip to main content

qiskit-qubit-mapping-toolkit

Graph-theoretic initial layout and routing heuristics for mapping logical Qiskit circuits onto hardware coupling maps.

This project fills a gap in my own Qiskit Ecosystem portfolio: prior projects (qiskit-graph-walks, qiskit-zx-verified, qiskit-lean-bridge, etc.) analyze, verify, or visualize circuits, but none of them touch the compilation/transpilation pipeline — getting a circuit onto real hardware efficiently. This toolkit is a first step into that space, built around two ideas:

  1. IsomorphismLayout — search for a zero-SWAP embedding of the circuit's interaction graph into the device coupling graph via VF2 subgraph isomorphism, falling back to a degree-greedy placement when no exact embedding exists.
  2. WalkBasedLayout — score candidate qubit assignments using continuous-time quantum walk (CTQW) mixing signatures, extending the walk machinery from qiskit-graph-walks to the placement problem, then solve the resulting assignment via the Hungarian algorithm.

Both plug into either a baseline shortest-path SWAP router or a lookahead SWAP router (Sabre-style candidate scoring over a front layer plus an upcoming-gates window), and an evaluation harness that benchmarks results against Qiskit's built-in SabreLayout + SabreSwap.

All four passes are also registered as Qiskit transpiler stage plugins, so they work directly through transpile() — see Using it through transpile() below.

Honest framing

This is a research/pedagogical toolkit, not a production replacement for Sabre. BaselineSwapRouter is a deliberately simple, easy-to-verify shortest-path SWAP inserter with no lookahead or SWAP-choice optimization — it exists as a correctness-first reference implementation so the layout heuristics can be measured on a level playing field, and as a floor to compare smarter routing against. LookaheadSwapRouter builds on that floor with a Sabre-style scoring function (front layer + weighted lookahead window) and closes most of the gap: on a 19-qubit heavy-hex topology it beats Sabre's SWAP count on structured circuits (line, ring) and comes within a few SWAPs on denser random circuits — see docs/algorithm_notes.md for the full table. Where this toolkit wins outright regardless of router is on circuits whose interaction graph is exactly embeddable: IsomorphismLayout finds the zero-SWAP embedding directly rather than converging to it iteratively.

Install

pip install qiskit-qubit-mapping-toolkit

Or from source:

git clone https://github.com/RexRowan/qiskit-qubit-mapping-toolkit
cd qiskit-qubit-mapping-toolkit
pip install -e ".[dev]"

Requires qiskit>=2.0,<3 (this project's standard version bound across the Ecosystem portfolio).

Using it through transpile()

Every layout heuristic and router is also registered as a Qiskit transpiler stage plugin, so you don't need to import anything from this package at all:

from qiskit import transpile

transpiled = transpile(
    circuit,
    coupling_map=coupling_map,
    layout_method="qqm_isomorphism",   # or "qqm_walk_based"
    routing_method="qqm_lookahead",    # or "qqm_baseline"
)

Plugin names are prefixed with qqm_ to avoid colliding with Qiskit's own built-in plugin names — notably "lookahead" (no prefix) is already a reserved built-in routing method. See registered names any time with:

from qiskit.transpiler.preset_passmanagers.plugin import list_stage_plugins

list_stage_plugins("layout")    # [..., "qqm_isomorphism", "qqm_walk_based"]
list_stage_plugins("routing")   # [..., "qqm_baseline", "qqm_lookahead"]

Quickstart

from qiskit.transpiler import CouplingMap
from qiskit_qubit_mapping.benchmarks.circuits import linear_entangling_circuit
from qiskit_qubit_mapping.layout import IsomorphismLayout
from qiskit_qubit_mapping.metrics import compare_to_sabre

cmap = CouplingMap([[i, i + 1] for i in range(6)])   # a 7-qubit line
qc = linear_entangling_circuit(7)                     # interaction graph is also a line

results = compare_to_sabre(qc, cmap, IsomorphismLayout(cmap))
print(results["toolkit"])  # EvaluationResult(swap_count=0, depth=...)
print(results["sabre"])

For circuits without an exact embedding, use WalkBasedLayout instead, or run both and compare:

from qiskit_qubit_mapping.layout import WalkBasedLayout
from qiskit_qubit_mapping.metrics import evaluate_layout

result = evaluate_layout(qc, cmap, WalkBasedLayout(cmap))
print(result.swap_count, result.depth, result.layout_score)

For denser circuits, swap in the lookahead router — it's the toolkit's strongest routing option and the one to reach for by default once you're past quick correctness checks:

from qiskit_qubit_mapping.routing import LookaheadSwapRouter

result = evaluate_layout(qc, cmap, IsomorphismLayout(cmap), router_pass=LookaheadSwapRouter(cmap))
print(result.swap_count, result.depth)

Both layout heuristics are standard Qiskit AnalysisPass subclasses and compose with BaselineSwapRouter in a PassManager:

from qiskit.transpiler import PassManager
from qiskit_qubit_mapping import IsomorphismLayout, BaselineSwapRouter

pm = PassManager([IsomorphismLayout(cmap), BaselineSwapRouter(cmap)])
routed_circuit = pm.run(qc)

What's in the package

Module Contents
qiskit_qubit_mapping.layout IsomorphismLayout, WalkBasedLayout, shared LayoutResult dataclass
qiskit_qubit_mapping.routing BaselineSwapRouter, LookaheadSwapRouter, functional route_circuit() / route_circuit_lookahead()
qiskit_qubit_mapping.metrics evaluate_layout(), compare_to_sabre(), EvaluationResult
qiskit_qubit_mapping.benchmarks Small dependency-free benchmark circuit generators (line, ring, all-to-all, random-sparse)

See docs/usage.md for a full walkthrough of each heuristic, and docs/algorithm_notes.md for the reasoning behind the CTQW scoring function and measured Sabre comparisons.

Testing

pip install -e ".[test]"
pytest tests/ -v

The test suite includes statevector-fidelity checks (tests/test_routing.py, tests/test_lookahead_routing.py) that verify both BaselineSwapRouter's and LookaheadSwapRouter's SWAP insertion is semantics-preserving, not just "runs without crashing" — routing a Bell pair, a GHZ state, and a denser random circuit across non-adjacent physical qubits and confirming the marginal measurement distributions match the unrouted circuit exactly. There's also a direct regression test that LookaheadSwapRouter never uses more SWAPs than BaselineSwapRouter on the same circuit.

Roadmap

  • Noise-aware layout scoring incorporating backend calibration data (readout/gate error rates), not just topology
  • Bidirectional/iterative layout refinement (Sabre-style forward-backward passes) to close the remaining gap on very dense circuits
  • Lean 4 verification that both routers' SWAP insertion preserves circuit semantics in general, extending the verification approach from qiskit-zx-verified

License

Apache 2.0 — see LICENSE.

Metadata

Release files for qiskit-qubit-mapping-toolkit 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qiskit-qubit-mapping-toolkit 0.1.1
File Size Uploaded
qiskit_qubit_mapping_toolkit-0.1.1.tar.gz 28.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qiskit-qubit-mapping-toolkit 0.1.1
File Interpreter ABI Platform
qiskit_qubit_mapping_toolkit-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 57.0 kB

Release files / qiskit_qubit_mapping_toolkit-0.1.1.tar.gz

Download URL qiskit_qubit_mapping_toolkit-0.1.1.tar.gz
Size 28.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2441cc5e7a65ffce5ecdd5d08e2099a8d10262bd793c0d9dd9eb720f1f5e8345
BLAKE2b-256 checksum
How to use checksums
e18c249da227027661c4a83c0be2931c0bbd7d4b3f669d765e2656f9b00083da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.1

Release files / qiskit_qubit_mapping_toolkit-0.1.1-py3-none-any.whl

Download URL qiskit_qubit_mapping_toolkit-0.1.1-py3-none-any.whl
Size 28.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59862ca65ecbe9b77bc2380341727cc536907d1a126c15f6c732fb5b0a92b3c7
BLAKE2b-256 checksum
How to use checksums
4f78a26e6c888be79cfb79b7371be110b9fb46867ca9f9ceba5919f9d4d7422c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.1

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page