ייצוג מחשבים קוונטיים עבור ה-Transpiler
Package versions
The code on this page was developed using the following requirements. We recommend using these versions or newer.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
כדי להמיר Circuit מופשט ל-Circuit ISA שיכול לרוץ על QPU ספציפי (יחידת עיבוד קוונטי), ה-Transpiler זקוק למידע מסוים על ה-QPU. מידע זה נמצא בשני מקומות: אובייקט BackendV2 (או BackendV1 הישן) שאתה מתכנן להגיש אליו עבודות, ותכונת ה-Target של ה-Backend.
- ה-
Targetמכיל את כל האילוצים הרלוונטיים של מכשיר, כגון Gate הבסיסיים הטבעיים שלו, קישוריות Qubit, ומידע פולס או תזמון. - ה-
BackendמחזיקTargetכברירת מחדל, מכיל מידע נוסף -- כגוןInstructionScheduleMap, ומספק את הממשק להגשת עבודות Circuit קוונטי.
תוכל גם לספק מידע במפורש עבור ה-Transpiler לשימוש, לדוגמה, אם יש לך מקרה שימוש ספציפי, או אם אתה מאמין שמידע זה יסייע ל-Transpiler לייצר Circuit מאופטם יותר.
הדיוק שבו ה-Transpiler מייצר את ה-Circuit המתאים ביותר לחומרה ספציפית תלוי בכמה מידע יש ל-Target או ל-Backend על האילוצים שלהם.
מכיוון שאלגוריתמים רבים מהאלגוריתמים הבסיסיים של הקומפילציה הם סטוכסטיים, אין ערובה שיימצא Circuit טוב יותר.
דף זה מציג מספר דוגמאות של העברת מידע QPU ל-Transpiler. דוגמאות אלו משתמשות ב-target מה-Backend המדומה FakeSherbrooke.
תצורת ברירת מחדל
השימוש הפשוט ביותר ב-Transpiler הוא לספק את כל מידע ה-QPU על ידי מתן ה-Backend או Target. כדי להבין טוב יותר כיצד ה-Transpiler עובד, בנה Circuit ועבד אותו עם מידע שונה, כדלקמן.
ייבא את הספריות הנדרשות ואתחל את ה-QPU:
כדי להמיר Circuit מופשט ל-Circuit ISA שיכול לרוץ על מעבד ספציפי, ה-Transpiler זקוק למידע מסוים על המעבד. בדרך כלל, מידע זה מאוחסן ב-Backend או ב-Target שסופק ל-Transpiler, ואין צורך במידע נוסף. עם זאת, תוכל גם לספק מידע במפורש עבור ה-Transpiler לשימוש, לדוגמה, אם יש לך מקרה שימוש ספציפי, או אם אתה מאמין שמידע זה יסייע ל-Transpiler לייצר Circuit מאופטם יותר.
נושא זה מציג מספר דוגמאות של העברת מידע ל-Transpiler. דוגמאות אלו משתמשות ב-target מה-Backend המדומה FakeSherbrooke.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
ה-Circuit לדוגמה משתמש במופע של efficient_su2 מספריית ה-Circuit של Qiskit.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")
דוגמה זו משתמשת בהגדרות ברירת מחדל לעיבוד ל-target של ה-backend, המספקת את כל המידע הדרוש להמרת ה-Circuit לכזה שיפעל על ה-Backend.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)
דוגמה זו משמשת בסעיפים מאוחרים יותר של נושא זה להמחשה שמפת הקישוריות ו-Gate הבסיס הם מקטעי המידע החיוניים להעביר ל-Transpiler לבנייה אופטימלית של Circuit. ה-QPU יכול בדרך כלל לבחור הגדרות ברירת מחדל למידע אחר שאינו מועבר, כגון תזמון ולוח זמנים.
מפת קישוריות
מפת הקישוריות היא גרף המראה אילו Qubit מחוברים ולכן יש ביניהם Gate דו-Qubit. לפעמים גרף זה הוא כיווני, כלומר Gate דו-Qubit יכולים לנוע רק בכיוון אחד. עם זאת, ה-Transpiler תמיד יכול להפוך את כיוון ה-Gate על ידי הוספת Gate חד-Qubit נוספים. Circuit קוונטי מופשט תמיד יכול להיות מיוצג על גרף זה, גם אם הקישוריות שלו מוגבלת, על ידי הצגת Gate SWAP להזזת המידע הקוונטי.
ה-Qubit מה-Circuits המופשטים שלנו נקראים Qubit וירטואליים ואלה שבמפת הקישוריות הם Qubit פיזיים. ה-Transpiler מספק מיפוי בין Qubit וירטואליים לפיזיים. אחד הצעדים הראשונים בקומפילציה, שלב ה-layout, מבצע מיפוי זה.
למרות ששלב הניתוב שזור עם שלב ה-layout — הבוחר את ה-Qubit בפועל — כברירת מחדל, נושא זה מתייחס אליהם כשלבים נפרדים לפשטות. השילוב של ניתוב ו-layout נקרא מיפוי Qubit. למד עוד על שלבים אלה בנושא שלבי Transpiler.
העבר את ארגומנט המילה המפתח coupling_map כדי לראות את השפעתו על ה-Transpiler:
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)
כפי שמוצג לעיל, הוכנסו מספר Gate SWAP (כל אחד מורכב משלושה Gate CX), מה שיגרום לשגיאות רבות במכשירים הנוכחיים. כדי לראות אילו Qubit נבחרים בטופולוגיית Qubit בפועל, השתמש ב-plot_circuit_layout מ-Qiskit Visualizations:
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")
זה מראה שה-Qubit הווירטואלי 0-11 שלנו מוּפּו בצורה טריוויאלית לשורת Qubit פיזיים 0-11. בואו נחזור לברירת המחדל (optimization_level=1), המשתמשת ב-VF2Layout אם נדרש ניתוב כלשהו.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)
כעת אין Gate SWAP שהוכנסו וה-Qubit הפיזיים שנבחרו זהים לאלה בעת השימוש במחלקת target.
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")
כעת ה-layout הוא בצורת טבעת. מכיוון ש-layout זה מכבד את הקישוריות של ה-Circuit, אין Gate SWAP, מה שמספק Circuit הרבה יותר טוב לביצוע.
Gate בסיס
כל מחשב קוונטי תומך בסט הוראות מוגבל, הנקרא Gate הבסיס שלו. כל Gate ב-Circuit חייב להיות מתורגם לאלמנטים של סט זה. סט זה צריך להיות מורכב מ-Gate חד- ודו-Qubit המספקים סט Gate אוניברסלי, כלומר כל פעולה קוונטית ניתנת לפירוק לאותם Gate. זה נעשה על ידי BasisTranslator, וניתן לציין את Gate הבסיס כארגומנט מילת מפתח ל-Transpiler לספק מידע זה.
basis_gates = list(target.operation_names)
print(basis_gates)
['sx', 'switch_case', 'x', 'if_else', 'measure', 'for_loop', 'delay', 'ecr', 'id', 'reset', 'rz']
ה-Gate חד-Qubit ברירת המחדל על ibm_sherbrooke הם rz, x, ו-sx, וה-Gate דו-Qubit ברירת המחדל הוא ecr (echoed cross-resonance). Gate CX בנויים מ-Gate ecr, לכן על חלק מה-QPU ecr מצוין כ-Gate הבסיס דו-Qubit, בעוד על אחרים cx הוא ברירת המחדל. Gate ה-ecr הוא החלק המשזר של Gate ה-cx. בנוסף ל-Gate הבקרה, ישנן גם הוראות delay ומדידה.
ל-QPU יש Gate בסיס ברירת מחדל, אך תוכל לבחור כל Gate שתרצה, כל עוד אתה מספק את ההוראה או מוסיף Gate פולס (ראה יצירת מעברי Transpiler.) Gate הבסיס ברירת המחדל הם אלה שכיול בוצע עליהם ב-QPU, לכן אין צורך לספק הוראות/Gate פולס נוספים. לדוגמה, על חלק מה-QPU cx הוא ה-Gate דו-Qubit ברירת המחדל ו-ecr על אחרים. ראה את רשימת ה-Gate ופעולות ילידיות אפשריות לפרטים נוספים.
pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)
שים לב שאובייקטי CXGate פורקו ל-Gate ecr ו-Gate בסיס חד-Qubit.
שיעורי שגיאת מכשיר
מחלקת Target יכולה להכיל מידע על שיעורי השגיאה לפעולות על המכשיר.
לדוגמה, הקוד הבא מאחזר את המאפיינים עבור Gate echoed cross-resonance (ECR) בין Qubit 1 ל-0 (שים לב שה-Gate ECR הוא כיווני):
target["ecr"][(1, 0)]
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
הפלט מציג את משך ה-Gate (בשניות) ואת שיעור השגיאה שלו. כדי לחשוף מידע שגיאה ל-Transpiler, בנה מודל target עם basis_gates ו-coupling_map מלעיל ואכלס אותו בערכי שגיאה מ-Backend FakeSherbrooke.
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp
err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)
for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)
עבד עם ה-target החדש שלנו err_targ כ-target:
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)
מכיוון שה-target כולל מידע שגיאה, המעבר VF2PostLayout מנסה למצוא את ה-Qubit האופטימליים לשימוש, וכתוצאה מכך אותו Circuit שנמצא במקור עם אותם Qubit פיזיים.
הצעדים הבאים
- הבן את הגדרות ברירת מחדל של Transpilation ואפשרויות תצורה.
- עיין בנושא פרמטרים נפוצים לשימוש ב-Transpilation.
- נסה את המדריך השווה הגדרות Transpiler.
- ראה את תיעוד ה-API של Transpile.