Einführung in den Qiskit AI-gestützten Transpiler-Service
Geschätzte QPU-Nutzung: Keine (HINWEIS: Dieses Tutorial führt keine Jobs aus, da es sich auf Transpilation fokussiert)
Hintergrund
Der Qiskit AI-gestützte Transpiler-Service (QTS) führt maschinelles Lernen-basierte Optimierungen sowohl in Routing- als auch in Synthesis-Passes ein. Diese AI-Modi wurden entwickelt, um die Einschränkungen der traditionellen Transpilation anzugehen, insbesondere für große Schaltungen und komplexe Hardware-Topologien.
Ab Juli 2025 wurde der Transpiler-Service zur neuen IBM Quantum® Platform migriert und ist nicht mehr verfügbar. Für die neuesten Updates zum Status des Transpiler-Service verweisen wir auf die Transpiler-Service-Dokumentation. Du kannst den AI-Transpiler weiterhin lokal verwenden, ähnlich wie bei der Standard-Qiskit-Transpilation. Ersetze einfach generate_preset_pass_manager() durch generate_ai_pass_manager(). Diese Funktion konstruiert einen Pass-Manager, der die AI-gestützten Routing- und Synthesis-Passes direkt in deinen lokalen Transpilations-Workflow integriert.
Hauptmerkmale der AI-Passes
-
Routing-Passes: AI-gestütztes Routing kann Qubit-Pfade dynamisch basierend auf der spezifischen Schaltung und dem Backend anpassen und den Bedarf an übermäßigen SWAP-Gates reduzieren.
AIRouting: Layout-Auswahl und Schaltungs-Routing
-
Synthesis-Passes: AI-Techniken optimieren die Zerlegung von Multi-Qubit-Gates und minimieren die Anzahl der Zwei-Qubit-Gates, die typischerweise anfälliger für Fehler sind.
AICliffordSynthesis: Clifford-Gate-SyntheseAILinearFunctionSynthesis: Synthese von Linear-FunktionsschaltungenAIPermutationSynthesis: Synthese von PermutationsschaltungenAIPauliNetworkSynthesis: Synthese von Pauli-Netzwerkschaltungen (nur im Qiskit Transpiler Service verfügbar, nicht in der lokalen Umgebung)
-
Vergleich mit traditioneller Transpilation: Der Standard-Qiskit-Transpiler ist ein robustes Werkzeug, das ein breites Spektrum von Quantenschaltungen effektiv handhaben kann. Wenn Schaltungen jedoch größer werden oder Hardware-Konfigurationen komplexer werden, können AI-Passes zusätzliche Optimierungsgewinne liefern. Durch die Verwendung gelernter Modelle für Routing und Synthese verfeinert QTS Schaltungslayouts weiter und reduziert den Overhead für herausfordernde oder groß angelegte Quantenaufgaben.
Dieses Tutorial evaluiert die AI-Modi unter Verwendung sowohl von Routing- als auch von Synthesis-Passes und vergleicht die Ergebnisse mit traditioneller Transpilation, um hervorzuheben, wo AI Leistungsvorteile bietet.
Weitere Details zu den verfügbaren AI-Passes findest du in der AI-Passes-Dokumentation.
Warum AI für Quantenschaltungs-Transpilation verwenden?
Da Quantenschaltungen in Größe und Komplexität zunehmen, haben traditionelle Transpilationsmethoden Schwierigkeiten, Layouts zu optimieren und Gate-Anzahlen effizient zu reduzieren. Größere Schaltungen, insbesondere solche mit Hunderten von Qubits, stellen erhebliche Herausforderungen an das Routing und die Synthese dar, aufgrund von Gerätebeschränkungen, begrenzter Konnektivität und Qubit-Fehlerraten.
Hier bietet die AI-gestützte Transpilation eine potenzielle Lösung. Durch die Nutzung von maschinellen Lerntechniken kann der AI-gestützte Transpiler in Qiskit intelligentere Entscheidungen über Qubit-Routing und Gate-Synthese treffen, was zu besserer Optimierung groß angelegter Quantenschaltungen führt.
Kurze Benchmarking-Ergebnisse

In Benchmarking-Tests hat der AI-Transpiler konsistent flachere Schaltungen höherer Qualität im Vergleich zum Standard-Qiskit-Transpiler produziert. Für diese Tests haben wir die Standard-Pass-Manager-Strategie von Qiskit verwendet, konfiguriert mit [generate_preset_passmanager]. Während diese Standardstrategie oft effektiv ist, kann sie bei größeren oder komplexeren Schaltungen Schwierigkeiten haben. Im Gegensatz dazu erreichten AI-gestützte Passes eine durchschnittliche Reduzierung der Zwei-Qubit-Gate-Anzahl um 24% und eine Reduzierung der Schaltungstiefe um 36% für große Schaltungen (100+ Qubits) bei der Transpilation auf die Heavy-Hex-Topologie von IBM Quantum Hardware. Weitere Informationen zu diesen Benchmarks findest du in diesem Blog.
Dieses Tutorial untersucht die wichtigsten Vorteile der AI-Passes und wie sie sich mit traditionellen Methoden vergleicht.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy pandas qiskit qiskit-ibm-runtime qiskit-ibm-transpiler
# This cell is hidden from users;
# it just disables a linting rule.
# ruff: noqa: F811
Anforderungen
Stelle vor Beginn dieses Tutorials sicher, dass du Folgendes installiert hast:
- Qiskit SDK v1.0 oder höher, mit Unterstützung für Visualisierung
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 oder höher - Qiskit IBM® Transpiler mit AI-Lokalmodus(
pip install 'qiskit-ibm-transpiler[ai-local-mode]')
Einrichtung
from qiskit import QuantumCircuit
from qiskit.circuit.library import efficient_su2, PermutationGate
from qiskit.synthesis.qft import synth_qft_full
from qiskit.circuit.random import random_circuit, random_clifford_circuit
from qiskit.transpiler import generate_preset_pass_manager, CouplingMap
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_transpiler import generate_ai_pass_manager
from qiskit.synthesis.permutation import (
synth_permutation_depth_lnn_kms,
synth_permutation_basic,
)
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import time
import logging
seed = 42
# Used for generating permutation circuits in part two for comparison
def generate_permutation_circuit(width, pattern):
circuit = QuantumCircuit(width)
circuit.append(
PermutationGate(pattern=pattern),
qargs=range(width),
)
return circuit
# Creates a Bernstein-Vazirani circuit given the number of qubits
def create_bv_circuit(num_qubits):
qc = QuantumCircuit(num_qubits, num_qubits - 1)
qc.x(num_qubits - 1)
qc.h(qc.qubits)
for i in range(num_qubits - 1):
qc.cx(i, num_qubits - 1)
qc.h(qc.qubits[:-1])
return qc
# Transpile a circuit with a given pass manager and return metrics
def transpile_with_metrics(pass_manager, circuit):
start = time.time()
qc_out = pass_manager.run(circuit)
elapsed = time.time() - start
depth_2q = qc_out.depth(lambda x: x.operation.num_qubits == 2)
gate_count = qc_out.size()
return qc_out, {
"depth_2q": depth_2q,
"gate_count": gate_count,
"time_s": elapsed,
}
# Used for collecting metrics for part 3 of synthesis methods
def synth_transpile_with_metrics(qc, pm, pattern_id, method):
start = time.time()
qc = pm.run(qc)
elapsed = time.time() - start
return {
"Pattern": pattern_id,
"Method": method,
"Depth (2Q)": qc.depth(lambda x: x.operation.num_qubits == 2),
"Gates": qc.size(),
"Time (s)": elapsed,
}
# Ignore logs like "INFO:qiskit_ibm_transpiler.wrappers.ai_local_synthesis:Running Linear Functions AI synthesis on local mode"
logging.getLogger(
"qiskit_ibm_transpiler.wrappers.ai_local_synthesis"
).setLevel(logging.WARNING)
Teil I. Qiskit-Muster
Sehen wir uns nun an, wie man den AI-Transpiler-Service mit einer einfachen Quantenschaltung unter Verwendung von Qiskit-Mustern verwendet. Der Schlüssel ist die Erstellung eines PassManager mit generate_ai_pass_manager() anstelle des Standard generate_preset_pass_manager().
Schritt 1: Klassische Eingaben auf ein Quantenproblem abbilden
In diesem Abschnitt testen wir den AI-Transpiler an der efficient_su2-Schaltung, einem weit verbreiteten hardwareeffizienten Ansatz. Diese Schaltung ist besonders relevant für variationelle Quantenalgorithmen (zum Beispiel VQE) und Quantum-Machine-Learning-Aufgaben, was sie zu einem idealen Testfall für die Bewertung der Transpilationsleistung macht.
Die efficient_su2-Schaltung besteht aus abwechselnden Schichten von Ein-Qubit-Rotationen und verschränkenden Gates wie CNOTs. Diese Schichten ermöglichen eine flexible Erkundung des Quantenzustandsraums, während die Gate-Tiefe überschaubar bleibt. Durch Optimierung dieser Schaltung wollen wir die Gate-Anzahl reduzieren, die Fidelität verbessern und Rauschen minimieren. Dies macht sie zu einem starken Kandidaten zum Testen der Effizienz des AI-Transpilers.
# For our transpilation, we will use a large circuit of 101 qubits
qc = efficient_su2(90, entanglement="circular", reps=1).decompose()
# Draw a smaller version of the circuit to get a visual representation
qc_small = efficient_su2(5, entanglement="circular", reps=1).decompose()
qc_small.draw(output="mpl")
Schritt 2: Problem für die Ausführung auf Quantenhardware optimieren
Ein Backend auswählen
Für dieses Beispiel wählen wir das am wenigsten ausgelastete betriebsbereite IBM Quantum Backend, das kein Simulator ist und mindestens 100 Qubits hat:
Hinweis: Da sich das am wenigsten ausgelastete Backend im Laufe der Zeit ändern kann, können für verschiedene Durchläufe unterschiedliche Geräte ausgewählt werden. Gerätespezifische Eigenschaften, wie Coupling-Maps, können zu Unterschieden in den transpilierten Schaltungen führen.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=100
)
cm = backend.coupling_map
print(f"Using backend: {backend.name}")
Using backend: ibm_torino
AI- und traditionelle Pass-Manager erstellen
Um die Effektivität des AI-Transpilers zu bewerten, führen wir zwei Transpilationsläufe durch. Zuerst transpilieren wir die Schaltung mit dem AI-Transpiler. Dann führen wir einen Vergleich durch, indem wir dieselbe Schaltung ohne den AI-Transpiler mit traditionellen Methoden transpilieren. Beide Transpilationsprozesse verwenden dieselbe Coupling-Map vom gewählten Backend und das Optimierungslevel wird auf 3 gesetzt, für einen fairen Vergleich.
Beide Methoden spiegeln den Standardansatz zur Erstellung von PassManager-Instanzen zur Transpilation von Schaltungen in Qiskit wider.
pm_ai = generate_ai_pass_manager(
optimization_level=3,
ai_optimization_level=3,
coupling_map=cm,
include_ai_synthesis=True, # used for part 3 when comparing synthesis methods
)
pm_no_ai = generate_preset_pass_manager(
optimization_level=3,
coupling_map=cm,
seed_transpiler=seed, # note that the AI pass manager does not currently support seeding
)
Transpiliere die Schaltungen und zeichne die Zeiten auf.
# Transpile using standard (non-AI) pass manager
_, metrics_no_ai = transpile_with_metrics(pm_no_ai, qc)
print(
f"Standard transpilation: Depth (2q) {metrics_no_ai['depth_2q']}, "
f"Gate count {metrics_no_ai['gate_count']}, Time {metrics_no_ai['time_s']}"
)
# Transpile using AI pass manager
_, metrics_ai = transpile_with_metrics(pm_ai, qc)
print(
f"AI transpilation : Depth (2q) {metrics_ai['depth_2q']}, "
f"Gate count {metrics_ai['gate_count']}, Time {metrics_ai['time_s']}"
)
Standard transpilation: Depth (2q) 95, Gate count 458, Time 0.04650712013244629
AI transpilation : Depth (2q) 90, Gate count 456, Time 0.9342479705810547
In diesem Test vergleichen wir die Leistung des AI-Transpilers und der Standard-Transpilationsmethode an der efficient_su2-Schaltung. Der AI-Transpiler erreicht eine merklich flachere Schaltungstiefe bei ähnlicher Gate-Anzahl.
-
Schaltungstiefe: Der AI-Transpiler produziert eine Schaltung mit geringerer Zwei-Qubit-Tiefe. Dies ist zu erwarten, da die AI-Passes darauf trainiert sind, die Tiefe zu optimieren, indem sie Qubit-Interaktionsmuster lernen und Hardware-Konnektivität effektiver als regelbasierte Heuristiken ausnutzen.
-
Gate-Anzahl: Die Gesamt-Gate-Anzahl bleibt zwischen den beiden Methoden ähnlich. Dies entspricht den Erwartungen, da die Standard-SABRE-basierte Transpilation explizit die Swap-Anzahl minimiert, die den Gate-Overhead dominiert. Der AI-Transpiler priorisiert stattdessen die Gesamttiefe und kann gelegentlich einige zusätzliche Gates für einen kürzeren Ausführungspfad eintauschen.
-
Transpilationszeit: Der AI-Transpiler benötigt mehr Zeit als die Standardmethode. Dies liegt an den zusätzlichen Rechenkosten für das Aufrufen gelernter Modelle während des Routings und der Synthese. Im Gegensatz dazu ist der SABRE-basierte Transpiler jetzt nach Neufassung und Optimierung in Rust deutlich schneller und bietet hocheffizientes heuristisches Routing im großen Maßstab.
Es ist wichtig zu beachten, dass diese Ergebnisse nur auf einer Schaltung basieren. Um ein umfassendes Verständnis davon zu erhalten, wie sich der AI-Transpiler im Vergleich zu traditionellen Methoden verhält, ist es notwendig, eine Vielzahl von Schaltungen zu testen. Die Leistung von QTS kann je nach Art der zu optimierenden Schaltung stark variieren. Für einen breiteren Vergleich verweisen wir auf die obigen Benchmarks oder besuche den Blog.
Schritt 3: Ausführung mit Qiskit Primitives
Da sich dieses Tutorial auf Transpilation konzentriert, werden keine Experimente auf dem Quantengerät ausgeführt. Das Ziel ist es, die Optimierungen aus Schritt 2 zu nutzen, um eine transpilierte Schaltung mit reduzierter Tiefe oder Gate-Anzahl zu erhalten.
Schritt 4: Nachbearbeitung und Rückgabe des Ergebnisses im gewünschten klassischen Format
Da es keine Ausführung für dieses Notebook gibt, gibt es keine Ergebnisse zur Nachbearbeitung.
Teil II. Analyse und Benchmarking der transpilierten Schaltungen
In diesem Abschnitt zeigen wir, wie man die transpilierte Schaltung analysiert und detaillierter mit der Originalversion vergleicht. Wir konzentrieren uns auf Metriken wie Schaltungstiefe, Gate-Anzahl und Transpilationszeit, um die Effektivität der Optimierung zu bewerten. Zusätzlich diskutieren wir, wie die Ergebnisse über verschiedene Schaltungstypen hinweg variieren können, und bieten Einblicke in die breitere Leistung des Transpilers über verschiedene Szenarien hinweg.
# Circuits to benchmark
seed = 42
circuits = [
{
"name": "Random",
"qc": random_circuit(num_qubits=30, depth=10, seed=seed),
},
{
"name": "Clifford",
"qc": random_clifford_circuit(
num_qubits=40, num_gates=200, seed=seed
),
},
{
"name": "QFT",
"qc": synth_qft_full(num_qubits=20, do_swaps=False).decompose(),
},
{
"name": "BV",
"qc": create_bv_circuit(40),
},
]
results = []
# Run the transpilation for each circuit and store the results
for circuit in circuits:
qc_no_ai, metrics_no_ai = transpile_with_metrics(pm_no_ai, circuit["qc"])
qc_ai, metrics_ai = transpile_with_metrics(pm_ai, circuit["qc"])
print("Completed transpilation for", circuit["name"])
results.append(
{
"Circuit": circuit["name"],
"Depth 2Q (No AI)": metrics_no_ai["depth_2q"],
"Gate Count (No AI)": metrics_no_ai["gate_count"],
"Time (No AI)": metrics_no_ai["time_s"],
"Depth 2Q (AI)": metrics_ai["depth_2q"],
"Gate Count (AI)": metrics_ai["gate_count"],
"Time (AI)": metrics_ai["time_s"],
}
)
df = pd.DataFrame(results)
df
Completed transpilation for Random
Completed transpilation for Clifford
Completed transpilation for QFT
Completed transpilation for BV
Circuit Depth 2Q (No AI) Gate Count (No AI) Time (No AI) \
0 Random 37 221 0.039347
1 Clifford 36 232 0.036633
2 QFT 165 924 0.077458
3 BV 65 155 0.024993
Depth 2Q (AI) Gate Count (AI) Time (AI)
0 24 181 0.773718
1 43 267 1.097431
2 130 913 3.660771
3 70 155 0.345522
Durchschnittliche prozentuale Reduzierung für jede Metrik. Positive sind Verbesserungen, negative sind Verschlechterungen.
# Average reduction from non-AI to AI transpilation as a percentage
avg_reduction_depth = (
(df["Depth 2Q (No AI)"] - df["Depth 2Q (AI)"]).mean()
/ df["Depth 2Q (No AI)"].mean()
* 100
)
avg_reduction_gates = (
(df["Gate Count (No AI)"] - df["Gate Count (AI)"]).mean()
/ df["Gate Count (No AI)"].mean()
* 100
)
avg_reduction_time = (
(df["Time (No AI)"] - df["Time (AI)"]).mean()
/ df["Time (No AI)"].mean()
* 100
)
print(f"Average reduction in depth: {avg_reduction_depth:.2f}%")
print(f"Average reduction in gate count: {avg_reduction_gates:.2f}%")
print(f"Average reduction in transpilation time: {avg_reduction_time:.2f}%")
Average reduction in depth: 11.88%
Average reduction in gate count: 1.04%
Average reduction in transpilation time: -3193.95%
fig, axs = plt.subplots(1, 3, figsize=(21, 6))
df.plot(
x="Circuit",
y=["Depth 2Q (No AI)", "Depth 2Q (AI)"],
kind="bar",
ax=axs[0],
)
axs[0].set_title("Circuit Depth Comparison")
axs[0].set_ylabel("Depth")
axs[0].set_xlabel("Circuit")
axs[0].tick_params(axis="x", rotation=45)
df.plot(
x="Circuit",
y=["Gate Count (No AI)", "Gate Count (AI)"],
kind="bar",
ax=axs[1],
)
axs[1].set_title("Gate Count Comparison")
axs[1].set_ylabel("Gate Count")
axs[1].set_xlabel("Circuit")
axs[1].tick_params(axis="x", rotation=45)
df.plot(x="Circuit", y=["Time (No AI)", "Time (AI)"], kind="bar", ax=axs[2])
axs[2].set_title("Time Comparison")
axs[2].set_ylabel("Time (seconds)")
axs[2].set_xlabel("Circuit")
axs[2].tick_params(axis="x", rotation=45)
fig.suptitle(
"Benchmarking AI transpilation vs Non-AI transpilation for various circuits"
)
plt.tight_layout()
plt.show()

Die Leistung des AI-Transpilers variiert je nach Art der zu optimierenden Schaltung erheblich. In einigen Fällen erreicht er bemerkenswerte Reduzierungen der Schaltungstiefe und Gate-Anzahl im Vergleich zum Standard-Transpiler. Diese Verbesserungen gehen jedoch oft mit einer erheblichen Erhöhung der Laufzeit einher.
Für bestimmte Schaltungstypen kann der AI-Transpiler etwas bessere Ergebnisse in Bezug auf die Schaltungstiefe erzielen, aber auch zu einer Erhöhung der Gate-Anzahl und einer erheblichen Laufzeitstrafe führen. Diese Beobachtungen legen nahe, dass die Vorteile des AI-Transpilers nicht bei allen Schaltungstypen einheitlich sind. Stattdessen hängt seine Effektivität von den spezifischen Eigenschaften der Schaltung ab, was ihn für einige Anwendungsfälle besser geeignet macht als für andere.
Wann sollten Benutzer AI-gestützte Transpilation wählen?
Der AI-gestützte Transpiler in Qiskit glänzt in Szenarien, in denen traditionelle Transpilationsmethoden Schwierigkeiten haben, insbesondere bei groß angelegten und komplexen Quantenschaltungen. Für Schaltungen mit Hunderten von Qubits oder solche, die auf Hardware mit komplizierten Coupling-Maps abzielen, bietet der AI-Transpiler überlegene Optimierung in Bezug auf Schaltungstiefe, Gate-Anzahl und Laufzeiteffizienz. In Benchmarking-Tests hat er traditionelle Methoden konsistent übertroffen und deutlich flachere Schaltungen geliefert und Gate-Anzahlen reduziert, was für die Verbesserung der Leistung und die Minderung von Rauschen auf echter Quantenhardware entscheidend ist.
Benutzer sollten AI-gestützte Transpilation in Betracht ziehen, wenn sie mit:
- Großen Schaltungen arbeiten, bei denen traditionelle Methoden den Maßstab nicht effizient handhaben können.
- Komplexen Hardware-Topologien, bei denen Gerätekonnektivität und Routing-Herausforderungen auftreten.
- Leistungssensitiven Anwendungen, bei denen die Reduzierung der Schaltungstiefe und die Verbesserung der Fidelität von größter Bedeutung sind.
Teil III. Erkundung der AI-gestützten Permutationsnetzwerk-Synthese
Permutationsnetzwerke sind grundlegend im Quantencomputing, insbesondere für Systeme, die durch eingeschränkte Topologien beschränkt sind. Diese Netzwerke erleichtern Langstreckeninteraktionen, indem sie Qubits dynamisch tauschen, um All-to-All-Konnektivität auf Hardware mit begrenzter Konnektivität zu imitieren. Solche Transformationen sind für die Implementierung komplexer Quantenalgorithmen auf kurzfristigen Geräten unerlässlich, bei denen Interaktionen oft über nächste Nachbarn hinausgehen.
In diesem Abschnitt heben wir die Synthese von Permutationsnetzwerken als überzeugenden Anwendungsfall für den AI-gestützten Transpiler in Qiskit hervor. Insbesondere nutzt der AIPermutationSynthesis-Pass AI-gesteuerte Optimierung, um effiziente Schaltungen für Qubit-Permutationsaufgaben zu generieren. Im Gegensatz dazu haben generische Synthese-Ansätze oft Schwierigkeiten, Gate-Anzahl und Schaltungstiefe auszubalancieren, insbesondere in Szenarien mit dichten Qubit-Interaktionen oder beim Versuch, volle Konnektivität zu erreichen.
Wir werden ein Qiskit-Musterbeispiel durchgehen, das die Synthese eines Permutationsnetzwerks zeigt, um All-to-All-Konnektivität für einen Satz von Qubits zu erreichen. Wir werden die Leistung von AIPermutationSynthesis mit den Standard-Synthesemethoden in Qiskit vergleichen. Dieses Beispiel wird zeigen, wie der AI-Transpiler für geringere Schaltungstiefe und Gate-Anzahl optimiert und seine Vorteile in praktischen Quanten-Workflows hervorhebt. Um den AI-Synthese-Pass zu aktivieren, verwenden wir die Funktion generate_ai_pass_manager() mit dem Parameter include_ai_synthesis auf True gesetzt.
Schritt 1: Klassische Eingaben auf ein Quantenproblem abbilden
Um ein klassisches Permutationsproblem auf einem Quantencomputer darzustellen, beginnen wir mit der Definition der Struktur der Quantenschaltungen. Für dieses Beispiel:
-
Quantenschaltungs-Initialisierung: Wir weisen 27 Qubits zu, um zum Backend zu passen, das wir verwenden werden, das 27 Qubits hat.
-
Permutationen anwenden: Wir generieren zehn zufällige Permutationsmuster (
pattern_1bispattern_10) unter Verwendung eines festen Seeds für Reproduzierbarkeit. Jedes Permutationsmuster wird auf eine separate Quantenschaltung angewendet (qc_1bisqc_10). -
Schaltungszerlegung: Jede Permutationsoperation wird in native Gate-Sets zerlegt, die mit der Ziel-Quantenhardware kompatibel sind. Wir analysieren die Tiefe und die Anzahl der Zwei-Qubit-Gates (nichtlokale Gates) für jede zerlegte Schaltung.
Die Ergebnisse geben Einblick in die Komplexität der Darstellung klassischer Permutationsprobleme auf einem Quantengerät und demonstrieren die Ressourcenanforderungen für verschiedene Permutationsmuster.
# Parameters
width = 27
num_circuits = 10
# Set random seed
np.random.seed(seed)
# Generate random patterns and circuits
patterns = [
np.random.permutation(width).tolist() for _ in range(num_circuits)
]
circuits = {
f"qc_{i}": generate_permutation_circuit(width, pattern)
for i, pattern in enumerate(patterns, start=1)
}
# Display one of the circuits
circuits["qc_1"].decompose(reps=3).draw(output="mpl", fold=-1)

Schritt 2: Problem für die Ausführung auf Quantenhardware optimieren
In diesem Schritt fahren wir mit der Optimierung unter Verwendung der AI-Synthese-Passes fort.
Für die AI-Synthese-Passes benötigt der PassManager nur die Coupling-Map des Backends. Es ist jedoch wichtig zu beachten, dass nicht alle Coupling-Maps kompatibel sind; nur diejenigen, auf denen der AIPermutationSynthesis-Pass trainiert wurde, werden funktionieren. Derzeit unterstützt der AIPermutationSynthesis-Pass Blöcke der Größen 65, 33 und 27 Qubits. Für dieses Beispiel verwenden wir eine 27-Qubit-QPU.
Zum Vergleich werden wir die Leistung der AI-Synthese gegen generische Permutations-Synthesemethoden in Qiskit evaluieren, einschließlich:
-
synth_permutation_depth_lnn_kms: Diese Methode synthetisiert eine Permutationsschaltung für eine lineare Nächste-Nachbar-(LNN)-Architektur unter Verwendung des Kutin-, Moulton- und Smithline-(KMS)-Algorithmus. Sie garantiert eine Schaltung mit einer Tiefe von höchstens und einer Größe von höchstens , wobei sowohl Tiefe als auch Größe in Bezug auf SWAP-Gates gemessen werden. -
synth_permutation_basic: Dies ist eine einfache Implementierung, die Permutationsschaltungen synthetisiert, ohne Beschränkungen für Konnektivität oder Optimierung für spezifische Architekturen aufzuerlegen. Sie dient als Basislinie für den Vergleich der Leistung mit fortgeschritteneren Methoden.
Jede dieser Methoden repräsentiert einen eigenen Ansatz zur Synthese von Permutationsnetzwerken und bietet einen umfassenden Benchmark gegen die AI-gestützten Methoden.
Weitere Details zu Synthesemethoden in Qiskit findest du in der Qiskit-API-Dokumentation.
Definiere die Coupling-Map, die die 27-Qubit-QPU repräsentiert.
coupling_map = [
[1, 0],
[2, 1],
[3, 2],
[3, 5],
[4, 1],
[6, 7],
[7, 4],
[7, 10],
[8, 5],
[8, 9],
[8, 11],
[11, 14],
[12, 10],
[12, 13],
[12, 15],
[13, 14],
[16, 14],
[17, 18],
[18, 15],
[18, 21],
[19, 16],
[19, 22],
[20, 19],
[21, 23],
[23, 24],
[25, 22],
[25, 24],
[26, 25],
]
CouplingMap(coupling_map).draw()

Transpiliere jede der Permutationsschaltungen unter Verwendung der AI-Synthese-Passes und generischer Synthesemethoden.
results = []
pm_no_ai_synth = generate_preset_pass_manager(
coupling_map=cm,
optimization_level=1, # set to 1 since we are using the synthesis methods
)
# Transpile and analyze all circuits
for i, (qc_name, qc) in enumerate(circuits.items(), start=1):
pattern = patterns[i - 1] # Get the corresponding pattern
qc_depth_lnn_kms = synth_permutation_depth_lnn_kms(pattern)
qc_basic = synth_permutation_basic(pattern)
# AI synthesis
results.append(
synth_transpile_with_metrics(
qc.decompose(reps=3),
pm_ai,
qc_name,
"AI",
)
)
# Depth-LNN-KMS Method
results.append(
synth_transpile_with_metrics(
qc_depth_lnn_kms.decompose(reps=3),
pm_no_ai_synth,
qc_name,
"Depth-LNN-KMS",
)
)
# Basic Method
results.append(
synth_transpile_with_metrics(
qc_basic.decompose(reps=3),
pm_no_ai_synth,
qc_name,
"Basic",
)
)
results_df = pd.DataFrame(results)
Zeichne die Metriken (Tiefe, Gate-Anzahl, Zeit) für jede Schaltung nach der Transpilation auf.
# Calculate averages for each metric
average_metrics = results_df.groupby("Method")[
["Depth (2Q)", "Gates", "Time (s)"]
].mean()
average_metrics = average_metrics.round(3) # Round to two decimal places
print("\n=== Average Metrics ===")
print(average_metrics)
# Identify the best non-AI method based on least average depth
non_ai_methods = [
method for method in results_df["Method"].unique() if method != "AI"
]
best_non_ai_method = average_metrics.loc[non_ai_methods][
"Depth (2Q)"
].idxmin()
print(
f"\nBest Non-AI Method (based on least average depth): {best_non_ai_method}"
)
# Compare AI to the best non-AI method
ai_metrics = average_metrics.loc["AI"]
best_non_ai_metrics = average_metrics.loc[best_non_ai_method]
comparison = {
"Metric": ["Depth (2Q)", "Gates", "Time (s)"],
"AI": [
ai_metrics["Depth (2Q)"],
ai_metrics["Gates"],
ai_metrics["Time (s)"],
],
best_non_ai_method: [
best_non_ai_metrics["Depth (2Q)"],
best_non_ai_metrics["Gates"],
best_non_ai_metrics["Time (s)"],
],
"Improvement (AI vs Best Non-AI)": [
ai_metrics["Depth (2Q)"] - best_non_ai_metrics["Depth (2Q)"],
ai_metrics["Gates"] - best_non_ai_metrics["Gates"],
ai_metrics["Time (s)"] - best_non_ai_metrics["Time (s)"],
],
}
comparison_df = pd.DataFrame(comparison)
print("\n=== Comparison of AI vs Best Non-AI Method ===")
comparison_df
=== Average Metrics ===
Depth (2Q) Gates Time (s)
Method
AI 23.9 82.8 0.248
Basic 29.8 91.0 0.012
Depth-LNN-KMS 70.8 531.6 0.017
Best Non-AI Method (based on least average depth): Basic
=== Comparison of AI vs Best Non-AI Method ===
Metric AI Basic Improvement (AI vs Best Non-AI)
0 Depth (2Q) 23.900 29.800 -5.900
1 Gates 82.800 91.000 -8.200
2 Time (s) 0.248 0.012 0.236
Die Ergebnisse zeigen, dass der AI-Transpiler alle anderen Qiskit-Synthesemethoden für diesen Satz zufälliger Permutationsschaltungen übertrifft. Wichtige Erkenntnisse umfassen:
- Tiefe: Der AI-Transpiler erreicht die niedrigste durchschnittliche Tiefe, was auf überlegene Optimierung von Schaltungslayouts hinweist.
- Gate-Anzahl: Er reduziert die Anzahl der Gates im Vergleich zu anderen Methoden erheblich und verbessert die Ausführungs-Fidelität und -Effizienz.
- Transpilationszeit: Alle Methoden laufen auf dieser Skala sehr schnell, was sie praktisch einsetzbar macht. Der AI-Transpiler hat jedoch eine bemerkenswerte Laufzeiterhöhung im Vergleich zu traditionellen Methoden aufgrund der Komplexität der verwendeten AI-Modelle.
Diese Ergebnisse etablieren den AI-Transpiler als den effektivsten Ansatz für diesen Benchmark, insbesondere für Tiefen- und Gate-Anzahl-Optimierung.
Stelle die Ergebnisse dar, um die Leistung der AI-Synthese-Passes mit den generischen Synthesemethoden zu vergleichen.
methods = results_df["Method"].unique()
fig, axs = plt.subplots(1, 3, figsize=(18, 5))
# Pivot the DataFrame and reorder columns to ensure AI is first
pivot_depth = results_df.pivot(
index="Pattern", columns="Method", values="Depth (2Q)"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_gates = results_df.pivot(
index="Pattern", columns="Method", values="Gates"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_time = results_df.pivot(
index="Pattern", columns="Method", values="Time (s)"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_depth.plot(kind="bar", ax=axs[0], legend=False)
axs[0].set_title("Circuit Depth Comparison")
axs[0].set_ylabel("Depth")
axs[0].set_xlabel("Pattern")
axs[0].tick_params(axis="x", rotation=45)
pivot_gates.plot(kind="bar", ax=axs[1], legend=False)
axs[1].set_title("2Q Gate Count Comparison")
axs[1].set_ylabel("Number of 2Q Gates")
axs[1].set_xlabel("Pattern")
axs[1].tick_params(axis="x", rotation=45)
pivot_time.plot(
kind="bar", ax=axs[2], legend=True, title="Legend"
) # Show legend on the last plot
axs[2].set_title("Time Comparison")
axs[2].set_ylabel("Time (seconds)")
axs[2].set_xlabel("Pattern")
axs[2].tick_params(axis="x", rotation=45)
fig.suptitle(
"Benchmarking AI Synthesis Methods vs Non-AI Synthesis Methods For Random Permutations Circuits",
fontsize=16,
y=1,
)
plt.tight_layout()
plt.show()

Dieses Diagramm hebt die individuellen Ergebnisse für jede Schaltung (qc_1 bis qc_10) über verschiedene Synthesemethoden hinweg hervor:
Während diese Ergebnisse die Effektivität des AI-Transpilers für Permutationsschaltungen unterstreichen, ist es wichtig, seine Einschränkungen zu beachten. Die AI-Synthesemethode ist derzeit nur für bestimmte Coupling-Maps verfügbar, was ihre breitere Anwendbarkeit einschränken kann. Diese Einschränkung sollte bei der Bewertung ihrer Verwendung in verschiedenen Szenarien berücksichtigt werden.
Insgesamt zeigt der AI-Transpiler vielversprechende Verbesserungen in der Tiefen- und Gate-Anzahl-Optimierung für diese spezifischen Schaltungen bei vergleichbaren Transpilationszeiten.
Schritt 3: Ausführung mit Qiskit Primitives
Da sich dieses Tutorial auf Transpilation konzentriert, werden keine Experimente auf dem Quantengerät ausgeführt. Das Ziel ist es, die Optimierungen aus Schritt 2 zu nutzen, um eine transpilierte Schaltung mit reduzierter Tiefe oder Gate-Anzahl zu erhalten.
Schritt 4: Nachbearbeitung und Rückgabe des Ergebnisses im gewünschten klassischen Format
Da es keine Ausführung für dieses Notebook gibt, gibt es keine Ergebnisse zur Nachbearbeitung.
Tutorial-Umfrage
Bitte nimm an dieser kurzen Umfrage teil, um Feedback zu diesem Tutorial zu geben. Deine Erkenntnisse helfen uns, unser Inhaltsangebot und unsere Benutzererfahrung zu verbessern.