{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "ce3d197d-7b14-4c60-8d39-a202146d0663",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"実行者の入出力\"\n",
        "description: \"Executorプリミティブへの入力と出力を理解する。\"\n",
        "---\n",
        "\n",
        "<span id=\"executor-inputs-and-outputs\" />\n",
        "\n",
        "# 実行者の入出力\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "44219323-9419-471a-86c4-488ef0162420",
      "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.4.0\n",
        "    qiskit-ibm-runtime~=0.46.1\n",
        "    samplomatic~=0.18.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "43c044dc-259d-4759-b6a7-a05bd9d3667f",
      "metadata": {},
      "source": [
        "「Executor」プリミティブは、 [指向型実行モデル](/docs/guides/directed-execution-model)の一部であり、エラー軽減ワークフローをカスタマイズする際により高い柔軟性を提供します。\n",
        "\n",
        "Executorプリミティブの入出力は[、Sampler](/docs/guides/sampler-input-output) プリミティブや [Estimator](/docs/guides/estimator-input-output) プリミティブのそれとは大きく異なります。 `QuantumProgram`たとえば、Executorはパブのリストを入力として受け取るのではなく、オブジェクトの `QuantumProgramItem` リストを含むを受け取ります。 これらのコンテナクラスは、単純なタプルデータ構造である PUB よりも高い柔軟性を提供します。\n",
        "\n",
        "`QuantumProgramItem``QuantumProgramResult`実行結果の出力はであり、これは反復可能オブジェクトであり、各入力に対して1つの要素を含みます。\n",
        "\n",
        "<span id=\"programs\" />\n",
        "\n",
        "<span id=\"inputs-quantum-programs\" />\n",
        "\n",
        "## 入力：量子プログラム\n",
        "\n",
        "[`QuantumProgram`](/docs/api/qiskit-ibm-runtime/quantum-program-quantum-program)前述の通り、Executorプリミティブへの入力は、オブジェクトの\n",
        "[`QuantumProgramItem`](/docs/api/qiskit-ibm-runtime/quantum-program-quantum-program-item) 反復可能オブジェクトである。  これらのオブジェクトには、次の2つのタイプがあります：\n",
        "\n",
        "* `CircuitItem`…通常、回路とそのパラメータ値（ある場合）が格納されます。\n",
        "* `SamplexItem`、通常は以下の内容を格納します：\n",
        "  * 回路のテンプレート\n",
        "  * samplexオブジェクト。実行時にランダムなパラメータのセットを生成するために使用されます（たとえば、ツイリングの実行やノイズの注入など）\n",
        "  * samplexへの引数（元の回路のパラメータ値が含まれる場合がある）\n",
        "\n",
        "これらの項目はそれぞれ、実行者が行うべき異なるタスクを表しています。\n",
        "\n",
        "<span id=\"before-you-begin\" />\n",
        "\n",
        "### 開始前に\n",
        "\n",
        "`samplex`このページにあるコード例の一部では、Samplomatic パッケージの一部である を使用しています。  したがって、これらのコードブロックを実行する前に、次のコードブロックに示すように、Samplomaticをインストールする必要があります。  詳細については、 [Samplomaticのドキュメント](https://qiskit.github.io/samplomatic)を参照してください。\n",
        "\n",
        "```python\n",
        "pip install samplomatic\n",
        "\n",
        "# For visualization support, include the visualization dependencies.\n",
        "# pip install samplomatic[vis]\n",
        "```\n",
        "\n",
        "<span id=\"example-create-a-quantumprogram-with-two-different-tasks\" />\n",
        "\n",
        "### 例：2つの異なるタスクを含む を作成 `QuantumProgram` する\n",
        "\n",
        "まず量子プログラムを初期化し、次に以下の例に示すように、または `append_samplex_item``append_circuit_item` （samplexが存在する場合）を使用してプログラム項目を追加します。\n",
        "\n",
        "次のセルでは、を `QuantumProgram` 初期化し、プログラム内の各項目のすべての構成について1024回の実行を行うよう指定しています。\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Samplerとは異なり、t `QuantumProgram` は単一のショット値のみを受け取ります。 `QuantumProgram`別のショット値が必要な場合は、別途設定が必要となり、それは別の作業となります。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "81fc7c9e-2cc9-416a-b3d5-74f45eab48fc",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime.quantum_program import QuantumProgram\n",
        "from qiskit_ibm_runtime import Executor, QiskitRuntimeService\n",
        "from qiskit.circuit import Parameter, QuantumCircuit\n",
        "import numpy as np\n",
        "from samplomatic import build\n",
        "from samplomatic.transpiler import generate_boxing_pass_manager\n",
        "\n",
        "# Initialize an empty program\n",
        "program = QuantumProgram(shots=1024)\n",
        "\n",
        "# Initialize and transpile a 3-qubit quantum circuit with 2 parameters.\n",
        "circuit = QuantumCircuit(3)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.cx(1, 2)\n",
        "circuit.rz(Parameter(\"theta\"), 0)\n",
        "circuit.rz(Parameter(\"phi\"), 1)\n",
        "\n",
        "# `measure_all` adds a 3-bit classical register named \"meas\"\n",
        "circuit.measure_all()\n",
        "\n",
        "# Choose the least busy backend\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Generate a preset pass manager\n",
        "# This will be used to convert the abstract circuit to an\n",
        "# equivalent Instruction Set Architecture (ISA) circuit.\n",
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend, optimization_level=0\n",
        ")\n",
        "\n",
        "# Transpile the circuit\n",
        "isa_circuit = preset_pass_manager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a1cc6580-3f31-4322-b0ea-f6bcf032a872",
      "metadata": {},
      "source": [
        "<span id=\"append-a-circuititem\" />\n",
        "\n",
        "### 追加する `CircuitItem`\n",
        "\n",
        "`QuantumProgram`次に、バックエンドの命令セットアーキテクチャ（ISA）に従ってトランスパイルされたターゲット回路を、.に追加します。 この回路には2つのパラメータがあるため、パラメータの値（この例では10組）も指定する必要があります。 これ `CircuitItem` を実行することが、プログラムが最初に行う処理です。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "e6f6762f-1627-450a-b74b-96ad4a3b1c9c",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the transpiled circuit and an array\n",
        "# containing 10 sets of parameter values to the program\n",
        "program.append_circuit_item(\n",
        "    isa_circuit,\n",
        "    circuit_arguments=np.random.rand(\n",
        "        10, 2\n",
        "    ),  # 10 sets of parameter values and 2 parameters\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "96f9ac43-8ce4-4389-bff4-5bd68b799974",
      "metadata": {},
      "source": [
        "<span id=\"append-a-samplexitem\" />\n",
        "\n",
        "### 追加する `SamplexItem`\n",
        "\n",
        "回路内の項目は、いかなるランダム化も行わずに実行されます。 それどころか、samplexアイテムでは、コンテンツをどのようにランダム化するかを指定することができます。 次のセルでは、関数を使用して `generate_boxing_pass_manager()` 回路のゲートと測定値をボックスにまとめ、各ボックスに回転する注釈を追加します。 その後、この `build()` 関数を使用して、テンプレート回路とサンプルクス・ペアを生成します。\n",
        "\n",
        "これ `SamplexItem` を実行するのは、プログラムが実行する2番目のタスクです。\n",
        "\n",
        "およびその引数に関する `samplex` 詳細については、Samplomatic [API](https://github.com/Qiskit/samplomatic/) ドキュメントを参照してください。 関 `generate_boxing_pass_manager()` 数の使用方法については、『Samplomatic [Transpiler ガイド](https://qiskit.github.io/samplomatic/guides/transpiler.html) 』を参照してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "4ac19f46-226b-4b13-b278-1e39e719484b",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "TensorInterface(<\n",
            "  - 'parameter_values' <float64[2]>: Input parameter values to use during sampling.\n",
            ">)\n"
          ]
        }
      ],
      "source": [
        "# Transpile the circuit, additionally grouping gates and measurements into annotated boxes\n",
        "preset_pass_manager = generate_preset_pass_manager(\n",
        "    backend=backend, optimization_level=0\n",
        ")\n",
        "\n",
        "# Use the boxing pass manager to group gates\n",
        "# and measurements into boxes and add\n",
        "# a`Twirl` annotation.\n",
        "preset_pass_manager.post_scheduling = generate_boxing_pass_manager(\n",
        "    # Add gate twirling\n",
        "    enable_gates=True,\n",
        "    # Add measurement twirling\n",
        "    enable_measures=True,\n",
        ")\n",
        "boxed_circuit = preset_pass_manager.run(circuit)\n",
        "\n",
        "# Build the template circuit and the samplex.  The template circuit has parametric gates\n",
        "# without fixed values and the samplex randomly generates the parameter\n",
        "# values on the server side at runtime to perform twirling.\n",
        "template_circuit, samplex = build(boxed_circuit)\n",
        "\n",
        "# Determine what arguments are required by the samplex.\n",
        "# Input the arguments in samplex_arguments.\n",
        "print(samplex.inputs())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "0e3b4d3d-12ea-47f2-a605-b64eed03cf95",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Append the template circuit and samplex as a samplex item\n",
        "program.append_samplex_item(\n",
        "    template_circuit,\n",
        "    samplex=samplex,\n",
        "    samplex_arguments={\n",
        "        # the arguments required by the samplex.sample method\n",
        "        \"parameter_values\": np.random.rand(10, 2),\n",
        "    },\n",
        "    shape=(28, 10),  # 28 randomizations and 10 sets of parameter values\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "eb850401-3d4f-4fac-8965-fb9ac4827ebd",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Initialize an Executor with the default options\n",
        "executor = Executor(mode=backend)\n",
        "\n",
        "# Submit the job\n",
        "job = executor.run(program)\n",
        "\n",
        "# Retrieve the result\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "541f5d2d-b974-4ae5-81e0-ef2b6e1dbe82",
      "metadata": {},
      "source": [
        "<span id=\"outputs\" />\n",
        "\n",
        "## 出力\n",
        "\n",
        "[`QuantumProgramResult`](/docs/api/qiskit-ibm-runtime/results-quantum-program-result)Executor の出力は、反復可能なオブジェクトである。 入力 `QuantumProgramItem` 項目ごとに1つのエントリが含まれており、入力項目の順序と同じ順序で並んでいます。 これらの出力項目のそれぞれは辞書であり、そのキーは（とりわけ）入力回路における従来のレジスタ名に対応する文字列となっています。そのため、Samplerの出力の場合のように、これらの名前を覚える必要はもうありません。 `np.ndarray`辞書の値は 型です。\n",
        "\n",
        "前の例の結果には、以下の項目が含まれています：\n",
        "\n",
        "<span id=\"circuititem-result\" />\n",
        "\n",
        "### `CircuitItem` の結果\n",
        "\n",
        "`CircuitItem`最初の項目には、プログラム内の最初のタスク（a）を実行した結果が含まれています。 `meas`ここには、入力回路における古典的なレジスタの名前である「」という単一のキーが含まれています。 `(parameter sets, shots, register bits)`このキーの値は、形状が の配列 `np.ndarray` にマッピングされます。上記の例では、その形状は (10, 1024, 3) となります。\n",
        "\n",
        "以下のコードは、この情報にアクセスする方法を示しています：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "d652d69a-7a4e-4e5c-8469-97cb9ec92010",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Result shape: (10, 1024, 3)\n"
          ]
        }
      ],
      "source": [
        "# Access the results of the classical register of task #0, a CircuitItem\n",
        "result_0 = result[0][\"meas\"]\n",
        "print(f\"Result shape: {result_0.shape}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7185353a-e7a0-4bb2-b605-664184e684ed",
      "metadata": {},
      "source": [
        "<span id=\"samplexitem-result\" />\n",
        "\n",
        "### `SamplexItem` の結果\n",
        "\n",
        "`SamplexItem`2番目の項目には、プログラム内の2番目のタスク（a）を実行した結果が含まれています。 このアイテムには複数のキーが含まれています。 key（入力回路の古典的レジスタの名前）は `meas` 、そのレジスタの結果の配列に対応付けられます。 `(randomizations, parameter sets, shots, classical bits)`この配列の次元は、この例では (28, 10, 1024, 3) です。 `measurement_flips.meas` さらに、出力には キーが含まれており、これは レジスタの `meas` 測定によるビット反転を元に戻すための補正値です。  この例の場合、ビット反転を行うのに1ショットしか必要としないため、出力形状は(28, 10, 1, 3)となります。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "884af6e2-614a-4b18-83dc-04505ddbc488",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Result shape: (28, 10, 1024, 3)\n",
            "Bit-flip corrections shape: (28, 10, 1, 3)\n"
          ]
        }
      ],
      "source": [
        "# Access the results of the classical register of task #1\n",
        "result_1 = result[1][\"meas\"]\n",
        "print(f\"Result shape: {result_1.shape}\")\n",
        "\n",
        "# Access the bit-flip corrections\n",
        "flips_1 = result[1][\"measurement_flips.meas\"]\n",
        "print(f\"Bit-flip corrections shape: {flips_1.shape}\")\n",
        "\n",
        "# Undo the bit flips via classical XOR\n",
        "unflipped_result_1 = result_1 ^ flips_1"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bb0c9225-9a52-4d94-b75d-6ae408f4e029",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * Executor [を使用した例](/docs/guides/executor-examples)をご覧ください。\n",
        "  * [指向型実行モデル](/docs/guides/directed-execution-model)について学びましょう。\n",
        "  * [「Executor」のブロードキャストについて](/docs/guides/executor-broadcasting)理解する。\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": 4
}