{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "ba5ec3d7-2a51-4ffa-b270-cbe18e98a454",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"KI-gestützte Transpiler-Pass\"\n",
        "description: \"Was sind die AI-Transpiler-Durchläufe und wie werden sie verwendet?\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Eprint */}\n",
        "\n",
        "<span id=\"ai-powered-transpiler-passes\" />\n",
        "\n",
        "# KI-gestützte Transpiler-Pass\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3c78c2c0-7afc-4cf3-988d-9e044b5d0fca",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7244dd08-62a0-4c10-8c0d-0bd01eebe68f",
      "metadata": {},
      "source": [
        "Die KI-gestützten Transpiler-Passes sind Passes, die bei bestimmten Transpiling-Aufgaben als direkter Ersatz für „herkömmliche“ Qiskit-Passes dienen. Sie liefern oft bessere Ergebnisse als bestehende heuristische Algorithmen (z. B. geringere Suchbreite und CNOT-Zahl), sind aber auch wesentlich schneller als Optimierungsalgorithmen wie Solver für die Boolesche Erfüllbarkeit. Der KI-Transpiler führt die Durchläufe in Ihrer lokalen Umgebung aus.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Die KI-gesteuerten Transpilerpässe befinden sich im Beta-Status und können sich noch ändern.\n",
        "  Wenn Sie Feedback haben oder das Entwicklerteam kontaktieren möchten, verwenden Sie bitte diesen [Qiskit Slack Workspace-Kanal](https://qiskit.slack.com/archives/C06KF8YHUAU).\n",
        "</Admonition>\n",
        "\n",
        "Die folgenden Ausweise sind derzeit erhältlich:\n",
        "\n",
        "**Routing-Pässe**\n",
        "\n",
        "* `AIRouting`: Auswahl des Layouts und Entflechtung der Schaltkreise\n",
        "\n",
        "**Die Schaltungssynthese läuft**\n",
        "\n",
        "* `AICliffordSynthesis`: Synthese von Clifford-Schaltungen\n",
        "* `AILinearFunctionSynthesis`: Synthese von Schaltkreisen mit linearer Funktion\n",
        "* `AIPermutationSynthesis`: Synthese von Permutationsschaltungen\n",
        "\n",
        "Um die AI-Transpiler-Pässe zu verwenden, installieren Sie zunächst das `qiskit-ibm-transpiler` Paket. Weitere Informationen zu den verschiedenen verfügbaren Optionen finden Sie in der [API-Dokumentation](/docs/api/qiskit-ibm-transpiler) zu qiskit-ibm-transpiler.\n",
        "\n",
        "```sh\n",
        "pip install qiskit-ibm-transpiler\n",
        "```\n",
        "\n",
        "<span id=\"ai-routing-pass\" />\n",
        "\n",
        "## KI-Routing-Pass\n",
        "\n",
        "Der Pass `AIRouting` dient sowohl als Layout- als auch als Routing-Stufe. Sie kann innerhalb einer `PassManager` wie folgt verwendet werden:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c104fcd0-4a85-4927-b026-93f4a6fdab51",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "from qiskit_ibm_transpiler.ai.routing import AIRouting\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "import logging\n",
        "\n",
        "backend = QiskitRuntimeService().backend(\"ibm_fez\")\n",
        "ai_passmanager = PassManager(\n",
        "    [\n",
        "        AIRouting(\n",
        "            backend=backend,\n",
        "            optimization_level=2,\n",
        "            layout_mode=\"optimize\",\n",
        "        )\n",
        "    ]\n",
        ")\n",
        "\n",
        "\n",
        "circuit = efficient_su2(101, entanglement=\"circular\", reps=1)\n",
        "logging.getLogger(\n",
        "    \"qiskit_ibm_transpiler.wrappers.ai_local_synthesis\"\n",
        ").setLevel(logging.WARNING)\n",
        "transpiled_circuit = ai_passmanager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "28c2cfa3-e4d8-48d5-9d6c-b02fcf548ef1",
      "metadata": {},
      "source": [
        "Hier bestimmt `backend` , für welche Kopplungskarte geroutet werden soll, `optimization_level` (1, 2 oder 3) bestimmt den Rechenaufwand, der für den Prozess aufgewendet werden soll (ein höherer Wert führt in der Regel zu besseren Ergebnissen, dauert aber länger), und `layout_mode` gibt an, wie die Layout-Auswahl behandelt werden soll.\n",
        "Die Website `layout_mode` bietet die folgenden Optionen:\n",
        "\n",
        "* `keep`: Dies respektiert das Layout, das durch die vorherigen Transpiler-Durchläufe festgelegt wurde (oder verwendet das triviale Layout, wenn es nicht festgelegt wurde). Sie wird in der Regel nur verwendet, wenn die Schaltung auf bestimmten Qubits des Geräts ausgeführt werden muss. Sie führt oft zu schlechteren Ergebnissen, weil sie weniger Spielraum für Optimierungen hat.\n",
        "* `improve`: Dabei wird das durch die vorangegangenen Transpilerdurchläufe festgelegte Layout als Ausgangspunkt verwendet. Sie ist nützlich, wenn Sie eine gute Vorstellung vom Layout haben, z. B. bei Schaltungen, die so aufgebaut sind, dass sie ungefähr der Kopplungskarte des Geräts entsprechen. Es ist auch nützlich, wenn Sie andere spezifische Layout-Durchgänge in Kombination mit dem `AIRouting` -Durchgang ausprobieren möchten.\n",
        "* `optimize`: Dies ist der Standardmodus. Sie eignet sich am besten für allgemeine Schaltungen, bei denen man das Layout nicht gut einschätzen kann. In diesem Modus werden vorherige Layout-Auswahlen ignoriert.\n",
        "\n",
        "<span id=\"ai-circuit-synthesis-passes\" />\n",
        "\n",
        "## AI-Schaltungssynthese passiert\n",
        "\n",
        "Die KI-Schaltungssynthese ermöglicht es Ihnen, Teile verschiedener Schaltungstypen ([Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford), [Lineare Funktion](/docs/api/qiskit/qiskit.circuit.library.LinearFunction), [Permutation](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation), Pauli-Netzwerk) zu optimieren, indem Sie sie neu synthetisieren. Ein typischer Weg, den Synthesedurchlauf zu verwenden, ist der folgende:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8655f68d-f88a-4a15-ad89-f39f2ba3fe71",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "\n",
        "from qiskit_ibm_transpiler.ai.routing import AIRouting\n",
        "from qiskit_ibm_transpiler.ai.synthesis import AILinearFunctionSynthesis\n",
        "from qiskit_ibm_transpiler.ai.collection import CollectLinearFunctions\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "ibm_kingston = QiskitRuntimeService().backend(\"ibm_kingston\")\n",
        "ai_passmanager = PassManager(\n",
        "    [\n",
        "        AIRouting(\n",
        "            backend=ibm_kingston,\n",
        "            optimization_level=3,\n",
        "            layout_mode=\"optimize\",\n",
        "            local_mode=True,\n",
        "        ),  # Route circuit\n",
        "        CollectLinearFunctions(),  # Collect Linear Function blocks\n",
        "        AILinearFunctionSynthesis(\n",
        "            backend=ibm_kingston, local_mode=True\n",
        "        ),  # Re-synthesize Linear Function blocks\n",
        "    ]\n",
        ")\n",
        "\n",
        "circuit = efficient_su2(10, entanglement=\"full\", reps=1)\n",
        "\n",
        "transpiled_circuit = ai_passmanager.run(circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "779f180e-c29f-4a96-b4b0-e3d2a4c8a1b9",
      "metadata": {},
      "source": [
        "Die Synthese respektiert die Kopplungskarte des Geräts: Sie kann sicher nach anderen Routing-Durchläufen ausgeführt werden, ohne die Schaltung zu stören, so dass die Gesamtschaltung immer noch den Beschränkungen des Geräts folgt. Standardmäßig wird die Synthese die ursprüngliche Teilschaltung nur dann ersetzen, wenn die synthetisierte Teilschaltung die ursprüngliche verbessert (derzeit wird nur die CNOT-Anzahl überprüft), aber dies kann erzwungen werden, um die Schaltung immer zu ersetzen, indem `replace_only_if_better=False` gesetzt wird.\n",
        "\n",
        "Die folgenden Synthesepässe sind unter `qiskit_ibm_transpiler.ai.synthesis` erhältlich:\n",
        "\n",
        "* *AICliffordSynthese* : Synthese für [Clifford-Schaltungen](/docs/api/qiskit/qiskit.quantum_info.Clifford) (Blöcke aus `H`, `S` und `CX` Gattern). Derzeit bis zu neun Qubit-Blöcke.\n",
        "* *AILinearFunctionSynthesis* : Synthese für [lineare Funktionsschaltungen](/docs/api/qiskit/qiskit.circuit.library.LinearFunction) (Blöcke aus `CX` und `SWAP` Gattern). Derzeit bis zu neun Qubit-Blöcke.\n",
        "* *AIPermutationSynthese* : Synthese für [Permutationsschaltungen](/docs/api/qiskit/qiskit.circuit.library.Permutation#permutation) (Blöcke von `SWAP` Gattern). Derzeit verfügbar für 65-, 33- und 27-Qubit-Blöcke.\n",
        "* *AIPauliNetworkSynthesis* : Synthese für Pauli-Netzwerk-Schaltungen (Blöcke aus `H`, `S`, `SX`, `CX`, `RX`, `RY` und `RZ` Gattern). Derzeit bis zu sechs Qubit-Blöcke.\n",
        "\n",
        "Wir gehen davon aus, dass wir die Größe der unterstützten Blöcke schrittweise erhöhen werden.\n",
        "\n",
        "Alle Durchläufe verwenden einen Thread-Pool, um mehrere Anfragen parallel zu senden. Standardmäßig entspricht die Anzahl der maximalen Threads der Anzahl der Kerne plus vier (Standardwerte für das Objekt `ThreadPoolExecutor` Python ). Sie können jedoch einen eigenen Wert mit dem Argument `max_threads` bei der Instanziierung des Passes festlegen. Die folgende Zeile instanziiert zum Beispiel den Pass `AILinearFunctionSynthesis` , der maximal 20 Threads verwenden kann.\n",
        "\n",
        "```python\n",
        "AILinearFunctionSynthesis(backend=ibm_torino, max_threads=20)  # Re-synthesize Linear Function blocks using 20 threads max\n",
        "```\n",
        "\n",
        "Sie können auch die Umgebungsvariable `AI_TRANSPILER_MAX_THREADS` auf die gewünschte Anzahl der maximalen Threads setzen, und alle danach instanziierten Synthesedurchläufe werden diesen Wert verwenden.\n",
        "\n",
        "Damit die KI-Synthesepässe eine Teilschaltung synthetisieren können, muss sie auf einem zusammenhängenden Teilgraphen der Kopplungskarte liegen (eine Möglichkeit, dies zu erreichen, ist ein Routing-Pass vor dem Sammeln der Blöcke, aber dies ist nicht die einzige Möglichkeit). Die Synthesedurchläufe prüfen automatisch, ob der spezifische Teilgraph unterstützt wird. Ist dies nicht der Fall, wird eine Warnung ausgegeben und der ursprüngliche Teilschaltkreis bleibt unverändert.\n",
        "\n",
        "Die folgenden benutzerdefinierten Sammelpässe für Cliffords, lineare Funktionen und Permutationen, die von `qiskit_ibm_transpiler.ai.collection` importiert werden können, ergänzen die Synthesepässe:\n",
        "\n",
        "* *SammelnCliffords* : Sammelt Clifford-Blöcke als `Instruction` Objekte und speichert die ursprüngliche Teilschaltung, um sie nach der Synthese mit ihr zu vergleichen.\n",
        "* *SammleLineareFunktionen* : Sammelt Blöcke von `SWAP` und `CX` als `LinearFunction` Objekte und speichert die ursprüngliche Teilschaltung, um sie nach der Synthese mit ihr zu vergleichen.\n",
        "* *CollectPermutations* : Sammelt Blöcke von `SWAP` Schaltungen als `Permutations`.\n",
        "* *SammelnPauliNetzwerke* : Sammelt Pauli-Netz-Blöcke und speichert die ursprüngliche Teilschaltung, um sie nach der Synthese mit ihr zu vergleichen.\n",
        "\n",
        "Diese benutzerdefinierten Sammelpässe begrenzen die Größe der gesammelten Teilschaltungen, so dass sie von den KI-gesteuerten Synthesepässen unterstützt werden. Es wird daher empfohlen, sie nach den Routing-Durchläufen und vor den Synthese-Durchläufen zu verwenden, um eine bessere Gesamtoptimierung zu erreichen.\n",
        "\n",
        "<span id=\"hybrid-heuristic-ai-circuit-transpilation\" />\n",
        "\n",
        "## Hybride heuristische KI-Schaltungstranspilierung\n",
        "\n",
        "Unter `qiskit-ibm-transpiler` können Sie einen hybriden Passmanager konfigurieren, der das Beste aus der Heuristik von Qiskit und den KI-gesteuerten Transpiler-Pässen kombiniert. Diese Funktion verhält sich ähnlich wie die Methode von Qiskit `generate_pass_manager` . Ein typischer Weg, `generate_ai_pass_manager` zu verwenden, ist der folgende:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2f5bbf22-22cd-46fa-885c-851f769552f0",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_transpiler import generate_ai_pass_manager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "\n",
        "backend = QiskitRuntimeService().backend(\"ibm_kingston\")\n",
        "kingston_coupling_map = backend.coupling_map\n",
        "\n",
        "\n",
        "su2_circuit = efficient_su2(101, entanglement=\"circular\", reps=1)\n",
        "\n",
        "ai_transpiler_pass_manager = generate_ai_pass_manager(\n",
        "    coupling_map=kingston_coupling_map,\n",
        "    ai_optimization_level=3,\n",
        "    optimization_level=3,\n",
        "    ai_layout_mode=\"optimize\",\n",
        ")\n",
        "\n",
        "ai_su2_transpiled_circuit = ai_transpiler_pass_manager.run(su2_circuit)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7f34294b-c520-439a-b1d7-2962af07aced",
      "metadata": {},
      "source": [
        "Die folgenden Optionen werden in diesem Beispiel verwendet:\n",
        "\n",
        "* `coupling_map` - Gibt an, welche Kopplungskarte für die Transpilierung verwendet werden soll.\n",
        "* `ai_optimization_level` - Gibt die Optimierungsstufe (1-3) an, die für die AI-Komponenten des PassManager verwendet werden soll.\n",
        "* `optimization_level` - Gibt an, wie stark die Schaltung für die heuristischen Komponenten der PassManager optimiert werden soll.\n",
        "* `ai_layout_mode` - Gibt an, wie der AI-Routing-Teil von PassManager das Layout behandelt. Die Konfigurationsmöglichkeiten für diesen Parameter `ai_layout_mode` finden Sie im Abschnitt [AI Routing Pass](#ai-routing-pass).\n",
        "\n",
        "<span id=\"citation\" />\n",
        "\n",
        "## Quelle\n",
        "\n",
        "Quellenangabe\n",
        "Wenn Sie in Ihrer Forschungsarbeit eine der KI-gestützten Funktionen aus dem `qiskit-ibm-transpiler` Paket verwenden, geben Sie bitte die folgende empfohlene Quellenangabe an:\n",
        "\n",
        "```\n",
        "@misc{2405.13196,\n",
        "Author = {David Kremer and Victor Villar and Hanhee Paik and Ivan Duran and Ismael Faro and Juan Cruz-Benito},\n",
        "Title = {Practical and efficient quantum circuit synthesis and transpiling with Reinforcement Learning},\n",
        "Year = {2024},\n",
        "Eprint = {arXiv:2405.13196},\n",
        "}\n",
        "```\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
}