Skip to main contentIBM Quantum Documentation
This page is from an old version of Qiskit SDK. Go to the latest version

Transpiler Stage Plugin Interface

qiskit.transpiler.preset_passmanagers.plugin

This module defines the plugin interface for providing custom stage implementations for the preset pass managers and the transpile() function. This enables external Python packages to provide PassManager objects that can be used for each named stage.

The plugin interfaces are built using setuptools entry points which enable packages external to Qiskit to advertise they include a transpiler stage(s).

For details on how to instead write plugins for transpiler synthesis methods, see qiskit.transpiler.passes.synthesis.plugin.


Plugin Stages

Currently, there are 6 stages in the preset pass managers, all of which actively load external plugins via corresponding entry points.

Stage NameEntry PointReserved NamesDescription and expectations
initqiskit.transpiler.initNo reserved namesThis stage runs first and is typically used for any initial logical optimization. Because most layout and routing algorithms are only designed to work with 1 and 2 qubit gates, this stage is also used to translate any gates that operate on more than 2 qubits into gates that only operate on 1 or 2 qubits.
layoutqiskit.transpiler.layouttrivial, dense, noise_adaptive, sabreThe output from this stage is expected to have the layout property set field set with a Layout object. Additionally, the circuit is typically expected to be embedded so that it is expanded to include all qubits and the ApplyLayout pass is expected to be run to apply the layout. The embedding of the Layout can be generated with generate_embed_passmanager().
routingqiskit.transpiler.routingbasic, stochastic, lookahead, sabre, toqmThe output from this stage is expected to have the circuit match the connectivity constraints of the target backend. This does not necessarily need to match the directionality of the edges in the target as a later stage typically will adjust directional gates to match that constraint (but there is no penalty for doing that in the routing stage).
translationqiskit.transpiler.translationtranslator, synthesis, unrollerThe output of this stage is expected to have every operation be a nativeinstruction on the target backend.
optimizationqiskit.transpiler.optimizationThere are no reserved plugin namesThis stage is expected to perform optimization and simplification. The constraints from earlier stages still apply to the output of this stage. After the optimization stage is run we expect the circuit to still be executable on the target.
schedulingqiskit.transpiler.schedulingalap, asapThis is the last stage run and it is expected to output a scheduled circuit such that all idle periods in the circuit are marked by explicit Delay instructions.

Writing Plugins

To write a pass manager stage plugin there are 2 main steps. The first step is to create a subclass of the abstract plugin class PassManagerStagePlugin which is used to define how the PassManager for the stage will be constructed. For example, to create a layout stage plugin that just runs VF2Layout (with increasing amount of trials, depending on the optimization level) and falls back to using TrivialLayout if VF2Layout is unable to find a perfect layout:

from qiskit.transpiler.preset_passmanagers.plugin import PassManagerStagePlugin
from qiskit.transpiler.preset_passmanagers import common
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import VF2Layout, TrivialLayout
from qiskit.transpiler.passes.layout.vf2_layout import VF2LayoutStopReason
 
 
def _vf2_match_not_found(property_set):
    return property_set["layout"] is None or (
        property_set["VF2Layout_stop_reason"] is not None
        and property_set["VF2Layout_stop_reason"] is not VF2LayoutStopReason.SOLUTION_FOUND
 
 
class VF2LayoutPlugin(PassManagerStagePlugin):
 
    def pass_manager(self, pass_manager_config, optimization_level):
        layout_pm = PassManager(
            [
                VF2Layout(
                    coupling_map=pass_manager_config.coupling_map,
                    properties=pass_manager_config.backend_properties,
                    max_trials=optimization_level * 10 + 1
                    target=pass_manager_config.target
                )
            ]
        )
        layout_pm.append(
            TrivialLayout(pass_manager_config.coupling_map),
            condition=_vf2_match_not_found,
        )
        layout_pm += common.generate_embed_passmanager(pass_manager_config.coupling_map)
        return layout_pm

The second step is to expose the PassManagerStagePlugin subclass as a setuptools entry point in the package metadata. This can be done by simply adding an entry_points entry to the setuptools.setup call in the setup.py or the plugin package with the necessary entry points under the appropriate namespace for the stage your plugin is for. You can see the list of stages, entry points, and expectations from the stage in Plugin Stages. For example, continuing from the example plugin above:

entry_points = {
    'qiskit.transpiler.layout': [
        'vf2 = qiskit_plugin_pkg.module.plugin:VF2LayoutPlugin',
    ]
},

Note that the entry point name = path is a single string not a Python expression. There isn’t a limit to the number of plugins a single package can include as long as each plugin has a unique name. So a single package can expose multiple plugins if necessary. Refer to Plugin Stages for a list of reserved names for each stage.


Plugin API

PassManagerStagePlugin()A PassManagerStagePlugin is a plugin interface object for using custom stages in transpile().
PassManagerStagePluginManager()Manager class for preset pass manager stage plugins.
list_stage_plugins(stage_name)Get a list of installed plugins for a stage.
Was this page helpful?
Report a bug or request content on GitHub.