165 lines
18 KiB
Plaintext
165 lines
18 KiB
Plaintext
---
|
||
title: plugin
|
||
description: API reference for qiskit.transpiler.preset_passmanagers.plugin
|
||
in_page_toc_min_heading_level: 2
|
||
python_api_type: module
|
||
python_api_name: qiskit.transpiler.preset_passmanagers.plugin
|
||
---
|
||
|
||
<span id="module-qiskit.transpiler.preset_passmanagers.plugin" />
|
||
|
||
<span id="qiskit-transpiler-plugins" />
|
||
|
||
<span id="transpiler-stage-plugin-interface-qiskit-transpiler-preset-passmanagers-plugin" />
|
||
|
||
# Transpiler Stage Plugin Interface
|
||
|
||
<span id="module-qiskit.transpiler.preset_passmanagers.plugin" />
|
||
|
||
`qiskit.transpiler.preset_passmanagers.plugin`
|
||
|
||
This module defines the plugin interface for providing custom stage implementations for the preset pass managers and the [`transpile()`](compiler#qiskit.compiler.transpile "qiskit.compiler.transpile") function. This enables external Python packages to provide [`PassManager`](qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") objects that can be used for each named stage.
|
||
|
||
The plugin interfaces are built using setuptools [entry points](https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html) 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`](transpiler_synthesis_plugins#module-qiskit.transpiler.passes.synthesis.plugin "qiskit.transpiler.passes.synthesis.plugin").
|
||
|
||
<span id="stage-table" />
|
||
|
||
## Plugin Stages
|
||
|
||
Currently, there are 6 stages in the preset pass managers, all of which actively load external plugins via corresponding entry points.
|
||
|
||
| Stage Name | Entry Point | Reserved Names | Description and expectations |
|
||
| -------------- | -------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| `init` | `qiskit.transpiler.init` | `default` | This 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. |
|
||
| `layout` | `qiskit.transpiler.layout` | `trivial`, `dense`, `sabre`, `default` | The output from this stage is expected to have the `layout` property set field set with a [`Layout`](qiskit.transpiler.Layout "qiskit.transpiler.Layout") object. Additionally, the circuit is typically expected to be embedded so that it is expanded to include all qubits and the [`ApplyLayout`](qiskit.transpiler.passes.ApplyLayout "qiskit.transpiler.passes.ApplyLayout") pass is expected to be run to apply the layout. The embedding of the [`Layout`](qiskit.transpiler.Layout "qiskit.transpiler.Layout") can be generated with [`generate_embed_passmanager()`](transpiler_preset#qiskit.transpiler.preset_passmanagers.common.generate_embed_passmanager "qiskit.transpiler.preset_passmanagers.common.generate_embed_passmanager"). |
|
||
| `routing` | `qiskit.transpiler.routing` | `basic`, `stochastic`, `lookahead`, `sabre` | The 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). The output of this stage is also expected to have the `final_layout` property set field set with a [`Layout`](qiskit.transpiler.Layout "qiskit.transpiler.Layout") object that maps the [`Qubit`](circuit#qiskit.circuit.Qubit "qiskit.circuit.Qubit") to the output final position of that qubit in the circuit. If there is an existing `final_layout` entry in the property set (such as might be set by an optimization pass that introduces a permutation) it is expected that the final layout will be the composition of the two layouts (this can be computed using [`DAGCircuit.compose()`](qiskit.dagcircuit.DAGCircuit#compose "qiskit.dagcircuit.DAGCircuit.compose"), for example: `second_final_layout.compose(first_final_layout, dag.qubits)`). |
|
||
| `translation` | `qiskit.transpiler.translation` | `translator`, `synthesis`, `unroller` | **The output of this stage is expected to have every operation be a native**instruction on the target backend. |
|
||
| `optimization` | `qiskit.transpiler.optimization` | `default` | This 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. |
|
||
| `scheduling` | `qiskit.transpiler.scheduling` | `alap`, `asap`, `default` | This 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`](circuit#qiskit.circuit.Delay "qiskit.circuit.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`](qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin "qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin") which is used to define how the [`PassManager`](qiskit.transpiler.PassManager "qiskit.transpiler.PassManager") for the stage will be constructed. For example, to create a `layout` stage plugin that just runs [`VF2Layout`](qiskit.transpiler.passes.VF2Layout "qiskit.transpiler.passes.VF2Layout") (with increasing amount of trials, depending on the optimization level) and falls back to using [`TrivialLayout`](qiskit.transpiler.passes.TrivialLayout "qiskit.transpiler.passes.TrivialLayout") if `VF2Layout` is unable to find a perfect layout:
|
||
|
||
```python
|
||
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`](qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin "qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin") subclass as a setuptools entry point in the package metadata. This can be done an `entry-points` table in `pyproject.toml` for 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](#stage-table). For example, continuing from the example plugin above:
|
||
|
||
```python
|
||
.. code-block:: toml
|
||
```
|
||
|
||
> \[project.entry-points.”qiskit.transpiler.layout”] “vf2” = “qiskit\_plugin\_pkg.module.plugin:VF2LayoutPlugin”
|
||
|
||
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](#stage-table) for a list of reserved names for each stage.
|
||
|
||
## Plugin API
|
||
|
||
| | |
|
||
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||
| [`PassManagerStagePlugin`](qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin "qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin")() | A `PassManagerStagePlugin` is a plugin interface object for using custom stages in [`transpile()`](compiler#qiskit.compiler.transpile "qiskit.compiler.transpile"). |
|
||
| [`PassManagerStagePluginManager`](qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePluginManager "qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePluginManager")() | Manager class for preset pass manager stage plugins. |
|
||
|
||
### list\_stage\_plugins
|
||
|
||
<Function id="qiskit.transpiler.preset_passmanagers.plugin.list_stage_plugins" github="https://github.com/Qiskit/qiskit/tree/stable/1.1/qiskit/transpiler/preset_passmanagers/plugin.py#L283-L309" signature="qiskit.transpiler.preset_passmanagers.plugin.list_stage_plugins(stage_name)">
|
||
Get a list of installed plugins for a stage.
|
||
|
||
**Parameters**
|
||
|
||
**stage\_name** ([*str*](https://docs.python.org/3/library/stdtypes.html#str "(in Python v3.12)")) – The stage name to get the plugin names for
|
||
|
||
**Returns**
|
||
|
||
The list of installed plugin names for the specified stages
|
||
|
||
**Return type**
|
||
|
||
plugins
|
||
|
||
**Raises**
|
||
|
||
[**TranspilerError**](transpiler#qiskit.transpiler.TranspilerError "qiskit.transpiler.TranspilerError") – If an invalid stage name is specified.
|
||
</Function>
|
||
|
||
### passmanager\_stage\_plugins
|
||
|
||
<Function id="qiskit.transpiler.preset_passmanagers.plugin.passmanager_stage_plugins" github="https://github.com/Qiskit/qiskit/tree/stable/1.1/qiskit/transpiler/preset_passmanagers/plugin.py#L312-L353" signature="qiskit.transpiler.preset_passmanagers.plugin.passmanager_stage_plugins(stage)">
|
||
Return a dict with, for each stage name, the class type of the plugin.
|
||
|
||
This function is useful for getting more information about a plugin:
|
||
|
||
```python
|
||
from qiskit.transpiler.preset_passmanagers.plugin import passmanager_stage_plugins
|
||
routing_plugins = passmanager_stage_plugins('routing')
|
||
basic_plugin = routing_plugins['basic']
|
||
help(basic_plugin)
|
||
```
|
||
|
||
```python
|
||
Help on BasicSwapPassManager in module ...preset_passmanagers.builtin_plugins object:
|
||
|
||
class BasicSwapPassManager(...preset_passmanagers.plugin.PassManagerStagePlugin)
|
||
| Plugin class for routing stage with :class:`~.BasicSwap`
|
||
|
|
||
| Method resolution order:
|
||
| BasicSwapPassManager
|
||
| ...preset_passmanagers.plugin.PassManagerStagePlugin
|
||
| abc.ABC
|
||
| builtins.object
|
||
...
|
||
```
|
||
|
||
**Parameters**
|
||
|
||
**stage** ([*str*](https://docs.python.org/3/library/stdtypes.html#str "(in Python v3.12)")) – The stage name to get
|
||
|
||
**Returns**
|
||
|
||
the key is the name of the plugin and the value is the class type for each.
|
||
|
||
**Return type**
|
||
|
||
[dict](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.12)")
|
||
|
||
**Raises**
|
||
|
||
[**TranspilerError**](transpiler#qiskit.transpiler.TranspilerError "qiskit.transpiler.TranspilerError") – If an invalid stage name is specified.
|
||
</Function>
|
||
|