{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "ba5ec3d7-2a51-4ffa-b270-cbe18e98a454",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"AI搭載トランスパイラが通過する\"\n",
        "description: \"AIトランスパイラパスとは何か、そしてそれらをどのように使用するのか\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Eprint */}\n",
        "\n",
        "<span id=\"ai-powered-transpiler-passes\" />\n",
        "\n",
        "# AI搭載トランスパイラが通過する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3c78c2c0-7afc-4cf3-988d-9e044b5d0fca",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7244dd08-62a0-4c10-8c0d-0bd01eebe68f",
      "metadata": {},
      "source": [
        "AIを活用したトランスパイラ・パスは、一部のトランスパイル処理において、「従来の」Qiskitパスのそのままの代替として機能するパスです。 これらは、既存のヒューリスティックアルゴリズム（探索深度やCNOT数の低減など）よりも優れた結果を出すことが多いだけでなく、ブール満足可能性ソルバーなどの最適化アルゴリズムよりもはるかに高速である。 AIトランスパイラは、ローカル環境で実行されます。\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  AIを搭載したトランスパイラー・パスはベータ版のリリース状態であり、変更される可能性がある。\n",
        "  フィードバックや開発チームへの連絡は、こちらの [Qiskit Slack Workspaceチャンネルを](https://qiskit.slack.com/archives/C06KF8YHUAU)ご利用ください。\n",
        "</Admonition>\n",
        "\n",
        "現在入手可能なパスは以下の通り：\n",
        "\n",
        "**ルーティング・パス**\n",
        "\n",
        "* `AIRouting`:レイアウトの選択と回路配線\n",
        "\n",
        "**回路合成パス**\n",
        "\n",
        "* `AICliffordSynthesis`:クリフォード回路合成\n",
        "* `AILinearFunctionSynthesis`:線形関数回路合成\n",
        "* `AIPermutationSynthesis`:順列回路合成\n",
        "\n",
        "AIトランスパイラ・パスを使用するには、まずパッケージを `qiskit-ibm-transpiler` インストールしてください。 利用可能な各種オプションの詳細については、 [qiskit-ibm-transpiler の API ドキュメント](/docs/api/qiskit-ibm-transpiler)をご覧ください。\n",
        "\n",
        "```sh\n",
        "pip install qiskit-ibm-transpiler\n",
        "```\n",
        "\n",
        "<span id=\"ai-routing-pass\" />\n",
        "\n",
        "## AIルーティングパス\n",
        "\n",
        "`AIRouting` パスはレイアウト・ステージとしても配線ステージとしても機能する。 `PassManager` 、以下のように使用できる：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "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",
        "import logging\n",
        "\n",
        "backend = QiskitRuntimeService().backend(\"ibm_fez\")\n",
        "ai_passmanager = PassManager(\n",
        "    [\n",
        "        AIRouting(\n",
        "            backend=backend,\n",
        "            optimization_level=2,\n",
        "            layout_mode=\"optimize\",\n",
        "        )\n",
        "    ]\n",
        ")\n",
        "\n",
        "\n",
        "circuit = efficient_su2(101, entanglement=\"circular\", reps=1)\n",
        "logging.getLogger(\n",
        "    \"qiskit_ibm_transpiler.wrappers.ai_local_synthesis\"\n",
        ").setLevel(logging.WARNING)\n",
        "transpiled_circuit = ai_passmanager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "28c2cfa3-e4d8-48d5-9d6c-b02fcf548ef1",
      "metadata": {},
      "source": [
        "ここで、 `backend` は、どのカップリングマップをルーティングするかを決定し、 `optimization_level` （1、2、または3）は、プロセスに費やす計算工数を決定し（通常、高い方が良い結果が得られるが、時間がかかる）、 `layout_mode` は、レイアウト選択を処理する方法を指定する。\n",
        "`layout_mode` には以下のオプションがある：\n",
        "\n",
        "* `keep`:これは、前のトランスパイラ・パスが設定したレイアウトを尊重します（設定されていない場合は、トリビアル・レイアウトを使用します）。 通常、デバイスの特定の量子ビットで回路を実行しなければならない場合にのみ使用される。 最適化の余地が少ないため、悪い結果を生むことが多い。\n",
        "* `improve`:これは、前のトランスパイラ・パスが設定したレイアウトを出発点として使用します。 例えば、デバイスのカップリング・マップにほぼ沿うように回路が作られている場合など、レイアウトの初期推測がうまくいく場合に便利です。 また、他の特定のレイアウトパスを `AIRouting` パスと組み合わせて試したい場合にも便利です。\n",
        "* `optimize`:これはデフォルトのモードである。 レイアウトをうまく推測できないような一般的な回路に最適です。 このモードでは、以前のレイアウト選択は無視されます。\n",
        "\n",
        "<span id=\"ai-circuit-synthesis-passes\" />\n",
        "\n",
        "## AI回路合成通過\n",
        "\n",
        "AI回路合成パスにより、異なる回路タイプ （[クリフォード](/docs/api/qiskit/qiskit.quantum_info.Clifford)、 [線形関数](/docs/api/qiskit/qiskit.circuit.library.LinearFunction)、 [パーミュテーション](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation)、パウリ・ネットワーク）の断片を再合成して最適化することができる。 合成パスの典型的な使い方は以下の通り：\n",
        "\n"
      ]
    },
    {
      "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.circuit.library import efficient_su2\n",
        "\n",
        "ibm_kingston = QiskitRuntimeService().backend(\"ibm_kingston\")\n",
        "ai_passmanager = PassManager(\n",
        "    [\n",
        "        AIRouting(\n",
        "            backend=ibm_kingston,\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_kingston, local_mode=True\n",
        "        ),  # Re-synthesize Linear Function blocks\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": [
        "合成はデバイスのカップリング・マップを尊重します。回路を乱すことなく、他の配線パスの後に安全に実行できるため、回路全体はデバイスの制約に従ったままです。 デフォルトでは、合成されたサブサーキットが元のサブサーキットを改善した場合にのみ、合成は元のサブサーキットを置き換えますが（現在はCNOTカウントのチェックのみ）、 `replace_only_if_better=False` を設定することで、常に回路を置き換えるように強制することができます。\n",
        "\n",
        "以下の合成パスは `qiskit_ibm_transpiler.ai.synthesis` から入手可能です：\n",
        "\n",
        "* *AICliffordSynthesis* ： [クリフォード](/docs/api/qiskit/qiskit.quantum_info.Clifford)回路（ `H`、 `S`、 `CX` ゲートのブロック）の合成。 現在は9量子ビットブロックまで。\n",
        "* *AILinearFunctionSynthesis* ： [線形関数](/docs/api/qiskit/qiskit.circuit.library.LinearFunction)回路（ `CX` および `SWAP` ゲートのブロック）の合成。 現在は9量子ビットブロックまで。\n",
        "* *AIPermutationSynthesis* ： [パーミュテーション](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation)回路（ `SWAP` ゲートのブロック）の合成。 現在、65、33、27量子ビット・ブロックで利用可能。\n",
        "* *AIPauliNetworkSynthesis* ：パウリネットワーク回路（ `H`、 `S`、 `SX`、 `CX`、 `RX`、 `RY` 、 `RZ` ゲートのブロック）の合成。 現在は6量子ビットブロックまで。\n",
        "\n",
        "今後、対応ブロックのサイズを徐々に大きくしていく予定だ。\n",
        "\n",
        "すべてのパスは、スレッドプールを使って複数のリクエストを並行して送信する。 デフォルトでは、最大スレッド数はコア数＋4（ `ThreadPoolExecutor` Python オブジェクトのデフォルト値）。 しかし、パスのインスタンス化時に `max_threads` 引数で独自の値を設定することができます。 例えば、以下の行は `AILinearFunctionSynthesis` パスをインスタンス化し、最大20スレッドを使用できるようにしている。\n",
        "\n",
        "```python\n",
        "AILinearFunctionSynthesis(backend=ibm_torino, max_threads=20)  # Re-synthesize Linear Function blocks using 20 threads max\n",
        "```\n",
        "\n",
        "また、環境変数 `AI_TRANSPILER_MAX_THREADS` 、希望する最大スレッド数に設定することもできる。その後にインスタンス化されたすべての合成パスは、その値を使用する。\n",
        "\n",
        "AI合成パスがサブサーキットを合成するためには、そのサブサーキットがカップリング・マップの連結された部分グラフ上に配置されていなければならない（これを行う1つの方法は、ブロックを収集する前に配線パスを行うことであるが、これだけが唯一の方法ではない）。 合成パスは、特定の部分グラフがサポートされているかどうかを自動的にチェックし、サポートされていない場合は警告を発し、元の部分回路を変更しない。\n",
        "\n",
        "`qiskit_ibm_transpiler.ai.collection` からインポートできる、クリフォード、一次関数、および順列のための以下のカスタムコレクションパスも、合成パスを補完します：\n",
        "\n",
        "* *CollectCliffords* ：クリフォード・ブロックを `Instruction` オブジェクトとして収集し、合成後に比較するために元のサブ回路を保存します。\n",
        "* *CollectLinearFunctions* ： `SWAP` と `CX` のブロックを `LinearFunction` オブジェクトとして収集し、合成後に比較するために元のサブ回路を保存します。\n",
        "* *CollectPermutations* ： `SWAP` 回路のブロックを `Permutations` として収集する。\n",
        "* *CollectPauliNetworks* ：パウリ・ネットワーク・ブロックを収集し、合成後に比較するために元のサブ回路を保存します。\n",
        "\n",
        "これらのカスタム収集パスは、収集されたサブ回路のサイズを制限するため、AI搭載の合成パスでサポートされます。 したがって、より良い全体最適化のためには、配線パスの後、合成パスの前に使用することを推奨する。\n",
        "\n",
        "<span id=\"hybrid-heuristic-ai-circuit-transpilation\" />\n",
        "\n",
        "## ハイブリッド・ヒューリスティック-AI回路トランスパイレーション\n",
        "\n",
        "`qiskit-ibm-transpiler` 、QiskitのヒューリスティックパスとAIを搭載したトランスパイラーパスの長所を組み合わせたハイブリッドパスマネージャーを設定することができます。 この機能はQiskit `generate_pass_manager` メソッドと同様の動作をします。 `generate_ai_pass_manager` の典型的な使い方は以下の通り：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "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_kingston\")\n",
        "kingston_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=kingston_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": [
        "この例では以下のオプションを使用する：\n",
        "\n",
        "* `coupling_map` - 移調に使用するカップリング・マップを指定する。\n",
        "* `ai_optimization_level` - PassManager のAIコンポーネントに使用する最適化のレベル（1～3）を指定する。\n",
        "* `optimization_level` - PassManager のヒューリスティックな構成要素に対して、回路上でどの程度の最適化を行うかを指定する。\n",
        "* `ai_layout_mode` - PassManager のAIルーティング部がどのようにレイアウトを処理するかを指定する。 この `ai_layout_mode` パラメーターの設定オプションについては、 [AIルーティングパスの](#ai-routing-pass)セクションを参照してください。\n",
        "\n",
        "<span id=\"citation\" />\n",
        "\n",
        "## 引用\n",
        "\n",
        "引用\n",
        "研究において本パッケージ `qiskit-ibm-transpiler` のAIを活用した機能を利用する場合は、以下の推奨引用形式に従ってください：\n",
        "\n",
        "```\n",
        "@misc{2405.13196,\n",
        "Author = {David Kremer and Victor Villar and Hanhee Paik and Ivan Duran and Ismael Faro and Juan Cruz-Benito},\n",
        "Title = {Practical and efficient quantum circuit synthesis and transpiling with Reinforcement Learning},\n",
        "Year = {2024},\n",
        "Eprint = {arXiv:2405.13196},\n",
        "}\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "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"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}