Zum Hauptinhoid springan

Einführung in den Qiskit KI-gstützten Transpiler-Service

Gschätzte QPU-Nutzung: Koa (HINWEIS: Des Tutorial führt koa Jobs aus, weil's sich auf Transpilation fokussiert)

Hintergrund

Da Qiskit KI-gstützte Transpiler-Service (QTS) führt maschinelles-Lernen-basierti Optimierungen sowohl in Routing- als aa in Synthesis-Passes ei. De KI-Modi san entwickelt worn, um de Einschränkungen von da traditionellen Transpilation anzugehen, insbesondere für große Schaltungen und komplexe Hardware-Topologien.

Ab Juli 2025 is da Transpiler-Service zur neuen IBM Quantum® Platform migriert worn und is ned mehr verfügbar. Für de neusten Updates zum Status vom Transpiler-Service verweisen mia auf de Transpiler-Service-Dokumentation. Ihr könnts de KI-Transpiler weiterhin lokal verwenden, ähnlich wie bei da Standard-Qiskit-Transpilation. Ersetzt einfach generate_preset_pass_manager() durch generate_ai_pass_manager(). De Funktion konstruiert an Pass-Manager, der de KI-gstützten Routing- und Synthesis-Passes direkt in eiren lokalen Transpilations-Workflow integriert.

Hauptmerkmal von de KI-Passes

  • Routing-Passes: KI-gstütztes Routing ka Qubit-Pfade dynamisch basierend auf da spezifischen Schaltung und em Backend anpassen und den Bedarf an übermäßigen SWAP-Gates reduzieren.

    • AIRouting: Layout-Auswahl und Schaltungs-Routing
  • Synthesis-Passes: KI-Techniken optimieren de Zerlegung von Multi-Qubit-Gates und minimieren de Anzahl von de Zwei-Qubit-Gates, de typischerweise anfälliger für Fehler san.

    • AICliffordSynthesis: Clifford-Gate-Synthese
    • AILinearFunctionSynthesis: Synthese von Linear-Funktionsschaltungen
    • AIPermutationSynthesis: Synthese von Permutationsschaltungen
    • AIPauliNetworkSynthesis: Synthese von Pauli-Netzwerkschaltungen (nur im Qiskit Transpiler Service verfügbar, ned in da lokalen Umgebung)
  • Vergleich mit traditioneller Transpilation: Da Standard-Qiskit-Transpiler is a robustes Werkzeug, das a breites Spektrum von Quantenschaltungen effektiv handhaben ka. Wenn Schaltungen aber größer wern oder Hardware-Konfigurationen komplexer wern, können KI-Passes zusätzliche Optimierungsgewinne liefern. Durch de Verwendung von glernten Modellen für Routing und Synthese verfeinert QTS Schaltungslayouts weiter und reduziert den Overhead für herausfordernde oder groß angelegte Quantenaufgaben.

Des Tutorial evaluiert de KI-Modi unter Verwendung sowohl von Routing- als aa von Synthesis-Passes und vergleicht de Ergebnisse mit traditioneller Transpilation, um hervorzuheben, wo KI Leistungsvorteile bietet.

Weitere Details zu de verfügbaren KI-Passes findet ihr in da KI-Passes-Dokumentation.

Warum KI für Quantenschaltungs-Transpilation verwenden?

Weil Quantenschaltungen in Größe und Komplexität zunehmen, ham traditionelle Transpilationsmethoden Schwierigkeiten, Layouts zu optimieren und Gate-Anzahlen effizient zu reduzieren. Größere Schaltungen, insbesondere solche mit Hunderten von Qubits, stellen erhebliche Herausforderungen ans Routing und de Synthese, wegen Gerätebeschränkungen, begrenzter Konnektivität und Qubit-Fehlerraten.

Do bietet de KI-gstützte Transpilation a potenzielle Lösung. Durch de Nutzung von maschinellen Lerntechniken ka da KI-gstützte Transpiler in Qiskit gscheitere Entscheidungen über Qubit-Routing und Gate-Synthese treffen, was zu besserer Optimierung von groß angelegten Quantenschaltungen führt.

Kurze Benchmarking-Ergebnisse

Graph showing AI transpiler performance against Qiskit

In Benchmarking-Tests ham da KI-Transpiler konsistent flachere Schaltungen höherer Qualität im Vergleich zum Standard-Qiskit-Transpiler produziert. Für de Tests ham mia de Standard-Pass-Manager-Strategie von Qiskit verwendet, konfiguriert mit [generate_preset_passmanager]. Während de Standardstrategie oft effektiv is, ka sie bei größeren oder komplexeren Schaltungen Schwierigkeiten ham. Im Gegensatz dazu ham KI-gstützte Passes a durchschnittliche Reduzierung von da Zwei-Qubit-Gate-Anzahl um 24% und a Reduzierung von da Schaltungstiefe um 36% für große Schaltungen (100+ Qubits) bei da Transpilation auf de Heavy-Hex-Topologie von IBM Quantum Hardware erreicht. Weitere Informationen zu de Benchmarks findet ihr in dem Blog.

Des Tutorial untersucht de wichtigsten Vorteile von de KI-Passes und wie se sich mit traditionellen Methoden vergleichen.

# Added by doQumentation — installs packages not in the Binder environment
!pip install -q qiskit-ibm-transpiler
# This cell is hidden from users;
# it just disables a linting rule.
# ruff: noqa: F811

Anforderungen

Stellt vor em Beginn von dem Tutorial sicher, dass ihr Folgendes installiert ham:

  • 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 KI-Lokalmodus(pip install 'qiskit-ibm-transpiler[ai-local-mode]')

Setup

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

Jetzt schauma mia uns an, wie man de KI-Transpiler-Service mit a einfachen Quantenschaltung unter Verwendung von Qiskit-Mustern verwendet. Da Schlüssel is de Erstellung von an PassManager mit generate_ai_pass_manager() anstelle vom Standard generate_preset_pass_manager().

Schritt 1: Klassische Eingaben auf a Quantenproblem abbilden

In dem Abschnitt testen mia de KI-Transpiler an da efficient_su2-Schaltung, an weit verbreitetem hardwareeffizienten Ansatz. De Schaltung is besonders relevant für variationelle Quantenalgorithmen (zum Beispiel VQE) und Quantum-Machine-Learning-Aufgaben, was sie zu an idealen Testfall für de Bewertung von da Transpilationsleistung macht.

De efficient_su2-Schaltung besteht aus abwechselnden Schichten von Ein-Qubit-Rotationen und verschränkenden Gates wie CNOTs. De Schichten ermöglichen a flexible Erkundung vom Quantenzustandsraum, während de Gate-Tiefe überschaubar bleibt. Durch Optimierung von dera Schaltung wollen mia de Gate-Anzahl reduzieren, de Fidelität verbessern und Rauschen minimieren. Des macht sie zu an starken Kandidaten zum Testen von da Effizienz vom KI-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")

Output of the previous code cell

Schritt 2: Problem für de Ausführung auf Quantenhardware optimieren

A Backend auswählen

Für des Beispiel wählen mia des am wenigsten ausgelastete betriebsbereite IBM Quantum Backend, des koa Simulator is und mindestens 100 Qubits hat:

Hinweis: Weil sich des am wenigsten ausgelastete Backend im Laufe von da Zeit ändern ka, können für verschiedene Durchläufe unterschiedliche Geräte ausgewählt wern. Gerätespezifische Eigenschaften, wie Coupling-Maps, können zu Unterschieden in de 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

KI- und traditionelle Pass-Manager erstellen

Um de Effektivität vom KI-Transpilers zu bewerten, führen mia zwoa Transpilationsläufe durch. Zuerst transpilieren mia de Schaltung mit em KI-Transpiler. Dann führen mia an Vergleich durch, indem mia dieselbe Schaltung ohne den KI-Transpiler mit traditionellen Methoden transpilieren. Beade Transpilationsprozesse verwenden dieselbe Coupling-Map vom gwählten Backend und des Optimierungslevel wird auf 3 gsetzt, für an fairen Vergleich.

Beade 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
)

Transpiliert de Schaltungen und zeichnet de 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 dem Test vergleichen mia de Leistung vom KI-Transpiler und von da Standard-Transpilationsmethode an da efficient_su2-Schaltung. Da KI-Transpiler erreicht a merklich flachere Schaltungstiefe bei ähnlicher Gate-Anzahl.

  • Schaltungstiefe: Da KI-Transpiler produziert a Schaltung mit geringerer Zwei-Qubit-Tiefe. Des is zu erwarten, weil de KI-Passes darauf trainiert san, de Tiefe zu optimieren, indem sie Qubit-Interaktionsmuster lernen und Hardware-Konnektivität effektiver als regelbasierte Heuristiken ausnutzen.

  • Gate-Anzahl: De Gesamt-Gate-Anzahl bleibt zwischn de zwoa Methoden ähnlich. Des entspricht de Erwartungen, weil de Standard-SABRE-basierte Transpilation explizit de Swap-Anzahl minimiert, de den Gate-Overhead dominiert. Da KI-Transpiler priorisiert stattdessen de Gesamttiefe und ka gelegentlich a paar zusätzliche Gates für an kürzeren Ausführungspfad eintauschen.

  • Transpilationszeit: Da KI-Transpiler braucht mehr Zeit als de Standardmethode. Des liegt an de zusätzlichen Rechenkosten für des Aufrufen von glernten Modellen während vom Routing und da Synthese. Im Gegensatz dazu is da SABRE-basierte Transpiler jetzt nach Neufassung und Optimierung in Rust deutlich schneller und bietet hocheffizientes heuristisches Routing im großen Maßstab.

's is wichtig z'beachten, dass de Ergebnisse nur auf aner Schaltung basieren. Um a umfassendes Verständnis davon z'kriegen, wie sich da KI-Transpiler im Vergleich zu traditionellen Methoden verhält, is es notwendig, a Vielzahl von Schaltungen z'testen. De Leistung von QTS ka je nach Art von da zu optimierenden Schaltung stark variieren. Für an breiteren Vergleich verweisen mia auf de obigen Benchmarks oder besucht de Blog.

Schritt 3: Ausführung mit Qiskit Primitives

Weil sich des Tutorial auf Transpilation konzentriert, wern koa Experimente auf em Quantengerät ausgeführt. Des Ziel is es, de Optimierungen aus Schritt 2 z'nutzen, um a transpilierte Schaltung mit reduzierter Tiefe oder Gate-Anzahl z'kriegen.

Schritt 4: Nachbearbeitung und Rückgabe vom Ergebnis im gwünschten klassischen Format

Weil's koa Ausführung für des Notebook gibt, gibt's koa Ergebnisse zur Nachbearbeitung.

Teil II. Analyse und Benchmarking von de transpilierten Schaltungen

In dem Abschnitt zeigen mia, wie man de transpilierte Schaltung analysiert und detaillierter mit da Originalversion vergleicht. Mia konzentrieren uns auf Metriken wie Schaltungstiefe, Gate-Anzahl und Transpilationszeit, um de Effektivität von da Optimierung z'bewerten. Zusätzlich diskutieren mia, wie de Ergebnisse über verschiedene Schaltungstypen hinweg variieren können, und bieten Einblicke in de breitere Leistung vom Transpiler ü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 san Verbesserungen, negative san 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()

Output of the previous code cell

De Leistung vom KI-Transpilers variiert je nach Art von da zu optimierenden Schaltung erheblich. In manchen Fällen erreicht er bemerkenswerte Reduzierungen von da Schaltungstiefe und Gate-Anzahl im Vergleich zum Standard-Transpiler. De Verbesserungen gehen aber oft mit aner erheblichen Erhöhung von da Laufzeit einher.

Für bestimmte Schaltungstypen ka da KI-Transpiler a bisserl bessere Ergebnisse in Bezug auf de Schaltungstiefe erzielen, aber aa zu aner Erhöhung von da Gate-Anzahl und aner erheblichen Laufzeitstrafe führen. De Beobachtungen legen nahe, dass de Vorteile vom KI-Transpilers ned bei allen Schaltungstypen einheitlich san. Stattdessen hängt sei Effektivität von de spezifischen Eigenschaften von da Schaltung ab, was ihn für manchi Anwendungsfälle besser geeignet macht als für andere.

Wann solletn Benutzer KI-gstützte Transpilation wählen?

Da KI-gstützte Transpiler in Qiskit glänzt in Szenarien, wo traditionelle Transpilationsmethoden Schwierigkeiten ham, insbesondere bei groß angelegten und komplexen Quantenschaltungen. Für Schaltungen mit Hunderten von Qubits oder solche, de auf Hardware mit komplizierten Coupling-Maps abzielen, bietet da KI-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 de Verbesserung von da Leistung und de Minderung von Rauschen auf echter Quantenhardware entscheidend is.

Benutzer solletn KI-gstützte Transpilation in Betracht ziehen, wenn sie mit:

  • Großen Schaltungen arbeiten, wo traditionelle Methoden den Maßstab ned effizient handhaben können.
  • Komplexen Hardware-Topologien, wo Gerätekonnektivität und Routing-Herausforderungen auftreten.
  • Leistungssensitiven Anwendungen, wo de Reduzierung von da Schaltungstiefe und de Verbesserung von da Fidelität von größter Bedeutung san.

Teil III. Erkundung von da KI-gstützten Permutationsnetzwerk-Synthese

Permutationsnetzwerke san grundlegend im Quantencomputing, insbesondere für Systeme, de durch eingeschränkte Topologien begrenzt san. De Netzwerke erleichtern Langstreckeninteraktionen, indem sie Qubits dynamisch tauschen, um All-to-All-Konnektivität auf Hardware mit begrenzter Konnektivität nachzuahmen. Solche Transformationen san für de Implementierung komplexer Quantenalgorithmen auf kurzfristigen Geräten unerlässlich, bei denen Interaktionen oft über nächste Nachbarn hinausgehen.

In dem Abschnitt heben mia de Synthese von Permutationsnetzwerken als überzeugenden Anwendungsfall für de KI-gstützten Transpiler in Qiskit hervor. Insbesondere nutzt da AIPermutationSynthesis-Pass KI-gesteuerte Optimierung, um effiziente Schaltungen für Qubit-Permutationsaufgaben z'generieren. Im Gegensatz dazu ham generische Synthese-Ansätze oft Schwierigkeiten, Gate-Anzahl und Schaltungstiefe auszubalancieren, insbesondere in Szenarien mit dichten Qubit-Interaktionen oder beim Versuch, volle Konnektivität z'erreichen.

Mia wern a Qiskit-Musterbeispiel durchgehen, des de Synthese von an Permutationsnetzwerk zeigt, um All-to-All-Konnektivität für an Satz von Qubits z'erreichen. Mia wern de Leistung von AIPermutationSynthesis mit de Standard-Synthesemethoden in Qiskit vergleichen. Des Beispiel wird zeigen, wie da KI-Transpiler für geringere Schaltungstiefe und Gate-Anzahl optimiert und seine Vorteile in praktischen Quanten-Workflows hervorhebt. Um de KI-Synthese-Pass z'aktivieren, verwenden mia de Funktion generate_ai_pass_manager() mit em Parameter include_ai_synthesis auf True gsetzt.

Schritt 1: Klassische Eingaben auf a Quantenproblem abbilden

Um a klassisches Permutationsproblem auf an Quantencomputer darzustellen, fangen mia mit da Definition von da Struktur von de Quantenschaltungen an. Für des Beispiel:

  1. Quantenschaltungs-Initialisierung: Mia weisen 27 Qubits zu, um zum Backend z'passen, des mia verwenden wern und des 27 Qubits hat.

  2. Permutationen anwenden: Mia generieren zehn zufällige Permutationsmuster (pattern_1 bis pattern_10) unter Verwendung von an festen Seeds für Reproduzierbarkeit. Jedes Permutationsmuster wird auf a separate Quantenschaltung angewandt (qc_1 bis qc_10).

  3. Schaltungszerlegung: Jede Permutationsoperation wird in native Gate-Sets zerlegt, de mit da Ziel-Quantenhardware kompatibel san. Mia analysieren de Tiefe und de Anzahl von de Zwei-Qubit-Gates (nichtlokale Gates) für jede zerlegte Schaltung.

De Ergebnisse geben Einblick in de Komplexität von da Darstellung klassischer Permutationsprobleme auf an Quantengerät und demonstrieren de 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)

Output of the previous code cell

Schritt 2: Problem für de Ausführung auf Quantenhardware optimieren

In dem Schritt fahren mia mit da Optimierung unter Verwendung von de KI-Synthese-Passes fort.

Für de KI-Synthese-Passes braucht da PassManager nur de Coupling-Map vom Backend. 's is aber wichtig z'beachten, dass ned alle Coupling-Maps kompatibel san; nur diejenigen, auf denen da AIPermutationSynthesis-Pass trainiert worn is, wern funktionieren. Derzeit unterstützt da AIPermutationSynthesis-Pass Blöcke von de Größen 65, 33 und 27 Qubits. Für des Beispiel verwenden mia a 27-Qubit-QPU.

Zum Vergleich wern mia de Leistung von da KI-Synthese gegen generische Permutations-Synthesemethoden in Qiskit evaluieren, einschließlich:

  • synth_permutation_depth_lnn_kms: De Methode synthetisiert a Permutationsschaltung für a lineare Nächste-Nachbar-(LNN)-Architektur unter Verwendung vom Kutin-, Moulton- und Smithline-(KMS)-Algorithmus. Sie garantiert a Schaltung mit aner Tiefe von höchstens nn und aner Größe von höchstens n(n1)/2n(n-1)/2, wobei sowohl Tiefe als aa Größe in Bezug auf SWAP-Gates gmessen wern.

  • synth_permutation_basic: Des is a einfache Implementierung, de Permutationsschaltungen synthetisiert, ohne Beschränkungen für Konnektivität oder Optimierung für spezifische Architekturen aufzuerlegen. Sie dient als Basislinie für de Vergleich von da Leistung mit fortgeschritteneren Methoden.

Jede von de Methoden repräsentiert an eigenen Ansatz zur Synthese von Permutationsnetzwerken und bietet an umfassenden Benchmark gegen de KI-gstützten Methoden.

Weitere Details zu Synthesemethoden in Qiskit findet ihr in da Qiskit-API-Dokumentation.

Definiert de Coupling-Map, de de 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()

Output of the previous code cell

Transpiliert jede von de Permutationsschaltungen unter Verwendung von de KI-Synthese-Passes und generischen 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)

Zeichnet de Metriken (Tiefe, Gate-Anzahl, Zeit) für jede Schaltung nach da 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

De Ergebnisse zeigen, dass da KI-Transpiler alle anderen Qiskit-Synthesemethoden für den Satz zufälliger Permutationsschaltungen übertrifft. Wichtige Erkenntnisse umfassen:

  1. Tiefe: Da KI-Transpiler erreicht de niedrigste durchschnittliche Tiefe, was auf überlegene Optimierung von Schaltungslayouts hinweist.
  2. Gate-Anzahl: Er reduziert de Anzahl von de Gates im Vergleich zu anderen Methoden erheblich und verbessert de Ausführungs-Fidelität und -Effizienz.
  3. Transpilationszeit: Alle Methoden laufen auf dera Skala sehr schnell, was sie praktisch einsetzbar macht. Da KI-Transpiler hat aber a bemerkenswerte Laufzeiterhöhung im Vergleich zu traditionellen Methoden wegen da Komplexität von de verwendeten KI-Modellen.

De Ergebnisse etablieren de KI-Transpiler als den effektivsten Ansatz für den Benchmark, insbesondere für Tiefen- und Gate-Anzahl-Optimierung.

Stellt de Ergebnisse dar, um de Leistung von de KI-Synthese-Passes mit de generischen Synthesemethoden z'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()

Output of the previous code cell

Des Diagramm hebt de individuellen Ergebnisse für jede Schaltung (qc_1 bis qc_10) über verschiedene Synthesemethoden hinweg hervor:

Während de Ergebnisse de Effektivität vom KI-Transpilers für Permutationsschaltungen unterstreichen, is es wichtig, seine Einschränkungen z'beachten. De KI-Synthesemethode is derzeit nur für bestimmte Coupling-Maps verfügbar, was ihre breitere Anwendbarkeit einschränken ka. De Einschränkung sollt bei da Bewertung von ihrer Verwendung in verschiedenen Szenarien berücksichtigt wern.

Insgesamt zeigt da KI-Transpiler vielversprechende Verbesserungen in da Tiefen- und Gate-Anzahl-Optimierung für de spezifischen Schaltungen bei vergleichbaren Transpilationszeiten.

Schritt 3: Ausführung mit Qiskit Primitives

Weil sich des Tutorial auf Transpilation konzentriert, wern koa Experimente auf em Quantengerät ausgeführt. Des Ziel is es, de Optimierungen aus Schritt 2 z'nutzen, um a transpilierte Schaltung mit reduzierter Tiefe oder Gate-Anzahl z'kriegen.

Schritt 4: Nachbearbeitung und Rückgabe vom Ergebnis im gwünschten klassischen Format

Weil's koa Ausführung für des Notebook gibt, gibt's koa Ergebnisse zur Nachbearbeitung.

Tutorial-Umfrage

Bitte mochts bei dera kurzen Umfrage mit, um Feedback zu dem Tutorial z'geben. Eiere Erkenntnisse helfen uns, unser Inhaltsangebot und unsere Benutzererfahrung z'verbessern.

Link zur Umfrage