From b286c6def1b312053c392b80390c0c4fdebb6e31 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 16 Aug 2022 08:50:05 -0400 Subject: [PATCH] Use Sabre by default for optimization levels 1 and 2 This commit updates the preset pass manager construction to use the SabreLayout and SabreSwap passes by default for optimization level 1 and level 2. With the recently merged #7977 the performance of the sabre swap pass has improved significantly enough to be considered for use by default with optimization levels 1 and 2. While for small numbers of target device qubits (< 30) the SabreLayout/SabreSwap pass doesn't quite match the runtime performance of DenseLayout/StochasticSwap it typically has better runtime performance for larger target devices. Additionally, the runtime performance of Sabre should also improve further after #8388 is finished. However, the output quality from the sabre passes is typically better resulting in fewer swap gates being inserted. With the combination of better quality and comparable runtime performance it makes sense to use sabre as the default for optimization levels 1 and 2. For optimization level 0 stochastic swap is still used there because we want to continue to leverage TrivialLayout for that level and to get the full quality advantages SabreSwap and SabreLayout should be used together. --- qiskit/transpiler/preset_passmanagers/level1.py | 6 +++--- qiskit/transpiler/preset_passmanagers/level2.py | 4 ++-- .../sabres-for-everyone-3148ccf2064ccb0d.yaml | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/sabres-for-everyone-3148ccf2064ccb0d.yaml diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py index 5da52fb23052..b5555c678363 100644 --- a/qiskit/transpiler/preset_passmanagers/level1.py +++ b/qiskit/transpiler/preset_passmanagers/level1.py @@ -69,8 +69,8 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout - layout_method = pass_manager_config.layout_method or "dense" - routing_method = pass_manager_config.routing_method or "stochastic" + layout_method = pass_manager_config.layout_method or "sabre" + routing_method = pass_manager_config.routing_method or "sabre" translation_method = pass_manager_config.translation_method or "translator" scheduling_method = pass_manager_config.scheduling_method instruction_durations = pass_manager_config.instruction_durations @@ -154,7 +154,7 @@ def _vf2_match_not_found(property_set): elif routing_method == "lookahead": routing_pass = LookaheadSwap(coupling_map, search_depth=4, search_width=4) elif routing_method == "sabre": - routing_pass = SabreSwap(coupling_map, heuristic="lookahead", seed=seed_transpiler) + routing_pass = SabreSwap(coupling_map, heuristic="decay", seed=seed_transpiler) elif routing_method == "toqm": HAS_TOQM.require_now("TOQM-based routing") from qiskit_toqm import ToqmSwap, ToqmStrategyO1, latencies_from_target diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py index c2ee13ad8500..aab26dddfeb5 100644 --- a/qiskit/transpiler/preset_passmanagers/level2.py +++ b/qiskit/transpiler/preset_passmanagers/level2.py @@ -71,8 +71,8 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout - layout_method = pass_manager_config.layout_method or "dense" - routing_method = pass_manager_config.routing_method or "stochastic" + layout_method = pass_manager_config.layout_method or "sabre" + routing_method = pass_manager_config.routing_method or "sabre" translation_method = pass_manager_config.translation_method or "translator" scheduling_method = pass_manager_config.scheduling_method instruction_durations = pass_manager_config.instruction_durations diff --git a/releasenotes/notes/sabres-for-everyone-3148ccf2064ccb0d.yaml b/releasenotes/notes/sabres-for-everyone-3148ccf2064ccb0d.yaml new file mode 100644 index 000000000000..2be30c7a290e --- /dev/null +++ b/releasenotes/notes/sabres-for-everyone-3148ccf2064ccb0d.yaml @@ -0,0 +1,17 @@ +--- +upgrade: + - | + The preset pass managers for levels 1 and 2, which will be used when + ``optimization_level=1`` or ``optimization_level=2`` with + :func:`~.transpile` or :func:`~.generate_preset_pass_manager` and output + from :func:`~.level_1_pass_manager` and :func:`~.level_2_pass_manager`, + will now use :class:`~.SabreLayout` and :func:`~SabreSwap` by default + instead of the previous defaults :class:`~.DenseLayout` and + :class:`~.StochasticSwap`. This change was made to improve the output + quality of the transpiler, the :class:`~.SabreLayout` and + :func:`~SabreSwap` combination typically results in fewer + :class:`~.SwapGate` objects being inserted into the output circuit. + If you would like to use the previous default passes you can set + ``layout_method='dense'`` and ``routing_method='stochastic'`` on + :func:`~.transpile` or :func:`~.generate_preset_pass_manager to + leverage :class:`~.DenseLayout` and :class:`~.StochasticSwap` respectively.