Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stage plugin interface for transpile #8305

Merged
merged 42 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
16c4ab6
Add stage plugin interface for transpile
mtreinish Jul 6, 2022
5ec9324
Fix docs builds
mtreinish Jul 7, 2022
5eca33c
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Jul 7, 2022
dfeb064
Fix doc warning
mtreinish Jul 7, 2022
c1afe2c
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Jul 20, 2022
150c838
Make routing methods all plugins
mtreinish Jul 20, 2022
d900f8a
Merge branch 'main' into add-transpile-plugins
mtreinish Jul 21, 2022
2839d5e
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Jul 22, 2022
19df4a0
Add plugin usage to level 3
mtreinish Jul 22, 2022
0e11723
Add plugin support to level 0 preset pass manager
mtreinish Jul 22, 2022
fb72d1d
Add default plugin to reserved routing methods list
mtreinish Jul 22, 2022
4ea9949
Add release notes
mtreinish Jul 22, 2022
e96b120
Add tests
mtreinish Jul 22, 2022
a0054ed
Apply suggestions from code review
mtreinish Jul 27, 2022
0599830
Apply suggestions from code review
mtreinish Jul 27, 2022
26ae3c4
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Jul 27, 2022
62b4f3f
Remove raise on non-builtin layout method argument
mtreinish Jul 27, 2022
a52f7ed
Fix typo
mtreinish Jul 27, 2022
5dec6c8
Deduplicate code in built-in routing plugins
mtreinish Jul 27, 2022
adaa169
Make vf2 call limit function private
mtreinish Jul 29, 2022
58f6306
Deduplicate code in stochastic swap plugin
mtreinish Jul 29, 2022
7963e84
Expand example plugin documentation to show more complete use case
mtreinish Jul 29, 2022
b2d186d
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Jul 29, 2022
3c19b4a
Update qiskit/transpiler/preset_passmanagers/level1.py
mtreinish Jul 29, 2022
2c03969
Add missing TODO comment
mtreinish Jul 29, 2022
e0a7d38
Unify vf2 call limit handling
mtreinish Jul 30, 2022
eca7f38
Merge branch 'main' into add-transpile-plugins
mtreinish Aug 2, 2022
08a4972
Remove default plugin from entry points
mtreinish Aug 2, 2022
4190774
Simplify level 3 optimization stage logic
mtreinish Aug 2, 2022
38931c8
Update qiskit/transpiler/preset_passmanagers/plugin.py
mtreinish Aug 2, 2022
9b928a0
Prefer toqm plugin if one is available
mtreinish Aug 2, 2022
7b67905
Apply suggestions from code review
mtreinish Aug 4, 2022
89b6d3b
Merge branch 'main' into add-transpile-plugins
mtreinish Aug 4, 2022
0afc56d
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Aug 17, 2022
23a2b36
Fix lint
mtreinish Aug 17, 2022
6cb6b20
Remove unnecessary elses in builtin plugins
mtreinish Aug 17, 2022
d756597
Apply suggestions from code review
mtreinish Aug 25, 2022
7120d2d
Merge remote-tracking branch 'origin/main' into add-transpile-plugins
mtreinish Aug 25, 2022
d731d06
Make optimization level a plugin argument
mtreinish Aug 25, 2022
f185c59
Add test coverage for all built-in routing plugins
mtreinish Aug 25, 2022
6d344c0
Reorder stage variables to execution order
mtreinish Aug 25, 2022
c4816d3
Merge branch 'main' into add-transpile-plugins
mergify[bot] Aug 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/apidocs/terra.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Qiskit Terra API Reference
transpiler_passes
transpiler_preset
transpiler_plugins
transpiler_synthesis_plugins
transpiler_builtin_plugins
utils
utils_mitigation
Expand Down
2 changes: 1 addition & 1 deletion docs/apidocs/transpiler_plugins.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _qiskit-transpiler-plugins:

.. automodule:: qiskit.transpiler.passes.synthesis.plugin
.. automodule:: qiskit.transpiler.preset_passmanagers.plugin
:no-members:
:no-inherited-members:
:no-special-members:
6 changes: 6 additions & 0 deletions docs/apidocs/transpiler_synthesis_plugins.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.. _qiskit-transpiler-synthesis-plugins:

.. automodule:: qiskit.transpiler.passes.synthesis.plugin
:no-members:
:no-inherited-members:
:no-special-members:
36 changes: 33 additions & 3 deletions qiskit/compiler/transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def transpile(
unitary_synthesis_method: str = "default",
unitary_synthesis_plugin_config: dict = None,
target: Target = None,
init_method: str = None,
optimization_method: str = None,
) -> Union[QuantumCircuit, List[QuantumCircuit]]:
"""Transpile one or more circuits, according to some desired transpilation targets.

Expand Down Expand Up @@ -150,17 +152,29 @@ def transpile(

[qr[0], None, None, qr[1], None, qr[2]]

layout_method: Name of layout selection pass ('trivial', 'dense', 'noise_adaptive', 'sabre')
layout_method: Name of layout selection pass ('trivial', 'dense', 'noise_adaptive', 'sabre').
This can also be the external plugin name to use for the ``layout`` stage.
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"layout"`` for the ``stage_name`` argument.
routing_method: Name of routing pass
('basic', 'lookahead', 'stochastic', 'sabre', 'toqm', 'none'). Note
that to use method 'toqm', package 'qiskit-toqm' must be installed.
This can also be the external plugin name to use for the ``routing`` stage.
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"routing"`` for the ``stage_name`` argument.
translation_method: Name of translation pass ('unroller', 'translator', 'synthesis')
This can also be the external plugin name to use for the ``translation`` stage.
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"translation"`` for the ``stage_name`` argument.
scheduling_method: Name of scheduling pass.
* ``'as_soon_as_possible'``: Schedule instructions greedily, as early as possible
on a qubit resource. (alias: ``'asap'``)
* ``'as_late_as_possible'``: Schedule instructions late, i.e. keeping qubits
in the ground state when possible. (alias: ``'alap'``)
If ``None``, no scheduling will be done.
If ``None``, no scheduling will be done. This can also be the external plugin name
to use for the ``scheduling`` stage. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"scheduling"`` for the ``stage_name``
argument.
instruction_durations: Durations of instructions.
Applicable only if scheduling_method is specified.
The gate lengths defined in ``backend.properties`` are used as default.
Expand Down Expand Up @@ -246,6 +260,16 @@ def callback_func(**kwargs):
the ``backend`` argument, but if you have manually constructed a
:class:`~qiskit.transpiler.Target` object you can specify it manually here.
This will override the target from ``backend``.
init_method: The plugin name to use for the ``init`` stage. By default an external
plugin is not used. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"init"`` for the stage
name argument.
optimization_method: The plugin name to use for the
``optimization`` stage. By default an external
plugin is not used. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"optimization"`` for the
``stage_name`` argument.

Returns:
The transpiled circuit(s).

Expand Down Expand Up @@ -310,6 +334,8 @@ def callback_func(**kwargs):
unitary_synthesis_method,
unitary_synthesis_plugin_config,
target,
init_method,
optimization_method,
)
# Get transpile_args to configure the circuit transpilation job(s)
if coupling_map in unique_transpile_args:
Expand Down Expand Up @@ -392,7 +418,7 @@ def _log_transpile_time(start_time, end_time):
def _combine_args(shared_transpiler_args, unique_config):
# Pop optimization_level to exclude it from the kwargs when building a
# PassManagerConfig
level = shared_transpiler_args.pop("optimization_level")
level = shared_transpiler_args.get("optimization_level")
pass_manager_config = shared_transpiler_args
pass_manager_config.update(unique_config.pop("pass_manager_config"))
pass_manager_config = PassManagerConfig(**pass_manager_config)
Expand Down Expand Up @@ -560,6 +586,8 @@ def _parse_transpile_args(
unitary_synthesis_method,
unitary_synthesis_plugin_config,
target,
init_method,
optimization_method,
) -> Tuple[List[Dict], Dict]:
"""Resolve the various types of args allowed to the transpile() function through
duck typing, overriding args, etc. Refer to the transpile() docstring for details on
Expand Down Expand Up @@ -627,6 +655,8 @@ def _parse_transpile_args(
shared_dict = {
"optimization_level": optimization_level,
"basis_gates": basis_gates,
"init_method": init_method,
"optimization_method": optimization_method,
}

list_transpile_args = []
Expand Down
4 changes: 4 additions & 0 deletions qiskit/transpiler/passes/synthesis/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
which enable packages external to qiskit to advertise they include a synthesis
plugin.

See :mod:`qiskit.transpiler.preset_passmanagers.plugin` for details on how
to write plugins for transpiler stages.


Writing Plugins
===============

Expand Down
22 changes: 18 additions & 4 deletions qiskit/transpiler/passmanager_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def __init__(
unitary_synthesis_method="default",
unitary_synthesis_plugin_config=None,
target=None,
init_method=None,
optimization_method=None,
optimization_level=None,
mtreinish marked this conversation as resolved.
Show resolved Hide resolved
):
"""Initialize a PassManagerConfig object

Expand All @@ -50,12 +53,16 @@ def __init__(
coupling_map (CouplingMap): Directed graph represented a coupling
map.
layout_method (str): the pass to use for choosing initial qubit
placement.
placement. This will be the plugin name if an external layout stage
plugin is being used.
routing_method (str): the pass to use for routing qubits on the
architecture.
architecture. This will be a plugin name if an external routing stage
plugin is being used.
translation_method (str): the pass to use for translating gates to
basis_gates.
scheduling_method (str): the pass to use for scheduling instructions.
basis_gates. This will be a plugin name if an external translation stage
plugin is being used.
scheduling_method (str): the pass to use for scheduling instructions. This will
be a plugin name if an external scheduling stage plugin is being used.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any plan to replace *_method with the plugin interface?

instruction_durations (InstructionDurations): Dictionary of duration
(in dt) for each instruction.
backend_properties (BackendProperties): Properties returned by a
Expand All @@ -70,14 +77,20 @@ def __init__(
:class:`~qiskit.transpiler.passes.UnitarySynthesis` pass. Will
search installed plugins for a valid method.
target (Target): The backend target
init_method (str): The plugin name for the init stage plugin to use
optimization_method (str): The plugin name for the optimization stage plugin
to use.
optimization_level (int): The optimization level being used for compilation.
"""
self.initial_layout = initial_layout
self.basis_gates = basis_gates
self.inst_map = inst_map
self.coupling_map = coupling_map
self.init_method = init_method
self.layout_method = layout_method
self.routing_method = routing_method
self.translation_method = translation_method
self.optimization_method = optimization_method
self.scheduling_method = scheduling_method
self.instruction_durations = instruction_durations
self.backend_properties = backend_properties
Expand All @@ -87,6 +100,7 @@ def __init__(
self.unitary_synthesis_method = unitary_synthesis_method
self.unitary_synthesis_plugin_config = unitary_synthesis_plugin_config
self.target = target
self.optimization_level = optimization_level

@classmethod
def from_backend(cls, backend, **pass_manager_options):
Expand Down
36 changes: 32 additions & 4 deletions qiskit/transpiler/preset_passmanagers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ def generate_preset_pass_manager(
seed_transpiler=None,
unitary_synthesis_method="default",
unitary_synthesis_plugin_config=None,
init_method=None,
optimization_method=None,
):
"""Generate a preset :class:`~.PassManager`

Expand Down Expand Up @@ -103,18 +105,30 @@ def generate_preset_pass_manager(
layout_method (str): The :class:`~.Pass` to use for choosing initial qubit
placement. Valid choices are ``'trivial'``, ``'dense'``, ``'noise_adaptive'``,
and, ``'sabre'`` repsenting :class:`~.TrivialLayout`, :class:`~DenseLayout`,
:class:`~.NoiseAdaptiveLayout`, :class:`~.SabreLayout` respectively.
:class:`~.NoiseAdaptiveLayout`, :class:`~.SabreLayout` respectively. This can also
be the external plugin name to use for the ``layout`` stage of the output
:class:`~.StagedPassManager`. You can see a list of installed plugins by using
:func:`~.list_stage_plugins` with ``"layout"`` for the ``stage_name`` argument.
routing_method (str): The pass to use for routing qubits on the
architecture. Valid choices are ``'basic'``, ``'lookahead'``, ``'stochastic'``,
``'sabre'``, and ``'none'`` representing :class:`~.BasicSwap`,
:class:`~.LookaheadSwap`, :class:`~.StochasticSwap`, :class:`~.SabreSwap`, and
erroring if routing is required respectively.
erroring if routing is required respectively. This can also be the external plugin
name to use for the ``routing`` stage of the output :class:`~.StagedPassManager`.
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"routing"`` for the ``stage_name`` argument.
translation_method (str): The method to use for translating gates to
basis gates. Valid choices ``'unroller'``, ``'translator'``, ``'synthesis'``
representing :class:`~.Unroller`, :class:`~.BasisTranslator`, and
:class:`~.UnitarySynthesis` respectively.
:class:`~.UnitarySynthesis` respectively. This can also be the external plugin
name to use for the ``translation`` stage of the output :class:`~.StagedPassManager`.
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"translation"`` for the ``stage_name`` argument.
scheduling_method (str): The pass to use for scheduling instructions. Valid choices
are ``'alap'`` and ``'asap'``.
are ``'alap'`` and ``'asap'``. This can also be the external plugin name to use
for the ``scheduling`` stage of the output :class:`~.StagedPassManager`. You can
see a list of installed plugins by using :func:`~.list_stage_plugins` with
``"scheduling"`` for the ``stage_name`` argument.
backend_properties (BackendProperties): Properties returned by a
backend, including information on gate errors, readout errors,
qubit coherence times, etc.
Expand All @@ -134,6 +148,17 @@ def generate_preset_pass_manager(
the ``unitary_synthesis`` argument. As this is custom for each
unitary synthesis plugin refer to the plugin documentation for how
to use this option.
init_method (str): The plugin name to use for the ``init`` stage of
the output :class:`~.StagedPassManager`. By default an external
plugin is not used. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"init"`` for the stage
name argument.
optimization_method (str): The plugin name to use for the
``optimization`` stage of the output
:class:`~.StagedPassManager`. By default an external
plugin is not used. You can see a list of installed plugins by
using :func:`~.list_stage_plugins` with ``"optimization"`` for the
``stage_name`` argument.

Returns:
StagedPassManager: The preset pass manager for the given options
Expand Down Expand Up @@ -172,6 +197,9 @@ def generate_preset_pass_manager(
unitary_synthesis_method=unitary_synthesis_method,
unitary_synthesis_plugin_config=unitary_synthesis_plugin_config,
initial_layout=initial_layout,
init_method=init_method,
optimization_method=optimization_method,
optimization_level=optimization_level,
)

if backend is not None:
Expand Down
Loading