Sari la conținutul principal

Introducere în serviciul de transpilare AI Qiskit

Utilizare estimată QPU: Nicio (NOTĂ: Acest tutorial nu execută joburi deoarece se concentrează pe transpilare)

Fundal

Serviciul de transpilare AI Qiskit (QTS) introduce optimizări bazate pe învățare automată atât în pasele de rutare, cât și în cele de sinteză. Aceste moduri AI au fost concepute pentru a aborda limitările transpilării tradiționale, în special pentru circuite la scară largă și topologii de hardware complexe.

Începând cu iulie 2025, Serviciul de Transpilare a fost migrat pe noua platformă IBM Quantum® și nu mai este disponibil. Pentru cele mai recente actualizări despre starea Serviciului de Transpilare, consultați documentația serviciului de transpilare. Poți utiliza în continuare transpilarea AI local, similar cu transpilarea standard Qiskit. Înlocuiește pur și simplu generate_preset_pass_manager() cu generate_ai_pass_manager(). Această funcție construiește un manager de pase care integrează pasele de rutare și sinteză AI direct în fluxul tău local de transpilare.

Caracteristici cheie ale paselor AI

  • Pase de rutare: rutarea bazată pe AI poate ajusta dinamic căile qubiților în funcție de circuitul și backend-ul specific, reducând nevoia de porți SWAP excesive.

    • AIRouting: Selectarea layout-ului și rutarea circuitului
  • Pase de sinteză: tehnicile AI optimizează descompunerea porților multi-qubit, minimizând numărul de porți cu doi qubiți, care sunt în general mai predispuse la erori.

    • AICliffordSynthesis: Sinteza porților Clifford
    • AILinearFunctionSynthesis: Sinteza circuitelor cu funcții liniare
    • AIPermutationSynthesis: Sinteza circuitelor de permutare
    • AIPauliNetworkSynthesis: Sinteza rețelelor Pauli (disponibilă doar în Serviciul de Transpilare Qiskit, nu în mediul local)
  • Comparație cu transpilarea tradițională: transpilarea standard Qiskit este un instrument robust care poate gestiona eficient un spectru larg de circuite cuantice. Totuși, când circuitele cresc în dimensiune sau configurațiile hardware devin mai complexe, pasele AI pot oferi câștiguri suplimentare de optimizare. Prin utilizarea modelelor învățate pentru rutare și sinteză, QTS rafinează în continuare layout-urile circuitelor și reduce overhead-ul pentru sarcini cuantice dificile sau la scară largă.

Acest tutorial evaluează modurile AI folosind atât pase de rutare, cât și de sinteză, comparând rezultatele cu transpilarea tradițională pentru a evidenția unde AI oferă câștiguri de performanță.

Pentru mai multe detalii despre pasele AI disponibile, consultați documentația paselor AI.

De ce să folosești AI pentru transpilarea circuitelor cuantice?

Pe măsură ce circuitele cuantice cresc în dimensiune și complexitate, metodele tradiționale de transpilare se confruntă cu dificultăți în optimizarea layout-urilor și reducerea eficientă a numărului de porți. Circuitele mai mari, în special cele care implică sute de qubiți, impun provocări semnificative pentru rutare și sinteză din cauza constrângerilor dispozitivelor, conectivității limitate și ratelor de eroare ale qubiților.

Tocmai aici transpilarea bazată pe AI oferă o soluție potențială. Prin valorificarea tehnicilor de învățare automată, transpilarea AI din Qiskit poate lua decizii mai inteligente privind rutarea qubiților și sinteza porților, ducând la o optimizare mai bună a circuitelor cuantice la scară largă.

Rezultate sumare ale benchmarkingului

Grafic care arată performanța transpilatorului AI față de Qiskit

În testele de benchmarking, transpilarea AI a produs în mod constant circuite mai puțin adânci și de calitate mai înaltă față de transpilarea standard Qiskit. Pentru aceste teste, am utilizat strategia implicită a managerului de pase din Qiskit, configurată cu [generate_preset_passmanager]. Deși această strategie implicită este adesea eficientă, poate să întâmpine dificultăți cu circuitele mai mari sau mai complexe. Prin contrast, pasele bazate pe AI au obținut o reducere medie de 24% a numărului de porți cu doi qubiți și o reducere de 36% a adâncimii circuitelor pentru circuitele mari (100+ qubiți) la transpilarea către topologia heavy-hex a hardware-ului IBM Quantum. Pentru mai multe informații despre aceste benchmarkuri, consultați acest blog.

Acest tutorial explorează beneficiile cheie ale paselor AI și modul în care acestea se compară cu metodele tradiționale.

# 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

Cerințe

Înainte de a începe acest tutorial, asigură-te că ai instalate următoarele:

  • Qiskit SDK v1.0 sau o versiune mai recentă, cu suport pentru vizualizare
  • Qiskit Runtime (pip install qiskit-ibm-runtime) v0.22 sau o versiune mai recentă
  • Qiskit IBM® Transpiler cu modul AI local (pip install 'qiskit-ibm-transpiler[ai-local-mode]')

Configurare

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)

Partea I. Tipare Qiskit

Să vedem acum cum se utilizează serviciul de transpilare AI cu un circuit cuantic simplu, folosind tipare Qiskit. Cheia constă în crearea unui PassManager cu generate_ai_pass_manager() în loc de standardul generate_preset_pass_manager().

Pasul 1: Mapează intrările clasice la o problemă cuantică

În această secțiune, vom testa transpilarea AI pe circuitul efficient_su2, un ansatz eficient hardware utilizat pe scară largă. Acest circuit este deosebit de relevant pentru algoritmii cuantici variaționali (de exemplu, VQE) și sarcinile de învățare automată cuantică, făcându-l un caz de test ideal pentru evaluarea performanței transpilării.

Circuitul efficient_su2 constă din straturi alternante de rotații pe un singur qubit și porți de entanglement de tipul CNOT. Aceste straturi permit explorarea flexibilă a spațiului de stări cuantice, menținând în același timp adâncimea porților la un nivel gestionabil. Prin optimizarea acestui circuit, urmărim să reducem numărul de porți, să îmbunătățim fidelitatea și să minimizăm zgomotul. Acesta este un candidat puternic pentru testarea eficienței transpilatorului AI.

# 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")

Rezultatul celulei de cod anterioare

Pasul 2: Optimizează problema pentru execuția pe hardware cuantic

Alege un backend

Pentru acest exemplu, selectăm cel mai puțin ocupat backend IBM Quantum operațional care nu este un simulator și are cel puțin 100 de qubiți:

Notă: Deoarece backend-ul cel mai puțin ocupat se poate schimba în timp, pot fi selectate dispozitive diferite pentru rulări diferite. Proprietățile specifice dispozitivului, cum ar fi hărțile de cuplare, pot duce la diferențe în circuitele transpilate.

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

Creează manageri de pase AI și tradiționali

Pentru a evalua eficacitatea transpilatorului AI, vom efectua două rulări de transpilare. Mai întâi, vom transpila circuitul folosind transpilarea AI. Apoi, vom rula o comparație prin transpilarea aceluiași circuit fără transpilarea AI, folosind metode tradiționale. Ambele procese de transpilare vor utiliza aceeași hartă de cuplare de la backend-ul ales și nivelul de optimizare setat la 3 pentru o comparație echitabilă.

Ambele metode reflectă abordarea standard pentru crearea instanțelor PassManager în vederea transpilării circuitelor în Qiskit.

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
)

Transpilează circuitele și înregistrează timpii.

# 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

În acest test, comparăm performanța transpilatorului AI și a metodei de transpilare standard pe circuitul efficient_su2. Transpilarea AI obține o adâncime a circuitului vizibil mai mică, menținând un număr similar de porți.

  • Adâncimea circuitului: Transpilarea AI produce un circuit cu o adâncime mai mică pe doi qubiți. Acest lucru este de așteptat, deoarece pasele AI sunt antrenate să optimizeze adâncimea prin învățarea tiparelor de interacțiune dintre qubiți și exploatarea mai eficientă a conectivității hardware față de euristicile bazate pe reguli.

  • Numărul de porți: Numărul total de porți rămâne similar între cele două metode. Acest lucru este în concordanță cu așteptările, deoarece transpilarea standard bazată pe SABRE minimizează explicit numărul de swap-uri, care domină overhead-ul de porți. Transpilarea AI prioritizează în schimb adâncimea globală și poate ocazional să facă un compromis cu câteva porți suplimentare pentru o cale de execuție mai scurtă.

  • Timpul de transpilare: Transpilarea AI durează mai mult decât metoda standard. Acest lucru se datorează costului computațional suplimentar al invocării modelelor învățate în timpul rutării și sintezei. Prin contrast, transpilarea bazată pe SABRE este acum semnificativ mai rapidă după ce a fost rescrisă și optimizată în Rust, oferind rutare euristică extrem de eficientă la scară.

Este important de menționat că aceste rezultate se bazează pe un singur circuit. Pentru a obține o înțelegere cuprinzătoare a modului în care transpilarea AI se compară cu metodele tradiționale, este necesar să testezi o varietate de circuite. Performanța QTS poate varia semnificativ în funcție de tipul circuitului optimizat. Pentru o comparație mai amplă, consultați benchmarkurile de mai sus sau vizitați blogul.

Pasul 3: Execută folosind primitivele Qiskit

Deoarece acest tutorial se concentrează pe transpilare, niciun experiment nu va fi executat pe dispozitivul cuantic. Scopul este de a valorifica optimizările din Pasul 2 pentru a obține un circuit transpilat cu adâncime sau număr de porți redus.

Pasul 4: Post-procesează și returnează rezultatul în formatul clasic dorit

Deoarece nu există execuție pentru acest notebook, nu există rezultate de post-procesat.

Partea II. Analizează și evaluează circuitele transpilate

În această secțiune, vom demonstra cum să analizăm circuitul transpilat și să îl evaluăm comparativ cu versiunea originală în mai mult detaliu. Ne vom concentra pe metrici precum adâncimea circuitului, numărul de porți și timpul de transpilare pentru a evalua eficacitatea optimizării. În plus, vom discuta cum pot diferi rezultatele în funcție de diferitele tipuri de circuite, oferind perspective asupra performanței mai largi a transpilatorului în scenarii variate.

# 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

Reducerea procentuală medie pentru fiecare metrică. Valorile pozitive reprezintă îmbunătățiri, cele negative reprezintă degradări.

# 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()

Rezultatul celulei de cod anterioare

Performanța transpilatorului AI variază semnificativ în funcție de tipul circuitului optimizat. În unele cazuri, obține reduceri notabile ale adâncimii circuitului și ale numărului de porți față de transpilarea standard. Totuși, aceste îmbunătățiri vin adesea cu o creștere substanțială a timpului de rulare.

Pentru anumite tipuri de circuite, transpilarea AI poate produce rezultate ușor mai bune în ceea ce privește adâncimea circuitului, dar poate conduce și la o creștere a numărului de porți și la o penalizare semnificativă a timpului de rulare. Aceste observații sugerează că beneficiile transpilatorului AI nu sunt uniforme pentru toate tipurile de circuite. În schimb, eficacitatea sa depinde de caracteristicile specifice ale circuitului, făcându-l mai potrivit pentru anumite cazuri de utilizare decât pentru altele.

Când ar trebui utilizatorii să aleagă transpilarea bazată pe AI?

Transpilerul bazat pe AI din Qiskit excelează în scenariile în care metodele tradiționale de transpilare întâmpină dificultăți, în special pentru circuite cuantice de mari dimensiuni și complexe. Pentru circuite care implică sute de qubiți sau care vizează hardware cu hărți de cuplare complexe, transpilerul AI oferă o optimizare superioară în ceea ce privește adâncimea circuitului, numărul de porți și eficiența la execuție. În testele de benchmarking, acesta a depășit în mod constant metodele tradiționale, producând circuite semnificativ mai puțin adânci și reducând numărul de porți — aspecte esențiale pentru îmbunătățirea performanței și atenuarea zgomotului pe hardware-ul cuantic real.

Utilizatorii ar trebui să ia în considerare transpilarea bazată pe AI atunci când lucrează cu:

  • Circuite mari în care metodele tradiționale nu reușesc să gestioneze eficient scala.
  • Topologii hardware complexe unde apar provocări legate de conectivitate și rutare.
  • Aplicații sensibile la performanță, unde reducerea adâncimii circuitului și îmbunătățirea fidelității sunt esențiale.

Partea III. Explorarea sintezei de rețele de permutare bazate pe AI

Rețelele de permutare sunt fundamentale în calculul cuantic, mai ales pentru sistemele constrânse de topologii restrictive. Aceste rețele facilitează interacțiunile pe distanțe mari prin schimbul dinamic de qubiți pentru a simula o conectivitate totală pe hardware cu conectivitate limitată. Astfel de transformări sunt esențiale pentru implementarea algoritmilor cuantici complecși pe dispozitivele de tip NISQ, unde interacțiunile depășesc adesea vecinii imediați.

În această secțiune, evidențiem sinteza rețelelor de permutare ca un caz de utilizare reprezentativ pentru transpilerul AI din Qiskit. Mai precis, pasul AIPermutationSynthesis utilizează optimizarea bazată pe AI pentru a genera circuite eficiente pentru sarcini de permutare a qubiților. Prin contrast, abordările de sinteză generice au adesea dificultăți în a echilibra numărul de porți cu adâncimea circuitului, mai ales în scenarii cu interacțiuni dense între qubiți sau atunci când se urmărește conectivitatea completă.

Vom parcurge un exemplu de tipare Qiskit care prezintă sinteza unei rețele de permutare pentru a obține conectivitate totală pentru un set de qubiți. Vom compara performanța AIPermutationSynthesis cu metodele standard de sinteză din Qiskit. Acest exemplu va demonstra cum transpilerul AI optimizează pentru adâncime mai mică a circuitului și număr redus de porți, evidențiindu-și avantajele în fluxurile de lucru cuantice practice. Pentru a activa pasul de sinteză AI, vom folosi funcția generate_ai_pass_manager() cu parametrul include_ai_synthesis setat la True.

Pasul 1: Maparea intrărilor clasice la o problemă cuantică

Pentru a reprezenta o problemă de permutare clasică pe un calculator cuantic, începem prin definirea structurii circuitelor cuantice. Pentru acest exemplu:

  1. Inițializarea circuitului cuantic: Alocăm 27 de qubiți pentru a corespunde backend-ului pe care îl vom folosi, care are 27 de qubiți.

  2. Aplicarea permutărilor: Generăm zece tipare de permutare aleatoare (pattern_1 până la pattern_10) folosind o sămânță fixă pentru reproductibilitate. Fiecare tipar de permutare este aplicat unui circuit cuantic separat (qc_1 până la qc_10).

  3. Descompunerea circuitului: Fiecare operație de permutare este descompusă în seturi de porți native compatibile cu hardware-ul cuantic țintă. Analizăm adâncimea și numărul de porți cu doi qubiți (porți nelocale) pentru fiecare circuit descompus.

Rezultatele oferă o perspectivă asupra complexității reprezentării problemelor de permutare clasice pe un dispozitiv cuantic, demonstrând cerințele de resurse pentru diferite tipare de permutare.

# 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

Pasul 2: Optimizarea problemei pentru execuția pe hardware cuantic

În acest pas, continuăm cu optimizarea folosind pasurile de sinteză AI.

Pentru pasurile de sinteză AI, PassManager necesită doar harta de cuplare a backend-ului. Totuși, este important de reținut că nu toate hărțile de cuplare sunt compatibile; vor funcționa doar cele pe care pasul AIPermutationSynthesis a fost antrenat. În prezent, pasul AIPermutationSynthesis suportă blocuri de dimensiunile 65, 33 și 27 de qubiți. Pentru acest exemplu folosim un QPU de 27 de qubiți.

Pentru comparație, vom evalua performanța sintezei AI față de metodele generice de sinteză a permutărilor din Qiskit, inclusiv:

  • synth_permutation_depth_lnn_kms: Această metodă sintetizează un circuit de permutare pentru o arhitectură liniară cu vecini imediați (LNN) folosind algoritmul Kutin, Moulton și Smithline (KMS). Garantează un circuit cu o adâncime de cel mult nn și o dimensiune de cel mult n(n1)/2n(n-1)/2, unde atât adâncimea cât și dimensiunea sunt măsurate în termeni de porți SWAP.

  • synth_permutation_basic: Aceasta este o implementare directă care sintetizează circuite de permutare fără a impune constrângeri privind conectivitatea sau optimizarea pentru arhitecturi specifice. Servește ca referință pentru compararea performanței cu metode mai avansate.

Fiecare dintre aceste metode reprezintă o abordare distinctă pentru sinteza rețelelor de permutare, oferind un benchmark cuprinzător față de metodele bazate pe AI.

Pentru mai multe detalii despre metodele de sinteză din Qiskit, consultați documentația API Qiskit. Definește harta de cuplare reprezentând QPU-ul de 27 de qubiți.

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

Transpilează fiecare circuit de permutare folosind pasurile de sinteză AI și metodele generice de sinteză.

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)

Înregistrează metricile (adâncime, număr de porți, timp) pentru fiecare circuit după transpilare.

# 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

Rezultatele demonstrează că transpilerul AI depășește toate celelalte metode de sinteză din Qiskit pentru acest set de circuite de permutare aleatoare. Concluziile principale includ:

  1. Adâncime: Transpilerul AI obține cea mai mică adâncime medie, indicând o optimizare superioară a layout-urilor de circuit.
  2. Număr de porți: Reduce semnificativ numărul de porți față de alte metode, îmbunătățind fidelitatea execuției și eficiența.
  3. Timp de transpilare: Toate metodele rulează foarte rapid la această scară, ceea ce le face practice pentru utilizare. Totuși, transpilerul AI are o creștere notabilă a timpului de execuție față de metodele tradiționale, datorită complexității modelelor AI folosite.

Aceste rezultate stabilesc transpilerul AI ca cea mai eficientă abordare pentru acest benchmark, în special pentru optimizarea adâncimii și a numărului de porți. Vizualizează rezultatele pentru a compara performanța pasurilor de sinteză AI față de metodele generice de sinteză.

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

Acest grafic evidențiază rezultatele individuale pentru fiecare circuit (qc_1 până la qc_10) în cadrul diferitelor metode de sinteză:

Deși aceste rezultate subliniază eficacitatea transpilerului AI pentru circuitele de permutare, este important să se țină cont de limitările sale. Metoda de sinteză AI este disponibilă în prezent doar pentru anumite hărți de cuplare, ceea ce îi poate restricționa aplicabilitatea mai largă. Această constrângere trebuie avută în vedere la evaluarea utilizării sale în scenarii diferite.

În general, transpilerul AI demonstrează îmbunătățiri promițătoare în optimizarea adâncimii și a numărului de porți pentru aceste circuite specifice, menținând în același timp timpi de transpilare comparabili.

Pasul 3: Execuția folosind primitivele Qiskit

Deoarece acest tutorial se axează pe transpilare, nu vor fi executate experimente pe dispozitivul cuantic. Scopul este de a valorifica optimizările din Pasul 2 pentru a obține un circuit transpilat cu adâncime sau număr de porți redus.

Pasul 4: Post-procesarea și returnarea rezultatului în formatul clasic dorit

Deoarece nu există execuție pentru acest notebook, nu există rezultate de post-procesat.

Sondaj tutorial

Te rog să completezi acest scurt sondaj pentru a oferi feedback despre acest tutorial. Opiniile tale ne vor ajuta să îmbunătățim conținutul și experiența utilizatorilor.

Link către sondaj

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.