דלג לתוכן הראשי

מבוא לשירות Transpiler מבוסס AI של Qiskit

שימוש משוער ב-QPU: ללא (הערה: מדריך זה אינו מריץ עבודות מכיוון שהוא מתמקד ב-transpilation)

רקע

שירות Transpiler מבוסס AI של Qiskit (QTS) מציג אופטימיזציות מבוססות למידת מכונה הן ב-routing והן ב-synthesis passes. מצבי AI אלו תוכננו להתמודד עם המגבלות של transpilation מסורתית, במיוחד עבור מעגלים בקנה מידה גדול וטופולוגיות חומרה מורכבות.

החל מיולי 2025, שירות Transpiler הועבר לפלטפורמת IBM Quantum® החדשה ואינו זמין יותר. לעדכונים האחרונים על סטטוס שירות Transpiler, עיין בתיעוד שירות transpiler. עדיין תוכל להשתמש ב-AI transpiler באופן מקומי, בדומה ל-transpilation סטנדרטי של Qiskit. פשוט החלף את generate_preset_pass_manager() ב-generate_ai_pass_manager(). פונקציה זו בונה pass manager שמשלב את ה-routing וה-synthesis passes מבוססי AI ישירות לתהליך ה-transpilation המקומי שלך.

תכונות מפתח של AI passes

  • Routing passes: ניתוב מבוסס AI יכול להתאים באופן דינמי נתיבי qubit על בסיס המעגל וה-backend הספציפיים, ולהפחית את הצורך בשערי SWAP מוגזמים.

    • AIRouting: בחירת פריסה וניתוב מעגל
  • Synthesis passes: טכניקות AI מייעלות את הפירוק של שערים מרובי qubit, וממזערות את מספר השערים הדו-qubit, שהם בדרך כלל נוטים יותר לשגיאות.

    • AICliffordSynthesis: סינתזת שער Clifford
    • AILinearFunctionSynthesis: סינתזת מעגל פונקציה לינארית
    • AIPermutationSynthesis: סינתזת מעגל תמורה
    • AIPauliNetworkSynthesis: סינתזת מעגל Pauli Network (זמין רק בשירות Qiskit Transpiler, לא בסביבה מקומית)
  • השוואה עם transpilation מסורתית: ה-transpiler הסטנדרטי של Qiskit הוא כלי חזק שיכול להתמודד עם מגוון רחב של מעגלים קוונטיים באופן יעיל. עם זאת, כאשר המעגלים גדלים בקנה מידה או כאשר תצורות החומרה הופכות מורכבות יותר, AI passes יכולים להעניק רווחי אופטימיזציה נוספים. על ידי שימוש במודלים למידה עבור routing ו-synthesis, QTS ממשיך לשכלל את פריסות המעגל ולהפחית את העומס עבור משימות קוונטיות מאתגרות או בקנה מידה גדול.

מדריך זה מעריך את מצבי ה-AI תוך שימוש הן ב-routing והן ב-synthesis passes, תוך השוואת התוצאות ל-transpilation מסורתית כדי להדגיש היכן AI מציע רווחי ביצועים.

לפרטים נוספים על ה-AI passes הזמינים, עיין בתיעוד AI passes.

מדוע להשתמש ב-AI עבור transpilation של מעגלים קוונטיים?

כאשר מעגלים קוונטיים גדלים בגודל ובמורכבות, שיטות transpilation מסורתיות מתקשות לייעל פריסות ולהפחית את ספירת השערים ביעילות. מעגלים גדולים יותר, במיוחד אלה שכוללים מאות qubit, מציבים אתגרים משמעותיים על routing ו-synthesis עקב מגבלות מכשיר, קישוריות מוגבלת ושיעורי שגיאה של qubit.

כאן AI-powered transpilation מציע פתרון פוטנציאלי. על ידי מינוף טכניקות למידת מכונה, ה-AI-powered transpiler ב-Qiskit יכול לקבל החלטות חכמות יותר לגבי ניתוב qubit וסינתזת שער, מה שמוביל לאופטימיזציה טובה יותר של מעגלים קוונטיים בקנה מידה גדול.

תוצאות benchmarking תמציתיות

גרף המציג ביצועי AI transpiler מול Qiskit

במבחני benchmarking, ה-AI transpiler ייצר באופן עקבי מעגלים רדודים יותר ובאיכות גבוהה יותר בהשוואה ל-transpiler הסטנדרטי של Qiskit. לצורך מבחנים אלה השתמשנו באסטרטגיית pass manager ברירת המחדל של Qiskit, שהוגדרה עם [generate_preset_passmanager]. בעוד שאסטרטגיית ברירת המחדל היא לעתים קרובות יעילה, היא יכולה להתקשות עם מעגלים גדולים או מורכבים יותר. לעומת זאת, AI-powered passes השיגו הפחתה ממוצעת של 24% בספירת שערים דו-qubit והפחתה של 36% בעומק המעגל עבור מעגלים גדולים (100+ qubit) בעת transpilation לטופולוגיית heavy-hex של חומרת IBM Quantum. למידע נוסף על benchmarks אלה, עיין בבלוג.

מדריך זה חוקר את היתרונות המרכזיים של AI passes וכיצד הוא משתווה לשיטות מסורתיות.

# 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

דרישות

לפני תחילת מדריך זה, וודא שהדברים הבאים מותקנים:

  • Qiskit SDK v1.0 או חדש יותר, עם תמיכה בvisualization
  • Qiskit Runtime (pip install qiskit-ibm-runtime) v0.22 או חדש יותר
  • Qiskit IBM® Transpiler עם מצב AI מקומי(pip install 'qiskit-ibm-transpiler[ai-local-mode]')

הגדרה

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)

חלק I. Qiskit patterns

בואו נראה כעת כיצד להשתמש בשירות AI transpiler עם מעגל קוונטי פשוט, תוך שימוש ב-Qiskit patterns. המפתח הוא יצירת PassManager עם generate_ai_pass_manager() במקום generate_preset_pass_manager() הסטנדרטי.

שלב 1: מיפוי קלטים קלאסיים לבעיה קוונטית

בחלק זה נבחן את ה-AI transpiler על מעגל efficient_su2, ansatz יעיל לחומרה הנמצא בשימוש נרחב. מעגל זה רלוונטי במיוחד עבור אלגוריתמים קוונטיים וריאציוניים (לדוגמה, VQE) ומשימות למידת מכונה קוונטית, מה שהופך אותו למקרה בוחן אידיאלי להערכת ביצועי transpilation.

מעגל efficient_su2 מורכב משכבות מתחלפות של סיבובים של qubit בודד ושערי שזירה כמו CNOT. שכבות אלו מאפשרות חקירה גמישה של מרחב המצב הקוונטי תוך שמירה על עומק השער ניתן לניהול. על ידי אופטימיזציה של מעגל זה, אנו שואפים להפחית את ספירת השער, לשפר את הנאמנות ולמזער את הרעש. זה הופך אותו למועמד חזק לבדיקת היעילות של ה-AI 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")

פלט של תא הקוד הקודם

שלב 2: אופטימיזציה של בעיה להרצה על חומרה קוונטית

בחירת backend

לדוגמה זו, אנו בוחרים את ה-backend התפעולי הפחות עסוק של IBM Quantum שאינו סימולטור ויש לו לפחות 100 qubit:

הערה: מכיוון שה-backend הפחות עסוק יכול להשתנות לאורך זמן, מכשירים שונים עשויים להיבחר עבור הרצות שונות. מאפייני מכשיר ספציפיים, כגון מפות coupling, יכולים להוביל להבדלים במעגלים ה-transpiled.

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

יצירת pass managers של AI ומסורתיים

כדי להעריך את היעילות של ה-AI transpiler, נבצע שתי הרצות transpilation. ראשית, נבצע transpile למעגל באמצעות ה-AI transpiler. לאחר מכן, נריץ השוואה על ידי transpiling של אותו מעגל ללא ה-AI transpiler, תוך שימוש בשיטות מסורתיות. שני תהליכי ה-transpilation ישתמשו באותה מפת coupling מה-backend הנבחר ורמת האופטימיזציה תוגדר ל-3 להשוואה הוגנת.

שתי השיטות הללו משקפות את הגישה הסטנדרטית ליצירת מופעי PassManager ל-transpile מעגלים ב-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
)

ביצוע transpile למעגלים ותיעוד הזמנים.

# 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

במבחן זה, אנו משווים את הביצועים של ה-AI transpiler ושיטת ה-transpilation הסטנדרטית על מעגל efficient_su2. ה-AI transpiler משיג עומק מעגל רדוד באופן בולט תוך שמירה על ספירת שער דומה.

  • עומק מעגל: ה-AI transpiler מייצר מעגל עם עומק דו-qubit נמוך יותר. זה צפוי, מכיוון שה-AI passes מאומנים לייעל עומק על ידי למידת דפוסי אינטראקציה של qubit וניצול קישוריות חומרה בצורה יעילה יותר מאשר היוריסטיקות מבוססות כללים.

  • ספירת שער: ספירת השער הכוללת נשארת דומה בין שתי השיטות. זה תואם את הציפיות מכיוון שה-transpilation המבוסס על SABRE הסטנדרטי ממזער במפורש את ספירת swap, שמהווה את רוב עומס השער. ה-AI transpiler במקום זאת נותן עדיפות לעומק הכולל ועשוי לסחור לפעמים כמה שערים נוספים עבור נתיב הרצה קצר יותר.

  • זמן transpilation: ה-AI transpiler לוקח זמן רב יותר להרצה מאשר השיטה הסטנדרטית. זה נובע מהעלות החישובית הנוספת של קריאה למודלים למידה במהלך routing ו-synthesis. לעומת זאת, ה-SABRE-based transpiler הוא כעת מהיר משמעותית לאחר שנכתב מחדש ואופטימיזציה ב-Rust, ומספק ניתוב היוריסטי יעיל ביותר בקנה מידה.

חשוב לציין שתוצאות אלו מבוססות על מעגל אחד בלבד. כדי לקבל הבנה מקיפה כיצד ה-AI transpiler משתווה לשיטות מסורתיות, יש צורך לבדוק מגוון מעגלים. הביצועים של QTS יכולים להשתנות מאוד בהתאם לסוג המעגל המיועל. להשוואה רחבה יותר, עיין ב-benchmarks לעיל או בקר בבלוג.

שלב 3: הרצה באמצעות Qiskit primitives

מכיוון שמדריך זה מתמקד ב-transpilation, לא יבוצעו ניסויים על המכשיר הקוונטי. המטרה היא למנף את האופטימיזציות משלב 2 כדי להשיג מעגל transpiled עם עומק או ספירת שער מופחתים.

שלב 4: עיבוד לאחר והחזרת תוצאה בפורמט קלאסי רצוי

מכיוון שאין הרצה למחברת זו, אין תוצאות לעבד.

חלק II. ניתוח ו-benchmarking של המעגלים ה-transpiled

בחלק זה נדגים כיצד לנתח את המעגל ה-transpiled ולבצע benchmarking מולו מול הגרסה המקורית בפירוט רב יותר. נתמקד במדדים כמו עומק מעגל, ספירת שער וזמן transpilation כדי להעריך את היעילות של האופטימיזציה. בנוסף, נדון כיצד התוצאות עשויות להיות שונות בין סוגי מעגל שונים, ונציע תובנות לגבי הביצועים הרחבים יותר של ה-transpiler בתרחישים שונים.

# 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

אחוז הפחתה ממוצע עבור כל מדד. חיוביים הם שיפורים, שליליים הם הידרדרות.

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

פלט של תא הקוד הקודם

הביצועים של ה-AI transpiler משתנים באופן משמעותי על בסיס סוג המעגל המיועל. במקרים מסוימים, הוא משיג הפחתות ניכרות בעומק המעגל ובספירת השער בהשוואה ל-transpiler הסטנדרטי. עם זאת, שיפורים אלו מגיעים לעתים קרובות עם עלייה משמעותית בזמן הרצה.

עבור סוגים מסוימים של מעגלים, ה-AI transpiler עשוי להניב תוצאות מעט טובות יותר מבחינת עומק המעגל אך עשוי גם להוביל לעלייה בספירת השער ועונש זמן ריצה משמעותי. תצפיות אלו מצביעות על כך שהיתרונות של ה-AI transpiler אינם אחידים בכל סוגי המעגל. במקום זאת, היעילות שלו תלויה במאפיינים הספציפיים של המעגל, מה שהופך אותו למתאים יותר לחלק ממקרי השימוש מאשר לאחרים.

מתי משתמשים צריכים לבחור ב-AI-powered transpilation?

ה-AI-powered transpiler ב-Qiskit מצטיין בתרחישים שבהם שיטות transpilation מסורתיות מתקשות, במיוחד עם מעגלים קוונטיים בקנה מידה גדול ומורכבים. עבור מעגלים הכוללים מאות qubit או כאלה המכוונים לחומרה עם מפות coupling מורכבות, ה-AI transpiler מציע אופטימיזציה מעולה מבחינת עומק מעגל, ספירת שער ויעילות זמן ריצה. במבחני benchmarking, הוא הצליח באופן עקבי לעלות על שיטות מסורתיות, להעניק מעגלים רדודים משמעותית ולהפחית את ספירת השער, שהם קריטיים לשיפור ביצועים ולהקטנת רעש על חומרה קוונטית אמיתית.

משתמשים צריכים לשקול AI-powered transpilation כשעובדים עם:

  • מעגלים גדולים שבהם שיטות מסורתיות נכשלות להתמודד ביעילות עם הקנה מידה.
  • טופולוגיות חומרה מורכבות שבהן מתעוררים אתגרי קישוריות מכשיר וניתוב.
  • יישומים רגישים לביצועים שבהם הפחתת עומק מעגל ושיפור נאמנות הם בעלי חשיבות עליונה.

חלק III. חקירת סינתזת רשת תמורה מופעלת AI

רשתות תמורה הן בסיסיות במחשוב קוונטי, במיוחד עבור מערכות המוגבלות על ידי טופולוגיות מוגבלות. רשתות אלה מאפשרות אינטראקציות לטווח ארוך על ידי החלפה דינמית של qubit כדי לחקות קישוריות all-to-all על חומרה עם קישוריות מוגבלת. טרנספורמציות כאלה הן חיוניות ליישום אלגוריתמים קוונטיים מורכבים על מכשירי טווח קצר, שבהם אינטראקציות משתרעות לעתים קרובות מעבר לשכנים קרובים.

בחלק זה אנו מדגישים את הסינתזה של רשתות תמורה כמקרה שימוש משכנע עבור ה-AI-powered transpiler ב-Qiskit. באופן ספציפי, ה-AIPermutationSynthesis pass ממנף אופטימיזציה מונחית AI כדי לייצר מעגלים יעילים עבור משימות תמורת qubit. לעומת זאת, גישות סינתזה גנריות לעתים קרובות נאבקות לאזן בין ספירת שער ועומק מעגל, במיוחד בתרחישים עם אינטראקציות qubit צפופות או בעת ניסיון להשיג קישוריות מלאה.

נעבור על דוגמה של Qiskit patterns המציגה את הסינתזה של רשת תמורה כדי להשיג קישוריות all-to-all עבור קבוצת qubit. נשווה את הביצועים של AIPermutationSynthesis מול שיטות הסינתזה הסטנדרטיות ב-Qiskit. דוגמה זו תדגים כיצד ה-AI transpiler מייעל עבור עומק מעגל נמוך יותר וספירת שער, תוך הדגשת היתרונות שלו בתהליכי עבודה קוונטיים מעשיים. כדי להפעיל את ה-AI synthesis pass, נשתמש בפונקציה generate_ai_pass_manager() עם הפרמטר include_ai_synthesis מוגדר ל-True.

שלב 1: מיפוי קלטים קלאסיים לבעיה קוונטית

כדי לייצג בעיית תמורה קלאסית על מחשב קוונטי, אנו מתחילים בהגדרת המבנה של המעגלים הקוונטיים. לדוגמה זו:

  1. אתחול מעגל קוונטי: אנו מקצים 27 qubit כדי להתאים ל-backend שבו נשתמש, שיש לו 27 qubit.

  2. החלת תמורות: אנו מייצרים עשרה דפוסי תמורה אקראיים (pattern_1 עד pattern_10) תוך שימוש ב-seed קבוע לשחזוריות. כל דפוס תמורה מוחל על מעגל קוונטי נפרד (qc_1 עד qc_10).

  3. פירוק מעגל: כל פעולת תמורה מפורקת לסטים של שערים מקוריים התואמים לחומרה הקוונטית היעד. אנו מנתחים את העומק ואת מספר השערים הדו-qubit (שערים לא מקומיים) עבור כל מעגל מפורק.

התוצאות מספקות תובנה לגבי המורכבות של ייצוג בעיות תמורה קלאסיות על מכשיר קוונטי, תוך הדגמת דרישות המשאבים עבור דפוסי תמורה שונים.

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

פלט של תא הקוד הקודם

שלב 2: אופטימיזציה של בעיה להרצה על חומרה קוונטית

בשלב זה אנו ממשיכים עם אופטימיזציה תוך שימוש ב-AI synthesis passes.

עבור ה-AI synthesis passes, ה-PassManager דורש רק את מפת ה-coupling של ה-backend. עם זאת, חשוב לציין שלא כל מפות coupling תואמות; רק אלו שה-AIPermutationSynthesis pass אומן עליהן יעבדו. נכון לעכשיו, ה-AIPermutationSynthesis pass תומך בבלוקים בגדלים של 65, 33 ו-27 qubit. לדוגמה זו נשתמש ב-QPU של 27 qubit.

להשוואה, נעריך את הביצועים של AI synthesis מול שיטות סינתזת תמורה גנריות ב-Qiskit, כולל:

  • synth_permutation_depth_lnn_kms: שיטה זו מסנתזת מעגל תמורה עבור ארכיטקטורת linear nearest-neighbor (LNN) תוך שימוש באלגוריתם Kutin, Moulton, ו-Smithline (KMS). היא מבטיחה מעגל עם עומק של לכל היותר nn וגודל של לכל היותר n(n1)/2n(n-1)/2, כאשר גם עומק וגם גודל נמדדים במונחים של שערי SWAP.

  • synth_permutation_basic: זהו יישום פשוט שמסנתז מעגלי תמורה מבלי להטיל מגבלות על קישוריות או אופטימיזציה עבור ארכיטקטורות ספציפיות. הוא משמש כקו בסיס להשוואת ביצועים עם שיטות מתקדמות יותר.

כל אחת מהשיטות הללו מייצגת גישה נפרדת לסינתזת רשתות תמורה, ומספקת benchmark מקיף מול השיטות מבוססות ה-AI.

לפרטים נוספים על שיטות סינתזה ב-Qiskit, עיין בתיעוד Qiskit API. הגדרת מפת ה-coupling המייצגת QPU בן 27 qubit.

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

פלט של תא הקוד הקודם

ביצוע Transpile לכל אחד ממעגלי התמורה תוך שימוש ב-AI synthesis passes ובשיטות סינתזה גנריות.

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)

תיעוד המדדים (עומק, ספירת שער, זמן) עבור כל מעגל לאחר transpilation.

# 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

התוצאות מדגימות שה-AI transpiler מעלה על כל שיטות הסינתזה האחרות של Qiskit עבור סט זה של מעגלי תמורה אקראיים. ממצאים מרכזיים כוללים:

  1. עומק: ה-AI transpiler משיג את העומק הממוצע הנמוך ביותר, מה שמצביע על אופטימיזציה מעולה של פריסות מעגל.
  2. ספירת שער: הוא מפחית באופן משמעותי את מספר השערים בהשוואה לשיטות אחרות, תוך שיפור הנאמנות והיעילות של ההרצה.
  3. זמן transpilation: כל השיטות רצות מהר מאוד בקנה מידה זה, מה שהופך אותן למעשיות לשימוש. עם זאת, ל-AI transpiler יש עלייה ניכרת בזמן ריצה בהשוואה לשיטות מסורתיות עקב המורכבות של מודלי ה-AI בשימוש.

תוצאות אלו מבססות את ה-AI transpiler כגישה היעילה ביותר עבור benchmark זה, במיוחד עבור אופטימיזציה של עומק וספירת שער. הצגת התוצאות כדי להשוות את הביצועים של ה-AI synthesis passes מול שיטות הסינתזה הגנריות.

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

פלט של תא הקוד הקודם

גרף זה מדגיש את התוצאות האינדיבידואליות עבור כל מעגל (qc_1 עד qc_10) בשיטות סינתזה שונות:

בעוד שתוצאות אלו מדגישות את היעילות של ה-AI transpiler עבור מעגלי תמורה, חשוב לציין את המגבלות שלו. שיטת ה-AI synthesis זמינה כרגע רק עבור מפות coupling מסוימות, מה שעשוי להגביל את יכולת היישום הרחבה יותר שלה. מגבלה זו צריכה להילקח בחשבון בעת הערכת השימוש בה בתרחישים שונים.

בסך הכל, ה-AI transpiler מדגים שיפורים מבטיחים באופטימיזציה של עומק וספירת שער עבור מעגלים ספציפיים אלה תוך שמירה על זמני transpilation דומים.

שלב 3: הרצה באמצעות Qiskit primitives

מכיוון שמדריך זה מתמקד ב-transpilation, לא יבוצעו ניסויים על המכשיר הקוונטי. המטרה היא למנף את האופטימיזציות משלב 2 כדי להשיג מעגל transpiled עם עומק או ספירת שער מופחתים.

שלב 4: עיבוד לאחר והחזרת תוצאה בפורמט קלאסי רצוי

מכיוון שאין הרצה למחברת זו, אין תוצאות לעבד.

סקר מדריך

אנא מלא סקר קצר זה כדי לספק משוב על מדריך זה. התובנות שלך יעזרו לנו לשפר את תכני ההצעה וחוויית המשתמש שלנו.

קישור לסקר