{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "6b7abc7b-b435-43d1-9fd8-c349ee8710f3",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Qiskit Serverless -Rechen- und Datenressourcen verwalten\"\n",
        "description: \"Verwalten Sie Rechenleistung und Daten in Ihrem Qiskit-Muster mit „ Qiskit Serverless ”.\"\n",
        "---\n",
        "\n",
        "<span id=\"manage-qiskit-serverless-compute-and-data-resources\" />\n",
        "\n",
        "# Qiskit Serverless -Rechen- und Datenressourcen verwalten\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3b0771d6-95c9-46dc-955a-f8702f6a2632",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "<Accordion>\n",
        "  <AccordionItem title=\"Paketversionen\">\n",
        "    Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt.\n",
        "    Wir empfehlen die Verwendung dieser oder neuerer Versionen.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.0.0\n",
        "    qiskit-ibm-runtime~=0.37.0\n",
        "    qiskit-serverless~=0.27.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95b2f280-f685-455f-83e9-b172445d7c6a",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  **Qiskit Serverless wird aktualisiert, und seine Funktionen ändern sich schnell.** Während dieser Entwicklungsphase finden Sie Release Notes und die aktuellste Dokumentation auf der Seite „[ Qiskit Serverless](https://qiskit.github.io/qiskit-serverless/index.html) “ () unter GitHub.\n",
        "</Admonition>\n",
        "\n",
        "Mit Qiskit Serverless können Sie Berechnungen und Daten über Ihr [Qiskit-Muster](/docs/guides/intro-to-patterns) hinweg verwalten, einschließlich CPUs, QPUs und anderen Rechenbeschleunigern.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "380354c0-5cab-464d-b10f-c94055de3605",
      "metadata": {},
      "source": [
        "<span id=\"set-detailed-statuses\" />\n",
        "\n",
        "## Detaillierte Status festlegen\n",
        "\n",
        "Serverlose Workloads haben mehrere Phasen innerhalb eines Workflows. Standardmäßig sind die folgenden Status mit `job.status()` einsehbar:\n",
        "\n",
        "* **`QUEUED`**: die Arbeitslast steht in der Warteschlange für klassische Ressourcen\n",
        "* **`INITIALIZING`**: die Arbeitsbelastung ist festgelegt\n",
        "* **`RUNNING`**: die Arbeitslast läuft derzeit auf klassischen Ressourcen\n",
        "* **`DONE`**: die Arbeitslast wurde erfolgreich abgeschlossen\n",
        "\n",
        "Sie können auch benutzerdefinierte Status festlegen, die die jeweilige Phase des Workflows näher beschreiben, und zwar wie folgt.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Wenn Sie die Codezellen lokal in einem Notizbuch ausführen, wird der `%%writefile` [magische Befehl](https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-writefile) angezeigt. Wenn man Zellen mit diesem magischen Befehl ausführt, werden sie auf der Festplatte gespeichert, anstatt ausgeführt zu werden.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "a69df8bc-5033-45bf-a837-cffa9d29b844",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Writing ./source_files/status_example.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile ./source_files/status_example.py\n",
        "\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit_serverless import update_status, Job\n",
        "\n",
        "# # If your function has a mapping stage, particularly application functions, you can set the status\n",
        "# to \"RUNNING: MAPPING\" as follows:\n",
        "update_status(Job.MAPPING)\n",
        "\n",
        "# # While handling transpilation, error suppression, and so forth, you can set the status to\n",
        "# \"RUNNING: OPTIMIZING_FOR_HARDWARE\":\n",
        "update_status(Job.OPTIMIZING_HARDWARE)\n",
        "\n",
        "# # After you submit jobs to IBM Quantum Compute Service, the underlying quantum job will be queued. You can set\n",
        "# status to \"RUNNING: WAITING_FOR_QPU\":\n",
        "update_status(Job.WAITING_QPU)\n",
        "\n",
        "# # When the Quantum Compute job starts running on the QPU, set the following status\n",
        "# \"RUNNING: EXECUTING_QPU\":\n",
        "update_status(Job.EXECUTING_QPU)\n",
        "\n",
        "## Once QPU is completed and post-processing has begun, set the status \"RUNNING: POST_PROCESSING\":\n",
        "update_status(Job.POST_PROCESSING)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a8746eae-6f15-4faf-8771-0f3062efc723",
      "metadata": {},
      "source": [
        "Nach erfolgreicher Beendigung dieses Arbeitsaufwands (mit `save_result()`) wird dieser Status automatisch auf `DONE` aktualisiert.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b2d40a63-3359-46e9-8f1b-4746b449b407",
      "metadata": {},
      "source": [
        "<span id=\"parallel-workflows\" />\n",
        "\n",
        "## Parallele Arbeitsabläufe\n",
        "\n",
        "Verwenden Sie bei klassischen Aufgaben, die parallelisiert werden können, den `@distribute_task` Decorator, um die für die Ausführung einer Aufgabe erforderlichen Rechenressourcen zu definieren. Rufen Sie zunächst das `transpile_remote.py` Beispiel aus dem Abschnitt [„Schreiben Sie Ihr erstes Programm für Qiskit Serverless “](/docs/guides/serverless-first-program) mit dem folgenden Code in Erinnerung.\n",
        "\n",
        "Für den folgenden Code müssen Sie [Ihre Anmeldedaten](/docs/guides/cloud-setup) bereits gespeichert haben. Wie in diesem Beispiel wird der Laufzeitservice `get_runtime_service()` so erstellt, dass alle von ihm gestarteten „ Qiskit Runtime “-Jobs und -Sitzungen dem übergeordneten „ Qiskit Serverless “-Job zugeordnet werden. Weitere Informationen finden Sie unter „[Schreiben Sie Ihr erstes Programm unter Qiskit Serverless](/docs/guides/serverless-first-program) “.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "475d82f0-15cc-4db3-b3b0-54b07822b2a0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Writing ./source_files/transpile_remote.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile ./source_files/transpile_remote.py\n",
        "\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_serverless import distribute_task, get_runtime_service\n",
        "\n",
        "service = get_runtime_service()\n",
        "\n",
        "@distribute_task(target={\"cpu\": 1})\n",
        "def transpile_remote(circuit, optimization_level, backend):\n",
        "    \"\"\"\n",
        "    Transpiles an abstract circuit (or list of circuits)\n",
        "    into an ISA circuit for a given backend.\n",
        "    \"\"\"\n",
        "    pass_manager = generate_preset_pass_manager(\n",
        "        optimization_level=optimization_level,\n",
        "        backend=service.backend(backend)\n",
        "    )\n",
        "    isa_circuit = pass_manager.run(circuit)\n",
        "    return isa_circuit"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5914f1d-f898-4db4-8d1e-ccc8081883b9",
      "metadata": {},
      "source": [
        "In diesem Beispiel haben Sie die Funktion `transpile_remote()` mit `@distribute_task(target={\"cpu\": 1})` dekoriert. Bei der Ausführung wird eine asynchrone parallele Arbeitsaufgabe mit einem einzigen CPU-Kern erstellt und mit einem Verweis zur Verfolgung der Arbeitsaufgabe zurückgegeben. Um das Ergebnis abzurufen, übergeben Sie den Verweis an die Funktion `get()` . Auf diese Weise können wir mehrere Aufgaben parallel ausführen:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "e8fd31e6-9ab9-4d75-9ef9-a2b9ff9ad37a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/transpile_remote.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "\n",
        "# If you include the preceding `%%writefile` command\n",
        "# (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than\n",
        "# executing the code.\n",
        "\n",
        "from time import time\n",
        "from qiskit_serverless import get, get_arguments, save_result, update_status, Job\n",
        "\n",
        "# Get arguments\n",
        "arguments = get_arguments()\n",
        "circuit = arguments.get(\"circuit\")\n",
        "optimization_level = arguments.get(\"optimization_level\")\n",
        "backend = arguments.get(\"backend\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "74fdcd4a-01cd-46ca-aa24-2a8a3605346f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/transpile_remote.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command\n",
        "# (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "# Start distributed transpilation\n",
        "update_status(Job.OPTIMIZING_HARDWARE)\n",
        "\n",
        "start_time = time()\n",
        "transpile_worker_references = [\n",
        "    transpile_remote(circuit, optimization_level, backend)\n",
        "    for circuit in arguments.get(\"circuit_list\")\n",
        "]\n",
        "\n",
        "transpiled_circuits = get(transpile_worker_references)\n",
        "end_time = time()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "81696ede-3aa5-4e8c-9d35-fdd70c1bf4db",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/transpile_remote.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command\n",
        "# (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "# Save result, with metadata\n",
        "result = {\n",
        "    \"circuits\": transpiled_circuits,\n",
        "    \"metadata\": {\n",
        "        \"resource_usage\": {\n",
        "            \"RUNNING: OPTIMIZING_FOR_HARDWARE\": {\n",
        "                \"CPU_TIME\": end_time - start_time,\n",
        "                \"QPU_TIME\": 0,\n",
        "            },\n",
        "        }\n",
        "    },\n",
        "}\n",
        "\n",
        "save_result(result)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "611fe030-4494-46b5-9ea1-9678ac513210",
      "metadata": {},
      "source": [
        "<span id=\"explore-different-task-configurations\" />\n",
        "\n",
        "### Untersuchen Sie verschiedene Aufgabenkonfigurationen\n",
        "\n",
        "Über `@distribute_task()` können Sie CPU, GPU und Speicher für Ihre Aufgaben flexibel zuweisen. Für Qiskit Serverless auf IBM Quantum® Platform ist jedes Programm mit 16 CPU-Kernen und 32 GB RAM ausgestattet, die je nach Bedarf dynamisch zugewiesen werden können.\n",
        "\n",
        "CPU-Kerne können als ganze CPU-Kerne oder sogar als Bruchteile davon zugewiesen werden, wie im Folgenden gezeigt wird.\n",
        "\n",
        "Der Speicher wird in der Anzahl der Bytes zugewiesen. Ein Kilobyte besteht aus 1024 Bytes, ein Megabyte aus 1024 Kilobytes und ein Gigabyte aus 1024 Megabytes. Um 2 GB Speicher für Ihren Worker zuzuweisen, müssen Sie `\"mem\": 2 * 1024 * 1024 * 1024` zuweisen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "cea90969-cfbf-4181-9ffa-524f3709dc69",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Appending to ./source_files/transpile_remote.py\n"
          ]
        }
      ],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command\n",
        "# (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "@distribute_task(target={\n",
        "    \"cpu\": 16,\n",
        "    \"mem\": 2 * 1024 * 1024 * 1024\n",
        "})\n",
        "def transpile_remote(circuit, optimization_level, backend):\n",
        "    return None"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6bc45489-56d0-4f46-8659-9df4d1555516",
      "metadata": {},
      "source": [
        "<span id=\"manage-data-across-your-program\" />\n",
        "\n",
        "## Verwalten Sie Daten in Ihrem gesamten Programm\n",
        "\n",
        "Qiskit Serverless ermöglicht Ihnen die Verwaltung von Dateien im Verzeichnis `/data` über alle Ihre Programme hinweg. Dies beinhaltet mehrere Einschränkungen:\n",
        "\n",
        "* Derzeit werden nur die Dateien `tar` und `h5` unterstützt\n",
        "* Dies ist nur ein flacher `/data` Speicher, und kann keine `/data/folder/` Unterverzeichnisse haben\n",
        "\n",
        "Im Folgenden wird gezeigt, wie Sie Dateien hochladen können. Stellen Sie sicher, dass Sie sich mit Ihrem IBM Quantum -Konto bei Qiskit Serverless authentifiziert haben (Anweisungen finden Sie unter „[Hochladen auf Qiskit Serverless](/docs/guides/serverless-first-program#upload-to-qiskit-serverless) “).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "0183278f-8ce3-4466-9255-097b2d211052",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'{\"message\":\"/usr/src/app/media/5e1f442128cdf60018496a04/transpile_demo.tar\"}'"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import tarfile\n",
        "from qiskit_serverless import IBMServerlessClient\n",
        "\n",
        "# Create a tar\n",
        "filename = \"transpile_demo.tar\"\n",
        "file = tarfile.open(filename, \"w\")\n",
        "file.add(\"./source_files/transpile_remote.py\")\n",
        "file.close()\n",
        "\n",
        "# Get a reference to a QiskitFunction\n",
        "serverless = IBMServerlessClient()\n",
        "transpile_remote_demo = next(\n",
        "    program\n",
        "    for program in serverless.list()\n",
        "    if program.title == \"transpile_remote_serverless\"\n",
        ")\n",
        "\n",
        "# Upload the tar to Serverless data directory\n",
        "serverless.file_upload(file=filename, function=transpile_remote_demo)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4f762470-945f-48d5-a65b-c60d3b2dae3f",
      "metadata": {},
      "source": [
        "Als nächstes können Sie alle Dateien in Ihrem Verzeichnis `data` auflisten. Diese Daten sind für alle Programme zugänglich.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "14241fc4-d0cb-4803-8752-a460e1f48708",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "['classifier_name.pkl.tar', 'output.json.tar', 'transpile_demo.tar']"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.files(function=transpile_remote_demo)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a97bd83e-8250-43bb-b1c4-d40d822c7ba2",
      "metadata": {},
      "source": [
        "Dies kann von einem Programm aus geschehen, indem man `file_download()` verwendet, um die Datei in die Programmumgebung herunterzuladen und die `tar` zu dekomprimieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "ef649b2a-ed95-4dd2-89d9-61438faa7c1e",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile ./source_files/extract_tarfile.py\n",
        "# If you include the preceding `%%writefile` command\n",
        "# (visible only when you read this locally in a\n",
        "# notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "import tarfile\n",
        "from qiskit_serverless import IBMServerlessClient\n",
        "\n",
        "# For `token`, use the 44-character API_KEY you created\n",
        "# and saved from the IBM Quantum Platform Home dashboard\n",
        "serverless = IBMServerlessClient(token=\"<YOUR_API_KEY>\")\n",
        "files = serverless.files()\n",
        "demo_file = files[0]\n",
        "downloaded_tar = serverless.file_download(demo_file)\n",
        "\n",
        "\n",
        "with tarfile.open(downloaded_tar, 'r') as tar:\n",
        "    tar.extractall()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5b93dbdb-2060-468b-8496-ba98142a780b",
      "metadata": {},
      "source": [
        "An diesem Punkt kann Ihr Programm mit den Dateien interagieren, wie Sie es bei einem lokalen Experiment tun würden. `file_upload()` die Dateien `file_download()` und `file_delete()` können von Ihrem lokalen Experiment oder Ihrem hochgeladenen Programm aufgerufen werden, um eine einheitliche und flexible Datenverwaltung zu gewährleisten.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a004dd78-0e0a-4a3b-83cb-333469533ef6",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"info\" title=\"Empfehlungen\">\n",
        "  * Sehen Sie sich ein vollständiges Beispiel an, in dem [bestehender Code auf](/docs/guides/serverless-port-code) „ Qiskit Serverless “ portiert wird.\n",
        "  * Lesen Sie einen Artikel, in dem Forscher Qiskit Serverless und quantenzentriertes Supercomputing zur [Erforschung der Quantenchemie](https://arxiv.org/abs/2405.05068v1) einsetzen.\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": 2
}