{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "8fe3ca32",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Systemhardware\"\n",
        "description: \"In dieser Lektion wird moderne Quantencomputer-Hardware behandelt. Es basiert auf einem Live-Kurs, der an der Universität Tokio angeboten wird.\"\n",
        "---\n",
        "\n",
        "<span id=\"hardware\" />\n",
        "\n",
        "# Systemhardware\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Masao Tokunari und Tamiya Onodera (14. Juni 2024)\n",
        "\n",
        "  Dieser Kurs basiert auf einem Live-Kurs an der Universität von Tokio.\n",
        "\n",
        "  Die pdf-Vorlesung dieser Lektion wurde in zwei Teile aufgeteilt. [Download Teil 1](https://ibm.ent.box.com/public/static/ruz8wf353hncenmaywjlfjilflaumnzt.zip) und [Download Teil 2](https://ibm.ent.box.com/public/static/tg8vv00ern2bmxmm033xt9oe0fcvwamc.zip). Beachten Sie, dass einige Codeschnipsel veraltet sein könnten, da es sich um statische Bilder handelt.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e0cf0747",
      "metadata": {},
      "source": [
        "<span id=\"1-introduction\" />\n",
        "\n",
        "## 1. Einführung\n",
        "\n",
        "Diese Lektion beschäftigt sich mit moderner Quantencomputer-Hardware.\n",
        "\n",
        "Wir beginnen damit, einige Versionen zu überprüfen und einige relevante Pakete zu importieren.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "798d0ab4-34f5-4c64-83f0-02ef5149e6f3",
      "metadata": {},
      "outputs": [],
      "source": [
        "import statistics\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2cc2f2a3-947f-439b-b683-911539f1e6f2",
      "metadata": {},
      "source": [
        "<span id=\"2-backend-and-target\" />\n",
        "\n",
        "## 2. Backend und Ziel\n",
        "\n",
        "Qiskit bietet eine API, um statische und dynamische Informationen über ein Quantengerät zu erhalten. Wir verwenden eine Backend-Instanz als Schnittstelle zu einem Gerät, das eine Target-Instanz enthält, ein abstraktes Maschinenmodell, das die relevanten Merkmale wie die Befehlssatzarchitektur (ISA) und alle damit verbundenen Eigenschaften oder Beschränkungen zusammenfasst.\n",
        "Lassen Sie uns diese Backend-Instanzen verwenden, um einige der Informationen zu erhalten, die Sie auf der Seite [Compute-Ressourcen](/computers) auf IBM Quantum® Platform sehen.   Zunächst erstellen wir eine Backend-Instanz für ein Gerät von Interesse.  Im Folgenden wählen wir \"ibm\\_kyoto\", \"ibm\\_kawasaki\" oder den am wenigsten ausgelasteten Eagle-Rechner. Ihr Zugang zu QPUs kann sich unterscheiden; aktualisieren Sie den Backend-Namen entsprechend.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b92ad1bf-6ad4-420c-8a3a-5bfc488d5923",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'ibm_strasbourg'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "# backend = service.backend(\"ibm_kawasaki\") # an Eagle, if you have access to ibm_kawasaki\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=127\n",
        ")  # Eagle\n",
        "backend.name"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c082da02-fcc5-4506-b4fe-9015e99e63dc",
      "metadata": {},
      "source": [
        "Wir beginnen mit einigen grundlegenden (statischen) Informationen über das Gerät.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "33c39786-d44a-47bb-8245-72eb6b97e394",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "ibm_strasbourg, 127 qubits\n",
            "processor type = {'family': 'Eagle', 'revision': 3} \n",
            "basis gates = ['ecr', 'id', 'rz', 'sx', 'x']\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(\n",
        "    f\"\"\"\n",
        "{backend.name}, {backend.num_qubits} qubits\n",
        "processor type = {backend.processor_type}\n",
        "basis gates = {backend.basis_gates}\n",
        "\"\"\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "31675447-1a26-4168-a038-09cc7535e037",
      "metadata": {},
      "source": [
        "<span id=\"21-exercise\" />\n",
        "\n",
        "### 2.1 Übung\n",
        "\n",
        "Versuchen Sie, die grundlegenden Informationen über ein Heron-Gerät, \"ibm\\_strasbourg\", zu erhalten. Probieren Sie es selbst aus, aber wir haben unten einen Code eingefügt, den Sie selbst überprüfen können.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "f29afd7e-af40-4cd5-bc0e-a864663a616d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "ibm_strasbourg, 133 qubits\n",
            "processor type = {'family': 'Heron', 'revision': '1'} \n",
            "basis gates = ['cz', 'id', 'rz', 'sx', 'x']\n",
            "\n"
          ]
        }
      ],
      "source": [
        "a_heron = service.backend(\"ibm_strasbourg\")  # a Heron\n",
        "\n",
        "# your code here\n",
        "print(\n",
        "    f\"\"\"\n",
        "{backend.name}, {a_heron.num_qubits} qubits\n",
        "processor type = {a_heron.processor_type}\n",
        "basis gates = {a_heron.basis_gates}\n",
        "\"\"\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "08fef064-3fc6-4c27-9288-a2e3aa7f5d08",
      "metadata": {},
      "source": [
        "<span id=\"22-coupling-map\" />\n",
        "\n",
        "### 2.2 Kopplungskarte\n",
        "\n",
        "Wir zeichnen nun die Kopplungskarte des Geräts. Wie Sie sehen können, sind die Knoten Qubits, die nummeriert sind. Die Kanten zeigen Paare an, auf die man das 2-Qubit-Verschränkungsgatter direkt anwenden kann.  Die Topologie wird als \"Heavy-Hex-Gitter\" bezeichnet.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "51b87458-a5e8-4e77-a34d-39fe425a5f01",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/51b87458-a5e8-4e77-a34d-39fe425a5f01-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# This function requires that Graphviz is installed. If you need to install Graphviz\n",
        "# you can refer to:\n",
        "# https://graphviz.org/download/#executable-packages for instructions.\n",
        "try:\n",
        "    fig = backend.coupling_map.draw()\n",
        "except RuntimeError as ex:\n",
        "    print(ex)\n",
        "fig"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "881a5350-282c-4a89-b9e2-ac6bf61c6571",
      "metadata": {},
      "source": [
        "<span id=\"3-qubit-properties\" />\n",
        "\n",
        "## 3. Eigenschaften von Qubits\n",
        "\n",
        "Das Eagle-Gerät hat 127 Qubits.   Wir wollen die Eigenschaften einiger von ihnen kennenlernen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "9bcb9ce2-5ea8-487b-a7ac-a2956e8cbc34",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0: QubitProperties(t1=0.000183686508736532, t2=0.00023613944465408068, frequency=4832100227.116953)\n",
            "1: QubitProperties(t1=0.00048794378526038294, t2=9.007098375327869e-05, frequency=4736264354.075363)\n",
            "2: QubitProperties(t1=0.00021247781834456527, t2=7.81037910324034e-05, frequency=4859349851.150393)\n",
            "3: QubitProperties(t1=0.0002936462084765663, t2=0.00011400214529510604, frequency=4679749549.503852)\n",
            "4: QubitProperties(t1=0.00044229440258559125, t2=0.0003181648356339447, frequency=4845872064.050596)\n"
          ]
        }
      ],
      "source": [
        "for qn in range(backend.num_qubits):\n",
        "    if qn >= 5:\n",
        "        break\n",
        "    print(f\"{qn}: {backend.qubit_properties(qn)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "be601762",
      "metadata": {},
      "source": [
        "Berechnen wir den Median der T1 -Zeiten der Qubits.   Vergleichen Sie das Ergebnis mit dem, das für das Gerät auf [IBM Quantum Platform](/) angezeigt wird.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "e8f398b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median T1: 285.43 μs'"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "t1s = [backend.qubit_properties(qq).t1 for qq in range(backend.num_qubits)]\n",
        "f\"Median T1: {(statistics.median(t1s)*10**6):.2f} \\u03bcs\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01695904-2cb2-4f1d-9396-82cc94429d81",
      "metadata": {},
      "source": [
        "<span id=\"31-exercise\" />\n",
        "\n",
        "### 3.1 Übung\n",
        "\n",
        "Berechnen Sie bitte den Median der T2 Zeiten der Qubits. Probieren Sie es selbst aus, aber wir haben unten einen Code eingefügt, den Sie selbst überprüfen können.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "49fbe7a4-3dea-442f-ae3f-e82df93d406a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median T2: 173.10 μs'"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Your code here\n",
        "\n",
        "t2s = [backend.qubit_properties(qq).t2 for qq in range(backend.num_qubits)]\n",
        "f\"Median T2: {(statistics.median(t2s)*10**6):.2f} \\u03bcs\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7bdf8873-359e-4b03-98af-ede989a4a96d",
      "metadata": {},
      "source": [
        "<span id=\"32-gate-and-readout-errors\" />\n",
        "\n",
        "### 3.2 Gate- und Auslesefehler\n",
        "\n",
        "Wir wenden uns nun den Torfehlern zu. Zu Beginn untersuchen wir die Datenstruktur der Zielinstanz. Es ist ein Wörterbuch, dessen Schlüssel die Namen der Operationen sind.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c9188662",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "dict_keys(['measure', 'id', 'sx', 'delay', 'x', 'for_loop', 'rz', 'if_else', 'ecr', 'reset', 'switch_case'])"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "target = backend.target\n",
        "target.keys()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "46e3a8ac-65dc-4973-bd72-820676727f4e",
      "metadata": {},
      "source": [
        "Seine Werte sind ebenfalls Wörterbücher.  Schauen wir uns einige der Elemente des Wertes (Wörterbuch) für die Operation \"sx\" an.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "c9b30ede-c00f-4e18-bb72-3bfc06e6afa5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0,) InstructionProperties(duration=6e-08, error=0.0007401311759115297)\n",
            "1 (1,) InstructionProperties(duration=6e-08, error=0.0003163759907528654)\n",
            "2 (2,) InstructionProperties(duration=6e-08, error=0.0003183859004638003)\n",
            "3 (3,) InstructionProperties(duration=6e-08, error=0.00042235914178831863)\n",
            "4 (4,) InstructionProperties(duration=6e-08, error=0.011163151923589715)\n"
          ]
        }
      ],
      "source": [
        "for i, qq in enumerate(target[\"sx\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, qq, target[\"sx\"][qq])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a322b40-bbf0-4b54-a151-9ba52f7bffe1",
      "metadata": {},
      "source": [
        "Dasselbe gilt für die Operationen \"ecr\" und \"measure\".\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "f9cac843-4789-4ca3-84bd-0a4c165820a9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0, 14) InstructionProperties(duration=6.6e-07, error=0.01486295709788732)\n",
            "1 (1, 0) InstructionProperties(duration=6.6e-07, error=0.015201590794522601)\n",
            "2 (2, 1) InstructionProperties(duration=6.6e-07, error=0.00697838102630724)\n",
            "3 (2, 3) InstructionProperties(duration=6.6e-07, error=0.008075067943986797)\n",
            "4 (3, 4) InstructionProperties(duration=6.6e-07, error=0.0630164507876913)\n"
          ]
        }
      ],
      "source": [
        "for i, edge in enumerate(target[\"ecr\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, edge, target[\"ecr\"][edge])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "af36138a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0,) InstructionProperties(duration=1.6e-06, error=0.0078125)\n",
            "1 (1,) InstructionProperties(duration=1.6e-06, error=0.155029296875)\n",
            "2 (2,) InstructionProperties(duration=1.6e-06, error=0.057373046875)\n",
            "3 (3,) InstructionProperties(duration=1.6e-06, error=0.02880859375)\n",
            "4 (4,) InstructionProperties(duration=1.6e-06, error=0.01318359375)\n"
          ]
        }
      ],
      "source": [
        "for i, qq in enumerate(target[\"measure\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, qq, target[\"measure\"][qq])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5d0c106a-3641-42ed-9230-7dc6dbd47252",
      "metadata": {},
      "source": [
        "Wie Sie sehen können, sind die Fehler beim Auslesen tendenziell größer als die der 2-Qubit-Operation, die wiederum tendenziell größer sind als die der 1-Qubit-Operation.\n",
        "\n",
        "Nachdem wir die Datenstrukturen verstanden haben, können wir nun die Medianfehler für die „sx“- und die „ecr“-Gatter berechnen. Vergleichen Sie die Ergebnisse erneut mit denen, die für das Gerät auf [IBM Quantum Platform](/) angezeigt werden.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "b239d726",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median SX error: 2.277e-04'"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "sx_errors = [inst_prop.error for inst_prop in target[\"sx\"].values()]\n",
        "f\"Median SX error: {(statistics.median(sx_errors)):.3e}\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "8003f34b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median ECR error: 6.895e-03'"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ecr_errors = [inst_prop.error for inst_prop in target[\"ecr\"].values()]\n",
        "f\"Median ECR error: {(statistics.median(ecr_errors)):.3e}\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "695ee4bd",
      "metadata": {},
      "source": [
        "<span id=\"4-appendix\" />\n",
        "\n",
        "## 4. Anhang\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b538e8b5",
      "metadata": {},
      "source": [
        "Ein beliebtes Merkmal von Qiskit ist seine Visualisierungsfunktion. Es umfasst Schaltkreisvisualisierer, Zustands- und Verteilungsvisualisierer und Zielvisualisierer.   Die ersten beiden haben Sie bereits in den vorherigen Jupyter-Notebooks verwendet.   Lassen Sie uns einige Möglichkeiten des Zielvisualisierers nutzen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "97fead46",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/97fead46-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_gate_map\n",
        "\n",
        "plot_gate_map(backend, font_size=14)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "c9e05530",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/c9e05530-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_error_map\n",
        "\n",
        "plot_error_map(backend)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "22a48124-e6b4-4144-bee1-f01fa4c7ccbb",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'2.0.2'"
            ]
          },
          "execution_count": 24,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Check Qiskit version\n",
        "import qiskit\n",
        "\n",
        "qiskit.__version__"
      ]
    },
    {
      "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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}