From 966aab1bb624cb45f8de77d305f5407d94dbd82d Mon Sep 17 00:00:00 2001 From: danielleodigie <97267313+danielleodigie@users.noreply.github.com> Date: Tue, 8 Aug 2023 18:34:09 -0400 Subject: [PATCH] Implementing Scheduling Pass as Plugins (#10545) * Draft for implementing scheduling pass as plugin * Handling None case * Linting * Adding Default Scheduling Plugin * removing unused imports --- .../preset_passmanagers/builtin_plugins.py | 52 +++++++++++++++++++ .../transpiler/preset_passmanagers/level0.py | 19 +++---- .../transpiler/preset_passmanagers/level1.py | 19 +++---- .../transpiler/preset_passmanagers/level2.py | 23 +++----- .../transpiler/preset_passmanagers/level3.py | 13 ++--- setup.py | 5 ++ 6 files changed, 78 insertions(+), 53 deletions(-) diff --git a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py index 8a44950d4367..2da12d7da8cf 100644 --- a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py +++ b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py @@ -21,6 +21,7 @@ from qiskit.transpiler.passes import Error from qiskit.transpiler.preset_passmanagers import common from qiskit.transpiler.preset_passmanagers.plugin import PassManagerStagePlugin +from qiskit.transpiler.timing_constraints import TimingConstraints class BasicSwapPassManager(PassManagerStagePlugin): @@ -315,3 +316,54 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana seed_transpiler=seed_transpiler, use_barrier_before_measurement=True, ) + + +class AlapSchedulingPassManager(PassManagerStagePlugin): + """Plugin class for alap scheduling stage.""" + + def pass_manager(self, pass_manager_config, optimization_level=None) -> PassManager: + """Build scheduling stage PassManager""" + + instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method + timing_constraints = pass_manager_config.timing_constraints + inst_map = pass_manager_config.inst_map + target = pass_manager_config.target + + return common.generate_scheduling( + instruction_durations, scheduling_method, timing_constraints, inst_map, target + ) + + +class AsapSchedulingPassManager(PassManagerStagePlugin): + """Plugin class for alap scheduling stage.""" + + def pass_manager(self, pass_manager_config, optimization_level=None) -> PassManager: + """Build scheduling stage PassManager""" + + instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method + timing_constraints = pass_manager_config.timing_constraints + inst_map = pass_manager_config.inst_map + target = pass_manager_config.target + + return common.generate_scheduling( + instruction_durations, scheduling_method, timing_constraints, inst_map, target + ) + + +class DefaultSchedulingPassManager(PassManagerStagePlugin): + """Plugin class for alap scheduling stage.""" + + def pass_manager(self, pass_manager_config, optimization_level=None) -> PassManager: + """Build scheduling stage PassManager""" + + instruction_durations = pass_manager_config.instruction_durations + scheduling_method = None + timing_constraints = pass_manager_config.timing_constraints or TimingConstraints() + inst_map = pass_manager_config.inst_map + target = pass_manager_config.target + + return common.generate_scheduling( + instruction_durations, scheduling_method, timing_constraints, inst_map, target + ) diff --git a/qiskit/transpiler/preset_passmanagers/level0.py b/qiskit/transpiler/preset_passmanagers/level0.py index b0790f1026f2..ce8a5eedb232 100644 --- a/qiskit/transpiler/preset_passmanagers/level0.py +++ b/qiskit/transpiler/preset_passmanagers/level0.py @@ -17,7 +17,6 @@ from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig -from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager from qiskit.transpiler.passmanager import StagedPassManager @@ -53,7 +52,6 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa """ plugin_manager = PassManagerStagePluginManager() basis_gates = pass_manager_config.basis_gates - inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout init_method = pass_manager_config.init_method @@ -61,12 +59,10 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa routing_method = pass_manager_config.routing_method or "stochastic" translation_method = pass_manager_config.translation_method or "translator" optimization_method = pass_manager_config.optimization_method - scheduling_method = pass_manager_config.scheduling_method - instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method or "default" seed_transpiler = pass_manager_config.seed_transpiler backend_properties = pass_manager_config.backend_properties approximation_degree = pass_manager_config.approximation_degree - timing_constraints = pass_manager_config.timing_constraints or TimingConstraints() unitary_synthesis_method = pass_manager_config.unitary_synthesis_method unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config target = pass_manager_config.target @@ -163,14 +159,11 @@ def _swap_mapped(property_set): pre_opt += translation else: pre_opt = None - if scheduling_method is None or scheduling_method in {"alap", "asap"}: - sched = common.generate_scheduling( - instruction_durations, scheduling_method, timing_constraints, inst_map, target=target - ) - else: - sched = plugin_manager.get_passmanager_stage( - "scheduling", scheduling_method, pass_manager_config, optimization_level=0 - ) + + sched = plugin_manager.get_passmanager_stage( + "scheduling", scheduling_method, pass_manager_config, optimization_level=0 + ) + init = common.generate_control_flow_options_check( layout_method=layout_method, routing_method=routing_method, diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py index c56cd820262c..cbe63265589d 100644 --- a/qiskit/transpiler/preset_passmanagers/level1.py +++ b/qiskit/transpiler/preset_passmanagers/level1.py @@ -17,7 +17,6 @@ from __future__ import annotations from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig -from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager from qiskit.transpiler.passmanager import StagedPassManager from qiskit.transpiler import ConditionalController, FlowController @@ -67,7 +66,6 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa """ plugin_manager = PassManagerStagePluginManager() basis_gates = pass_manager_config.basis_gates - inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout init_method = pass_manager_config.init_method @@ -77,14 +75,12 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa routing_method = pass_manager_config.routing_method or "sabre" translation_method = pass_manager_config.translation_method or "translator" optimization_method = pass_manager_config.optimization_method - scheduling_method = pass_manager_config.scheduling_method - instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method or "default" seed_transpiler = pass_manager_config.seed_transpiler backend_properties = pass_manager_config.backend_properties approximation_degree = pass_manager_config.approximation_degree unitary_synthesis_method = pass_manager_config.unitary_synthesis_method unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config - timing_constraints = pass_manager_config.timing_constraints or TimingConstraints() target = pass_manager_config.target hls_config = pass_manager_config.hls_config @@ -256,14 +252,11 @@ def _unroll_condition(property_set): optimization = plugin_manager.get_passmanager_stage( "optimization", optimization_method, pass_manager_config, optimization_level=1 ) - if scheduling_method is None or scheduling_method in {"alap", "asap"}: - sched = common.generate_scheduling( - instruction_durations, scheduling_method, timing_constraints, inst_map, target=target - ) - else: - sched = plugin_manager.get_passmanager_stage( - "scheduling", scheduling_method, pass_manager_config, optimization_level=1 - ) + + sched = plugin_manager.get_passmanager_stage( + "scheduling", scheduling_method, pass_manager_config, optimization_level=1 + ) + init = common.generate_control_flow_options_check( layout_method=layout_method, routing_method=routing_method, diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py index 62880e3eeec9..ca7a515c4a43 100644 --- a/qiskit/transpiler/preset_passmanagers/level2.py +++ b/qiskit/transpiler/preset_passmanagers/level2.py @@ -18,7 +18,6 @@ from __future__ import annotations from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig -from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager from qiskit.transpiler.passmanager import StagedPassManager from qiskit.transpiler import ConditionalController, FlowController @@ -69,7 +68,6 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa """ plugin_manager = PassManagerStagePluginManager() basis_gates = pass_manager_config.basis_gates - inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout init_method = pass_manager_config.init_method @@ -77,13 +75,11 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa routing_method = pass_manager_config.routing_method or "sabre" translation_method = pass_manager_config.translation_method or "translator" optimization_method = pass_manager_config.optimization_method - scheduling_method = pass_manager_config.scheduling_method - instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method or "default" seed_transpiler = pass_manager_config.seed_transpiler backend_properties = pass_manager_config.backend_properties approximation_degree = pass_manager_config.approximation_degree unitary_synthesis_method = pass_manager_config.unitary_synthesis_method - timing_constraints = pass_manager_config.timing_constraints or TimingConstraints() unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config target = pass_manager_config.target hls_config = pass_manager_config.hls_config @@ -242,18 +238,11 @@ def _unroll_condition(property_set): optimization = plugin_manager.get_passmanager_stage( "optimization", optimization_method, pass_manager_config, optimization_level=2 ) - if scheduling_method is None or scheduling_method in {"alap", "asap"}: - sched = common.generate_scheduling( - instruction_durations, - scheduling_method, - timing_constraints, - inst_map, - target=target, - ) - else: - sched = plugin_manager.get_passmanager_stage( - "scheduling", scheduling_method, pass_manager_config, optimization_level=2 - ) + + sched = plugin_manager.get_passmanager_stage( + "scheduling", scheduling_method, pass_manager_config, optimization_level=2 + ) + init = common.generate_control_flow_options_check( layout_method=layout_method, routing_method=routing_method, diff --git a/qiskit/transpiler/preset_passmanagers/level3.py b/qiskit/transpiler/preset_passmanagers/level3.py index 81ca9af75eee..53c4f148d711 100644 --- a/qiskit/transpiler/preset_passmanagers/level3.py +++ b/qiskit/transpiler/preset_passmanagers/level3.py @@ -18,7 +18,6 @@ from __future__ import annotations from qiskit.transpiler.basepasses import BasePass from qiskit.transpiler.passmanager_config import PassManagerConfig -from qiskit.transpiler.timing_constraints import TimingConstraints from qiskit.transpiler.passmanager import PassManager from qiskit.transpiler.passmanager import StagedPassManager @@ -74,7 +73,6 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa """ plugin_manager = PassManagerStagePluginManager() basis_gates = pass_manager_config.basis_gates - inst_map = pass_manager_config.inst_map coupling_map = pass_manager_config.coupling_map initial_layout = pass_manager_config.initial_layout init_method = pass_manager_config.init_method @@ -82,13 +80,11 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa routing_method = pass_manager_config.routing_method or "sabre" translation_method = pass_manager_config.translation_method or "translator" optimization_method = pass_manager_config.optimization_method - scheduling_method = pass_manager_config.scheduling_method - instruction_durations = pass_manager_config.instruction_durations + scheduling_method = pass_manager_config.scheduling_method or "default" seed_transpiler = pass_manager_config.seed_transpiler backend_properties = pass_manager_config.backend_properties approximation_degree = pass_manager_config.approximation_degree unitary_synthesis_method = pass_manager_config.unitary_synthesis_method - timing_constraints = pass_manager_config.timing_constraints or TimingConstraints() unitary_synthesis_plugin_config = pass_manager_config.unitary_synthesis_plugin_config target = pass_manager_config.target hls_config = pass_manager_config.hls_config @@ -299,12 +295,9 @@ def _unroll_condition(property_set): else: pre_optimization = common.generate_pre_op_passmanager(remove_reset_in_zero=True) - if scheduling_method is None or scheduling_method in {"alap", "asap"}: - sched = common.generate_scheduling( - instruction_durations, scheduling_method, timing_constraints, inst_map, target=target - ) - elif isinstance(scheduling_method, PassManager): + if isinstance(scheduling_method, PassManager): sched = scheduling_method + else: sched = plugin_manager.get_passmanager_stage( "scheduling", scheduling_method, pass_manager_config, optimization_level=3 diff --git a/setup.py b/setup.py index c80aa0296778..06d07404ab4d 100644 --- a/setup.py +++ b/setup.py @@ -146,5 +146,10 @@ "sabre = qiskit.transpiler.preset_passmanagers.builtin_plugins:SabreSwapPassManager", "none = qiskit.transpiler.preset_passmanagers.builtin_plugins:NoneRoutingPassManager", ], + "qiskit.transpiler.scheduling": [ + "alap = qiskit.transpiler.preset_passmanagers.builtin_plugins:AlapSchedulingPassManager", + "asap = qiskit.transpiler.preset_passmanagers.builtin_plugins:AsapSchedulingPassManager", + "default = qiskit.transpiler.preset_passmanagers.builtin_plugins:DefaultSchedulingPassManager", + ], }, )