{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "797fe94d-93a3-4a7b-8d60-0706d5ab21d5",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Transpiler-Einstellungen vergleichen\"\n",
        "description: \"Entdecken Sie die Transpilation-Pipeline während des gesamten Prozesses der Erstellung, Transpilation und Einreichung von Schaltkreisen.\"\n",
        "---\n",
        "\n",
        "<span id=\"compare-transpiler-settings\" />\n",
        "\n",
        "# Transpiler-Einstellungen vergleichen\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d403684a-9dc5-433b-a788-789881878d6c",
      "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=\"Paketversionen\">\n",
        "    Der Code auf dieser Seite wurde unter Berücksichtigung der folgenden Anforderungen entwickelt.\n",
        "    Wir empfehlen, diese Versionen oder neuere zu verwenden.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a6affcc2-72f4-4f06-8c4c-fc52715b0285",
      "metadata": {},
      "source": [
        "Unterschiedliche Transpiler-Einstellungen bieten verschiedene Arten der Schaltungsoptimierung, oft auf Kosten einer längeren klassischen Verarbeitungszeit. Dieser Leitfaden führt Sie durch den gesamten Prozess der Erstellung, Transpilation und Einreichung von Schaltkreisen, um die Leistungsfähigkeit verschiedener Einstellungen zu demonstrieren.\n",
        "\n",
        "Beachten Sie, dass dieselbe Einstellung die Ergebnisse eines Schaltkreises verbessern, während sie die eines anderen beeinträchtigen könnte. Überprüfen Sie unbedingt die resultierenden transpilierten Schaltkreise, bevor Sie sie auf der eigentlichen Hardware ausführen.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "39f9c961-c52d-46fc-a2aa-464462474b56",
      "metadata": {},
      "source": [
        "<span id=\"set-up-and-create-sample-circuit\" />\n",
        "\n",
        "## Einrichten und Erstellen einer Beispielschaltung\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "790b4934-ae24-4e69-be9f-d82ae639a5e6",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create circuit to test transpiler on\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import grover_operator, DiagonalGate\n",
        "\n",
        "# Use Statevector object to calculate the ideal output\n",
        "from qiskit.quantum_info import Statevector\n",
        "from qiskit.visualization import plot_histogram\n",
        "from qiskit.transpiler import PassManager\n",
        "\n",
        "from qiskit.circuit.library import XGate\n",
        "from qiskit.quantum_info import hellinger_fidelity"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe0a4958-b406-4fe4-9415-38a772ad152c",
      "metadata": {},
      "source": [
        "Erstellen Sie einen kleinen Schaltkreis, den der Transpiler optimieren soll. Dieses Beispiel erstellt einen Schaltkreis, der Grovers Algorithmus mit einem Orakel ausführt, das den Zustand `111`markiert. Als Nächstes simulieren Sie die ideale Verteilung (das Ergebnis, das Sie erwarten würden, wenn Sie dies unendlich oft auf einem perfekten Quantencomputer ausführen würden) zum späteren Vergleich.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "4ac958d4-b9b5-4939-a359-a9edca7ddb6a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/4ac958d4-b9b5-4939-a359-a9edca7ddb6a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "oracle = DiagonalGate([1] * 7 + [-1])\n",
        "qc = QuantumCircuit(3)\n",
        "qc.h([0, 1, 2])\n",
        "qc = qc.compose(grover_operator(oracle))\n",
        "\n",
        "qc.draw(output=\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "6313186e-bc40-432e-9ada-8594d6a26d55",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/6313186e-bc40-432e-9ada-8594d6a26d55-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ideal_distribution = Statevector.from_instruction(qc).probabilities_dict()\n",
        "\n",
        "plot_histogram(ideal_distribution)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "964ca1e0-d1c9-40ed-bcf1-babc50f847ed",
      "metadata": {},
      "source": [
        "<span id=\"transpile\" />\n",
        "\n",
        "## Transpile\n",
        "\n",
        "Als Nächstes transpilieren Sie die Schaltkreise für die QPU. Sie werden die Leistung des Transpilers mit `optimization_level` auf `0` (niedrigste Stufe) gegenüber `3` (höchste Stufe) vergleichen. Die niedrigste Optimierungsstufe führt das absolute Minimum aus, das erforderlich ist, um den Schaltkreis auf dem Gerät zum Laufen zu bringen. Sie ordnet die Qubits des Schaltkreises den Qubits des Geräts zu und fügt Swap-Gates hinzu, um alle Zwei-Qubit-Operationen zu ermöglichen. Die höchste Optimierungsstufe ist wesentlich intelligenter und nutzt zahlreiche Tricks, um die Gesamtanzahl der Gates zu reduzieren. Da Multi-Qubit-Gatter hohe Fehlerraten aufweisen und Qubits mit der Zeit dekoherieren, sollten kürzere Schaltkreise bessere Ergebnisse liefern.\n",
        "\n",
        "<Admonition type=\"important\">\n",
        "  In diesem Beispiel wird die Hardware „ IBM Quantum® “ verwendet, Sie können es jedoch auf jeder Qiskit-kompatiblen QPU ausprobieren.  Ihre Ergebnisse können davon abweichen.\n",
        "</Admonition>\n",
        "\n",
        "Die folgende Zelle transpiliert `qc` für beide Werte von `optimization_level`, gibt die Anzahl der Zwei-Qubit-Gatter aus und fügt die transpilierten Schaltungen zu einer Liste hinzu. Einige der Algorithmen des Transpilers sind randomisiert, daher wird ein Startwert für die Reproduzierbarkeit festgelegt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "61181ac0-3f89-417f-a31e-9430f63e670b",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Use IBM Quantum Compute Service to run jobs on hardware\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    SamplerV2 as Sampler,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "c3062a60-1cdc-46e7-8eb3-efc62a1396bd",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'ibm_fez'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Select the backend with the fewest number of jobs in the queue\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=127\n",
        ")\n",
        "backend.name"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2a3ebe8c-e47d-4440-b004-f47f6af826f0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Two-qubit gates (optimization_level=0):  21\n",
            "Two-qubit gates (optimization_level=3):  12\n"
          ]
        }
      ],
      "source": [
        "# Need to add measurements to the circuit\n",
        "qc.measure_all()\n",
        "\n",
        "# Find the correct two-qubit gate\n",
        "twoQ_gates = set([\"ecr\", \"cz\", \"cx\"])\n",
        "for gate in backend.basis_gates:\n",
        "    if gate in twoQ_gates:\n",
        "        twoQ_gate = gate\n",
        "\n",
        "circuits = []\n",
        "for optimization_level in [0, 3]:\n",
        "    pm = generate_preset_pass_manager(\n",
        "        optimization_level, backend=backend, seed_transpiler=0\n",
        "    )\n",
        "    t_qc = pm.run(qc)\n",
        "    print(\n",
        "        f\"Two-qubit gates (optimization_level={optimization_level}): \",\n",
        "        t_qc.count_ops()[twoQ_gate],\n",
        "    )\n",
        "    circuits.append(t_qc)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "99928d6b-a7e7-40c9-b59c-104fc430b57c",
      "metadata": {},
      "source": [
        "Da CNOTs in der Regel eine hohe Fehlerrate aufweisen, sollte die `optimization_level=3` mit transpilierte Schaltung eine deutlich bessere Leistung erzielen.\n",
        "\n",
        "Eine weitere Möglichkeit, die Leistung zu verbessern, ist [die](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) dynamische Entkopplung, bei der eine Abfolge von Schaltvorgängen auf inaktivierte Qubits angewendet wird. Dadurch werden einige unerwünschte Wechselwirkungen mit der Umgebung verhindert. Die folgende Zelle fügt dem mit transpilierten Schaltkreis eine `optimization_level=3` dynamische Entkopplung hinzu und fügt ihn der Liste hinzu.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "b20ebca3-4adb-4a95-9f6a-bb4cbd836daf",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.transpiler.passes.scheduling import (\n",
        "    ASAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "# Get gate durations so the transpiler knows how long each operation takes\n",
        "durations = backend.target.durations()\n",
        "\n",
        "# This is the sequence we'll apply to idling qubits\n",
        "dd_sequence = [XGate(), XGate()]\n",
        "\n",
        "# Run scheduling and dynamic decoupling passes on circuit\n",
        "pm = PassManager(\n",
        "    [\n",
        "        ASAPScheduleAnalysis(durations),\n",
        "        PadDynamicalDecoupling(durations, dd_sequence),\n",
        "    ]\n",
        ")\n",
        "circ_dd = pm.run(circuits[1])\n",
        "\n",
        "# Add this new circuit to our list\n",
        "circuits.append(circ_dd)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "c1c91fbd-acfe-413e-a6c9-ad97f4dd5543",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/c1c91fbd-acfe-413e-a6c9-ad97f4dd5543-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "circ_dd.draw(output=\"mpl\", style=\"iqp\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5bcc75c7-8af0-4862-8e3c-ec4d06aed1f1",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuit\" />\n",
        "\n",
        "## Führen Sie den Parcours durch\n",
        "\n",
        "Nun verfügen Sie über eine Liste von Schaltkreisen, die mit unterschiedlichen Einstellungen transpiliert wurden. Führen Sie anschließend diese Schaltkreise mit der Sampler-Primitive aus und speichern Sie die Ergebnisse in `result`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "c1b36384-fd9b-4e24-a399-32d35fc6fa5b",
      "metadata": {},
      "outputs": [],
      "source": [
        "sampler = Sampler(backend)\n",
        "job = sampler.run(\n",
        "    [(circuit) for circuit in circuits],  # sample all three circuits\n",
        "    shots=8000,\n",
        ")\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c85b4da4-592f-45a6-87a2-a8f2d3415576",
      "metadata": {},
      "source": [
        "<span id=\"view-results\" />\n",
        "\n",
        "## Ansichtsergebnisse\n",
        "\n",
        "Zeichnen Sie schließlich die Ergebnisse der Gerätemessungen gegen die ideale Verteilung auf. Man sieht, dass die Ergebnisse bei aufgrund der geringeren Gate-Anzahl `optimization_level=3` näher an der idealen Verteilung liegen, und `optimization_level=3 + dd` liegt aufgrund der dynamischen Entkopplung sogar noch näher daran.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "9e86132d-a8b2-40db-af42-53042dfa108b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/9e86132d-a8b2-40db-af42-53042dfa108b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "binary_prob = [\n",
        "    {\n",
        "        k: v / res.data.meas.num_shots\n",
        "        for k, v in res.data.meas.get_counts().items()\n",
        "    }\n",
        "    for res in result\n",
        "]\n",
        "plot_histogram(\n",
        "    binary_prob + [ideal_distribution],\n",
        "    bar_labels=False,\n",
        "    legend=[\n",
        "        \"optimization_level=0\",\n",
        "        \"optimization_level=3\",\n",
        "        \"optimization_level=3 + dd\",\n",
        "        \"ideal distribution\",\n",
        "    ],\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47a9eec8-7b31-4b2d-a291-559ddfd7a36b",
      "metadata": {},
      "source": [
        "Sie können dies überprüfen, indem Sie die [Hellinger-Fidelity](/docs/api/qiskit/quantum_info) zwischen jedem Ergebnissatz und der idealen Verteilung berechnen (je höher desto besser, wobei 1 die perfekte Fidelity darstellt).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "d2b5e797-176b-48b9-ac2b-ba73abe9300f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.717\n",
            "0.982\n",
            "0.981\n"
          ]
        }
      ],
      "source": [
        "for prob in binary_prob:\n",
        "    print(f\"{hellinger_fidelity(prob, ideal_distribution):.3f}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1b5b7bb9-eedb-45eb-a4cf-9b7708cbbb3e",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Entdecken Sie einige Ressourcen zur fortgeschrittenen Transpilierung, wie zum Beispiel:\n",
        "\n",
        "    * [Einen benutzerdefinierten Transpiler-Pass schreiben](/docs/guides/custom-transpiler-pass)\n",
        "    * [Erstellen und Transpilieren für benutzerdefinierte Backends](/docs/guides/custom-backend)\n",
        "    * [Transpiler-Plugins installieren und verwenden](/docs/guides/transpiler-plugins)\n",
        "\n",
        "  * Sehen Sie sich die verfügbaren [Tutorials](/docs/tutorials) an.\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
}