From 890aeb8c0cb3b42164adebfbe558e5b97b96a978 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Wed, 3 Nov 2021 07:38:06 -0400 Subject: [PATCH] Add back initial layout to level1 Since there seems to be a pretty baked in asumption for level 1 that it will use the trivial layout by default if it's a perfect mapping. This was causing the majority of the test failures and might be an unexpected breakage for people. However, in a future release we should remove this (likely when vf2layout is made noise aware). To anticipate this a FutureWarning is emitted when a trivial layout is used to indicate that this behavior will change in the future for level 1 and if you're relying on it you should explicitly set the layout_method='trivial'. --- .../transpiler/preset_passmanagers/level1.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py index 69907d4f401a..85707bf6b8d9 100644 --- a/qiskit/transpiler/preset_passmanagers/level1.py +++ b/qiskit/transpiler/preset_passmanagers/level1.py @@ -15,6 +15,8 @@ Level 1 pass manager: light optimization by simple adjacent gate collapsing. """ +import warnings + from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager @@ -33,6 +35,7 @@ from qiskit.transpiler.passes import NoiseAdaptiveLayout from qiskit.transpiler.passes import SabreLayout from qiskit.transpiler.passes import BarrierBeforeFinalMeasurements +from qiskit.transpiler.passes import Layout2qDistance from qiskit.transpiler.passes import BasicSwap from qiskit.transpiler.passes import LookaheadSwap from qiskit.transpiler.passes import StochasticSwap @@ -106,6 +109,24 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> PassManager: def _choose_layout_condition(property_set): return not property_set["layout"] + def _trivial_not_perfect(property_set): + # Verify that a trivial layout is perfect. If trivial_layout_score > 0 + # the layout is not perfect. The layout is unconditionally set by trivial + # layout so we need to clear it before contuing. + if property_set["trivial_layout_score"] is not None: + if property_set["trivial_layout_score"] != 0: + property_set["layout"]._wrapped = None + return True + warnings.warn( + "The current implicit default of using a trivial layout if it's a " + "perfect layout will change in a future release, if you're " + "depending on this behavior it is better to explicit set " + "layout_method='trivial' when calling transpile()", + FutureWarning, + stacklevel=4, # stack_level=4 to target caller of transpile() + ) + return False + def _vf2_match_not_found(property_set): # If a layout hasn't been set by the time we run vf2 layout we need to # run layout @@ -125,6 +146,15 @@ def _vf2_match_not_found(property_set): vf2_seed = -1 _choose_layout_0 = ( + [] + if pass_manager_config.layout_method + else [ + TrivialLayout(coupling_map), + Layout2qDistance(coupling_map, property_name="trivial_layout_score"), + ] + ) + + _choose_layout_1 = ( [] if pass_manager_config.layout_method else VF2Layout(coupling_map, seed=vf2_seed) ) @@ -286,6 +316,7 @@ def _contains_delay(property_set): pm1.append(_unroll3q) pm1.append(_given_layout) pm1.append(_choose_layout_0, condition=_choose_layout_condition) + pm1.append(_choose_layout_1, condition=_trivial_not_perfect) pm1.append(_improve_layout, condition=_vf2_match_not_found) pm1.append(_embed) pm1.append(_swap_check)