SabreSwap

class SabreSwap(*args, **kwargs)[source]

Map input circuit onto a backend topology via insertion of SWAPs.

Implementation of the SWAP-based heuristic search from the SABRE qubit mapping paper [1] (Algorithm 1). The hueristic aims to minimize the number of lossy SWAPs inserted and the depth of the circuit.

This algorithm starts from an initial layout of virtual qubits onto physical qubits, and iterates over the circuit DAG until all gates are exhausted, inserting SWAPs along the way. It only considers 2-qubit gates as only those are germane for the mapping problem (it is assumed that 3+ qubit gates are already decomposed).

In each iteration, it will first check if there are any gates in the front_layer that can be directly applied. If so, it will apply them and remove them from front_layer, and replenish that layer with new gates if possible. Otherwise, it will try to search for SWAPs, insert the SWAPs, and update the mapping.

The search for SWAPs is restricted, in the sense that we only consider physical qubits in the neighoborhood of those qubits involved in front_layer. These give rise to a swap_candidate_list which is scored according to some heuristic cost function. The best SWAP is implemented and current_layout updated.

References:

[1] Li, Gushu, Yufei Ding, and Yuan Xie. “Tackling the qubit mapping problem for NISQ-era quantum devices.” ASPLOS 2019. arXiv:1809.02573

SabreSwap initializer.

Parameters
  • coupling_map (CouplingMap) – CouplingMap of the target backend.

  • heuristic (str) – The type of heuristic to use when deciding best swap strategy (‘basic’ or ‘lookahead’ or ‘decay’).

  • seed (int) – random seed used to tie-break among candidate swaps.

Additional Information:

The search space of possible SWAPs on physical qubits is explored by assigning a score to the layout that would result from each SWAP. The goodness of a layout is evaluated based on how viable it makes the remaining virtual gates that must be applied. A few heuristic cost functions are supported

  • ‘basic’:

The sum of distances for corresponding physical qubits of interacting virtual qubits in the front_layer.

\[H_{basic} = \sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)]\]
  • ‘lookahead’:

This is the sum of two costs: first is the same as the basic cost. Second is the basic cost but now evaluated for the extended set as well (i.e. \(|E|\) number of upcoming successors to gates in front_layer F). This is weighted by some amount EXTENDED_SET_WEIGHT (W) to signify that upcoming gates are less important that the front_layer.

\[H_{decay} = \frac{1}{\abs{F}} \sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)] + W * \frac{1}{\abs{E}} \sum_{gate \in E} D[\pi(gate.q_1)][\pi(gate.q2)]\]
  • ‘decay’:

This is the same as ‘lookahead’, but the whole cost is multiplied by a decay factor. This increases the cost if the SWAP that generated the trial layout was recently used (i.e. it penalizes increase in depth).

\[H_{decay} = max(decay(SWAP.q_1), decay(SWAP.q_2)) { \frac{1}{\abs{F}} \sum_{gate \in F} D[\pi(gate.q_1)][\pi(gate.q2)] + W * \frac{1}{\abs{E}} \sum_{gate \in E} D[\pi(gate.q_1)][\pi(gate.q2)] }\]

Attributes

SabreSwap.is_analysis_pass

Check if the pass is an analysis pass.

SabreSwap.is_transformation_pass

Check if the pass is a transformation pass.

Methods

SabreSwap.name()

Return the name of the pass.

SabreSwap.run(dag)

Run the SabreSwap pass on dag.