Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more default trials to sabre layout #13360

Merged
merged 9 commits into from
Nov 6, 2024
64 changes: 64 additions & 0 deletions crates/accelerate/src/sabre/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,70 @@ pub fn sabre_layout_and_routing(
&target,
run_in_parallel,
));
starting_layouts.push(
(0..target.neighbors.num_qubits() as u32)
.map(Some)
.collect(),
);
starting_layouts.push(
(0..target.neighbors.num_qubits() as u32)
.rev()
.map(Some)
.collect(),
);
// This layout targets the largest ring on an IBM eagle device. It has been
// shown to have good results on some circuits targeting these backends. In
// all other cases this is no different from an additional random trial,
// see: https://xkcd.com/221/
ElePT marked this conversation as resolved.
Show resolved Hide resolved
if target.neighbors.num_qubits() == 127 {
starting_layouts.push(
[
0, 1, 2, 3, 4, 5, 6, 15, 22, 23, 24, 25, 34, 43, 42, 41, 40, 53, 60, 59, 61, 62,
72, 81, 80, 79, 78, 91, 98, 99, 100, 101, 102, 103, 92, 83, 82, 84, 85, 86, 73, 66,
65, 64, 63, 54, 45, 44, 46, 47, 35, 28, 29, 27, 26, 16, 7, 8, 9, 10, 11, 12, 13,
17, 30, 31, 32, 36, 51, 50, 49, 48, 55, 68, 67, 69, 70, 74, 89, 88, 87, 93, 106,
105, 104, 107, 108, 112, 126, 125, 124, 123, 122, 111, 121, 120, 119, 118, 110,
117, 116, 115, 114, 113, 109, 96, 97, 95, 94, 90, 75, 76, 77, 71, 58, 57, 56, 52,
37, 38, 39, 33, 20, 21, 19, 18, 14,
]
.into_iter()
.map(Some)
.collect(),
);
} else if target.neighbors.num_qubits() == 133 {
// Same for IBM Heron 133 qubit devices. This is the ring computed by using rustworkx's
// max(simple_cycles(graph), key=len) on the connectivity graph.
starting_layouts.push(
[
108, 107, 94, 88, 89, 90, 75, 71, 70, 69, 56, 50, 51, 52, 37, 33, 32, 31, 18, 12,
11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 15, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 36, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 53, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 74, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 91, 95, 96, 97,
110, 116, 117, 118, 119, 120, 111, 101, 102, 103, 104, 105, 112, 124, 125, 126,
127, 128, 113, 109,
]
.into_iter()
.map(Some)
.collect(),
);
} else if target.neighbors.num_qubits() == 156 {
// Same for IBM Heron 156 qubit devices. This is the ring computed by using rustworkx's
// max(simple_cycles(graph), key=len) on the connectivity graph.
starting_layouts.push(
[
136, 123, 122, 121, 116, 101, 102, 103, 96, 83, 82, 81, 76, 61, 62, 63, 56, 43, 42,
41, 36, 21, 22, 23, 16, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 19, 35, 34,
33, 32, 31, 30, 29, 28, 27, 26, 25, 37, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
59, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 77, 85, 86, 87, 88, 89, 90, 91, 92,
93, 94, 95, 99, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 117, 125,
126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 139, 155, 154, 153, 152, 151,
150, 149, 148, 147, 146, 145, 144, 143,
]
.into_iter()
.map(Some)
.collect(),
);
}
let outer_rng = match seed {
Some(seed) => Pcg64Mcg::seed_from_u64(seed),
None => Pcg64Mcg::from_entropy(),
Expand Down
5 changes: 4 additions & 1 deletion qiskit/transpiler/passes/layout/sabre_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,10 @@ def __init__(
(and ``routing_pass`` is not set) then the number of local
physical CPUs will be used as the default value. This option is
mutually exclusive with the ``routing_pass`` argument and an error
will be raised if both are used.
will be raised if both are used. In addition to the specified random
trials an additional 3 or 4 trials depending on the ``coupling_map``
value are run with common layouts in addition to the random trial
count specified by this value.
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
skip_routing (bool): If this is set ``True`` and ``routing_pass`` is not used
then routing will not be applied to the output circuit. Only the layout
will be set in the property set. This is a tradeoff to run custom
Expand Down
12 changes: 12 additions & 0 deletions releasenotes/notes/add-more-sabre-trials-9b421f05d2f48d18.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
features_transpiler:
- |
The :class:`.SabreLayout` transpiler pass has been updated to run an
additional 2 or 3 layout trials by default independently of the
``layout_trials`` keyword argument's value. For all backends a trivial
layout and it's reverse are included just like the :class:`.DenseLayout`
trial that were added in 1.2.0. In addition if the backends are 127,
133, or 156 qubits the largest rings on an IBM backend heavy hex
connectivity graph are added. On those backends which are commonly run
this can provide a good starting point for some circuits on these
backends and for all others it's just an additional random trial.
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions test/python/transpiler/test_sabre_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def test_layout_with_classical_bits(self):
self.assertIsInstance(res, QuantumCircuit)
layout = res._layout.initial_layout
self.assertEqual(
[layout[q] for q in qc.qubits], [11, 19, 18, 16, 26, 8, 21, 1, 5, 15, 3, 12, 14, 13]
[layout[q] for q in qc.qubits], [2, 0, 5, 1, 7, 3, 14, 6, 9, 8, 10, 11, 4, 12]
)

# pylint: disable=line-too-long
Expand Down Expand Up @@ -271,7 +271,7 @@ def test_layout_many_search_trials(self):
self.assertIsInstance(res, QuantumCircuit)
layout = res._layout.initial_layout
self.assertEqual(
[layout[q] for q in qc.qubits], [22, 7, 2, 12, 1, 5, 14, 4, 11, 0, 16, 15, 3, 10]
[layout[q] for q in qc.qubits], [0, 12, 7, 3, 6, 11, 1, 10, 4, 9, 2, 5, 13, 8]
)

def test_support_var_with_rust_fastpath(self):
Expand Down