{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d53161ce",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Transpiler-Optimierungsstufe festlegen\"\n",
        "description: \"So legen Sie den Optimierungsgrad für die Transpilation von Quantenschaltungen in Qiskit fest.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Cartan's */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6f5a4641-5b7f-4841-8bec-60fa44429030",
      "metadata": {},
      "source": [
        "<span id=\"set-transpiler-optimization-level\" />\n",
        "\n",
        "# Transpiler-Optimierungsstufe festlegen\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8a1db79c-9bee-4737-b8b5-13155062ca04",
      "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 die Verwendung dieser oder neuerer Versionen.\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": "bd9eb973-430c-4450-8de2-c061aa0ff742",
      "metadata": {},
      "source": [
        "Echte Quantenbauelemente sind mit Rauschen und Gatterfehlern behaftet, so dass eine Optimierung der Schaltungen zur Verringerung ihrer Tiefe und Gatteranzahl die Ergebnisse der Ausführung dieser Schaltungen erheblich verbessern kann.\n",
        "Die Funktion [`generate_preset_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager#qiskit.transpiler.generate_preset_pass_manager) funktion hat ein erforderliches Positionsargument, `optimization_level`, das steuert, wie viel Aufwand der Transpiler für die Optimierung von Schaltungen betreibt. Dieses Argument kann eine ganze Zahl mit einem der Werte 0, 1, 2 oder 3 sein.\n",
        "Höhere Optimierungsstufen erzeugen mehr optimierte Schaltungen auf Kosten einer längeren Kompilierzeit.\n",
        "In der folgenden Tabelle wird erläutert, welche Optimierungen mit den einzelnen Einstellungen vorgenommen werden.\n",
        "\n",
        "<Table>\n",
        "  <thead>\n",
        "    <Tr>\n",
        "      <Th>Optimier.- stufe</Th>\n",
        "      <Th>Beschreibung</Th>\n",
        "    </Tr>\n",
        "  </thead>\n",
        "\n",
        "  <tbody>\n",
        "    <Tr>\n",
        "      <Td>0</Td>\n",
        "\n",
        "      <Td>\n",
        "        Keine Optimierung: typischerweise für die Charakterisierung von Hardware verwendet\n",
        "\n",
        "        * Einfache Übersetzung\n",
        "        * Layout/Routing: `TrivialLayout` es wählt die gleichen physischen Qubit-Nummern wie die virtuellen und fügt SWAPs ein, damit es funktioniert (unter `SabreSwap`)\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>1</Td>\n",
        "\n",
        "      <Td>\n",
        "        Optimierung der Beleuchtung:\n",
        "\n",
        "        * Layout/Routing: Das Layout wird zunächst mit `TrivialLayout` ausprobiert. Wenn zusätzliche SWAPs erforderlich sind, wird mit `SabreSwap` ein Layout mit einer minimalen Anzahl von SWAPs gefunden. Anschließend wird mit `VF2LayoutPostLayout` versucht, die besten Qubits im Graphen auszuwählen.\n",
        "        * `InverseCancellation`\n",
        "        * 1Q gate-Optimierung\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>2</Td>\n",
        "\n",
        "      <Td>\n",
        "        Mittlere Optimierung:\n",
        "\n",
        "        * Layout/Routing: Optimierungsstufe 1 (ohne Trivialität) + Heuristik optimiert mit größerer suchtiefe und Versuchen der Optimierungsfunktion.  Da `TrivialLayout` nicht verwendet wird, wird nicht versucht, die gleichen physischen und virtuellen Qubit-Nummern zu verwenden.\n",
        "        * `CommutativeCancellation`\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>3</Td>\n",
        "\n",
        "      <Td>\n",
        "        Hohe Optimierung:\n",
        "\n",
        "        * Optimierungsstufe 2 + Heuristik optimiert auf Layout/Routing weiter mit größerem Aufwand/Versuchen\n",
        "        * Resynthese von Zwei-Qubit-Blöcken unter Verwendung [der Cartan'schen KAK-Zerlegung](https://arxiv.org/abs/quant-ph/0507171).\n",
        "        * Pässe, die die Einheitlichkeit durchbrechen:\n",
        "          * `OptimizeSwapBeforeMeasure`: Verschiebt die Messungen, um SWAPs zu vermeiden\n",
        "          * `RemoveDiagonalGatesBeforeMeasure`: Entfernt Gates vor den Messungen, die die Messungen nicht beeinflussen würden\n",
        "      </Td>\n",
        "    </Tr>\n",
        "  </tbody>\n",
        "</Table>\n",
        "\n",
        "<span id=\"optimization-level-in-action\" />\n",
        "\n",
        "## Optimierungsstufe in Aktion\n",
        "\n",
        "Da Zwei-Qubit-Gatter in der Regel die größte Fehlerquelle darstellen, können wir die \"Hardware-Effizienz\" der Transpilierung annähernd quantifizieren, indem wir die Anzahl der Zwei-Qubit-Gatter in der resultierenden Schaltung zählen.\n",
        "Hier werden wir die verschiedenen Optimierungsstufen an einer Eingangsschaltung ausprobieren, die aus einer zufälligen Unitary und einem SWAP-Gatter besteht.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "81173ebc-8359-48a6-b585-0477907b3b93",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/81173ebc-8359-48a6-b585-0477907b3b93-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit.library import UnitaryGate\n",
        "from qiskit.quantum_info import Operator, random_unitary\n",
        "\n",
        "UU = random_unitary(4, seed=12345)\n",
        "rand_U = UnitaryGate(UU)\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "qc.append(rand_U, range(2))\n",
        "qc.swap(0, 1)\n",
        "qc.draw(\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "34509d07-7804-46cb-b508-130436d9b01d",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  In diesen Beispielen wird das `FakeSherbrooke``qiskit_ibm_runtime` Mock-Backend von verwendet, Sie können es jedoch mit jedem Qiskit-kompatiblen echten oder simulierten Backend ausprobieren.  Ihre Ergebnisse können davon abweichen.\n",
        "</Admonition>\n",
        "\n",
        "Zunächst führen wir die Transpilation mit der Optimierungsstufe 0 durch.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "40cdd173-b437-48b1-8928-741e8411342e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/40cdd173-b437-48b1-8928-741e8411342e-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=0, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t1_exact = pass_manager.run(qc)\n",
        "qc_t1_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5169cb2-cd2a-40c0-93e5-c526580f84aa",
      "metadata": {},
      "source": [
        "Die transpilierte Schaltung hat sechs Zwei-Qubit-ECR-Gatter.\n",
        "\n",
        "Wiederholen Sie den Vorgang für Optimierungsstufe 1:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2dab5def-a017-42e9-92d6-e043ac4065b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/2dab5def-a017-42e9-92d6-e043ac4065b2-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t1_exact = pass_manager.run(qc)\n",
        "qc_t1_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "69d5d04b-746f-41c4-92e8-62a7eaffb5b2",
      "metadata": {},
      "source": [
        "Die transpilierte Schaltung hat immer noch sechs ECR-Gatter, aber die Anzahl der Ein-Qubit-Gatter hat sich verringert.\n",
        "\n",
        "Wiederholen Sie den Vorgang für Optimierungsstufe 2:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "77d76048-b1e8-4225-b35f-80dc9d458e8d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/77d76048-b1e8-4225-b35f-80dc9d458e8d-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=2, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t2_exact = pass_manager.run(qc)\n",
        "qc_t2_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4818fb06-88bd-43cb-b23c-eba5a3537e67",
      "metadata": {},
      "source": [
        "Dies führt zu den gleichen Ergebnissen wie Optimierungsstufe 1. Beachten Sie, dass eine Erhöhung des Optimierungsgrades nicht immer einen Unterschied macht.\n",
        "\n",
        "Wiederholen Sie den Vorgang mit der Optimierungsstufe 3:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "4109d0e2-df37-4850-8409-6b860c48595c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/4109d0e2-df37-4850-8409-6b860c48595c-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t3_exact = pass_manager.run(qc)\n",
        "qc_t3_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c9cf6dcf-733f-494f-a571-43d47d3908ce",
      "metadata": {},
      "source": [
        "Jetzt gibt es nur noch drei ECR-Tore. Wir erhalten dieses Ergebnis, weil Qiskit auf Optimierungsebene 3 versucht, Zwei-Qubit-Blöcke von Gattern zu re-synthetisieren, und jedes Zwei-Qubit-Gatter kann mit höchstens drei ECR-Gattern implementiert werden. Wir können sogar noch weniger ECR-Gatter erhalten, wenn wir `approximation_degree` auf einen Wert kleiner als 1 setzen, was dem Transpiler erlaubt, Annäherungen vorzunehmen, die einen gewissen Fehler in die Gatterzerlegung einbringen können (siehe [Häufig verwendete Parameter für die Transpilation](common-parameters#approximation-degree) ):\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "bf239116-b8bb-42aa-a27a-89206d9e108a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/bf239116-b8bb-42aa-a27a-89206d9e108a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=3,\n",
        "    approximation_degree=0.99,\n",
        "    backend=backend,\n",
        "    seed_transpiler=12345,\n",
        ")\n",
        "qc_t3_approx = pass_manager.run(qc)\n",
        "qc_t3_approx.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "247f60a9-b0ad-4e83-85ea-008dc808267f",
      "metadata": {},
      "source": [
        "Diese Schaltung hat nur zwei ECR-Gatter, aber es ist eine ungefähre Schaltung. Um zu verstehen, inwiefern sich die Wirkung von der exakten Schaltung unterscheidet, können wir die Treue zwischen dem unitären Operator, den diese Schaltung implementiert, und dem exakten unitären berechnen. Bevor wir die Berechnung durchführen, reduzieren wir zunächst die transpilierte Schaltung, die 127 Qubits enthält, auf eine Schaltung, die nur die aktiven Qubits enthält, von denen es zwei gibt.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "56988ecd-8a78-42ca-90eb-fc956674c64d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Synthesis fidelity\n",
            "Exact: 1.000+0.000j\n",
            "Approximate: 0.992+0.000j\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "\n",
        "def trace_to_fidelity_2q(trace: float) -> float:\n",
        "    return (4.0 + trace * trace.conjugate()) / 20.0\n",
        "\n",
        "\n",
        "# Reduce circuits down to 2 qubits so they are easy to simulate\n",
        "qc_t3_exact_small = QuantumCircuit.from_instructions(qc_t3_exact)\n",
        "qc_t3_approx_small = QuantumCircuit.from_instructions(qc_t3_approx)\n",
        "\n",
        "# Compute the fidelity\n",
        "exact_fid = trace_to_fidelity_2q(\n",
        "    np.trace(np.dot(Operator(qc_t3_exact_small).adjoint().data, UU))\n",
        ")\n",
        "approx_fid = trace_to_fidelity_2q(\n",
        "    np.trace(np.dot(Operator(qc_t3_approx_small).adjoint().data, UU))\n",
        ")\n",
        "print(\n",
        "    f\"Synthesis fidelity\\nExact: {exact_fid:.3f}\\nApproximate: {approx_fid:.3f}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "382f6ffc-1d17-4c4b-8ea1-2f828c705793",
      "metadata": {
        "jp-MarkdownHeadingCollapsed": true
      },
      "source": [
        "Die Anpassung des Optimierungsgrades kann auch andere Aspekte der Schaltung beeinflussen, nicht nur die Anzahl der ECR-Gatter. Beispiele dafür, wie sich die Änderung der Optimierungsstufe auf das Layout auswirkt, finden Sie unter „[Darstellung von Quantencomputern](/docs/guides/represent-quantum-computers) “.\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Nächste Schritte\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Empfehlungen\">\n",
        "  * Um mehr über die Funktion `generate_preset_passmanager` zu erfahren, beginnen Sie mit dem Thema [Standardeinstellungen und Konfigurationsoptionen für die Transpilation](defaults-and-configuration-options).\n",
        "  * Erfahren Sie mehr über die Transpilierung mit dem Thema [Transpiler-Stufen](transpiler-stages).\n",
        "  * Probieren Sie die Anleitung [zum Vergleichen der Transpiler-Einstellungen](/docs/guides/circuit-transpilation-settings) aus.\n",
        "  * Versuchen Sie das Tutorial [Build repetition codes](/docs/tutorials/repetition-codes).\n",
        "  * Siehe die [Transpile-API-Dokumentation](/docs/api/qiskit/transpiler).\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": 5
}