qiskit-documentation/docs/guides/transpiler-plugins.ipynb

406 lines
15 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "334fb4b3-9d8d-4ee2-ba20-b6008b13c6e5",
"metadata": {},
"source": [
"# Install and use transpiler plugins"
]
},
{
"cell_type": "markdown",
"id": "77dbb5da-59b0-4f02-8e94-f9b11ff1fda1",
"metadata": {
"tags": [
"version-info"
]
},
"source": [
"<details>\n",
"<summary><b>Package versions</b></summary>\n",
"\n",
"The code on this page was developed using the following requirements.\n",
"We recommend using these versions or newer.\n",
"\n",
"```\n",
"qiskit[all]~=1.2.4\n",
"qiskit-aer~=0.15.1\n",
"qiskit-ibm-runtime~=0.31.0\n",
"qiskit-serverless~=0.17.1\n",
"qiskit-ibm-catalog~=0.1\n",
"```\n",
"</details>"
]
},
{
"cell_type": "markdown",
"id": "1f0d6d62-b48f-45e2-bef4-735f21b23526",
"metadata": {},
"source": [
"To facilitate the development and reuse of custom transpilation code by the wider community of Qiskit users, the Qiskit SDK supports a plugin interface that enables third-party Python packages to declare that they provide extended transpilation functionality accessible via Qiskit.\n",
"\n",
"Currently, third-party plugins can provide extended transpilation functionality in three ways:\n",
"\n",
"- A [transpiler stage plugin](/api/qiskit/transpiler_plugins) provides a pass manager that can be used in place of one of the [6 stages](transpiler-stages) of a preset staged pass manager: `init`, `layout`, `routing`, `translation`, `optimization`, and `scheduling`.\n",
"- A [unitary synthesis plugin](/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin) provides extended functionality for unitary gate synthesis.\n",
"- A [high-level synthesis plugin](/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin) provides extended functionality for synthesizing \"high-level objects\" such as linear functions or Clifford operators. High-level objects are represented by subclasses of the [Operation](/api/qiskit/qiskit.circuit.Operation) class.\n",
"\n",
"The rest of the page describes how to list available plugins, install new ones, and use them."
]
},
{
"cell_type": "markdown",
"id": "aa9e4775-d7fb-473f-8864-c6c2f42d309c",
"metadata": {},
"source": [
"## List available plugins and install new ones\n",
"\n",
"Qiskit already includes some built-in plugins for transpilation. To install more, you can use your Python package manager. For example, you might run `pip install qiskit-toqm` to install the [Qiskit TOQM](https://github.com/qiskit-toqm/qiskit-toqm) routing stage plugin. A number of third-party plugins are part of the [Qiskit ecosystem](https://qiskit.github.io/ecosystem/#transpiler_plugin).\n",
"\n",
"### List available transpiler stage plugins\n",
"\n",
"Use the [list_stage_plugins](/api/qiskit/transpiler_plugins#qiskit.transpiler.preset_passmanagers.plugin.list_stage_plugins) function, passing the name of the stage whose plugins you want to list."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "17cf6ef8-7edf-428c-a779-8c934e67720d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['default', 'dense', 'sabre', 'trivial']"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from qiskit.transpiler.preset_passmanagers.plugin import list_stage_plugins\n",
"\n",
"list_stage_plugins(\"layout\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6077307e-3214-453d-af1b-c19ee2f917f4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['basic', 'lookahead', 'none', 'sabre', 'stochastic']"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list_stage_plugins(\"routing\")"
]
},
{
"cell_type": "markdown",
"id": "fde508b8-ac1d-42d8-84cc-60e37d78092e",
"metadata": {},
"source": [
" If `qiskit-toqm` were installed, then `toqm` would appear in the list of `routing` plugins."
]
},
{
"cell_type": "markdown",
"id": "c2214241-8bb7-47e4-91b2-d5225f9dd281",
"metadata": {},
"source": [
"### List available unitary synthesis plugins\n",
"\n",
"Use the [unitary_synthesis_plugin_names](/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.unitary_synthesis_plugin_names) function."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "5b8e4b56-79bd-4079-a22f-cf74f2a86f4a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['aqc', 'default', 'sk']"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from qiskit.transpiler.passes.synthesis import unitary_synthesis_plugin_names\n",
"\n",
"unitary_synthesis_plugin_names()"
]
},
{
"cell_type": "markdown",
"id": "5497ad2a-92aa-4461-8182-89472848e214",
"metadata": {},
"source": [
"### List available high-level synthesis plugins\n",
"\n",
"Use the [high_level_synthesis_plugin_names](/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.high_level_synthesis_plugin_names) function, passing the name of the type of \"high-level object\" to be synthesized. The name corresponds to the [`name`](/api/qiskit/qiskit.circuit.Operation#name) attribute of the [Operation](/api/qiskit/qiskit.circuit.Operation) class representing the type of object being synthesized."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "d88eee69-c021-41e1-9c69-6a461e77ab12",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['ag', 'bm', 'default', 'greedy', 'layers', 'lnn']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from qiskit.transpiler.passes.synthesis import (\n",
" high_level_synthesis_plugin_names,\n",
")\n",
"\n",
"high_level_synthesis_plugin_names(\"clifford\")"
]
},
{
"cell_type": "markdown",
"id": "be7d3c04-3c0f-4a84-9311-108f04f75196",
"metadata": {},
"source": [
"You can use the [HighLevelSynthesisPluginManager](/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPluginManager) class to list the names of all high-level synthesis plugins:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "7def6967-6125-43f4-b59f-617f0e2b298f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['clifford.ag',\n",
" 'clifford.bm',\n",
" 'clifford.default',\n",
" 'clifford.greedy',\n",
" 'clifford.layers',\n",
" 'clifford.lnn',\n",
" 'linear_function.default',\n",
" 'linear_function.kms',\n",
" 'linear_function.pmh',\n",
" 'permutation.acg',\n",
" 'permutation.basic',\n",
" 'permutation.default',\n",
" 'permutation.kms',\n",
" 'permutation.token_swapper',\n",
" 'qft.default',\n",
" 'qft.full',\n",
" 'qft.line']"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from qiskit.transpiler.passes.synthesis.plugin import (\n",
" HighLevelSynthesisPluginManager,\n",
")\n",
"\n",
"HighLevelSynthesisPluginManager().plugins.names()"
]
},
{
"cell_type": "markdown",
"id": "bfdf815b-78f8-40b4-b24e-bab68506237a",
"metadata": {},
"source": [
"## Use a plugin\n",
"\n",
"In this section, we show how to use transpiler plugins. In the code examples, we use plugins that come with Qiskit, but plugins installed from third-party packages are used the same way.\n",
"\n",
"### Use a transpiler stage plugin\n",
"\n",
"To use a transpiler stage plugin, specify its name with the appropriate argument to [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#generate_preset_pass_manager) or [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile). The argument is formed by appending `_method` to the name of the transpilation stage. For example, to use the `stochastic` routing plugin, we would specify `stochastic` for the `routing_method` argument:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "98b3b08c-0945-47dd-918a-ccd62e8efa54",
"metadata": {},
"outputs": [],
"source": [
"from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
"from qiskit_ibm_runtime import QiskitRuntimeService\n",
"\n",
"service = QiskitRuntimeService()\n",
"backend = service.backend(\"ibm_brisbane\")\n",
"\n",
"pass_manager = generate_preset_pass_manager(\n",
" optimization_level=3, backend=backend, routing_method=\"stochastic\"\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "955b3de1-0363-4c05-bca4-47dec38837fb",
"metadata": {},
"source": [
"### Use a unitary synthesis plugin\n",
"\n",
"To use a unitary synthesis plugin, specify its name as the `unitary_synthesis_method` argument to [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#generate_preset_pass_manager) or [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile):"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "134c7ce2-ae3b-496e-89a8-cfe554ed6e32",
"metadata": {},
"outputs": [],
"source": [
"pass_manager = generate_preset_pass_manager(\n",
" optimization_level=3,\n",
" backend=backend,\n",
" unitary_synthesis_method=\"sk\",\n",
" unitary_synthesis_plugin_config=dict(\n",
" basis_gates=[\"cz\", \"id\", \"rz\", \"sx\", \"x\"]\n",
" ),\n",
")"
]
},
{
"cell_type": "markdown",
"id": "a2b1c570-50f6-45ae-928d-274e827501fe",
"metadata": {},
"source": [
"Unitary synthesis is used in the `init`, `translation`, and `optimization` stages of the staged pass manager returned by [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#generate_preset_pass_manager) or used in [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile). See [Transpiler stages](transpiler-stages) for a description of these stages.\n",
"\n",
"Use the `unitary_synthesis_plugin_config` argument, a free-form dictionary, to pass options for the unitary synthesis method. The documentation of the synthesis method should explain the options it supports. See [this list](/api/qiskit/transpiler_synthesis_plugins#unitary-synthesis-plugins-2) for links to the documentation of the built-in unitary synthesis plugins."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "241012ed-3f75-4ac9-a5bf-cf55b4db5b1f",
"metadata": {},
"source": [
"### Use a high-level synthesis plugin\n",
"\n",
"First, create an [HLSConfig](/api/qiskit/qiskit.transpiler.passes.HLSConfig) to\n",
"store the names of the plugins to use for various high-level objects. For example:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "057d86eb-6d70-4772-8b9c-98fbe5566fac",
"metadata": {},
"outputs": [],
"source": [
"from qiskit.transpiler.passes import HLSConfig\n",
"\n",
"hls_config = HLSConfig(clifford=[\"layers\"], linear_function=[\"pmh\"])"
]
},
{
"cell_type": "markdown",
"id": "7b5e1b28-a8e9-4767-b0ae-9cc940f89ede",
"metadata": {},
"source": [
"This code cell creates a high-level synthesis configuration that uses the `layers` plugin\n",
"for synthesizing [Clifford](/api/qiskit/qiskit.quantum_info.Clifford#clifford) objects and the `pmh` plugin for synthesizing\n",
"[LinearFunction](/api/qiskit/qiskit.circuit.library.LinearFunction#linearfunction) objects. The names of the keyword arguments correspond to the\n",
"[`name`](/api/qiskit/qiskit.circuit.Operation#name) attribute of the [Operation](/api/qiskit/qiskit.circuit.Operation) class representing the type of object being synthesized.\n",
"For each high-level object, the list of given plugins are tried in sequence until one of them\n",
"succeeds (in the example above, each list only contains a single plugin).\n",
"\n",
"In addition to specifying\n",
"a plugin by its name, you can instead pass a `(name, options)` tuple, where the second element of the tuple is a dictionary containing options for the plugin. The documentation of the synthesis method should explain the options it supports. See [this list](/api/qiskit/transpiler_synthesis_plugins#high-level-synthesis-plugins-2) for links to the documentation of the built-in high-level synthesis plugins.\n",
"\n",
"Once you have created the `HLSConfig` object, pass it as the\n",
"`hls_config` argument to [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#generate_preset_pass_manager) or [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile):"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "a9245ac1-af79-48cf-85e3-16b27417f5b3",
"metadata": {},
"outputs": [],
"source": [
"pass_manager = generate_preset_pass_manager(\n",
" optimization_level=3, backend=backend, hls_config=hls_config\n",
")"
]
},
{
"cell_type": "markdown",
"id": "b1c5f3a7-01f1-4424-a8f8-f174f1e14905",
"metadata": {},
"source": [
"High-level synthesis is used in the `init`, `translation`, and `optimization` stages of the staged pass manager returned by [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#generate_preset_pass_manager) or used in [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile). See [Transpiler stages](transpiler-stages) for a description of these stages."
]
},
{
"cell_type": "markdown",
"id": "de7bff27-0e8e-48ac-9546-757b8ba36384",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
"<Admonition type=\"tip\" title=\"Recommendation\">\n",
" - [Create a transpiler plugin](./create-transpiler-plugin).\n",
" - Check out the tutorials on [IBM Quantum Learning](https://learning.quantum.ibm.com/catalog/tutorials) for examples of transpiling and running quantum circuits.\n",
"</Admonition>"
]
}
],
"metadata": {
"description": "How to install and use transpiler plugins in Qiskit.",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3"
},
"title": "Install and use transpiler plugins"
},
"nbformat": 4,
"nbformat_minor": 4
}