מבוא לשערים שבריים
הערכת שימוש: פחות מ-30 שניות על מעבד Heron r2 (הערה: זוהי הערכה בלבד. זמן הריצה שלך עשוי להשתנות.)
רקע
שערים שבריים ב-QPU של IBM
שערים שבריים הם שערים קוונטיים מפרמטרים המאפשרים ביצוע ישיר של סיבובים בזוויות שרירותיות (בתוך גבולות ספציפיים), ומבטלים את הצורך לפרק אותם למספר שערי בסיס. על ידי ניצול האינטראקציות המקוריות בין qubits פיזיים, משתמשים יכולים ליישם יוניטרים מסוימים בצורה יעילה יותר על חומרה.
QPU של IBM Quantum® Heron תומכים בשערים השבריים הבאים:
- עבור
- עבור כל ערך ממשי
שערים אלה יכולים להפחית באופן משמעותי הן את העומק והן את המשך של מעגלים קוונטיים. הם מועילים במיוחד ביישומים המסתמכים במידה רבה על ו-, כגון סימולציה המילטונית, אלגוריתם אופטימיזציה קוונטית משוערת (QAOA), ושיטות גרעין קוונטי. במדריך זה, אנו מתמקדים בגרעין הקוונטי כדוגמה מעשית.
מגבלות
שערים שבריים הם כרגע תכונה ניסיונית ומגיעים עם כמה אילוצים:
- מוגבל לזוויות בטווח .
- שימוש בשערים שבריים אינו נתמך עבור מעגלים דינמיים, Pauli twirling, ביטול שגיאות הסתברותי (PEC), ו-אקסטרפולציה של אפס רעש (ZNE) (באמצעות הגברת שגיאות הסתברותית (PEA)).
שערים שבריים דורשים זרימת עבודה שונה בהשוואה לגישה הסטנדרטית. מדריך זה מסביר כיצד לעבוד עם שערים שבריים באמצעות יישום מעשי.
ראה את הדברים הבאים לפרטים נוספים על שערים שבריים.
סקירה
זרימת העבודה לשימוש בשערים השבריים ע וקבת בדרך כלל אחר זרימת העבודה של דפוסי Qiskit. ההבדל המרכזי הוא שכל זוויות RZZ חייבות לעמוד באילוץ . ישנן שתי גישות כדי להבטיח שתנאי זה מתקיים. מדריך זה מתמקד ומציע את הגישה השנייה.
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-basis-constructor qiskit-ibm-runtime
1. יצירת ערכי פרמטרים העומדים באילוץ זווית RZZ
אם אתה בטוח שכל זוויות RZZ נמצאות בתוך הטווח התקף, תוכל לעקוב אחר זרימת העבודה הסטנדרטית של דפוסי Qiskit. במקרה זה, אתה פשוט מגיש את ערכי הפרמטרים כחלק מ-PUB. זרימת העבודה ממשיכה כדלקמן.
pm = generate_preset_pass_manager(backend=backend, ...)
t_circuit = pm.run(circuit)
t_observable = observable.apply_layout(t_circuit.layout)
sampler.run([(t_circuit, parameter_values)])
estimator.run([(t_circuit, t_observable, parameter_values)])
אם תנסה לשלוח PUB הכולל שער RZZ עם זווית מחוץ לטווח התקף, תיתקל בהודעת שגיאה כגון:
'The instruction rzz is supported only for angles in the range [0, pi/2], but an angle (20.0) outside of this range has been requested; via parameter value(s) γ[0]=10.0, substituted in parameter expression 2.0*γ[0].'
כדי להימנע משגיאה זו, עליך לשקול את הגישה השנייה המתוארת להלן.
2. הקצאת ערכי פרמטרים למעגלים לפני טרנספילציה
חבילת qiskit-ibm-runtime מספקת מעבר טרנספיילר מיוחד בשם FoldRzzAngle.
מעבר זה הופך מעגלים קוונטיים כך שכל זוויות RZZ יעמדו באילוץ זווית RZZ.
אם אתה מספק את ה-backend ל-generate_preset_pass_manager או transpile, Qiskit מיישם אוטומטית את FoldRzzAngle למעגלים הקוונטיים.
זה דורש ממך להקצות ערכי פרמטרים למעגלים קוונטיים לפני הטרנספילציה.
זרימת העבודה ממשיכה כדלקמן.
pm = generate_preset_pass_manager(backend=backend, ...)
b_circuit = circuit.assign_parameters(parameter_values)
t_circuit = pm.run(b_circuit)
t_observable = observable.apply_layout(t_circuit.layout)
sampler.run([(t_circuit,)])
estimator.run([(t_circuit, t_observable)])
שימו לב שזרימת עבודה זו גוררת עלות חישובית גבוהה יותר מהגישה הראשונה, מכיוון שהיא כוללת הקצאת ערכי פרמטרים למעגלים קוונטיים ואחסון המעגלים המקושרים לפרמטרים באופן מקומי. בנוסף, ישנה בעיה ידועה ב-Qiskit בה השינוי של שערי RZZ עשוי להיכשל בתרחישים מסוימים. לפתרון בעיה, עיין בסעיף פתרון בעיות. מדריך זה מדגים כיצד להשתמש בשערים שבריים באמצעות הגישה השנייה דרך דוגמה בהשראת שיטת הגרעין הקוונטי. כדי להבין טוב יותר היכן גרעינים קוונטיים צפויים להיות שימושיים, אנו ממליצים לקרוא את Liu, Arunachalam & Temme (2021).
אתה יכול גם לעבוד דרך המדריך אימון גרעין קוונטי ואת השיעור גרעינים קוונטיים בקורס למידת מכונה קוונטית ב-IBM Quantum Learning.
דרישות
לפני שמתחילים מדריך זה, ודא שיש לך את הדברים הבאים מותקנים:
- Qiskit SDK v2.0 ומעלה, עם תמיכה ב-ויזואליזציה
- Qiskit Runtime v0.37 ומעלה (
pip install qiskit-ibm-runtime) - Qiskit Basis Constructor (
pip install qiskit_basis_constructor)
הגדרה
import matplotlib.pyplot as plt
import numpy as np
from qiskit import QuantumCircuit, generate_preset_pass_manager
from qiskit.circuit import ParameterVector
from qiskit.circuit.library import unitary_overlap
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
הפעלת שערים שבריים ובדיקת שערי בסיס
כדי להשתמש בשערים שבריים, תוכל להשיג backend התומך בהם על ידי הגדרת אופציה use_fractional_gates=True.
אם ה-backend תומך בשערים שבריים, תראה את rzz ו-rx רשומים בין שערי הבסיס שלו.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=133
) # backend should be a heron device or later
backend_name = backend.name
backend_c = service.backend(backend_name) # w/o fractional gates
backend_f = service.backend(
backend_name, use_fractional_gates=True
) # w/ fractional gates
print(f"Backend: {backend_name}")
print(f"No fractional gates: {backend_c.basis_gates}")
print(f"With fractional gates: {backend_f.basis_gates}")
if "rzz" not in backend_f.basis_gates:
print(f"Backend {backend_name} does not support fractional gates")
Backend: ibm_fez
No fractional gates: ['cz', 'id', 'rz', 'sx', 'x']
With fractional gates: ['cz', 'id', 'rx', 'rz', 'rzz', 'sx', 'x']
זרימת עבודה עם שערים שבריים
שלב 1: מיפוי קלטים קלאסיים לבעיה קוונטית
מעגל גרעין קוונטי
בחלק זה, אנו בוחנים את מעגל הגרעין הקוונטי באמצעות שערי RZZ כדי להציג את זרימת העבודה עבור שערים שבריים.
אנו מתחילים בבניית מעגל קוונטי לחישוב ערכים בודדים של מטריצת הגרעין. זה נעשה על ידי שילוב מעגלי מפת תכונות ZZ עם חפיפה יוניטרית. פונקציית הגרעין לוקחת וקטורים במרחב הממופה לתכונות ומחזירה את המכפלה הפנימית שלהם כערך של מטריצת הגרעין: כאשר מייצג את המצב הקוונטי הממופה לתכונות.
אנו בונים ידנית מעגל מפת תכונות ZZ באמצעות שערי RZZ.
למרות ש-Qiskit מספק zz_feature_map מובנה, הוא אינו תומך כרגע בשערי RZZ נכון ל-Qiskit v2.0.2 (ראה בעיה).
לאחר מכן, אנו מחשבים את פונקציית הגרעין עבור קלטים זהים - לדוגמה, . במחשבים קוונטיים רועשים, ערך זה עשוי להיות פחות מ-1 עקב רעש. תוצאה קרובה יותר ל-1 מצביעה על רעש נמוך יותר בביצוע. במדריך זה, אנו מתייחסים לערך זה כ-נאמנות (fidelity), המוגדרת כ-
optimization_level = 2
shots = 2000
reps = 3
rng = np.random.default_rng(seed=123)
def my_zz_feature_map(num_qubits: int, reps: int = 1) -> QuantumCircuit:
x = ParameterVector("x", num_qubits * reps)
qc = QuantumCircuit(num_qubits)
qc.h(range(num_qubits))
for k in range(reps):
K = k * num_qubits
for i in range(num_qubits):
qc.rz(x[i + K], i)
pairs = [(i, i + 1) for i in range(num_qubits - 1)]
for i, j in pairs[0::2] + pairs[1::2]:
qc.rzz((np.pi - x[i + K]) * (np.pi - x[j + K]), i, j)
return qc
def quantum_kernel(num_qubits: int, reps: int = 1) -> QuantumCircuit:
qc = my_zz_feature_map(num_qubits, reps=reps)
inner_product = unitary_overlap(qc, qc, "x", "y", insert_barrier=True)
inner_product.measure_all()
return inner_product
def random_parameters(inner_product: QuantumCircuit) -> np.ndarray:
return np.tile(rng.random(inner_product.num_parameters // 2), 2)
def fidelity(result) -> float:
ba = result.data.meas
return ba.get_int_counts().get(0, 0) / ba.num_shots
מעגלי גרעין קוונטי וערכי הפרמטרים המתאימים שלהם נוצרים עבור מערכות עם 4 עד 40 qubits, והנאמנות שלהם מוערכת לאחר מכן.
qubits = list(range(4, 44, 4))
circuits = [quantum_kernel(i, reps=reps) for i in qubits]
params = [random_parameters(circ) for circ in circuits]
מעגל ארבעת ה-qubits מוצג להלן.
circuits[0].draw("mpl", fold=-1)

בזרימת העבודה הסטנדרטית של דפוסי Qiskit, ערכי פרמטרים מועברים בדרך כלל ל-Sampler או Estimator primitive כחלק מ-PUB. עם זאת, בעת שימוש ב-backend התומך בשערים שבריים, ערכי פרמטרים אלה חייבים להיות מוקצים במפורש למעגל הקוונטי לפני הטרנספילציה.
b_qc = [
circ.assign_parameters(param) for circ, param in zip(circuits, params)
]
b_qc[0].draw("mpl", fold=-1)

שלב 2: אופטימיזציה של בעיה לביצוע על חומרה קוונטית
לאחר מכן אנו מבצעים טרנספילציה של המעגל באמצעות מנהל המעברים בהתאם לדפוס Qiskit הסטנדרטי.
על ידי מתן backend התומך בשערים שבריים ל-generate_preset_pass_manager, מעבר מיוחד בשם FoldRzzAngle נכלל אוטומטית.
מעבר זה משנה את המעגל כדי לעמוד באילוצי זווית RZZ.
כתוצאה מכך, שערי RZZ עם ערכים שליליים באיור הקודם הופכים לערכים חיוביים, וכמה שערי X נוספים מתווספים.
backend_f = service.backend(name=backend_name, use_fractional_gates=True)
# pm_f includes `FoldRzzAngle` pass
pm_f = generate_preset_pass_manager(
optimization_level=optimization_level, backend=backend_f
)
t_qc_f = pm_f.run(b_qc)
print(t_qc_f[0].count_ops())
t_qc_f[0].draw("mpl", fold=-1)
OrderedDict([('rz', 35), ('rzz', 18), ('x', 13), ('rx', 9), ('measure', 4), ('barrier', 2)])

כדי להעריך את ההשפעה של שערים שבריים, אנו מעריכים את מספר השערים הלא-מקומיים (CZ ו-RZZ עבור backend זה), יחד עם עומקי המעגלים ומשכי הזמן, ומשווים מדדים אלה לאלה מזרימת עבודה סטנדרטית מאוחר יותר.
nnl_f = [qc.num_nonlocal_gates() for qc in t_qc_f]
depth_f = [qc.depth() for qc in t_qc_f]
duration_f = [
qc.estimate_duration(backend_f.target, unit="u") for qc in t_qc_f
]
שלב 3: ביצוע באמצעות primitives של Qiskit
אנו מריצים את המעגל המטרנספל עם ה-backend התומך בשערים שבריים.
sampler_f = SamplerV2(mode=backend_f)
sampler_f.options.dynamical_decoupling.enable = True
sampler_f.options.dynamical_decoupling.sequence_type = "XY4"
sampler_f.options.dynamical_decoupling.skip_reset_qubits = True
job = sampler_f.run(t_qc_f, shots=shots)
print(job.job_id())
d4bninsi51bc738j97eg