{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "cdc8dc1e-0cff-46c1-94d0-97456d278e27",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"最初の Qiskit Serverless プログラムを書いてみましょう\"\n",
        "description: \"並列トランスパイルプログラムを作成し、 IBM Quantum Platform にデプロイして再利用可能なリモートサービスとして使用する方法。\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mypath  */}\n",
        "\n",
        "<span id=\"write-your-first-qiskit-serverless-program\" />\n",
        "\n",
        "# 最初の Qiskit Serverless プログラムを書いてみましょう\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b6d632cb-d884-4963-9c8d-8f3a3acd8a7d",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "<Accordion>\n",
        "  <AccordionItem title=\"パッケージ・バージョン\">\n",
        "    このページのコードは、以下の要件に基づいて開発された。\n",
        "    これらのバージョンまたは新しいバージョンの使用をお勧めします。\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=1.3.1\n",
        "    qiskit-ibm-runtime~=0.34.0\n",
        "    qiskit-aer~=0.15.1\n",
        "    qiskit-serverless~=0.18.1\n",
        "    qiskit-ibm-catalog~=0.2\n",
        "    qiskit-addon-sqd~=0.8.1\n",
        "    qiskit-addon-utils~=0.1.0\n",
        "    qiskit-addon-mpf~=0.2.0\n",
        "    qiskit-addon-aqc-tensor~=0.1.2\n",
        "    qiskit-addon-obp~=0.1.0\n",
        "    scipy~=1.15.0\n",
        "    pyscf~=2.8.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1cc46aeb-aff6-4fab-9d78-69f2bfe98d98",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  **Qiskit Serverless アップグレードが行われており、その機能は急速に変化しています。** この開発フェーズでは、リリースノートと最新のドキュメントは [Qiskit Serverless GitHub](https://qiskit.github.io/qiskit-serverless/index.html) ページでご覧いただけます。\n",
        "</Admonition>\n",
        "\n",
        "この例では、ツール `qiskit-serverless` を使用して並列トランスパイルプログラムを作成し、その後、 IBM Quantum Platform にプログラムをアップロード `qiskit-ibm-catalog` して再利用可能なリモートサービスとして利用する方法について説明します。\n",
        "\n",
        "<span id=\"workflow-overview\" />\n",
        "\n",
        "## ワークフローの概要\n",
        "\n",
        "1. ローカルディレクトリを作成し、プログラムファイルを空にする (`./source_files/transpile_remote.py`)\n",
        "2. プログラムに、 Qiskit Serverless にアップロードすると回路をトランスパイルするコードを追加してください\n",
        "3. Qiskit Serverless への `qiskit-ibm-catalog` 認証に使用\n",
        "4. プログラムを Qiskit Serverless にアップロードしてください\n",
        "\n",
        "プログラムをアップロードしたら、 「[最初の『 Qiskit Serverless 』ワークロードをリモートで実行する](/docs/guides/serverless-run-first-workload) 」ガイドに従って、プログラムを実行し、回路をトランスパイルすることができます。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cad16f43-8548-4849-a4b8-09059a8b747c",
      "metadata": {},
      "source": [
        "<span id=\"example-remote-transpilation-with-qiskit-serverless\" />\n",
        "\n",
        "## 例： Qiskit Serverless を使用したリモート・トランスパイル\n",
        "\n",
        "この例では、プログラムファイルの作成と追加の手順を解説します。このファイルを Qiskit Serverless にアップロードすると、指定された に対して `circuit` をトランスパイルし、 `optimization_level``backend` ターゲット としてコンパイルされます。\n",
        "\n",
        "<Admonition type=\"tip\">\n",
        "  Qiskit Serverlessでは、ワークロードの `.py` ファイルを専用のディレクトリにセットアップする必要があります。 以下の構成はグッドプラクティスの一例である：\n",
        "\n",
        "  ```text\n",
        "  serverless_program\n",
        "  ├── program_uploader.ipynb\n",
        "  └── source_files\n",
        "      ├── transpile_remote.py\n",
        "      └── *.py\n",
        "  ```\n",
        "</Admonition>\n",
        "\n",
        "Serverlessは、特定のディレクトリ（この例では `source_files` ディレクトリ）の内容をアップロードし、リモートで実行します。 これらを設定したら、入力を取得して出力を返すように `transpile_remote.py` 調整できます。\n",
        "\n",
        "<span id=\"create-the-directory-and-an-empty-program-file\" />\n",
        "\n",
        "### ディレクトリと空のプログラムファイルを作成する\n",
        "\n",
        "まず、という名前の `source_files`ディレクトリを作成し、そのディレクトリ内にプログラムファイルを作成して、そのパスがになるようにします `./source_files/transpile_remote.py`。 これは、 Qiskit Serverless にアップロードするファイルです。\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a9b3fb7d-abd6-4a3e-b9b1-b21202d8db6d",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-your-program-file\" />\n",
        "\n",
        "### プログラムファイルにコードを追加する\n",
        "\n",
        "プログラムファイルに以下のコードを入力し、保存してください。\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  ノートブック内でコードセルをローカルに読み込んでいる場合、 [魔法の ](https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-writefile)`%%writefile` コマンドが表示されます。 この魔法のコマンドでセルを実行すると、実行されるのではなく、ディスクに保存されます。\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "214eb803-d1fa-4ac0-b955-8b24717086f4",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This cell is hidden from users, it creates a new folder\n",
        "from pathlib import Path\n",
        "\n",
        "Path(\"./source_files\").mkdir(exist_ok=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "64722041-22ed-42bd-8d83-d8e9f5e5b55b",
      "metadata": {
        "editable": true,
        "slideshow": {
          "slide_type": ""
        },
        "tags": []
      },
      "outputs": [],
      "source": [
        "%%writefile ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "def transpile_remote(circuit, optimization_level, backend):\n",
        "    \"\"\"Transpiles an abstract circuit into an ISA circuit for a given backend.\"\"\"\n",
        "    pass_manager = generate_preset_pass_manager(\n",
        "        optimization_level=optimization_level,\n",
        "\t\tbackend=backend\n",
        "    )\n",
        "    isa_circuit = pass_manager.run(circuit)\n",
        "    return isa_circuit"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7e80b5bb-0f76-43d1-a68c-97b4b22cc88a",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-get-program-arguments\" />\n",
        "\n",
        "### プログラムの引数を取得するコードを追加する\n",
        "\n",
        "次に、プログラム引数を設定する以下のコードをプログラムファイルに追加してください。\n",
        "\n",
        "最初の `transpile_remote.py` には3つの入力がある： `circuits` `backend_name` と `optimization_level`。 サーバーレスは現在、シリアライズ可能な入力と出力しか受け付けないように制限されている。 このため、 `backend` を直接渡すことはできないので、代わりに `backend_name` を文字列として使用する。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6819379b-d7b2-4fda-9e6b-459eec748a79",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit_serverless import get_arguments, save_result, distribute_task, get\n",
        "\n",
        "# Get program arguments\n",
        "arguments = get_arguments()\n",
        "circuits = arguments.get(\"circuits\")\n",
        "backend_name = arguments.get(\"backend_name\")\n",
        "optimization_level = arguments.get(\"optimization_level\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5ae9fb12-f06f-4f7d-8f37-1d872285deab",
      "metadata": {},
      "source": [
        "<span id=\"add-code-that-calls-the-backend\" />\n",
        "\n",
        "### バックエンドを呼び出すコードを追加する\n",
        "\n",
        "プログラムファイルに以下のコードを追加してください。これにより、 `QiskitRuntimeService`. を使用してバックエンドが呼び出されます。\n",
        "\n",
        "以下のコードでは、すでに を使用して認証情報を保存する手順を完了していることを前提としています `QiskitRuntimeService.save_account`。特に指定がない限り、保存されているデフォルトのアカウントが読み込まれます。 詳細については、「 [ログイン認証情報の保存](/docs/guides/save-credentials)」 および「 [IBM Quantum Compute Service アカウントの初期化](/docs/guides/initialize-account)」 を参照してください。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "4b0c7d24-9b87-4e00-bb1d-f82aa967cb1d",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(backend_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61e7cb3b-6d62-4b68-817a-39c0c1d95a9b",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-transpile\" />\n",
        "\n",
        "### トランスパイル用のコードを追加する\n",
        "\n",
        "最後に、プログラムファイルに次のコードを追加してください。 このコードは、渡された `circuits` すべての値に対して `transpile_remote()` 実行され、その `transpiled_circuits` 結果として を返します：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "041e7f85-e9e8-424d-8694-d54316225cc4",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "# Each circuit is being transpiled and will populate the array\n",
        "results = [\n",
        "    transpile_remote(circuit, 1, backend)\n",
        "    for circuit in circuits\n",
        "]\n",
        "\n",
        "save_result({\n",
        "    \"transpiled_circuits\": results\n",
        "})"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dac118ab-e447-4ddd-a5f8-d13e3953db76",
      "metadata": {},
      "source": [
        "<span id=\"upload-to-qiskit-serverless\" />\n",
        "\n",
        "<span id=\"authenticate-to-qiskit-serverless\" />\n",
        "\n",
        "### Qiskit Serverless に認証する\n",
        "\n",
        "APIキー `QiskitServerless` を使用して `qiskit-ibm-catalog` に認証してください（お手持ちの `QiskitRuntimeService` APIキーを使用するか、 [IBM Quantum Platform ダッシュボード]()で新しいAPIキーを作成できます）。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "8d1385c3-09a5-42c6-a5bc-53f686d8410e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction\n",
        "\n",
        "# Authenticate to the remote cluster and submit the pattern for remote execution\n",
        "serverless = QiskitServerless()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a0f64820-5fb1-41b9-9cb4-5095d0b5db43",
      "metadata": {},
      "source": [
        "<span id=\"run-code-to-upload\" />\n",
        "\n",
        "### コードを実行してアップロードする\n",
        "\n",
        "プログラムをアップロードするには、次のコードを実行してください。 Qiskit Serverless の内容（この場合は `working_dir` ）を に `source_files`圧縮し、それをアップ `tar`ロードした後、削除します。 は、 Qiskit Serverless`entrypoint` が実行するためのメインプログラムの実行ファイルを指定します。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "c1cdd46d-71e9-4711-a09b-6eca569ede6a",
      "metadata": {},
      "outputs": [],
      "source": [
        "transpile_remote_demo = QiskitFunction(\n",
        "    title=\"transpile_remote_serverless\",\n",
        "    entrypoint=\"transpile_remote.py\",\n",
        "    working_dir=\"./source_files/\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "8b675d04-bde8-4b3d-b9e5-99982ef742e1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(transpile_remote_serverless)"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.upload(transpile_remote_demo)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a840c18-3010-4d05-91cb-592e2692c1d7",
      "metadata": {},
      "source": [
        "<span id=\"verify-upload\" />\n",
        "\n",
        "### アップロードを確認する\n",
        "\n",
        "アップロードが正常に行われたかどうかを確認するには、次のコードのように を使用してください `serverless.list()`：\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "afaa3935-adf7-4b28-a8f0-583a82bbe3f1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(transpile_remote_serverless)"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get program from serverless.list() that matches the title of the one we uploaded\n",
        "next(\n",
        "    program\n",
        "    for program in serverless.list()\n",
        "    if program.title == \"transpile_remote_serverless\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a416b143-6f70-49dc-ab2f-ad66f042cab1",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"info\" title=\"推奨事項\">\n",
        "  * 「 [Qiskit Serverless ワークロードの初回リモート実行](/docs/guides/serverless-run-first-workload) 」のトピックで、入力の渡し方やプログラムのリモート実行方法について学びましょう。\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
}