Skip to content

Commit ea7c3e3

Browse files
authored
Add default routing stage plugin (Qiskit#13802)
This is added for a similar reason as the recent `default` translation-stage plugin (Qiskitgh-13794). We currently have no plans to change the default routing method, if not only because the `default` layout plugin does routing most of the time, but this makes the semantics of "just use the default method" clearer.
1 parent 83c20e9 commit ea7c3e3

File tree

11 files changed

+59
-24
lines changed

11 files changed

+59
-24
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ synthesis = "qiskit.transpiler.preset_passmanagers.builtin_plugins:UnitarySynthe
127127
translator = "qiskit.transpiler.preset_passmanagers.builtin_plugins:BasisTranslatorPassManager"
128128

129129
[project.entry-points."qiskit.transpiler.routing"]
130+
default = "qiskit.transpiler.preset_passmanagers.builtin_plugins:DefaultRoutingPassManager"
130131
basic = "qiskit.transpiler.preset_passmanagers.builtin_plugins:BasicSwapPassManager"
131132
lookahead = "qiskit.transpiler.preset_passmanagers.builtin_plugins:LookaheadSwapPassManager"
132133
none = "qiskit.transpiler.preset_passmanagers.builtin_plugins:NoneRoutingPassManager"

qiskit/transpiler/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@
505505
* - Method
506506
- Summary
507507
508+
* - :ref:`default <transpiler-preset-stage-routing-default>`
509+
- Use a Qiskit-chosen default routing method.
510+
508511
* - :ref:`sabre <transpiler-preset-stage-routing-sabre>`
509512
- Default. Uses `Qiskit's modified Sabre routing algorithm <sabre-lightsabre-paper_>`_ to
510513
swap map.
@@ -522,6 +525,16 @@
522525
* - :ref:`lookahead <transpiler-preset-stage-routing-lookahead>`
523526
- Breadth-first search with heuristic pruning to find swaps that make gates executable.
524527
528+
.. _transpiler-preset-stage-routing-default:
529+
530+
Built-in ``default`` plugin
531+
...........................
532+
533+
Use a Qiskit-chosen default method for routing. As of Qiskit 2.0, the chosen algorithm is the same
534+
as :ref:`transpiler-preset-stage-routing-sabre`, though in practice, usually the :ref:`built-in
535+
default layout-stage plugin <transpiler-preset-stage-layout-default>` will run the Sabre-based
536+
routing algorithm, and the routing stage will only be used to run :class:`.VF2PostLayout`.
537+
525538
.. _transpiler-preset-stage-routing-none:
526539
527540
Built-in ``none`` plugin

qiskit/transpiler/preset_passmanagers/builtin_plugins.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,17 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana
249249
)
250250

251251

252+
class DefaultRoutingPassManager(PassManagerStagePlugin):
253+
"""Plugin class for the "default" routing stage implementation."""
254+
255+
def pass_manager(self, pass_manager_config, optimization_level=None) -> PassManager:
256+
# The Sabre-based PM is the default implementation currently, but semantically the "default"
257+
# plugin has more scope to change its logic than one called "sabre". In practice, we don't
258+
# run the actually `SabreSwap` logic from this pass most of the time, because we do that
259+
# during default layout; we're looking for the VF2PostLayout stuff mostly.
260+
return SabreSwapPassManager().pass_manager(pass_manager_config, optimization_level)
261+
262+
252263
class BasicSwapPassManager(PassManagerStagePlugin):
253264
"""Plugin class for routing stage with :class:`~.BasicSwap`"""
254265

@@ -804,8 +815,7 @@ def _swap_mapped(property_set):
804815
seed=pass_manager_config.seed_transpiler,
805816
swap_trials=trial_count,
806817
layout_trials=trial_count,
807-
skip_routing=pass_manager_config.routing_method is not None
808-
and pass_manager_config.routing_method != "sabre",
818+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
809819
)
810820
layout.append(
811821
ConditionalController(
@@ -838,8 +848,7 @@ def _swap_mapped(property_set):
838848
seed=pass_manager_config.seed_transpiler,
839849
swap_trials=trial_count,
840850
layout_trials=trial_count,
841-
skip_routing=pass_manager_config.routing_method is not None
842-
and pass_manager_config.routing_method != "sabre",
851+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
843852
)
844853
layout.append(
845854
ConditionalController(
@@ -872,8 +881,7 @@ def _swap_mapped(property_set):
872881
seed=pass_manager_config.seed_transpiler,
873882
swap_trials=trial_count,
874883
layout_trials=trial_count,
875-
skip_routing=pass_manager_config.routing_method is not None
876-
and pass_manager_config.routing_method != "sabre",
884+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
877885
)
878886
layout.append(
879887
ConditionalController(
@@ -974,8 +982,7 @@ def _swap_mapped(property_set):
974982
seed=pass_manager_config.seed_transpiler,
975983
swap_trials=trial_count,
976984
layout_trials=trial_count,
977-
skip_routing=pass_manager_config.routing_method is not None
978-
and pass_manager_config.routing_method != "sabre",
985+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
979986
)
980987
elif optimization_level == 1:
981988
trial_count = _get_trial_count(5)
@@ -986,8 +993,7 @@ def _swap_mapped(property_set):
986993
seed=pass_manager_config.seed_transpiler,
987994
swap_trials=trial_count,
988995
layout_trials=trial_count,
989-
skip_routing=pass_manager_config.routing_method is not None
990-
and pass_manager_config.routing_method != "sabre",
996+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
991997
)
992998
elif optimization_level == 2:
993999
trial_count = _get_trial_count(20)
@@ -998,8 +1004,7 @@ def _swap_mapped(property_set):
9981004
seed=pass_manager_config.seed_transpiler,
9991005
swap_trials=trial_count,
10001006
layout_trials=trial_count,
1001-
skip_routing=pass_manager_config.routing_method is not None
1002-
and pass_manager_config.routing_method != "sabre",
1007+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
10031008
)
10041009
elif optimization_level == 3:
10051010
trial_count = _get_trial_count(20)
@@ -1010,8 +1015,7 @@ def _swap_mapped(property_set):
10101015
seed=pass_manager_config.seed_transpiler,
10111016
swap_trials=trial_count,
10121017
layout_trials=trial_count,
1013-
skip_routing=pass_manager_config.routing_method is not None
1014-
and pass_manager_config.routing_method != "sabre",
1018+
skip_routing=pass_manager_config.routing_method not in (None, "default", "sabre"),
10151019
)
10161020
else:
10171021
raise TranspilerError(f"Invalid optimization level: {optimization_level}")

qiskit/transpiler/preset_passmanagers/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
working={"default", "trivial", "dense", "sabre"}, not_working=set()
6363
),
6464
"routing_method": _ControlFlowState(
65-
working={"none", "stochastic", "sabre"}, not_working={"lookahead", "basic"}
65+
working={"default", "none", "stochastic", "sabre"}, not_working={"lookahead", "basic"}
6666
),
6767
"translation_method": _ControlFlowState(
6868
working={"default", "translator", "synthesis"},

qiskit/transpiler/preset_passmanagers/level0.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
4848
initial_layout = pass_manager_config.initial_layout
4949
init_method = pass_manager_config.init_method or "default"
5050
layout_method = pass_manager_config.layout_method or "default"
51-
routing_method = pass_manager_config.routing_method or "sabre"
51+
routing_method = pass_manager_config.routing_method or "default"
5252
translation_method = pass_manager_config.translation_method or "default"
5353
optimization_method = pass_manager_config.optimization_method or "default"
5454
scheduling_method = pass_manager_config.scheduling_method or "default"

qiskit/transpiler/preset_passmanagers/level1.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
4949
coupling_map = pass_manager_config.coupling_map
5050
initial_layout = pass_manager_config.initial_layout
5151
init_method = pass_manager_config.init_method or "default"
52-
# Unlike other presets, the layout and routing defaults aren't set here because they change
53-
# based on whether the input circuit has control flow.
5452
layout_method = pass_manager_config.layout_method or "default"
55-
routing_method = pass_manager_config.routing_method or "sabre"
53+
routing_method = pass_manager_config.routing_method or "default"
5654
translation_method = pass_manager_config.translation_method or "default"
5755
optimization_method = pass_manager_config.optimization_method or "default"
5856
scheduling_method = pass_manager_config.scheduling_method or "default"

qiskit/transpiler/preset_passmanagers/level2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
5353
initial_layout = pass_manager_config.initial_layout
5454
init_method = pass_manager_config.init_method or "default"
5555
layout_method = pass_manager_config.layout_method or "default"
56-
routing_method = pass_manager_config.routing_method or "sabre"
56+
routing_method = pass_manager_config.routing_method or "default"
5757
translation_method = pass_manager_config.translation_method or "default"
5858
optimization_method = pass_manager_config.optimization_method or "default"
5959
scheduling_method = pass_manager_config.scheduling_method or "default"

qiskit/transpiler/preset_passmanagers/level3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
5353
initial_layout = pass_manager_config.initial_layout
5454
init_method = pass_manager_config.init_method or "default"
5555
layout_method = pass_manager_config.layout_method or "default"
56-
routing_method = pass_manager_config.routing_method or "sabre"
56+
routing_method = pass_manager_config.routing_method or "default"
5757
translation_method = pass_manager_config.translation_method or "default"
5858
scheduling_method = pass_manager_config.scheduling_method
5959
optimization_method = pass_manager_config.optimization_method or "default"

qiskit/transpiler/preset_passmanagers/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
6565
* - :ref:`routing <transpiler-preset-stage-routing>`
6666
- ``qiskit.transpiler.routing``
67-
- ``basic``, ``stochastic``, ``lookahead``, ``sabre``
67+
- ``default``, ``basic``, ``stochastic``, ``lookahead``, ``sabre``
6868
- Insert gates into the circuit to ensure it matches the connectivity constraints of the
6969
:class:`.Target`. The inserted gates do not need to be in the target ISA yet, so are often
7070
just output as ``swap`` instructions. This stage is sometimes subsumed by ``layout``.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
---
3+
features_transpiler:
4+
- |
5+
A new :ref:`routing plugin stage <transpiler-preset-stage-routing>` is added, called
6+
``"default"``. In Qiskit 2.0, this is simply an alias for the previous default ``"sabre"``.
7+
The underlying default algorithm may change over the course of the Qiskit 2.x series for some or
8+
all targets, but you can always set ``routing_method="sabre"`` explicitly to maintain
9+
the current behavior.
10+
upgrade_transpiler:
11+
- |
12+
The :ref:`routing plugin stage <transpiler-preset-stage-routing>` name ``default`` is
13+
now reserved for the Qiskit built-in plugin of the same name.
14+
- |
15+
The default :ref:`routing plugin stage <transpiler-preset-stage-routing>` is now
16+
``"default"``. In Qiskit 2.0, this is simply an alias for the previous default ``"sabre"``.
17+
The underlying default algorithm may change over the course of the Qiskit 2.x series for some or
18+
all targets, but you can always set ``routing_method="sabre"`` explicitly to maintain
19+
the current behavior.

0 commit comments

Comments
 (0)