Skip to content

Commit b2d4c87

Browse files
authored
Simply Sabre release-valve calculation (Qiskit#15897)
There is an edge case in release-valve handling where, if the shortest path is a single swap (but the heuristics have been chosen such that it is unselectable normally), it is possible for the release valve to cause _two_ gates to be routed. The previous handling of this path was written in quite a complicated manner, likely to be able to use `closest_node` by name from its discovery earlier in the release-valve process. Instead, it is easier to recognise that, given a single swap: * the two qubits cannot be part of the same gate, or the gate would have been routable _without_ the swap; * the `closest_node` must touch one of these qubits because of the the Dijkstra search; * therefore we can simply add any routable gate that touches _either_ qubit without risk of duplication or forgetting `closest_swap`.
1 parent 2941838 commit b2d4c87

1 file changed

Lines changed: 5 additions & 20 deletions

File tree

  • crates/transpiler/src/passes/sabre

crates/transpiler/src/passes/sabre/route.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -703,27 +703,12 @@ impl State {
703703
// If we apply a single swap it could be that we route 2 nodes; that is a setup like
704704
// A - B - A - B
705705
// and we swap the middle two qubits. This cannot happen if we apply 2 or more swaps.
706-
if current_swaps.len() > 1 {
707-
smallvec![closest_node]
708-
} else {
709-
// check if the closest node has neighbors that are now routable -- for that we get
710-
// the other physical qubit that was swapped and check whether the node on it
711-
// is now routable
712-
let mut possible_other_qubit = current_swaps[0]
706+
match current_swaps.as_slice() {
707+
[swap] => swap
713708
.iter()
714-
// check if other nodes are in the front layer that are connected by this swap
715-
.filter_map(|&swap_qubit| self.front_layer.qubits()[swap_qubit.index()])
716-
// remove the closest_node, which we know we already routed
717-
.filter(|(node_index, _other_qubit)| *node_index != closest_node)
718-
.map(|(_node_index, other_qubit)| other_qubit);
719-
720-
// if there is indeed another candidate, check if that gate is routable
721-
if let Some(other_qubit) = possible_other_qubit.next() {
722-
if let Some(also_routed) = self.routable_node_on_qubit(problem, other_qubit) {
723-
return smallvec![closest_node, also_routed];
724-
}
725-
}
726-
smallvec![closest_node]
709+
.filter_map(|q| self.routable_node_on_qubit(problem, *q))
710+
.collect(),
711+
_ => smallvec![closest_node],
727712
}
728713
}
729714

0 commit comments

Comments
 (0)