{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "33f4bb3c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"回路のタイミングを可視化する\"\n",
        "description: \"生成された回路のタイミングを可視化し、表示やダウンロード、あるいはその両方が可能な図を作成します。\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mactex, backgroundcolor, lightgreen */}\n",
        "\n",
        "<span id=\"visualize-circuit-timing\" />\n",
        "\n",
        "# 回路のタイミングを可視化する\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bfada4f0",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"パッケージ・バージョン\">\n",
        "    このページのコードは、以下の要件に基づいて開発されました。\n",
        "    これらのバージョン以降のご利用をお勧めします。\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ad24e3a0",
      "metadata": {},
      "source": [
        "Qiskitに組み込まれている[タイムライン・ドロワー](/docs/guides/visualize-circuit-timing) は、静的な回路では有用ですが、ブロードキャストや分岐判定といった暗黙的な演算があるため、 [動的な回路](/docs/guides/classical-feedforward-and-control-flow)のタイミングを正確に反映できない場合があります。 動的なサーキットサポートの一環として、 IBM Quantum Compute Service は、要求があった場合、ジョブ結果内に正確なサーキットタイミング情報を返します。\n",
        "\n",
        "<Admonition type=\"note\" title=\"ノート\">\n",
        "  * これは実験的な機能です。 現在プレビュー版として公開されているため、内容は変更される可能性があります。\n",
        "  * この機能は、 IBM Quantum のサンプラージョブにのみ適用されます。\n",
        "  * 「コンパイル」メタデータには総実行時間が返されますが、これは課金対象となる時間（QPU時間）ではありません。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "995a99e8",
      "metadata": {},
      "source": [
        "<span id=\"enable-timing-data-retrieval\" />\n",
        "\n",
        "### タイミングデータの取得を有効にする\n",
        "\n",
        "タイミングデータの取得を有効にするには、プリミティブジョブの実行時に実験用 `scheduler_timing``True` フラグを に設定してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "ab8c6c23",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\n",
        "    \"execution\": {\n",
        "        \"scheduler_timing\": True,\n",
        "    },\n",
        "}\n",
        "\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "531b2abd",
      "metadata": {},
      "source": [
        "<span id=\"access-the-circuit-timing-data\" />\n",
        "\n",
        "### 回路のタイミングデータにアクセスする\n",
        "\n",
        "要求があった場合、各 PUB の回路タイミングデータは、ジョブ結果のメタデータ内の `[\"compilation\"][\"scheduler_timing\"][\"timing\"]`. このフィールドには、生のタイミング情報が格納されています。 タイミング情報を表示するには、 [「タイミングの可視化」](#visualize-timings) のセクションに記載されているように、組み込みの可視化ツールを使用してください。\n",
        "\n",
        "最初の PUB のサーキットタイムデータにアクセスするには、次のコードを使用してください：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b6958d99",
      "metadata": {},
      "outputs": [],
      "source": [
        "job_result = sampler_job.result()\n",
        "circuit_schedule = job_result[0].metadata[\"compilation\"][\"scheduler_timing\"]\n",
        "circuit_schedule_timing = circuit_schedule[\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "20400401",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-raw-timing-data\" />\n",
        "\n",
        "#### 生のタイミングデータを理解する\n",
        "\n",
        "この `draw_circuit_schedule_timing` メソッドを使用して回路のタイミングデータを可視化することが最も一般的な用途ですが、返される生のタイミングデータの構造を理解しておくと役立つ場合があります。 これにより、例えば、プログラムを使って情報を抽出できるようになります。\n",
        "\n",
        "で返されるタイミングデータ `[\"compilation\"][\"scheduler_timing\"][\"timing\"]` は、文字列のリストです。 各文字列は、あるチャネル上の単一の命令を表しており、カンマ区切りで以下のデータ型で構成されています：\n",
        "\n",
        "* `Branch` - その命令が制御フロー（then / else）にあるのか、それともメインブランチにあるのかを判定します。\n",
        "* `Instruction` - ゲートと、演算の対象となる量子ビット。\n",
        "* `Channel` - その命令によって割り当てられているチャネル。 次のいずれかです。\n",
        "  * `Qubit x` - 量子ビット *x* の駆動チャネル。\n",
        "  * `AWGRx_y` （任意波形発生器の表示） - 量子ビットを測定する際、表示チャンネル間の通信に使用される。 *x* および *y* の引数は、それぞれ読み出し機器の ID と量子ビット番号に対応しています。\n",
        "* `T0` - 完全なスケジュール内の授業開始時刻\n",
        "* `Duration` - 命令の実行時間（単位： *dt* 秒）。ここで、1 dt = 1 スケジューリングサイクル。 バックエンドの値 `dt` は、... [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt)を使用して確認できます。\n",
        "* `Pulse` - 使用されているパルス動作の種類。\n",
        "\n",
        "例:\n",
        "\n",
        "```python\n",
        "main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration\n",
        "main,reset_0,Qubit 0,7,64,play # A reset instruction on the main branch on qubit 0 at time 7 with duration 64 and a play operation\n",
        "...\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d34100f",
      "metadata": {},
      "source": [
        "<span id=\"visualize-timings\" />\n",
        "\n",
        "<span id=\"visualize-the-timings\" />\n",
        "\n",
        "### タイミングを視覚化する\n",
        "\n",
        "v0.43.0`qiskit-ibm-runtime` 以降では、回路のタイミングを可視化できます。 タイミングを可視化するには、まず [メソッド `draw_circuit_schedule_timing`](https://github.com/Qiskit/qiskit-ibm-runtime/blob/3d1bf1e1d49e5123841639fce259859c90ce9314/qiskit_ibm_runtime/visualization/draw_circuit_schedule_timings.py#L26) を使用して、結果のメタ `fig` データを に変換する必要があります。 このメソッドは図 `plotly` を返します。この図は、そのまま表示したり、ファイルに保存したり、あるいはその両方を行うことができます。  使用するコマンド `plotly` の詳細については、および [`fig.show()`](https://plotly.com/python-api-reference/generated/plotly.io.show.html) を参照してください [`fig.write_image(\"<path.format>\")`](https://plotly.com/python-api-reference/generated/plotly.io.write_image.html)。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "4ad3acfb",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "# Create a figure from the metadata\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule_timing,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2788e992",
      "metadata": {},
      "source": [
        "![出力の上にカーソルを合わせると、開始時刻、終了時刻、所要時間などの情報が表示されます。生成された図の](https://quantum.cloud.ibm.com/docs/images/guides/visualize-circuit-timing/image_1.avif \"例\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "323a7d38",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-generated-figure\" />\n",
        "\n",
        "#### 生成された図を理解する\n",
        "\n",
        "によって出力される回路タイミングデータの `draw_circuit_schedule_timing` 図は、以下の情報を示しています：\n",
        "\n",
        "* X軸*はdt* 秒単位の時間であり、ここで1 dt = 1スケジューリングサイクルである。 バックエンドの値 `dt` は、... [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt)を使用して確認できます。\n",
        "* Y軸はチャネルです（チャネルはパルスを発するデバイスだと考えてください）。\n",
        "  * `Receive channel` - それ自体が楽器ではない唯一のチャンネル。 これは、その時点でハブとの通信手順に参加しているすべてのチャネルで実行される命令です。\n",
        "  * `Qubit x` - 量子ビット x の駆動チャネル。\n",
        "  * `AWGRx_y` （任意波形発生器の表示） - 量子ビットを測定する際、表示チャンネル間の通信に使用される。 *x* および *y* の引数は、それぞれ読み出し機器の ID と量子ビット番号に対応しています。\n",
        "  * `Hub` - 放送を制御します。\n",
        "\n",
        "さらに、各命令は *X\\_Y* という形式をとっており、 *X* は命令名、 *Y* はパルス種別を表します。 A `play` は制御パルスを印加し、Bは量子ビットの状態 `capture` を記録する。 各手順にカーソルを合わせると、詳細を確認することもできます。 例えば、前の図は、1161 dtの時点で量子ビット10に印加されたXゲート用の制御パルスを示しています。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86af09ca",
      "metadata": {},
      "source": [
        "<span id=\"end-to-end-example\" />\n",
        "\n",
        "### エンドツーエンドの例\n",
        "\n",
        "この例では、オプションを有効にし、メタデータから回路のタイミング情報を取得して、画像として表示する方法を説明します。\n",
        "\n",
        "まず、環境を設定し、回路を定義してISA回路に変換し、ジョブを定義して実行します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b46908a0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>>  Job ID:    d9mqmk7urbec73e67nng (DONE)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService\n",
        "from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Create a dynamic circuit\n",
        "\n",
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "qc = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "qc.h(q0)\n",
        "qc.measure(q0, c0)\n",
        "with qc.if_test((c0, 1)):\n",
        "    qc.x(q0)\n",
        "qc.measure(q0, c0)\n",
        "\n",
        "# Convert to an ISA circuit for the given backend\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "# Generate samplers for backend targets\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\"execution\": {\"scheduler_timing\": True}}\n",
        "\n",
        "# Submit jobs\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()\n",
        "\n",
        "print(\n",
        "    f\">>> {' Job ID:':<10}  {sampler_job.job_id()} ({sampler_job.status()})\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1bd5993c",
      "metadata": {},
      "source": [
        "次に、試合日程を確認してください：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "7e943812",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'main,rz_0,Qubit 0,1393,0,shift_phase\\nmain,sx_0,Qubit 0,1393,9,play\\nmain,sx_0,Qubit 0,1397,0,shift_phase\\nmain,rz_0,Qubit 0,1402,0,shift_phase\\nmain,barrier,Qubit 0,1402,0,barrier\\nmain,measure_0,Qubit 0,1402,64,play\\nmain,measure_0,Qubit 0,1466,108,play\\nmain,measure_0,AWGR0_0,1523,325,capture\\nmain,measure_0,Qubit 0,1574,64,play\\nmain,measure_0,Qubit 0,1638,64,play\\nmain,barrier,Qubit 0,2049,0,barrier\\nmain,broadcast,Hub,1523,526,broadcast\\nmain,receive,Receive,2049,7,receive\\nthen,x_0,Qubit 0,2064,9,play\\nmain,barrier,Qubit 0,2082,0,barrier\\nmain,measure_0,Qubit 0,2082,64,play\\nmain,measure_0,Qubit 0,2146,108,play\\nmain,measure_0,AWGR0_0,2203,325,capture\\nmain,measure_0,Qubit 0,2254,64,play\\nmain,measure_0,Qubit 0,2318,64,play\\nmain,barrier,Qubit 0,2753,0,barrier\\nmain,barrier,Qubit 0,2753,0,barrier\\nmain,FINI_0,Qubit 0,2753,64,play\\nmain,FINI_0,Qubit 0,2817,108,play\\nmain,FINI_0,AWGR0_0,2874,325,capture\\nmain,FINI_0,Qubit 0,2925,64,play\\nmain,FINI_0,Qubit 0,2989,64,play\\nmain,FINI_0,Qubit 0,3424,9,play\\nmain,FINI_0,Qubit 0,3433,64,play\\nmain,FINI_0,Qubit 0,3497,108,play\\nmain,FINI_0,AWGR0_0,3554,325,capture\\nmain,FINI_0,Qubit 0,3605,64,play\\nmain,FINI_0,Qubit 0,3669,64,play\\nmain,FINI_0,Qubit 0,4104,9,play\\nmain,barrier,Qubit 0,4113,0,barrier\\n'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get the circuit schedule timing\n",
        "result[0].metadata[\"compilation\"][\"scheduler_timing\"][\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "04db1f41",
      "metadata": {},
      "source": [
        "最後に、タイミングを視覚化して保存することができます：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "9d1901c3",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "circuit_schedule = result[0].metadata[\"compilation\"][\"scheduler_timing\"][\n",
        "    \"timing\"\n",
        "]\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9daa7cf7",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * [従来のフィードフォワード制御と制御フロー](/docs/guides/classical-feedforward-and-control-flow) （動的回路）\n",
        "  * [回路を可視化する](/docs/guides/visualize-circuits)\n",
        "</Admonition>\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": 5
}