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

פרמטרים נפוצים לטרנספילציה

גרסאות חבילות

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

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

דף זה מתאר כמה מהפרמטרים הנפוצים יותר לטרנספילציה מקומית. פרמטרים אלו מוגדרים באמצעות ארגומנטים ל-generate_preset_pass_manager או ל-transpile.

מידת הקירוב

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

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

כאשר מידת הקירוב קטנה מ-1.0, עלולים להיוצר מעגלים עם שער CX אחד או שניים, מה שמוביל לפחות שגיאה מהחומרה, אך יותר שגיאה מהקירוב. מכיוון ש-CX הוא השער היקר ביותר מבחינת שגיאה, ייתכן שיהיה כדאי להפחית את מספרם על חשבון הנאמנות בסינתזה (טכניקה זו שימשה להגדלת הנפח הקוונטי על מכשירי IBM®: Validating quantum computers using randomized model circuits).

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

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import random_unitary
from qiskit.transpiler import generate_preset_pass_manager

UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)

qubits = QuantumRegister(2, name="q")
qc = QuantumCircuit(qubits)
qc.append(rand_U, qubits)
pass_manager = generate_preset_pass_manager(
optimization_level=1,
approximation_degree=0.85,
basis_gates=["sx", "rz", "cx"],
)
approx_qc = pass_manager.run(qc)
print(approx_qc.count_ops()["cx"])
2

תוצאה זו היא 2 כי הקירוב דורש פחות שערי CX.

זרע מחולל המספרים האקראיים

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

דוגמה:

pass_manager = generate_preset_pass_manager(
optimization_level=1, seed_transpiler=11, basis_gates=["sx", "rz", "cx"]
)
optimized_1 = pass_manager.run(qc)
optimized_1.draw("mpl")

Output of the previous code cell

פריסה ראשונית

לפני הטרנספילציה, ה-Qubitים הכלולים במעגל שלך הם Qubitים וירטואליים שאינם בהכרח תואמים ל-Qubitים פיזיים ב-Backend היעד. ניתן לציין את המיפוי הראשוני של Qubitים וירטואליים ל-Qubitים פיזיים באמצעות הארגומנט initial_layout. שים לב שפריסת ה-Qubit הסופית עשויה להיות שונה מהפריסה הראשונית מכיוון שהטרנספיילר עשוי לסדר מחדש Qubitים באמצעות שערי swap או אמצעים אחרים.

בדוגמה הבאה, אנו בונים פריסה ראשונית ל-Backend המדומה FakeSherbrooke על ידי יצירת אובייקט Layout. הפריסה שלנו ממפה את ה-Qubit הראשון של המעגל שלנו ל-Qubit 5 של Sherbrooke, ואת ה-Qubit השני של המעגל שלנו ל-Qubit 6 של Sherbrooke. שים לב ש-Qubitים פיזיים מיוצגים תמיד על ידי מספרים שלמים.

from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit.transpiler import Layout

backend = FakeSherbrooke()

a, b = qubits
initial_layout = Layout({a: 5, b: 6})

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Output of the previous code cell

בנוסף לציון אובייקט Layout, אפשר גם להעביר רשימה של מספרים שלמים, שבה האיבר ה-ii של הרשימה מכיל את ה-Qubit הפיזי שאליו יש למפות את ה-Qubit ה-ii. לדוגמה:

initial_layout = [5, 6]

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Output of the previous code cell

אפשר להשתמש בפונקציה plot_error_map כדי ליצור תרשים של גרף המכשיר עם מידע על שגיאות ועם ה-Qubitים הפיזיים מסומנים. אפשר גם לצפות בתרשימים דומים בדף Compute resources.

from qiskit.visualization import plot_error_map

plot_error_map(backend, figsize=(30, 24))

Output of the previous code cell

אפשרויות שלב ופלאגין של הטרנספיילר

אפשרויות אלו מסתיימות בסיומת _method. הן משפיעות על אופן פעולת הטרנספיילר ומשמשות לניסיון לקבל פלט טוב יותר, שונה, או ספציפי מהטרנספיילר.

  • init_method (str) - הפלאגין לשימוש בשלב האתחול.

  • layout_method (str) - ה-pass לבחירת פריסה (trivial, dense, sabre). יכול להיות גם שם הפלאגין החיצוני לשימוש בשלב הפריסה.

  • optimization_method (str) - הפלאגין לשימוש בשלב האופטימיזציה.

  • routing_method (str) - שם ה-pass לניתוב (basic, lookahead, default, sabre, none). יכול להיות גם שם הפלאגין החיצוני לשימוש בשלב הניתוב.

  • scheduling_method (str) - שם ה-pass לתזמון. יכול להיות גם שם הפלאגין החיצוני לשימוש בשלב התזמון.

    • as_soon_as_possible: תזמן הוראות באופן חמדני: מוקדם ככל האפשר על משאב Qubit (כינוי: asap).
    • as_late_as_possible: תזמן הוראות מאוחר. כלומר, שמור את ה-Qubitים במצב היסוד כשאפשר (כינוי: alap).
  • translation_method (str) - שם ה-pass לתרגום (unroller, translator, synthesis). יכול להיות גם שם הפלאגין החיצוני לשימוש בשלב התרגום.

  • unitary_synthesis_method (str) - שם שיטת סינתזת היוניטרי לשימוש. כברירת מחדל, נעשה שימוש ב-default.

הערה

כדי לראות רשימה של כל הפלאגינים המותקנים לשלב מסוים, הרץ list_stage_plugins("stage_name"). לדוגמה, אם רוצים לראות רשימה של כל הפלאגינים המותקנים לשלב הניתוב, הרץ list_stage_plugins(routing).

הצעדים הבאים