264 lines
14 KiB
Plaintext
264 lines
14 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ba5ec3d7-2a51-4ffa-b270-cbe18e98a454",
|
|
"metadata": {},
|
|
"source": [
|
|
"# AI transpiler passes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3c78c2c0-7afc-4cf3-988d-9e044b5d0fca",
|
|
"metadata": {
|
|
"tags": [
|
|
"version-info"
|
|
]
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "7244dd08-62a0-4c10-8c0d-0bd01eebe68f",
|
|
"metadata": {},
|
|
"source": [
|
|
"The AI-powered transpiler passes are passes that work as a drop-in replacement of \"traditional\" Qiskit passes for some transpiling tasks. They often produce better results than existing heuristic algorithms (such as lower depth and CNOT count), but are also much faster than optimization algorithms such as Boolean satisfiability solvers. The AI transpiler passes can run on your local environment or on the cloud using the Qiskit Transpiler Service if you are part of the IBM Quantum® Premium Plan.\n",
|
|
"\n",
|
|
"\n",
|
|
"<Admonition type=\"note\">\n",
|
|
" The AI-powered transpiler passes are in beta release status, subject to change.\n",
|
|
" If you have feedback or want to contact the developer team, please use this [Qiskit Slack Workspace channel](https://qiskit.slack.com/archives/C06KF8YHUAU).\n",
|
|
"</Admonition>\n",
|
|
"\n",
|
|
"The following passes are currently available:\n",
|
|
"\n",
|
|
"**Routing passes**\n",
|
|
" - `AIRouting`: Layout selection and circuit routing\n",
|
|
"\n",
|
|
"**Circuit synthesis passes**\n",
|
|
" - `AICliffordSynthesis`: Clifford circuit synthesis\n",
|
|
" - `AILinearFunctionSynthesis`: Linear function circuit synthesis\n",
|
|
" - `AIPermutationSynthesis`: Permutation circuit synthesis\n",
|
|
" - `AIPauliNetworkSynthesis`: Pauli Network circuit synthesis (only available in the Qiskit Transpiler Service, not in local environment)\n",
|
|
"\n",
|
|
"To use the AI transpiler passes, first [install the `qiskit-ibm-transpiler` package](/docs/guides/qiskit-transpiler-service#install-transpiler-service). Visit the [qiskit-ibm-transpiler API documentation](/docs/api/qiskit-ibm-transpiler) to get more information about the different options available.\n",
|
|
"\n",
|
|
"## Run the AI transpiler passes locally or on the cloud\n",
|
|
"\n",
|
|
"If you want to use the AI-powered transpiler passes in your local environment for free, install `qiskit-ibm-transpiler` with some extra dependencies as follows:\n",
|
|
"\n",
|
|
"```sh\n",
|
|
"pip install qiskit-ibm-transpiler[ai-local-mode]\n",
|
|
"```\n",
|
|
"\n",
|
|
"Without these extra dependencies, the AI-powered transpiler passes run on the cloud through the Qiskit Transpiler Service (available only for IBM Quantum Premium Plan users). After installing the extra dependencies, the default mode to run the AI-powered transpiler passes is to use your local machine.\n",
|
|
"\n",
|
|
"## AI routing pass\n",
|
|
"\n",
|
|
"The `AIRouting` pass acts both as a layout stage and a routing stage. It can be used within a `PassManager` as follows:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "c104fcd0-4a85-4927-b026-93f4a6fdab51",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from qiskit.transpiler import PassManager\n",
|
|
"from qiskit.circuit.library import efficient_su2\n",
|
|
"from qiskit_ibm_transpiler.ai.routing import AIRouting\n",
|
|
"from qiskit_ibm_runtime import QiskitRuntimeService\n",
|
|
"\n",
|
|
"backend = QiskitRuntimeService().backend(\"ibm_torino\")\n",
|
|
"ai_passmanager = PassManager(\n",
|
|
" [\n",
|
|
" AIRouting(\n",
|
|
" backend=backend,\n",
|
|
" optimization_level=2,\n",
|
|
" layout_mode=\"optimize\",\n",
|
|
" local_mode=True,\n",
|
|
" )\n",
|
|
" ]\n",
|
|
")\n",
|
|
"\n",
|
|
"\n",
|
|
"circuit = efficient_su2(101, entanglement=\"circular\", reps=1)\n",
|
|
"\n",
|
|
"transpiled_circuit = ai_passmanager.run(circuit)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "28c2cfa3-e4d8-48d5-9d6c-b02fcf548ef1",
|
|
"metadata": {},
|
|
"source": [
|
|
"Here, the `backend` determines which coupling map to route for, the `optimization_level` (1, 2, or 3) determines the computational effort to spend in the process (higher usually gives better results but takes longer), and the `layout_mode` specifies how to handle the layout selection.\n",
|
|
"The `layout_mode` includes the following options:\n",
|
|
"\n",
|
|
"- `keep`: This respects the layout set by the previous transpiler passes (or uses the trivial layout if not set). It is typically only used when the circuit must be run on specific qubits of the device. It often produces worse results because it has less room for optimization.\n",
|
|
"- `improve`: This uses the layout set by the previous transpiler passes as a starting point. It is useful when you have a good initial guess for the layout; for example, for circuits that are built in a way that approximately follows the device's coupling map. It is also useful if you want to try other specific layout passes combined with the `AIRouting` pass.\n",
|
|
"- `optimize`: This is the default mode. It works best for general circuits where you might not have good layout guesses. This mode ignores previous layout selections.\n",
|
|
"- `local_mode`: This flag determines where the `AIRouting` pass runs. If `False`, `AIRouting` runs remotely through the Qiskit Transpiler Service. If `True`, the package tries to run the pass in your local environment with a fallback to cloud mode if the required dependencies are not found.\n",
|
|
"\n",
|
|
"## AI circuit synthesis passes\n",
|
|
"\n",
|
|
"The AI circuit synthesis passes allow you to optimize pieces of different circuit types ([Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford), [Linear Function](/docs/api/qiskit/qiskit.circuit.library.LinearFunction), [Permutation](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation), Pauli Network) by re-synthesizing them. A typical way to use the synthesis pass is as follows:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8655f68d-f88a-4a15-ad89-f39f2ba3fe71",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from qiskit.transpiler import PassManager\n",
|
|
"\n",
|
|
"from qiskit_ibm_transpiler.ai.routing import AIRouting\n",
|
|
"from qiskit_ibm_transpiler.ai.synthesis import AILinearFunctionSynthesis\n",
|
|
"from qiskit_ibm_transpiler.ai.collection import CollectLinearFunctions\n",
|
|
"from qiskit_ibm_transpiler.ai.synthesis import AIPauliNetworkSynthesis\n",
|
|
"from qiskit_ibm_transpiler.ai.collection import CollectPauliNetworks\n",
|
|
"from qiskit.circuit.library import efficient_su2\n",
|
|
"\n",
|
|
"ibm_torino = QiskitRuntimeService().backend(\"ibm_torino\")\n",
|
|
"ai_passmanager = PassManager(\n",
|
|
" [\n",
|
|
" AIRouting(\n",
|
|
" backend=ibm_torino,\n",
|
|
" optimization_level=3,\n",
|
|
" layout_mode=\"optimize\",\n",
|
|
" local_mode=True,\n",
|
|
" ), # Route circuit\n",
|
|
" CollectLinearFunctions(), # Collect Linear Function blocks\n",
|
|
" AILinearFunctionSynthesis(\n",
|
|
" backend=ibm_torino, local_mode=True\n",
|
|
" ), # Re-synthesize Linear Function blocks\n",
|
|
" CollectPauliNetworks(), # Collect Pauli Networks blocks\n",
|
|
" AIPauliNetworkSynthesis(\n",
|
|
" backend=ibm_torino, local_mode=False\n",
|
|
" ), # Re-synthesize Pauli Network blocks. Only available in the Qiskit Transpiler Service\n",
|
|
" ]\n",
|
|
")\n",
|
|
"\n",
|
|
"circuit = efficient_su2(10, entanglement=\"full\", reps=1)\n",
|
|
"\n",
|
|
"transpiled_circuit = ai_passmanager.run(circuit)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "779f180e-c29f-4a96-b4b0-e3d2a4c8a1b9",
|
|
"metadata": {},
|
|
"source": [
|
|
"The synthesis respects the coupling map of the device: it can be run safely after other routing passes without disturbing the circuit, so the overall circuit will still follow the device restrictions. By default, the synthesis will replace the original sub-circuit only if the synthesized sub-circuit improves the original (currently only checking CNOT count), but this can be forced to always replace the circuit by setting `replace_only_if_better=False`.\n",
|
|
"\n",
|
|
"The following synthesis passes are available from `qiskit_ibm_transpiler.ai.synthesis`:\n",
|
|
"\n",
|
|
"- *AICliffordSynthesis*: Synthesis for [Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford) circuits (blocks of `H`, `S`, and `CX` gates). Currently up to nine qubit blocks.\n",
|
|
"- *AILinearFunctionSynthesis*: Synthesis for [Linear Function](/docs/api/qiskit/qiskit.circuit.library.LinearFunction) circuits (blocks of `CX` and `SWAP` gates). Currently up to nine qubit blocks.\n",
|
|
"- *AIPermutationSynthesis*: Synthesis for [Permutation](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation) circuits (blocks of `SWAP` gates). Currently available for 65, 33, and 27 qubit blocks.\n",
|
|
"- *AIPauliNetworkSynthesis*: Synthesis for Pauli Network circuits (blocks of `H`, `S`, `SX`, `CX`, `RX`, `RY` and `RZ` gates). Currently up to six qubit blocks. This pass is only available in the Qiskit Transpiler Service, not locally.\n",
|
|
"\n",
|
|
"We expect to gradually increase the size of the supported blocks.\n",
|
|
"\n",
|
|
"All passes use a thread pool to send several requests in parallel. By default, the number for max threads is the number of cores plus four (default values for the `ThreadPoolExecutor` Python object). However, you can set your own value with the `max_threads` argument at pass instantiation. For example, the following line instantiates the `AILinearFunctionSynthesis` pass, which allows it to use a maximum of 20 threads.\n",
|
|
"\n",
|
|
"```python\n",
|
|
"AILinearFunctionSynthesis(backend=ibm_torino, max_threads=20) # Re-synthesize Linear Function blocks using 20 threads max\n",
|
|
"```\n",
|
|
"\n",
|
|
"You can also set the environment variable `AI_TRANSPILER_MAX_THREADS` to the desired number of maximum threads, and all synthesis passes instantiated after that will use that value.\n",
|
|
"\n",
|
|
"For the AI synthesis passes to synthesize a sub-circuit, it must lay on a connected subgraph of the coupling map (one way to do this is with a routing pass before collecting the blocks, but this is not the only way to do it). The synthesis passes will automatically check that the specific subgraph is supported, and if not, it will raise a warning and leave the original sub-circuit unchanged.\n",
|
|
"\n",
|
|
"The following custom collection passes for Cliffords, Linear Functions and Permutations that can be imported from `qiskit_ibm_transpiler.ai.collection` also complement the synthesis passes:\n",
|
|
"\n",
|
|
"- *CollectCliffords*: Collects Clifford blocks as `Instruction` objects and stores the original sub-circuit to compare against it after synthesis.\n",
|
|
"- *CollectLinearFunctions*: Collects blocks of `SWAP` and `CX` as `LinearFunction` objects and stores the original sub-circuit to compare against it after synthesis.\n",
|
|
"- *CollectPermutations*: Collects blocks of `SWAP` circuits as `Permutations`.\n",
|
|
"- *CollectPauliNetworks*: Collects Pauli Network blocks and stores the original sub-circuit to compare against it after synthesis.\n",
|
|
"\n",
|
|
"These custom collection passes limit the sizes of the collected sub-circuits so they are supported by the AI-powered synthesis passes. Therefore, it is recommended to use them after the routing passes and before the synthesis passes for a better overall optimization.\n",
|
|
"\n",
|
|
"## Hybrid heuristic-AI circuit transpilation\n",
|
|
"\n",
|
|
"The `qiskit-ibm-transpiler` allows you to configure a hybrid pass manager that combines the best of Qiskit's heuristic and the AI-powered transpiler passes. This feature behaves similarly to the Qiskit `generate_pass_manager` method. A typical way to use `generate_ai_pass_manager` is as follows:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2f5bbf22-22cd-46fa-885c-851f769552f0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from qiskit_ibm_transpiler import generate_ai_pass_manager\n",
|
|
"from qiskit.circuit.library import efficient_su2\n",
|
|
"from qiskit_ibm_runtime import QiskitRuntimeService\n",
|
|
"\n",
|
|
"\n",
|
|
"backend = QiskitRuntimeService().backend(\"ibm_torino\")\n",
|
|
"torino_coupling_map = backend.coupling_map\n",
|
|
"\n",
|
|
"\n",
|
|
"su2_circuit = efficient_su2(101, entanglement=\"circular\", reps=1)\n",
|
|
"\n",
|
|
"ai_transpiler_pass_manager = generate_ai_pass_manager(\n",
|
|
" coupling_map=torino_coupling_map,\n",
|
|
" ai_optimization_level=3,\n",
|
|
" optimization_level=3,\n",
|
|
" ai_layout_mode=\"optimize\",\n",
|
|
")\n",
|
|
"\n",
|
|
"ai_su2_transpiled_circuit = ai_transpiler_pass_manager.run(su2_circuit)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "7f34294b-c520-439a-b1d7-2962af07aced",
|
|
"metadata": {},
|
|
"source": [
|
|
"The following options are used in this example:\n",
|
|
"* `coupling_map` - Specifies which coupling map to use for the transpilation.\n",
|
|
"* `ai_optimization_level` - Specifies the level of optimization (1-3) to use for the AI components of the PassManager.\n",
|
|
"* `optimization_level` - Specifies how much optimization to perform on the circuit for the heuristic components of the PassManager.\n",
|
|
"* `ai_layout_mode` - Specifies how the AI routing part of the PassManager handles the layout. Refer to the [AI routing pass](#ai-routing-pass) section to review the configuration options for this `ai_layout_mode` parameter.\n",
|
|
"\n",
|
|
"## Limits\n",
|
|
"\n",
|
|
"Refer to the [Qiskit Transpiler Service documentation](./qiskit-transpiler-service#limits-of-the-qiskit-transpiler-service) for more information about the limits that apply to the AI-powered transpiler passes.\n",
|
|
"\n",
|
|
"## Citation\n",
|
|
"\n",
|
|
"If you use any AI-powered feature from the Qiskit Transpiler Service in your research, use [the recommended citation](./qiskit-transpiler-service#citation)."
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"description": "What are the AI transpiler passes and how to use them",
|
|
"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": "AI-powered transpiler passes"
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
}
|