qiskit-documentation/translations/ja/transpile/transpile-with-pass-manager...

278 lines
34 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Transpile with pass managers\n",
"\n",
"The recommended way to transpile a circuit is to create a staged pass manager and then execute its `run` method with the circuit as input. This page explains how to transpile quantum circuits this way."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What is a (staged) pass manager?\n",
"\n",
"In the context of Qiskit, transpilation refers to the process of transforming an input circuit into a form that is suitable for execution on a quantum device. Transpilation typically occurs in a sequence of steps called transpiler passes. The circuit is processed by each transpiler pass in sequence, with the output of one pass becoming the input to the next. For example, one pass could go through the circuit and merge all consecutive sequences of single-qubit gates, and then the next pass could synthesize these gates into the basis set of the target device. The transpiler passes included with Qiskit are located in the [qiskit.transpiler.passes](/api/qiskit/transpiler_passes) module.\n",
"\n",
"A pass manager is an object that stores a list of transpiler passes and can execute them on a circuit. Create a pass manager by initializing a [`PassManager`](/api/qiskit/qiskit.transpiler.PassManager) with a list of transpiler passes. To run the transpilation on a circuit, call the [run](/api/qiskit/qiskit.transpiler.PassManager#run) method with a circuit as input.\n",
"\n",
"A staged pass manager is a special kind of pass manager that represents a level of abstraction above that of a normal pass manager. While a normal pass manager is composed of several transpiler passes, a staged pass manager is composed of several *pass managers*. This is a useful abstraction because transpilation typically happens in discrete stages, as described in [Transpiler stages](transpiler-stages), with each stage being represented by a pass manager. Staged pass managers are represented by the [`StagedPassManager`](/api/qiskit/qiskit.transpiler.StagedPassManager) class. The rest of this page describes how to create and customize (staged) pass managers."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generate a preset staged pass manager\n",
"\n",
"To create a preset staged pass manager with reasonable defaults, use the [`generate_preset_pass_manager`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.generate_preset_pass_manager) function:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"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",
"pass_manager = generate_preset_pass_manager(optimization_level=3, backend=backend)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See [Transpilation defaults and configuration options](defaults-and-configuration-options) for a description of the possible arguments to the `generate_preset_pass_manager` function. The arguments to `generate_preset_pass_manager` match the arguments to the [`transpile`](/api/qiskit/compiler#qiskit.compiler.transpile) function.\n",
"\n",
"If the preset pass managers don't fulfill your needs, customize transpilation by creating (staged) pass managers or even transpilation passes. The rest of this page describes how to create pass managers. For instructions on how to create transpilation passes, see [Write your own transpiler pass](custom-transpiler-pass)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create your own pass manager\n",
"\n",
"The [qiskit.transpiler.passes](/api/qiskit/transpiler_passes) module includes many transpiler passes that can be used to create pass managers. To create a pass manager, initialize a `PassManager` with a list of passes. For example, the following code creates a transpiler pass that merges adjacent two-qubit gates and then synthesizes them into a basis of [$R_y$](/api/qiskit/qiskit.circuit.library.RYGate), [$R_z$](/api/qiskit/qiskit.circuit.library.RZGate), and [$R_{xx}$](/api/qiskit/qiskit.circuit.library.RXXGate), gates."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from qiskit.transpiler import PassManager\n",
"from qiskit.transpiler.passes import (\n",
" Collect2qBlocks,\n",
" ConsolidateBlocks,\n",
" UnitarySynthesis,\n",
")\n",
"\n",
"basis_gates = [\"rx\", \"ry\", \"rxx\"]\n",
"translate = PassManager(\n",
" [\n",
" Collect2qBlocks(),\n",
" ConsolidateBlocks(basis_gates=basis_gates),\n",
" UnitarySynthesis(basis_gates),\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To demonstrate this pass manager in action, test it on a two-qubit circuit consisting of a Hadamard followed by two adjacent CX gates:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/kjs/.local/share/virtualenvs/scratch-h4kO_6N_/lib/python3.10/site-packages/qiskit/visualization/circuit/matplotlib.py:266: FutureWarning: The default matplotlib drawer scheme will be changed to \"iqp\" in a following release. To silence this warning, specify the current default explicitly as style=\"clifford\", or the new default as style=\"iqp\".\n",
" self._style, def_font_ratio = load_style(self._style)\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 370.906x200.667 with 1 Axes>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from qiskit import QuantumRegister, QuantumCircuit\n",
"\n",
"qubits = QuantumRegister(2, name=\"q\")\n",
"circuit = QuantumCircuit(qubits)\n",
"\n",
"a, b = qubits\n",
"circuit.h(a)\n",
"circuit.cx(a, b)\n",
"circuit.cx(b, a)\n",
"\n",
"circuit.draw(\"mpl\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To run the pass manager on the circuit, call the `run` method."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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btzYZd+tW7e6fL1lyxYaNGjAqVOnOHToEC+99BKdOnUiMjLS+a6Hp8LCwqhfvz533nlngcPMrRw/ftytOBwOBzExMfz5z38mJSWFkJAQlixZQuPGjSlRogRHjhyhfv36Lv/VrFnTo1j27t3r8k7Snj17XL7++OOP6dmzp/NrwzAYMWIES5YsYe3atdSpU8ej5xMRERERKW48+2keePfdd4mJiaFVq1a8+uqrNGvWjICAALZv387XX39Ny5Yt8z0mLCyMoUOHMmbMGCpUqMCdd97JhAkTOHfuHIMGDXLZ98iRI4waNYqnnnqKXbt2MXXqVN566y3Kly9PxYoVmTVrFlWrVuXIkSP87//+b+EzLyR34ti6dStr1qzh/vvvp3LlymzdupUffviByMhIypQpw+jRo3nuuefIy8ujffv2nD59ms2bNxMeHs6TTz4JwJIlS/jjH/9409vO8vLyOHDgAH/605+c29LS0ujTpw8A33//PTt27HD59Lbhw4fz4Ycf8vHHH1OmTBmys7MBKFu2rM/fXRMRERER8QWPB5p69eqRkpLC2LFj+eMf/0hmZiYlSpSgcePGjB49mmHDhhX4uL/+9a/k5eXRv39/fvrpJ1q1asWKFSsoX768y35PPPEE58+fp02bNgQGBjJy5Eji4+NxOBzMnz+fhIQEmjRpwl133cWUKVPo2LFjoRIvrICAgNvGER4ezsaNG5k8eTI//vgjtWrV4q233qJr164AvP7661SqVIlx48aRnp5OuXLlaNGiBS+88ILzGKdPn77lH71MS0vj3LlzLu/ING3alFdeeYWWLVvy9ddf06ZNGyIiIpzfnz59OkC+mv3jH/9gwIABv6IqIiIiIiL+4TCMnz9LWCylR48etG/fnqSkJH+HIiIiIiLiM175lDMpftq3b0+/fv38HYaIiIiIiE/pHRoRERERETEtvUMjIiIiIiKmpYFGRERERERMSwONiIiIiIiYlgYaERERERExLQ00IiIiIiJiWhpoRERERETEtDTQiIiIiIiIaWmgERERERER09JAIyIiIiIipqWBRkRERERETEsDjYiIiIiImJYGGhERERERMS0NNCIiIiIiYloaaERERERExLQ00IiIiIiIiGlpoBEREREREdPSQCMiIiIiIqalgUZERERERExLA42IiIiIiJiWBhoRERERETEtDTQiIiIi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",
"text/plain": [
"<Figure size 1039.79x200.667 with 1 Axes>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"translated = translate.run(circuit)\n",
"translated.draw(\"mpl\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a more advanced example that shows how to create a pass manager to implement the error suppression technique known as dynamical decoupling, see [Create a pass manager for dynamical decoupling](dynamical-decoupling-pass-manager)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create a staged pass manager\n",
"\n",
"A `StagedPassManager` is a pass manager that is composed of individual stages, where each stage is defined by a `PassManager` instance. You can create a `StagedPassManager` by specifying the desired stages. For example, the following code creates a staged pass manager with two stages, `init` and `translation`. The `translation` stage is defined by the pass manager that was created previously."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"from qiskit.transpiler import PassManager, StagedPassManager\n",
"from qiskit.transpiler.passes import UnitarySynthesis, Unroll3qOrMore\n",
"\n",
"basis_gates = [\"rx\", \"ry\", \"rxx\"]\n",
"init = PassManager([UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()])\n",
"staged_pm = StagedPassManager(\n",
" stages=[\"init\", \"translation\"], init=init, translation=translate\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is no limit on the number of stages you can put in a staged pass manager.\n",
"\n",
"Another useful way to create a staged pass manager is to begin with a preset staged pass manager and then swap out some of the stages. For example, the following code generates a preset pass manager with optimization level 3, and then specifies a custom `pre_layout` stage."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from qiskit.circuit.library import HGate, PhaseGate, RXGate, TdgGate, TGate\n",
"from qiskit.transpiler.passes import CXCancellation, InverseCancellation\n",
"\n",
"pass_manager = generate_preset_pass_manager(3, backend)\n",
"inverse_gate_list = [\n",
" HGate(),\n",
" (RXGate(np.pi / 4), RXGate(-np.pi / 4)),\n",
" (PhaseGate(np.pi / 4), PhaseGate(-np.pi / 4)),\n",
" (TGate(), TdgGate()),\n",
"]\n",
"logical_opt = PassManager(\n",
" [\n",
" CXCancellation(),\n",
" InverseCancellation(inverse_gate_list),\n",
" ]\n",
")\n",
"\n",
"# Add pre-layout stage to run extra logical optimization\n",
"pass_manager.pre_layout = logical_opt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The [stage generator functions](/api/qiskit/transpiler_preset#stage-generator-functions) might be useful for constructing custom pass managers.\n",
"They generate stages that provide common functionality used in many pass managers.\n",
"For example, [`generate_embed_passmanager`](/api/qiskit/transpiler_preset#qiskit.transpiler.preset_passmanagers.common.generate_embed_passmanager) can be used to generate a stage\n",
"to \"embed\" a selected initial `Layout` from a layout pass to the specified target device.\n",
"\n",
"## Next steps\n",
"\n",
"<Admonition type=\"tip\" title=\"Recommendation\">\n",
" - [Write a custom transpiler pass](custom-transpiler-pass).\n",
" - [Create a pass manager for dynamical decoupling](dynamical-decoupling-pass-manager).\n",
" - To learn how to use the `transpile` function, start with the [Transpilation default settings and configuration options](defaults-and-configuration-options) topic.\n",
" - Try the [Submit transpiled circuits](https://learning.quantum.ibm.com/tutorial/submit-transpiled-circuits) tutorial.\n",
" - See the [Transpile API documentation.](https://docs.quantum-computing.ibm.com/api/qiskit/transpiler)\n",
"</Admonition>\n"
]
}
],
"metadata": {
"celltoolbar": "Raw Cell Format",
"description": "How to transpile quantum circuits using pass managers in Qiskit.",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.12"
},
"title": "Transpile with pass managers"
},
"nbformat": 4,
"nbformat_minor": 4
}