דלג לתוכן הראשי
פרויקט זה בשלב בטא. מצאת באג? פתח issue ב-GitHub. יש שאלה או רעיון? שאל ב-Discussions — נשמח לשמוע ממך!
מה איכות התרגום בדף זה?

יצירת pass manager עבור decoupling דינמי

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

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

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0

דף זה מדגים כיצד להשתמש במעבר PadDynamicalDecoupling כדי להוסיף למעגל טכניקת דיכוי שגיאות בשם dynamical decoupling.

decoupling דינמי פועל על ידי הוספת רצפי פולסים (הידועים בשם רצפי decoupling דינמי) לקיוביטים במצב סרק כדי להפוך אותם סביב כדור בלוך, מה שמבטל את השפעת ערוצי הרעש, ובכך מדכא decoherence. רצפי פולסים אלה דומים לפולסי מיקוד מחדש שמשמשים בתהודה מגנטית גרעינית. לתיאור מלא, ראה A Quantum Engineer's Guide to Superconducting Qubits.

מכיוון שהמעבר PadDynamicalDecoupling פועל רק על מעגלים מתוזמנים וכולל שערים שאינם בהכרח שערי בסיס של ה-target שלנו, תזדקק גם למעברים ALAPScheduleAnalysis ו-BasisTranslator.

קבל את מידע ה-target מה-backend ושמור את שמות הפעולות בתור basis_gates מכיוון שיהיה צורך לשנות את ה-target כדי להוסיף מידע תזמון עבור השערים שבשימוש ב-decoupling דינמי.

הערה

ה-Backend המדומה FakeSherbrooke מ-qiskit_ibm_runtime משמש בדוגמאות אלה, אך תוכלו לנסות אותו על כל Backend אמיתי או מדומה התואם ל-Qiskit. התוצאות שלכם עשויות להיות שונות.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()

target = backend.target
basis_gates = list(target.operation_names)

צור מעגל efficient_su2 כדוגמה. ראשית, בצע טרנספילציה למעגל אל ה-backend מכיוון שפולסי decoupling דינמי צריכים להתווסף לאחר שהמעגל עבר טרנספילציה ותזמון. decoupling דינמי לרוב עובד הכי טוב כשיש הרבה זמן סרק במעגלים הקוונטיים - כלומר, יש קיוביטים שאינם בשימוש בזמן שאחרים פעילים. זה המצב במעגל זה מכיוון ששערי ecr הדו-קיוביטיים מיושמים ברצף באנזץ זה.

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

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

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

בגלל התזמון הקבוע של רצפי decoupling דינמי, יש להוסיף מידע על YGate ל-target מכיוון שהוא לא שער בסיס, בעוד ש-XGate כן. אנחנו יודעים מראש של-YGate יש אותו משך זמן ואותה שגיאה כמו ל-XGate, לכן אפשר פשוט לאחזר את המאפיינים האלה מה-target ולהוסיף אותם בחזרה עבור אובייקטי YGate. זו גם הסיבה ש-basis_gates נשמרו בנפרד, מכיוון שאנחנו מוסיפים את ההוראה YGate ל-target למרות שהיא לא שער בסיס בפועל של ibm_fez.

from qiskit.transpiler import InstructionProperties

y_gate_properties = {}
for qubit in range(target.num_qubits):
y_gate_properties.update(
{
(qubit,): InstructionProperties(
duration=target["x"][(qubit,)].duration,
error=target["x"][(qubit,)].error,
)
}
)

target.add_instruction(YGate(), y_gate_properties)

מעגלי אנזץ כמו efficient_su2 הם פרמטריים, כך שצריך לקשור אליהם ערכים לפני שליחתם ל-backend. כאן, הקצה פרמטרים אקראיים.

import numpy as np

rng = np.random.default_rng(1234)
qc_t.assign_parameters(
rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)

בשלב הבא, הרץ את המעברים המותאמים אישית. צור מופע של PassManager עם ALAPScheduleAnalysis ו-PadDynamicalDecoupling. הרץ תחילה את ALAPScheduleAnalysis כדי להוסיף מידע תזמון על המעגל הקוונטי לפני שאפשר להוסיף את רצפי decoupling הדינמי המרווחים באופן קבוע. מעברים אלה מורצים על המעגל באמצעות .run().

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)

dd_pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)
qc_dd = dd_pm.run(qc_t)

השתמש בכלי ההדמיה timeline_drawer כדי לראות את התזמון של המעגל ולוודא שרצף מרווח באופן קבוע של אובייקטי XGate ואובייקטי YGate מופיע במעגל.

from qiskit.visualization import timeline_drawer

timeline_drawer(qc_dd, idle_wires=False, target=target)

Output of the previous code cell

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

from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator

qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

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

צעדים הבאים​

המלצות