To't Hauptinholt springen

Inföhrung in'n Qiskit KI-unnerstütt Transpiler-Service

Schatt QPU-Bruuk: Nix (WOHRSCHU: Dit Tutorial föhrt keen Jobs ut, wieldat sik op Transpilation konzentreert)

Achtergrund

De Qiskit KI-unnerstütt Transpiler-Service (QTS) bringt maschinell-Lehr-baseert Optimierungs in Routing- un ook in Synthese-Passes rin. Disse KI-Modus sünd ontwikkelt worrn, üm de Inschränkungs vun de traditionelle Transpilation antogahn, besünners för grote Schaltungs un komplexe Hardware-Topologien.

Af Juli 2025 is de Transpiler-Service na de nee IBM Quantum® Plattform migreert worrn un is nich mehr vörhannen. För de neesten Updates övern Status vun'n Transpiler-Service kiekt bi de Transpiler-Service-Dokumentation. Ji künnt den KI-Transpiler wieterhinn lokal bruken, ähnlich as bi de Standard-Qiskit-Transpilation. Ersett eenfach generate_preset_pass_manager() dör generate_ai_pass_manager(). Disse Funkschon konstrueert en Pass-Manager, de de KI-unnerstütt Routing- un Synthese-Passes direkt in joon lokalen Transpilations-Workflow integreert.

Hööftmerkmaals vun de KI-Passes

  • Routing-Passes: KI-unnerstütt Routing kann Qubit-Paden dynamisch baseernd op de spezifische Schaltung un dat Backend anpassen un den Bedarf an överdreven SWAP-Gates reduzieren.

    • AIRouting: Layout-Utwahl un Schaltungs-Routing
  • Synthese-Passes: KI-Techniken optimiert de Updelung vun Multi-Qubit-Gates un minimeert de Tall vun de Twee-Qubit-Gates, de typischerwiese anfälliger för Fehlers sünd.

    • AICliffordSynthesis: Clifford-Gate-Synthese
    • AILinearFunctionSynthesis: Synthese vun Linear-Funkschonsschaltungs
    • AIPermutationSynthesis: Synthese vun Permutatschonsschaltungs
    • AIPauliNetworkSynthesis: Synthese vun Pauli-Netwarkschaltungs (blots in'n Qiskit Transpiler Service vörhannen, nich in de lokale Ümgeven)
  • Verglieken mit traditionelle Transpilation: De Standard-Qiskit-Transpiler is en robust Warktuug, dat en breet Spektrum vun Quantenschaltungs effektiv hanneln kann. Wenn Schaltungs aver grötter warrt oder Hardware-Konfigurationen komplexer warrt, künnt KI-Passes tosätzliche Optimierungsgewinns leevern. Dör de Bruuk vun leehrte Modells för Routing un Synthese verfienert QTS Schaltungslayouts wieder un reduziert den Overhead för rutfordernde oder groot anleggte Quantenopgaven.

Dit Tutorial evalueert de KI-Modus ünner Bruuk vun Routing- un ook vun Synthese-Passes un vergliekt de Resultaten mit traditionelle Transpilation, üm hervörtoheven, wo KI Leistungsv vördele beedt.

För mehr Details övern vörhannen KI-Passes kiekt bi de KI-Passes-Dokumentation.

Worüm KI för Quantenschaltungs-Transpilation bruken?

Wiel Quantenschaltungs in Grött un Komplexität toneehmt, hebbt traditionelle Transpilationsmethoden Swierigkeiten, Layouts to optimieren un Gate-Talls effizient to reduzieren. Grötere Schaltungs, besünners disse mit Hunnerten vun Qubits, stellt erhebliche Rutforderungs an dat Routing un de Synthese dar, wegen Gerätinschränkungs, begrenzte Konnektivität un Qubit-Fehleraten.

Dor beedt de KI-unnerstütt Transpilation en potenzielle Lösung. Dör de Nutzung vun maschinelle Lehrntechniken kann de KI-unnerstütt Transpiler in Qiskit klöökere Entscheidungs övern Qubit-Routing un Gate-Synthese treffen, wat to beter Optimierung vun groot anleggte Quantenschaltungs föhrt.

Korte Benchmarking-Resultaten

Graph showing AI transpiler performance against Qiskit

In Benchmarking-Tests hett de KI-Transpiler konsistent flackere Schaltungs högere Qualität vergläken mit'n Standard-Qiskit-Transpiler produzeert. För disse Tests hebbt wi de Standard-Pass-Manager-Strategie vun Qiskit bruukt, konfiguräert mit [generate_preset_passmanager]. Wohrenddess disse Standardstrategie oft effektiv is, kann se bi grötere oder komplexere Schaltungs Swierigkeiten hebben. In'n Gegensatz dorto hebbt KI-unnerstütt Passes en dörchsnittliche Reduzierung vun de Twee-Qubit-Gate-Tall üm 24% un en Reduzierung vun de Schaltungsdeepte üm 36% för grote Schaltungs (100+ Qubits) bi de Transpilation op de Heavy-Hex-Topologie vun IBM Quantum Hardware berikt. Mehr Informatschonen övern disse Benchmarks finnst in'n Blog.

Dit Tutorial ünnersöcht de wichtigsten Vördele vun de KI-Passes un wo se sik mit traditionelle Methoden vergliekt.

# 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

Anforderungs

Stellt vör'n Anfang vun dit Tutorial seker, dat ji Folgendes installeert hebbt:

  • Qiskit SDK v1.0 oder höger, mit Unnerstüttung för Visualisierung
  • Qiskit Runtime (pip install qiskit-ibm-runtime) v0.22 oder höger
  • 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)

Deel I. Qiskit-Musters

Nu kiekt wi uns an, wo wi den KI-Transpiler-Service mit en eenfache Quantenschaltung ünner Bruuk vun Qiskit-Musters bruken doot. De Slötel is de Opstellung vun en PassManager mit generate_ai_pass_manager() anstatt vun'n Standard generate_preset_pass_manager().

Schritt 1: Klassische Ingaven op en Quantenproblem afbilden

In dissen Afsnitt test wi den KI-Transpiler op de efficient_su2-Schaltung, en wiet verbreett hardwareeffizient Ansatz. Disse Schaltung is besünners relevant för variatschonelle Quantenalgorithmen (to'n Bispeel VQE) un Quantum-Machine-Learning-Opgaven, wat se to en idealen Testfall för de Bewerden vun de Transpilationsleistung maakt.

De efficient_su2-Schaltung besteiht ut afwesselnde Schichten vun Een-Qubit-Rotatschonen un verschränkende Gates as CNOTs. Disse Schichten möögliekt en flexibele Erkunnung vun'n Quantentostandsruum, wohrenddess de Gate-Deepte överschaubar blifft. Dör Optimierung vun de Schaltung wüllt wi de Gate-Tall reduzieren, de Fidelität verbätern un Ruuschen minimeren. Dat maakt se to en starken Kandidaten för dat Testen vun de Effizienz vun'n KI-Transpiler.

# 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 Utföhren op Quantenhardware optimieren

En Backend utwähln

För dit Bispeel wählt wi dat am wenigsten utlasten betriebsbereite IBM Quantum Backend, dat keen Simulator is un mindestens 100 Qubits hett:

Wohrschau: Wieldat sik dat am wenigsten utlasten Backend över de Tied ännern kann, künnt för verschedene Dörchlööp ünnerscheedliche Geräte utwählt warrn. Gerät-spezifische Egenschaften, as Coupling-Maps, künnt to Ünnerscheed in de transpileerten Schaltungs 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- un traditionelle Pass-Manager opstellen

Üm de Effektivität vun'n KI-Transpiler to bewerden, föhrt wi twee Transpilationslööp dör. Toeerst transpiliert wi de Schaltung mit den KI-Transpiler. Denn föhrt wi en Verglieken dör, indem wi desülvige Schaltung ahn den KI-Transpiler mit traditionelle Methoden transpiliert. Beide Transpilationsprozesse bruukt desülvige Coupling-Map vun'n wählte Backend un dat Optimierungslevel warrt op 3 sett, för en fairen Verglieken.

Beide Methoden spiegelt den Standardansatz to de Opstellung vun PassManager-Instanzen to de Transpilation vun Schaltungs 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
)

Transpileert de Schaltungs un tekent de Tiden op.

# 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 dissen Test vergliekt wi de Leistung vun'n KI-Transpiler un vun de Standard-Transpilationsmethode op de efficient_su2-Schaltung. De KI-Transpiler berikt en märklich flackere Schaltungsdeepte bi ähnliche Gate-Tall.

  • Schaltungsdeepte: De KI-Transpiler produzeert en Schaltung mit geringere Twee-Qubit-Deepte. Dat is to verwachten, wieldat de KI-Passes dorop traineert sünd, de Deepte to optimieren, indem se Qubit-Interaktschonsmusters lehrt un Hardware-Konnektivität effektiver as regel-baseerte Heuristiken utnutzt.

  • Gate-Tall: De Gesamt-Gate-Tall blifft twüschen de twee Methoden ähnlich. Dat entspricht de Verwachtungs, wieldat de Standard-SABRE-baseerte Transpilation explizit de Swap-Tall minimeert, de den Gate-Overhead domineert. De KI-Transpiler prioreseert stattdessen de Gesamtdeepte un kann gelägenlich en poor tosätzliche Gates för en körtere Utföhrenspfad intauschen.

  • Transpilationstied: De KI-Transpiler bruukt mehr Tied as de Standardmethode. Dat liggt an de tosätzlichen Rekenkosten för dat Opropen vun leehrte Modells wohrenddess dat Routing un de Synthese. In'n Gegensatz dorto is de SABRE-baseerte Transpiler nu na Neegestaltung un Optimierung in Rust düütlich sneller un beedt hoocheffizient heuristisch Routing in groten Maßstav.

Dat is wichtig to beachten, dat disse Resultaten blots op een Schaltung baseert. Üm en ümfatend Verständnis dorüm to kriegen, wo sik de KI-Transpiler vergläken mit traditionelle Methoden verhölt, is dat nödig, en Vielheit vun Schaltungs to testen. De Leistung vun QTS kann je na Oort vun de to optimierenden Schaltung stark variëren. För en breideren Verglieken kiekt bi de baven Benchmarks oder besökt den Blog.

Schritt 3: Utföhren mit Qiskit Primitives

Wieldat sik dit Tutorial op Transpilation konzentreert, warrt keen Experimenten op dat Quantengerät utföhrt. Dat Doel is dat, de Optimierungs ut Schritt 2 to nutzen, üm en transpileerde Schaltung mit reduzeerde Deepte oder Gate-Tall to kriegen.

Schritt 4: Naharbeiten un Törüchgaav vun dat Resultat in dat wünschte klassische Format

Wieldat dar keen Utföhren för dit Notebook givt, givt dat keen Resultaten to Naharbeiten.

Deel II. Analyse un Benchmarking vun de transpileerde Schaltungs

In dissen Afsnitt wiesen wi, wo wi de transpileerde Schaltung analyseert un detalleerter mit de Originalversion vergliekt. Wi konzentreert uns op Metriken as Schaltungsdeepte, Gate-Tall un Transpilationstied, üm de Effektivität vun de Optimierung to bewerden. Tosätzlich diskuteert wi, wo de Resultaten över verschedene Schaltungstypen henweg variëren künnt, un beedt Inblick in de breidere Leistung vun'n Transpiler över verschedene Szenarios henweg.

# 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

Dörchsnittliche prozentuale Reduzierung för jede Metrik. Positive sünd Verbäterungs, negative sünd Verschlechterungs.

# 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 vun'n KI-Transpiler variërt je na Oort vun de to optimierenden Schaltung erheblich. In enkelte Falls berikt he bemarkensweerte Reduzierungs vun de Schaltungsdeepte un Gate-Tall vergläken mit'n Standard-Transpiler. Disse Verbäterungs gaht aver oft mit en erhebliche Erhöhung vun de Looptied enher.

För bestimmte Schaltungstypen kann de KI-Transpiler en beten bätere Resultaten bezöglich de Schaltungsdeepte erzielen, aver ook to en Erhöhung vun de Gate-Tall un en erhebliche Looptiedstraf föhren. Disse Beobachtungs leggt nah, dat de Vördele vun'n KI-Transpiler nich bi alle Schaltungstypen eenheitlich sünd. Stattdessen hängt sien Effektivität vun de spezifischen Egenschaften vun de Schaltung af, wat em för enkelte Anwendungsfälle bäter egent maakt as för andere.

Wann schöllt Brukers KI-unnerstütt Transpilation wähln?

De KI-unnerstütt Transpiler in Qiskit glanzt in Szenarios, wo traditionelle Transpilationsmethoden Swierigkeiten hebbt, besünners bi groot anleggt un komplexe Quantenschaltungs. För Schaltungs mit Hunnerte vun Qubits oder disse, de op Hardware mit komplizeerde Coupling-Maps aftohöört, beedt de KI-Transpiler överlegen Optimierung bezöglich Schaltungsdeepte, Gate-Tall un Looptiedeffizienz. In Benchmarking-Tests hett he traditionelle Methoden konsistent överdröven un düütlich flackere Schaltungs levert un Gate-Talls reduziert, wat för de Verbäterung vun de Leistung un de Minnerung vun Ruuschen op echte Quantenhardware entscheidend is.

Brukers schöllt KI-unnerstütt Transpilation in Betracht trecken, wenn se mit:

  • Grote Schaltungs arbeiden doot, wo traditionelle Methoden den Maßstav nich effizient hanneln künnt.
  • Komplexe Hardware-Topologien, wo Gerät-konnektivität un Routing-Rutforderungs opdreedt.
  • Leistungssensitive Anwendungs, wo de Reduzierung vun de Schaltungsdeepte un de Verbäterung vun de Fidelität vun gröttste Bedüdung sünd.

Deel III. Erkunnen vun de KI-unnerstütt Permutatschonsnetzwark-Synthese

Permutatschonsnetzwarke sünd grundlegend in'n Quantencomputing, besünners för Systeme, de dör inschränkte Topologien beschränkt sünd. Disse Netzwarke erliechtern Langstreckeninteraktschonen, indem se Qubits dynamisch tauscht, üm All-to-All-Konnektivität op Hardware mit begrenzte Konnektivität natobauwen. Sülke Transformatschonen sünd för de Implementierung komplexer Quantenalgorithmen op kortfristige Geräde unerlässig, wo Interaktschonen oft över nächste Nahbern henusgaht.

In dissen Afsnitt hevt wi de Synthese vun Permutatschonsnetzwarke as överdügende Anwendung för den KI-unnerstütt Transpiler in Qiskit rut. Besünners nutzt de AIPermutationSynthesis-Pass KI-stüürt Optimierung, üm effiziente Schaltungs för Qubit-Permutatschonsopgaven to genereeren. In'n Gegensatz dorto hebbt generische Synthese-Ansätze oft Swierigkeiten, Gate-Tall un Schaltungsdeepte uttobalanzieren, besünners in Szenarios mit dichte Qubit-Interaktschonen oder bi'n Versök, volle Konnektivität to beriknen.

Wi warrt en Qiskit-Musterbispeel dörgahn, dat de Synthese vun en Permutatschonsnetzwark wiesen deit, üm All-to-All-Konnektivität för en Satz vun Qubits to beriknen. Wi warrt de Leistung vun AIPermutationSynthesis mit de Standard-Synthesemethoden in Qiskit verglieken. Dit Bispeel warrt wiesen, wo de KI-Transpiler för geringere Schaltungsdeepte un Gate-Tall optimiert un sien Vördele in praktische Quanten-Workflows ruttreckt. Üm den KI-Synthese-Pass to aktiveeren, bruukt wi de Funkschon generate_ai_pass_manager() mit den Parameter include_ai_synthesis op True sett.

Schritt 1: Klassische Ingaven op en Quantenproblem afbilden

Üm en klassisch Permutatschonsproblem op en Quantencomputer darto stellen, fangt wi mit de Definition vun de Struktur vun de Quantenschaltungs an. För dit Bispeel:

  1. Quantenschaltungs-Initialisierung: Wi wiest 27 Qubits to, üm to dat Backend to passen, dat wi bruken warrt, dat 27 Qubits hett.

  2. Permutatschonen anwenden: Wi genereert teihn tofällige Permutatschonsmusters (pattern_1 bet pattern_10) ünner Bruuk vun en fasten Seed för Reproduzeerbarkeit. Jedes Permutatschonsmuster warrt op en separate Quantenschaltung anwendt (qc_1 bet qc_10).

  3. Schaltungsupdelung: Jede Permutatschonsoperatschon warrt in native Gate-Sets updeelt, de mit de Teel-Quantenhardware kompatibel sünd. Wi analyseert de Deepte un de Tall vun de Twee-Qubit-Gates (nich-lokale Gates) för jede updeelte Schaltung.

De Resultaten geevt Inblick in de Komplexität vun de Darstellung klassische Permutatschonsprobleme op en Quantengerät un demonstreert de Ressourcenanforderungs för verschedene Permutatschonsmusters.

# 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 Utföhren op Quantenhardware optimieren

In dissen Schritt fahrt wi mit de Optimierung ünner Bruuk vun de KI-Synthese-Passes vört.

För de KI-Synthese-Passes bruukt de PassManager blots de Coupling-Map vun'n Backend. Dat is aver wichtig to beachten, dat nich alle Coupling-Maps kompatibel sünd; blots disse, op de de AIPermutationSynthesis-Pass traineert worrn is, warrt funkschoneern. Aktuell ünnerstütt de AIPermutationSynthesis-Pass Blocks vun de Grött 65, 33 un 27 Qubits. För dit Bispeel bruukt wi en 27-Qubit-QPU.

För Verglieken warrt wi de Leistung vun de KI-Synthese gegen generische Permutatschons-Synthesemethoden in Qiskit evalueren, inklusive:

  • synth_permutation_depth_lnn_kms: Disse Methode syntheseert en Permutatschonsschaltung för en linear Nächste-Nahber-(LNN)-Architektur ünner Bruuk vun'n Kutin-, Moulton- un Smithline-(KMS)-Algorithmus. Se garanteert en Schaltung mit en Deepte vun höchstens nn un en Grött vun höchstens n(n1)/2n(n-1)/2, wobei sowohl Deepte as ook Grött in Bezug op SWAP-Gates meten warrt.

  • synth_permutation_basic: Dat is en eenfache Implementierung, de Permutatschonsschaltungs syntheseert, ahn Inschränkungs för Konnektivität oder Optimierung för spezifische Architekturen optoleggen. Se deent as Basislinie för den Verglieken vun de Leistung mit vortschräden Methoden.

Jede vun disse Methoden representerrt en egen Ansatz to de Synthese vun Permutatschonsnetzwarke un beedt en ümfatend Benchmark gegen de KI-unnerstütt Methoden.

Mehr Details övern Synthesemethoden in Qiskit finnst in de Qiskit-API-Dokumentatschon.

Defineert de Coupling-Map, de de 27-Qubit-QPU representerrt.

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

Transpileert jede vun de Permutatschonsschaltungs ünner Bruuk vun de KI-Synthese-Passes un generische 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)

Tekent de Metriken (Deepte, Gate-Tall, Tied) för jede Schaltung na de Transpilation op.

# 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 Resultaten demonstreert, dat de KI-Transpiler alle andere Qiskit-Synthesemethoden för dissen Satz tofällige Permutatschonsschaltungs överdrifft. Wichtige Erkenntnisse ümfatt:

  1. Deepte: De KI-Transpiler berikt de lägste dörchsnittliche Deepte, wat op överlegen Optimierung vun Schaltungslayouts henwiesen deit.
  2. Gate-Tall: He reduziert de Tall vun de Gates vergläken mit andere Methoden erheblich un verbätert de Utföhren-Fidelität un -Effizienz.
  3. Transpilationstied: Alle Methoden löpt op disse Skala sehr gau, wat se praktisch insetzbar maakt. De KI-Transpiler hett aver en bemarkensweerte Looptiederhöhung vergläken mit traditionelle Methoden wegen de Komplexität vun de bruukte KI-Modells.

Disse Resultaten etabliert den KI-Transpiler as den effektivsten Ansatz för dissen Benchmark, besünners för Deepten- un Gate-Tall-Optimierung.

Stellt de Resultaten dar, üm de Leistung vun de KI-Synthese-Passes mit de generische Synthesemethoden to verglieken.

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

Dit Diagramm hevt de individuellen Resultaten för jede Schaltung (qc_1 bet qc_10) över verschedene Synthesemethoden henweg rut:

Wohrenddess disse Resultaten de Effektivität vun'n KI-Transpiler för Permutatschonsschaltungs ünnerstriekt, is dat wichtig, sien Inschränkungs to beachten. De KI-Synthesemethode is aktuell blots för bestimmte Coupling-Maps vörhannen, wat ehr breidere Anwendbarkeit inschränken kann. Disse Inschränkung schall bi de Bewerden vun ehr Bruuk in verschedene Szenarios berücksichticht warrn.

Insgesamt wiesen de KI-Transpiler veelverspäkende Verbäterungs in de Deepten- un Gate-Tall-Optimierung för disse spezifische Schaltungs bi verglichbare Transpilationstieden.

Schritt 3: Utföhren mit Qiskit Primitives

Wieldat sik dit Tutorial op Transpilation konzentreert, warrt keen Experimenten op dat Quantengerät utföhrt. Dat Doel is dat, de Optimierungs ut Schritt 2 to nutzen, üm en transpileerde Schaltung mit reduzeerde Deepte oder Gate-Tall to kriegen.

Schritt 4: Naharbeiten un Törüchgaav vun dat Resultat in dat wünschte klassische Format

Wieldat dar keen Utföhren för dit Notebook givt, givt dat keen Resultaten to Naharbeiten.

Tutorial-Ümfraag

Maakt mit bi disse korte Ümfraag, üm Feedback to dit Tutorial to geven. Joon Inblicken helpt uns, uns Inhaltsangebot un uns Brukerefohren to verbätern.

Link to de Ümfraag