כלי העזר של תוספי Qiskit
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
qiskit-addon-utils~=0.3.0
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-utils qiskit-ibm-runtime
חבילת כלי העזר של תוספי Qiskit היא אוסף של פונקציונליות להשלמת תהליכי עבודה הכוללים תוסף אחד או יותר של Qiskit. לדוגמה, החבילה מכילה פונקציות ליצירת המילטוניאנים, יצירת מעגלי אבולוציית זמן מסוג Trotter, ופריסה ושילוב של מעגלים קוונטיים.
התקנה
ישנן שתי דרכים להתקין את כלי העזר של תוספי Qiskit: מ-PyPI ובנייה מקוד המקור. מומלץ להתקין חבילות אלו בסביבה וירטואלית כדי להבטיח הפרדה בין תלויות החבילות.
התקנה מ-PyPI
הדרך הפשוטה ביותר להתקין את חבילת כלי העזר של תוספי Qiskit היא דרך PyPI.
pip install 'qiskit-addon-utils'
התקנה מקוד המקור
לחץ כאן לקרוא כיצד להתקין את החבילה הזו ידנית.
אם ברצונך לתרום לחבילה זו או להתקין אותה ידנית, שכפל תחילה את המאגר:
git clone git@github.com:Qiskit/qiskit-addon-utils.git
והתקן את החבילה דרך pip. אם אתה מתכנן להריץ את הדרכות שנמצאות במאגר החבילה, התקן גם את תלויות ה-notebook. אם אתה מתכנן לפתח במאגר, התקן את תלויות dev.
pip install tox jupyterlab -e '.[notebook-dependencies,dev]'
תחילת עבודה עם כלי העזר
ישנם מספר מודולים בחבילת qiskit-addon-utils, כולל אחד ליצירת בעיות לסימולציית מערכות קוונטיות, צביעת גרפים להצבת שערים במעגל קוונטי בצורה יעילה יותר, ופריסת מעגלים, שיכולה לסייע עם החזרה לאחור של אופרטורים. הסעיפים הבאים מסכמים כל מודול. תיעוד ה-API של החבילה מכיל גם הוא מידע שימושי.
יצירת בעיות
תכולת המודול qiskit_addon_utils.problem_generators כוללת:
- פונקציית
generate_xyz_hamiltonian()שמייצרת י יצוגSparsePauliOpהמודע לקישוריות של מודל XYZ מסוג איזינג:
- פונקציית
generate_time_evolution_circuit()שבונה מעגל המדמה את אבולוציית הזמן של אופרטור נתון. - שלושה אובייקטי
PauliOrderStrategyשונים לאיטרציה בין סדרי מחרוזות Pauli שונים. שימושי בעיקר בשימוש לצד צביעת גרפים, וניתן להשתמש בהם כארגומנטים גם בפונקציותgenerate_xyz_hamiltonian()וגם ב-generate_time_evolution_circuit().
צביעת גרפים
המודול qiskit_addon_utils.coloring משמש לצביעת הצלעות במפת הצימוד ולשימוש בצביעה זו כדי להציב שערים במעגל קוונטי בצורה יעילה יותר. מטרת מפת הצימוד הצבועה בצלעות היא למצוא קבוצת צבעי צלעות כך שאין שתי צלעות באותו הצבע שחולקות צומת משותפת. עבור QPU, פירוש הדבר שניתן להריץ שערים לאורך צלעות בעלות צבע זהה (חיבורי Qubit) בו-זמנית, והמעגל יבוצע מהר יותר.
כדוגמה מהירה, ניתן להשתמש בפונקציית auto_color_edges() כדי ליצור צביעת צלעות עבור מעגל נאיבי שמבצע CZGate לאורך כל חיבור Qubit. קטע הקוד שלהלן משתמש במפת הצימוד של ה-backend של FakeSherbrooke, יוצר מעגל נאיבי זה, ולאחר מכן משתמש בפונקציית auto_color_edges() כדי ליצור מעגל שקול יעיל יותר.
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit import QuantumCircuit
from qiskit_addon_utils.coloring import auto_color_edges
from qiskit_addon_utils.slicing import combine_slices, slice_by_depth
from collections import defaultdict
backend = FakeSherbrooke()
coupling_map = backend.coupling_map
# Create naive circuit
circuit = QuantumCircuit(backend.num_qubits)
for edge in coupling_map.graph.edge_list():
circuit.cz(edge[0], edge[1])
# Color the edges of the coupling map
coloring = auto_color_edges(coupling_map)
circuit_with_coloring = QuantumCircuit(backend.num_qubits)
# Make a reverse coloring dict in order to make the circuit
color_to_edge = defaultdict(list)
for edge, color in coloring.items():
color_to_edge[color].append(edge)
# Place edges in order of color
for edges in color_to_edge.values():
for edge in edges:
circuit_with_coloring.cz(edge[0], edge[1])
print(f"The circuit without using edge coloring has depth: {circuit.depth()}")
print(
f"The circuit using edge coloring has depth: {circuit_with_coloring.depth()}"
)
The circuit without using edge coloring has depth: 37
The circuit using edge coloring has depth: 3
פריסה
לבסוף, המודול qiskit-addon-utils.slicing מכיל פונקציות ומעברי Transpiler לעבודה עם יצירת "פרוסות" מעגל, חלוקות דמויות-זמן של QuantumCircuit המשתרעות על פני כל ה-Qubits. פרוסות אלו משמשות בעיקר להחזרה לאחור של אופרטורים. ארבע הדרכים העיקריות לפריסת מעגל הן לפי סוג שער, עומק, צביעה, או הוראות Barrier. הפלט של פונקציות הפריסה הללו מחזיר רשימה של אובייקטי QuantumCircuit. ניתן גם לשלב מחדש מעגלים פרוסים באמצעות פונקציית combine_slices(). קרא את מסמך API של המודול לקבלת מידע נוסף.
להלן מספר דוגמאות כיצד ליצור פרוסות אלו באמצעות המעגל הבא:
import numpy as np
from qiskit import QuantumCircuit
num_qubits = 9
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
במקרה שאין דרך ברורה לנצל את מבנה המעגל להחזרה לאחור של אופרטורים, ניתן לחלק את המעגל לפרוסות בעלות עומק נתון.
# Slice circuit into partitions of depth 1
slices = slice_by_depth(qc, 1)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
במקרים כמו ביצוע מעגלי Trotter לדמות את הדינמיקה של מערכת קוונטית, ייתכן שיהיה כדאי לפרוס לפי סוג שער.
from qiskit_addon_utils.slicing import slice_by_gate_types
slices = slice_by_gate_types(qc)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
אם עומס העבודה שלך מתוכנן לנצל את קישוריות ה-Qubit הפיזית של ה-QPU עליו הוא יורץ, ניתן ליצור פרוסות המבוססות על צביעת צלעות. קטע הקוד שלהלן יקצה צביעה בשלושה צבעים לצלעות המעגל ויפרוס את המעגל ביחס לצביעת הצלעות. (שים לב: פעולה זו משפיעה רק על שערים לא-מקומיים. שערים של Qubit יחיד יפורסו לפי סוג שער).
from qiskit_addon_utils.slicing import slice_by_coloring
# Assign a color to each set of connected qubits
coloring = {}
for i in range(num_qubits - 1):
coloring[(i, i + 1)] = i % 3
coloring[(num_qubits - 1, 0)] = 2
# Create a circuit with operations added in order of color
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
edges = [
edge for color in range(3) for edge in coloring if coloring[edge] == color
]
for edge in edges:
qc.cx(edge[0], edge[1])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
# Create slices by edge color
slices = slice_by_coloring(qc, coloring=coloring)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
אם יש לך אסטרטגיית פריסה מותאמת אישית, ניתן במקום זאת להציב מחסומים במעגל כדי לתחום היכן הוא יפורס ולהשתמש בפונקציית slice_by_barriers.
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qc.barrier()
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.barrier()
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
לאחר שהמחסומים במקום, ניתן לבחון כל אחת מהפרוסות בנפרד.
from qiskit_addon_utils.slicing import slice_by_barriers
slices = slice_by_barriers(qc)
slices[0].draw("mpl", scale=0.6)
slices[1].draw("mpl", scale=0.6)
slices[2].draw("mpl", scale=0.6)
הצעדים הבאים
- קרא את הסקירה של תוסף OBP.
- הבן כיצד תוסף SQD עובד.
- הכר את תוסף AQC-Tensor.