qilisdk.digital.circuit_transpiler_passes.sabre_swap_pass
Classes
SABRE routing (SWAP insertion) for 1Q/2Q circuits on an undirected coupling graph. |
Module Contents
- class SabreSwapPass(topology: qilisdk.digital.types.Topology, *, initial_layout: list[int] | None = None, seed: int | None = None, lookahead_size: int = 10, beta: float = 0.8, decay_delta: float = 0.001, decay_lambda: float = 0.99, max_swaps_factor: float = 64.0, max_attempts: int = 10)[source]
Bases:
qilisdk.digital.circuit_transpiler_passes.circuit_transpiler_pass.CircuitTranspilerPassSABRE routing (SWAP insertion) for 1Q/2Q circuits on an undirected coupling graph.
Inputs
- topologyTopology
Coupling map provided either as an edge list or as an undirected
PyGraphwhose node indices are physical qubits.- initial_layoutlist[int] | None
Logical -> physical mapping to start from (e.g., from SabreLayoutPass.last_layout). If None, uses the lowest-indexed physical qubits provided by the coupling graph.
Heuristic (SABRE-style)
When a 2Q gate’s mapped endpoints are non-adjacent, choose one SWAP on an edge touching the mapped endpoints of the current front-set gates that minimizes:
- cost = sum_{g in F} distance_matrix(p_u, p_v) * (1 + decay[p_u] + decay[p_v])
beta * sum_{g in E} distance_matrix(p_u, p_v)
where F is the per-qubit first unscheduled 2Q gate and E is a small look-ahead set. A light decay penalty discourages thrashing.
Behavior
Returns a new Circuit with 1Q gates mapped and SWAPs inserted before each non-adjacent 2Q gate so that every emitted 2Q gate acts on an edge of topology.
Preserves the original gate order (no reordering/commutation across the list).
Notes
Supports 1Q and 2Q gates (CNOT, CZ, SWAP, generic Controlled with one control). Multi-qubit (>2) non-SWAP gates should be decomposed before routing.
Configure SABRE swap routing behavior.
- param topology:
Coupling map as an edge list or
PyGraph.- type topology:
Topology- param initial_layout:
Optional initial logical-to-physical mapping; uses identity-style mapping when omitted.
- type initial_layout:
list[int] | None- param seed:
Base seed for stochastic swap scoring and retry attempts.
- type seed:
int | None- param lookahead_size:
Number of future two-qubit gates used in the extended SABRE cost.
- type lookahead_size:
- param beta:
Weight balancing extended-set cost against immediate front-set cost.
- type beta:
float- param decay_delta:
Penalty increment added to swapped physical qubits.
- type decay_delta:
float- param decay_lambda:
Per-iteration multiplier that relaxes accumulated decay penalties.
- type decay_lambda:
float- param max_swaps_factor:
Per-gate swap budget factor derived from current endpoint distance.
- type max_swaps_factor:
float- param max_attempts:
Maximum number of independent routing attempts with varied seeds.
- type max_attempts:
- topology: rustworkx.PyGraph[int, None][source]
- initial_layout = None[source]
- seed = None[source]
- lookahead_size = 10[source]
- beta[source]
- decay_delta[source]
- decay_lambda[source]
- max_swaps_factor[source]
- max_attempts = 10[source]
- last_swap_count: int | None = None[source]
- last_final_layout: list[int] | None = None[source]
- run(circuit: qilisdk.digital.Circuit) qilisdk.digital.Circuit[source]
Route a circuit onto the coupling graph using SABRE swap insertion.
The pass retries with different seeds when an attempt exceeds swap budget and stores diagnostics in context.
- Parameters:
circuit (
Circuit) – Logical circuit to route.- Returns:
Routed circuit with gates mapped to physical qubits and inserted SWAPs.
- Return type:
- Raises:
RuntimeError – If all attempts fail due to exhausted swap budgets.