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

QESEM: פונקציית Qiskit מאת Qedma

ראה את תיעוד ה-API

גרסאות חבילה

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

qiskit[all]~=2.5.0
qiskit-ibm-runtime~=0.47.0
הערה

Qiskit Functions הן תכונה ניסיונית הזמינה רק למשתמשי IBM Quantum® Premium Plan, Flex Plan ו-On-Prem (דרך IBM Quantum Platform API) Plan. הן נמצאות בשלב טרום-הוצאה לשוק וכפופות לשינויים.

סקירה כללית​

בעוד שיחידות עיבוד קוונטיות השתפרו מאוד בשנים האחרונות, שגיאות הנובעות מרעש ופגמים בחומרה הקיימת נותרות אתגר מרכזי עבור מפתחי אלגוריתמים קוונטיים. ככל שהתחום מתקרב לחישובים קוונטיים בקנה מידה של תועלת שלא ניתן לאמת קלאסית, פתרונות לביטול רעש בדיוק מובטח הופכים חשובים יותר ויותר. כדי להתגבר על אתגר זה, Qedma פיתחה את Quantum Error Mitigation (QESEM), המשולב בצורה חלקה ב-IBM Quantum Platform כ-פונקציית Qiskit.

עם QESEM, משתמשים יכולים להריץ את ה-Circuits הקוונטיים שלהם על QPUs רועשים ולקבל תוצאות מדויקות ללא שגיאות עם תקורות זמן QPU יעילות ביותר, קרוב לגבולות היסודיים. כדי להשיג זאת, QESEM מנצל חבילה של שיטות קנייניות שפותחו על ידי Qedma לאפיון והפחתת שגיאות. טכניקות הפחתת שגיאות כוללות אופטימיזציית Gate, Transpilation מודע לרעש, דיכוי שגיאות (ES) ומיתון שגיאות לא מוטה (EM). עם שילוב שיטות מבוססות-אפיון אלו, משתמשים יכולים להשיג תוצאות אמינות ללא שגיאות עבור Circuits קוונטיים גדולים וגנריים, ולפתוח יישומים שלא ניתן להשיגם אחרת.

לתיאור מלא של הרכיבים הבסיסיים, כמו גם הדגמה בקנה מידה של תועלת, ראה במאמר Reliable high-accuracy error mitigation for utility-scale quantum circuits.

תיאור​

תוכל להשתמש בפונקציית QESEM של Qedma כדי להעריך ולבצע בקלות את ה-Circuits שלך עם דיכוי ומיתון שגיאות, תוך השגת נפחי Circuit גדולים יותר ודיוק גבוה יותר. לשימוש ב-QESEM, עליך לספק Circuit קוונטי, קבוצה של observables למדידה, דיוק סטטיסטי יעד לכל observable, ו-QPU שנבחר. לפני הרצת ה-Circuit לדיוק היעד, תוכל להעריך את זמן ה-QPU הנדרש בהתבסס על חישוב אנליטי שאינו מחייב ביצוע Circuit. לאחר שתהיה מרוצה מהערכת זמן ה-QPU, תוכל להריץ את ה-Circuit עם QESEM.

כאשר אתה מריץ מעגל, QESEM מבצע פרוטוקול אפיון מכשיר המותאם למעגל שלך, ומניב מודל רעש אמין עבור השגיאות המתרחשות במעגל. בהתבסס על האפיון, QESEM מיישם תחילה Transpilation מודע לרעש כדי למפות את מעגל הקלט על קבוצת qubits ושערים פיזיים, אשר ממזערת את הרעש המשפיע על ה-observable היעד. אלה כוללים את השערים הזמינים באופן מקורי (CX/CZ על מכשירי IBM®), כמו גם שערים נוספים שעברו אופטימיזציה על ידי QESEM, ויוצרים את מערך השערים המורחב של QESEM. לאחר מכן QESEM מריץ קבוצה של מעגלי ES ו-EM מבוססי-אפיון על ה-QPU ואוסף את תוצאות המדידה שלהם. אלה עוברים לאחר מכן עיבוד קלאסי כדי לספק ערך תוחלת לא מוטה ופס שגיאה לכל observable, המתאים לדיוק המבוקש.

סקירת Qedma QESEM QESEM הוכח כמספק תוצאות בדיוק גבוה עבור מגוון יישומים קוונטיים ובנפחי Circuit הגדולים ביותר הניתנים להשגה כיום. QESEM מציע את התכונות הבאות הפונות למשתמש, המוצגות בסעיף הבנצ'מרקים להלן:

  • דיוק מובטח: QESEM מפיק הערכות לא מוטות לערכי ציפייה של observables. שיטת ה-EM שלו מצוידת בערבויות תיאורטיות, אשר - יחד עם האפיון החדשני של Qedma - מבטיחות שהמיתון מתכנס לפלט Circuit ללא רעש עד לדיוק המוגדר על ידי המשתמש. בניגוד לשיטות EM היוריסטיות רבות הנוטות לשגיאות שיטתיות או הטיות, הדיוק המובטח של QESEM חיוני להבטחת תוצאות אמינות ב-Circuits ו-observables גנריים.
  • מדרגיות ל-QPUs גדולים: זמן ה-QPU של QESEM תלוי בנפחי Circuit, אך אינו תלוי במספר ה-Qubits. Qedma הדגים את QESEM על המכשירים הקוונטיים הגדולים ביותר הזמינים כיום, כולל IBM Quantum Eagle בן 127 qubit ומכשירי Heron בני 133 qubit.
  • אגנוסטי ליישום: QESEM הוכח על מגוון יישומים, כולל סימולציית Hamiltonian, VQE, QAOA ואמידת משרעת. משתמשים יכולים להזין כל Circuit קוונטי ו-observable למדידה, ולקבל תוצאות מדויקות ללא שגיאות. המגבלות היחידות נקבעות על ידי מפרטי החומרה וזמן ה-QPU המוקצה, הקובעים את נפחי ה-Circuit הנגישים ואת דיוק הפלט. בניגוד לכך, פתרונות הפחתת שגיאות רבים ספציפיים ליישום או כוללים היוריסטיקה בלתי נשלטת, מה שהופך אותם לבלתי ישימים ל-Circuits ויישומים קוונטיים גנריים.
  • מערך Gate מורחב: QESEM תומך ב-Gates עם זוויות שבריות, ומספק Gates Rzz(θ)Rzz(\theta) שעברו אופטימיזציה על ידי Qedma על מכשירי IBM Quantum Heron ו-Eagle. מערך Gate מורחב זה מאפשר קומפילציה יעילה יותר ופותח נפחי Circuit גדולים יותר פי 2 בהשוואה לקומפילציית CX/CZ ברירת מחדל.
  • Multibase observables: QESEM תומך ב-observables קלט המורכבים ממחרוזות Pauli רבות שאינן מתחלפות, כגון Hamiltonians גנריים. בחירת בסיסי המדידה ואופטימיזציית הקצאת משאבי ה-QPU (shots ו-Circuits) מבוצעת אז באופן אוטומטי על ידי QESEM כדי למזער את זמן ה-QPU הנדרש לדיוק המבוקש. אופטימיזציה זו, המתחשבת בנאמנויות חומרה וקצבי ביצוע, מאפשרת לך להריץ Circuits עמוקים יותר ולהשיג דיוק גבוה יותר.

בנצ'מרקים​

QESEM נבדק על מגוון רחב של מקרי שימוש ויישומים. הדוגמאות הבאות יכולות לסייע לך להעריך אילו סוגי עומסי עבודה ניתן להריץ עם QESEM.

מדד ביצועים מרכזי לכימות קושי מיתון השגיאות וסימולציה קלאסית עבור Circuit ו-observable נתונים הוא נפח פעיל: מספר ה-Gate CNOT המשפיעים על ה-observable ב-Circuit. הנפח הפעיל תלוי בעומק ורוחב ה-Circuit, במשקל ה-observable ובמבנה ה-Circuit, הקובע את חרוט האור של ה-observable. לפרטים נוספים, ראה את ההרצאה מ-IBM Quantum Summit 2024. QESEM מספק ערך גדול במיוחד במשטר הנפח הגבוה, ומספק תוצאות אמינות ל-Circuits ו-observables גנריים.

נפח פעיל

יישוםמספר qubitsמכשירתיאור Circuitדיוקזמן כוללשימוש Runtime
VQE circuit8Eagle (r3)21 שכבות סה"כ, 9 בסיסי מדידה, שרשרת 1D98%35 דקות14 דקות
Kicked Ising28Eagle (r3)3 שכבות ייחודיות x 3 צעדים, טופולוגיית heavy-hex דו-ממדית97%22 דקות4 דקות
Kicked Ising28Eagle (r3)3 שכבות ייחודיות x 8 צעדים, טופולוגיית heavy-hex דו-ממדית97%116 דקות23 דקות
סימולציית Hamiltonian Trotterized40Eagle (r3)2 שכבות ייחודיות x 10 צעדי Trotter, שרשרת 1D97%3 שעות25 דקות
סימולציית Hamiltonian Trotterized119Eagle (r3)3 שכבות ייחודיות x 9 צעדי Trotter, טופולוגיית heavy-hex דו-ממדית95%6.5 שעות45 דקות
Kicked Ising136Heron (r2)3 שכבות ייחודיות x 15 צעדים, טופולוגיית heavy-hex דו-ממדית99%52 דקות9 דקות

הדיוק נמדד כאן ביחס לערך האידיאלי של ה-observable: ⟨O⟩ideal−ϵ⟨O⟩ideal\frac{\langle O \rangle_{ideal} - \epsilon}{\langle O \rangle_{ideal}}, כאשר 'ϵ\epsilon' הוא הדיוק האבסולוטי של המיתון (שנקבע על ידי קלט המשתמש), ו-⟨O⟩ideal\langle O \rangle_{ideal} הוא ה-observable במעגל ללא רעש. 'שימוש Runtime' מודד את השימוש של הבנצ'מרק ב-batch mode (סכום על שימוש של עבודות בודדות), ואילו 'זמן כולל' מודד שימוש ב-session mode (זמן קיר הניסוי), הכולל זמני חישוב ותקשורת קלאסיים נוספים. QESEM זמין לביצוע בשני המצבים, כך שמשתמשים יכולים לעשות את השימוש הטוב ביותר במשאביהם הזמינים.

ה-Circuits של Kicked Ising בן 28 qubit מדמים את Discrete Time Quasicrystal שנחקר על ידי Shinjo et al. (ראה arXiv 2403.16718 ו-Q2B24 Tokyo) על שלוש לולאות מחוברות של ibm_kawasaki. פרמטרי ה-Circuit שנלקחו כאן הם (θx,θz)=(0.9π,0)(\theta_x, \theta_z) = (0.9 \pi, 0), עם מצב ראשוני פרומגנטי ∣ψ0⟩=∣0⟩⊗n| \psi_0 \rangle = | 0 \rangle ^{\otimes n}. ה-observable הנמדד הוא הערך המוחלט של המגנטיזציה M=∣128∑i=027⟨Zi⟩∣M = |\frac{1}{28} \sum_{i=0}^{27} \langle Z_i \rangle|. ניסוי Kicked Ising בקנה מידה של תועלת הופעל על 136 ה-Qubits הטובים ביותר של ibm_fez; בנצ'מרק ספציפי זה הופעל בזווית Clifford (θx,θz)=(π,0)(\theta_x, \theta_z) = (\pi, 0), שבה הנפח הפעיל גדל לאט עם עומק ה-Circuit, מה שמאפשר - יחד עם נאמנויות מכשיר גבוהות - דיוק גבוה בזמן ריצה קצר.

ה-Circuits של סימולציית Hamiltonian Trotterized הם עבור מודל Transverse-Field Ising בזוויות שבריות: (θzz,θx)=(π/4,π/8)(\theta_{zz}, \theta_x) = (\pi / 4, \pi /8) ו-(θzz,θx)=(π/6,π/8)(\theta_{zz}, \theta_x) = (\pi / 6, \pi / 8) בהתאמה (ראה Q2B24 Tokyo). ה-Circuit בקנה מידה של תועלת הופעל על 119 ה-Qubits הטובים ביותר של ibm_brisbane, ואילו ניסוי ה-40 qubit הופעל על השרשרת הטובה הזמינה. הדיוק מדווח עבור המגנטיזציה; תוצאות בדיוק גבוה הושגו גם עבור observables במשקל גבוה יותר.

מעגל ה-VQE פותח יחד עם חוקרים ממרכז לטכנולוגיה וישומים קוונטיים ב-Deutsches Elektronen-Synchrotron (DESY). ה-observable היעד כאן היה Hamiltonian המורכב ממספר רב של מחרוזות Pauli שאינן מתחלפות, המדגיש את הביצועים האופטימיזציים של QESEM עבור observables מרובי בסיסים. המיתון הוחל על ansatz שעבר אופטימיזציה קלאסית; למרות שתוצאות אלה עדיין לא פורסמו, תוצאות באותה איכות יתקבלו עבור מעגלים שונים עם מאפיינים מבניים דומים.

תחילת עבודה​

אמת את זהותך באמצעות מפתח ה-API של IBM Quantum Platform, ובחר את פונקציית Qiskit של QESEM כדלקמן. (קטע קוד זה מניח שכבר שמרת את החשבון שלך בסביבה המקומית שלך.)

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

_needed = {"qiskit": "qiskit", "qiskit_ibm_catalog": "qiskit-ibm-catalog", "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")
import qiskit
from qiskit_ibm_catalog import QiskitFunctionsCatalog

catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")

# verify that you have access to the function
catalog.list()
# load the function
qesem_function = catalog.load("qedma/qesem")

דוגמאות​

דוגמת עבודת הערכת זמן​

עבודת הערכת הזמן שימושית להערכת זמן ה-QPU הנדרש עבור pub ו-backend_name נתונים. backend_name יכול גם להיות מוגדר לכל Backend סימולטור; לדוגמה, fake_fez.

QESEM משתמש בשיטת EM מבוססת אפיון, קוואזי-הסתברותית. לשיטה זו יש תקורת זמן QPU שגדלה בקירוב כמו:

TQPU=aeαIF⋅Vaϵ2+bT_{QPU} = a \frac{e^{\alpha IF\cdot V_a}}{\epsilon^2} + b

כאשר VaV_a הוא הנפח הפעיל של המעגל, ϵ\epsilon הוא דיוק היעד, ו-IFIF הוא חוסר הנאמנות של השערים המקוריים (native).

שים לב ש-"estimate_time_only": "empirical" משתמש בכמה דקות של זמן QPU כדי להעריך את הזמן הנדרש לעבודה (אם ה-Backend הוא התקן אמיתי; אם זהו סימולטור, אז אין שימוש בזמן QPU). זה בדרך כלל ייקח כ-5 דקות, אך לא יותר מ-10 דקות. אם חוסר הנאמנות משתנה באופן דרסטי בין עבודת הערכת הזמן האמפירית לעבודת המיתון, זמן ה-QPU ישתנה גם הוא באופן דרסטי.

כדי להתחיל, נסה דוגמה בסיסית זו להערכת זמן ה-QPU הנדרש להרצת QESEM עבור pub נתון:

# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend_name = service.least_busy().name
backend_name = "fake_fez"

circ = qiskit.QuantumCircuit(5)
circ.cx(0, 1)
circ.cx(2, 3)
circ.cx(1, 2)
circ.cx(3, 4)

avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("Z", [q], 1 / 5) for q in range(5)], num_qubits=5
)
other_observable = qiskit.quantum_info.SparsePauliOp.from_sparse_list(
[("ZZ", [0, 1], 1.0), ("XZ", [1, 4], 0.5)], num_qubits=5
)

time_estimation_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
options={
"estimate_time_only": "empirical",
},
backend_name=backend_name, # example: "fake_fez", "ibm_fez"
)
time_estimate_result = (
time_estimation_job.result()
) # a list of results per pub (circuit)

קטע הקוד הבא מתאר כיצד לאחזר מדדי ביצוע שונים מעבודת הערכת הזמן (estimate_time_only מוגדר):

pub_result = time_estimate_result[0]

print(
f"The estimated QPU time for mitigation for this PUB is: {pub_result.metadata['time_estimation_sec']}"
)
print(
f"The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f"Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f"Total shots: {pub_result.metadata['total_shots']}")
print(f"Resource usage breakdown: {pub_result.metadata['resource_usage']}")
The estimated QPU time for mitigation for this PUB is: 300
The QPU time that this time estimation job took is (here it is 0 because we used fake_fez): 0
Gates fidelity measured during the experiment: {'CZ': 0.9951354916722668, 'ID1Q': 0.9991246627329172}
Total shots: 220000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 33.6066133165732, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 184.53575124032795, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

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

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

השדה empirical_estimation_mitigation_results הוא רשימה של אובייקטי PrimitiveResult לכל פרמטר קלט. אם המעגל אינו פרמטרי, הרשימה תהיה באורך 1.

empirical_estimation_mitigation_results = time_estimate_result[0].metadata[
"empirical_estimation_mitigation_results"
][0] # a list per parameter
print("Partial results for the observables:")

print(
f" Mitigated expectation values: {empirical_estimation_mitigation_results.data.evs}"
)
print(
f" Mitigated error bars: {empirical_estimation_mitigation_results.data.stds}"
)
print(
f" Number of shots used for mitigation: {empirical_estimation_mitigation_results.metadata['mitigation_shots']}"
)
transpiled_circ = empirical_estimation_mitigation_results.metadata[
"transpiled_circ"
]
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Number of measurement bases: {transpiled_circ['num_measurement_bases']}\n"
)

# results per obs
emp_obs_results = empirical_estimation_mitigation_results.metadata["results"][
0
]
# print(f"Results for each observable: {results}")
print("Results for each observable:")

for i, (obs_array, result_dict) in enumerate(emp_obs_results):
# obs_array, result_dict = results
print(f"Observable {i+1}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} \u00b1 {result_dict['qesem']['error_bar']}"
)
Partial results for the observables:
Mitigated expectation values: [1.00347302 1.00693905]
Mitigated error bars: [0.00304061 0.00714276]
Number of shots used for mitigation: 180000
Qubit mapping: [[[0, 136], [1, 143], [2, 142], [3, 141], [4, 140]]]
Number of measurement bases: 2

Results for each observable:
Observable 1: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.003473015776871 ± 0.0030406128032204015
Observable 2: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0069390542613554 ± 0.0071427606736885925

דוגמת עבודת הפחתת QESEM​

הדוגמה הבאה מבצעת עבודת QESEM:

sample_job = qesem_function.run(
pubs=[(circ, [avg_magnetization, other_observable])],
backend_name=backend_name, # example: "ibm_fez"
# options = {
# "estimate_time_only": "empirical",
# "default_precision": 0.2, # Default precision is applied to all pubs that don't have a precision specified, see API reference for more details
# "max_execution_time": 3600, # You can specify a maximum QPU time in seconds, see API reference for more details
# "transpilation_level": "standard", # "minimal_with_layout_opt" for minimal transpilation, see API reference for more details
# "parallel_execution": True, # True for parallel execution, see API reference for more details
# },
)

לתיאור מפורט של כל שדה ואפשרות קלט, ראה את תיעוד ה-API של QESEM. תוכל להשתמש בממשקי ה-API המוכרים של Qiskit Serverless כדי לבדוק את סטטוס עומס העבודה של פונקציית Qiskit שלך או להחזיר תוצאות:

# Print the ID so you can use it later, if necessary
print(sample_job.job_id)
print(sample_job.status())
sample_result = sample_job.result()
3ac6b2df-15b0-4dc0-8f48-cf14bd20a1c8
DONE

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

for pub_idx, pub_result in enumerate(
sample_result
): # each element in the list is a result for a different pub, here we sent only one pub
print(f"\nPUB {pub_idx}:")
print(
f" The QPU time that this job took is (here it is 0 because we used fake_fez): {pub_result.metadata['total_qpu_time']}"
)
print(
f" Gates fidelity measured during the experiment: {pub_result.metadata['gate_fidelities']}"
)
print(f" Total shots: {pub_result.metadata['total_shots']}")
print(
f" Number of shots used for mitigation: {pub_result.metadata['mitigation_shots']}"
)
print(
f" Resource usage breakdown: {pub_result.metadata['resource_usage']}"
)
PUB 0:
The QPU time that this job took is (here it is 0 because we used fake_fez): 0.0
Gates fidelity measured during the experiment: {'CZ': 0.9953704216147041, 'ID1Q': 0.9991834123567518}
Total shots: 446000
Number of shots used for mitigation: 194000
Resource usage breakdown: {'RUNNING: MAPPING': {'CPU_TIME': 32.52745003718883, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU_TIME': 257.850521848537, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: WAITING_FOR_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: EXECUTING_QPU': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}, 'RUNNING: POST_PROCESSING': {'CPU_TIME': 0.0, 'GPU_TIME': 0.0, 'QPU_TIME': 0.0}}

ב-metadata["results"], התוצאות מקובצות תחילה לפי מופע מעגל ולאחר מכן לפי observable.

print("Full QESEM mitigation results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")

print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata.get("noisy_results")
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")

print(" Transpiled circuits:")
for circ_idx, transpiled_circ in enumerate(
pub_result.metadata["transpiled_circs"]
):
print(f" Circuit {circ_idx}:")
# print(f" Circuit: \n {transpiled_circ['circuit']}") # not printing it because it's long but you can see the transpiled circuit itself
print(f" Qubit mapping: {transpiled_circ['qubit_maps']}")
print(
f" Measurement bases: {transpiled_circ['num_measurement_bases']}"
)

print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Full QESEM mitigation results:

PUB 0:
Mitigated expectation values: [1.00648343 1.00636289]
Mitigated error bars: [0.00253812 0.00693586]
Unmitigated expectation values: [0.98031429 0.96357143]
Unmitigated error bars: [0.00124128 0.00578812]
Transpiled circuits:
Circuit 0:
Qubit mapping: [[[0, 140], [1, 141], [2, 142], [3, 143], [4, 136]]]
Measurement bases: 2
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 1.0064834305181962 ± 0.002538119914534849
Unmitigated value: 0.9803142857142859 ± 0.0012412835813609938
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0063628870614818 ± 0.006935859820870656
Unmitigated value: 0.9635714285714285 ± 0.005788121870526659

פירוט התוצאות העיקריות:

  • mitigated: ערך התוחלת של QESEM לאחר מיתון מלא.
  • unmitigated: התוצאה הגולמית של רעש פיזי ללא מיתון שגיאות.

תוצאות אקסטרפולציה היוריסטית של QESEM​

בהרצת QESEM רגילה עם precision float יחיד, התוצאות כוללות גם נקודות סקיילינג רעש שזמינות אוטומטית ומשמשות עבור ההיוריסטיקה של QESEM. נקודות אלה מחושבות ללא משאבי QPU נוספים.

סקייל 1.0 מייצג את רמת הרעש הפיזית של המכשיר עם הפחתת קריאה (REM), בעוד שסקייל 2.0 הוא נקודת הרעש המוגברת המשלימה, גם היא עם REM. נקודות אלה משמשות להפקת התוצאה qesem_heuristic.

  • qesem_heuristic: הערכה בסגנון ZNE המחושבת מהנתונים בסקיילינג רעש הזמינים. כרגע זה משתמש באקסטרפולציה אקספוננציאלית.

  • noise_scaling.results_with_REM: ערכי תוחלת בסקיילי רעש שונים, כולם עם מיתון קריאה (REM).

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

print("QESEM heuristic results:")

for pub_idx, pub_result in enumerate(sample_result):
print(f"\nPUB {pub_idx}:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
qesem_heuristic = result_dict["qesem_heuristic"][0]
print(" QESEM heuristic:")
print(
f" Value: {qesem_heuristic['value']} ± {qesem_heuristic['error_bar']}"
)
print(
f" Extrapolation: {qesem_heuristic['extrapolation']}"
)
print(
f" Scale factors: {qesem_heuristic['scale_factors']}"
)
noise_scaling = result_dict["noise_scaling"]
print(" Noise scaling results:")
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QESEM heuristic results:

PUB 0:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM heuristic:
Value: 1.0008161638888535 ± 0.0038859458884403964
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9918395459270772 ± 0.0012565417579355634
Scale factor 2.0: 0.982943441922748 ± 0.0028919278067695018
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM heuristic:
Value: 0.9960853148925298 ± 0.013811635038961175
Extrapolation: exponential
Scale factors: [1.0, 2.0]
Noise scaling results:
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 1.0: 0.9902860583785115 ± 0.005921236914723409
Scale factor 2.0: 0.984520565414274 ± 0.006909522262347639
הערה

הדוגמאות הבאות מתמקדות בקלטים ותוצאות ספציפיים לתכונה, ולכן הן לא מדפיסות את מדדי הביצוע המלאים בכל פעם. המטא-נתונים ברמה העליונה שהוצגו קודם, כגון total_qpu_time, gate_fidelities, total_shots, mitigation_shots, ו-resource_usage, זמינים גם עבור jobs אלה.

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

הערה

כל הדוגמאות הבאות יכולות גם לרוץ עם הערכת זמן אמפירית. כדי להפעיל זאת, העבירו "estimate_time_only": "empirical" באפשרויות הפונקציה.

דוגמת מעגל פרמטרי​

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

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

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

כרגע QESEM תומך רק באובזרבבל אחד לכל קבוצת פרמטרים. שתי שורות הפרמטרים למטה משולבות עם שני האובזרבבלים: השורה הראשונה נמדדת עם avg_magnetization, והשורה השנייה נמדדת עם other_observable.

# Transpile to the backend basis gates only. With minimal_with_layout_opt, QESEM handles hardware mapping/connectivity and observable layout internally.
from qiskit_ibm_runtime.fake_provider import FakeFez

backend = FakeFez()
basis = backend.operation_names
print(basis)

param0 = qiskit.circuit.Parameter("param0")
param1 = qiskit.circuit.Parameter("param1")
parametrized_circ = qiskit.QuantumCircuit(5)
parametrized_circ.rx(param0, 0)
parametrized_circ.rx(param1, 1)
parametrized_circ.cx(0, 1)
parametrized_circ.cx(2, 3)
parametrized_circ.cx(1, 2)
parametrized_circ.cx(3, 4)

parametrized_circ = qiskit.transpile(
parametrized_circ, basis_gates=basis, optimization_level=1
)
parametrized_parameter_values = [[0.5, 0.1], [0.0, 0.6]]
parametrized_observables = [avg_magnetization, other_observable]

parametrized_job = qesem_function.run(
pubs=[
(
parametrized_circ,
parametrized_observables,
parametrized_parameter_values,
0.1,
)
],
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
},
)
print(parametrized_job.job_id)
print(parametrized_job.status())
d1b0e29b-196c-4896-aec6-44a268ebd874
DONE
parametrized_result = parametrized_job.result()
print("Parameterized circuit QESEM results:")

for pub_idx, pub_result in enumerate(parametrized_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each parameter value:")
for param_idx, param_results in enumerate(pub_result.metadata["results"]):
print(
f" Parameter set {param_idx}: {parametrized_parameter_values[param_idx]}"
)
for obs_idx, (obs_array, result_dict) in enumerate(param_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Parameterized circuit QESEM results:

PUB 0:
Mitigated expectation values: [0.92392021 0.82517653]
Mitigated error bars: [0.00565281 0.00616016]
Unmitigated expectation values: [0.9028 0.78771429]
Unmitigated error bars: [0.00335142 0.00925413]
Results for each parameter value:
Parameter set 0: [0.5, 0.1]
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.923920210615709 ± 0.005652811570890183
Unmitigated value: 0.9028 ± 0.0033514176105045447
Parameter set 1: [0.0, 0.6]
Observable 0: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 0.8251765289285893 ± 0.006160161743353999
Unmitigated value: 0.7877142857142858 ± 0.009254130564027902

דוגמת ריבוי pubs​

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

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

עבודות ריבוי pubs דורשות "transpilation_level": "minimal_with_layout_opt". כמו בדוגמה הפרמטרית, יש לבצע טרנספילציה למעגלים לשערי הבסיס של ה-backend היעד לפני השליחה. לאחר מכן QESEM מטפל בקישוריות המכשיר, בפריסה ובמיפוי לקיוביטים באמינות גבוהה באופן פנימי.

כל PUB להלן מכיל מעגל אחד ואת אותם שני observables ששימשו קודם במחברת, כך שה-PrimitiveResult המוחזר מכיל PubResult אחד לכל מעגל קלט.

הדוגמה למטה משתמשת בשני מעגלי Trotter פשוטים עם אותה תבנית שכבות: ל-circ_a יש שכבת Trotter אחת, ו-circ_b חוזר על אותה תבנית שכבות פעמיים. זה הופך את המבנה המשותף למפורש.

def make_trotter_circuit(num_qubits, num_layers, zz_angle=0.2, x_angle=0.1):
trotter_circ = qiskit.QuantumCircuit(num_qubits)
for _ in range(num_layers):
for q in range(num_qubits):
trotter_circ.rx(x_angle, q)
trotter_circ.barrier()
for q in range(0, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
for q in range(1, num_qubits - 1, 2):
trotter_circ.rzz(zz_angle, q, q + 1)
trotter_circ.barrier()
return trotter_circ

circ_a = make_trotter_circuit(num_qubits=5, num_layers=1)
circ_b = make_trotter_circuit(num_qubits=5, num_layers=2)
multi_pubs = [
(
qiskit.transpile(qci, basis_gates=basis, optimization_level=1),
[avg_magnetization, other_observable],
)
for qci in [circ_a, circ_b]
]

multi_circ_job = qesem_function.run(
pubs=multi_pubs,
backend_name=backend_name,
options={
"max_execution_time": 300,
"transpilation_level": "minimal_with_layout_opt",
"default_precision": 0.1,
},
)
print(multi_circ_job.job_id)
print(multi_circ_job.status())
e34565b8-7262-4133-a120-de42ce624a99
DONE
multi_circ_result = multi_circ_job.result()
print("Multi-pub QESEM results:")

for pub_idx, pub_result in enumerate(multi_circ_result):
print(f"\nPUB {pub_idx}:")
print(f" Mitigated expectation values: {pub_result.data.evs}")
print(f" Mitigated error bars: {pub_result.data.stds}")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
print(
f" QESEM mitigated value: {result_dict['qesem']['value']} ± {result_dict['qesem']['error_bar']}"
)
print(
f" Unmitigated value: {result_dict['unmitigated']['value']} ± {result_dict['unmitigated']['error_bar']}"
)
Multi-pub QESEM results:

PUB 0:
Mitigated expectation values: [0.99502406 1.02209332]
Mitigated error bars: [0.00483819 0.00707488]
Unmitigated expectation values: [0.96934286 0.97271429]
Unmitigated error bars: [0.00124855 0.00617294]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.9950240647925642 ± 0.004838188086259301
Unmitigated value: 0.9693428571428573 ± 0.0012485470362492692
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.0220933230604674 ± 0.007074884384355636
Unmitigated value: 0.9727142857142859 ± 0.006172939375512439

PUB 1:
Mitigated expectation values: [0.98850017 1.02555188]
Mitigated error bars: [0.0077912 0.01672652]
Unmitigated expectation values: [0.93682857 0.95371429]
Unmitigated error bars: [0.00156245 0.00665735]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
QESEM mitigated value: 0.988500171577252 ± 0.007791203181151346
Unmitigated value: 0.9368285714285716 ± 0.001562451883089579
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
QESEM mitigated value: 1.02555188098689 ± 0.016726524388086233
Unmitigated value: 0.9537142857142858 ± 0.006657345655544263

דוגמת כיוונון שגיאה קוואזי-הסתברותי (QET)​

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

כדי להשתמש ב-QET עם ה-Qiskit Function, העבר מילון כדיוק ה-PUB. המילון ממפה כל סקייל רעש מבוקש לדיוק היעד שלו. תוצאות גורם סקייל שמוחזרות נשמרות ב-noise_scaling.results_with_REM וכוללות מיתון קריאה. לכן נקודת סקייל 1.0 אינה זהה לערך ה-unmitigated, מכיוון ש-1.0 כוללת מיתון קריאה בעוד ש-unmitigated לא.

כאשר מבוקש סקייל, QESEM גם מחזיר את הסקייל המשלים סביב 1.0 ללא שימוש נוסף ב-QPU. לדוגמה, בקשת 0.5 יכולה גם להחזיר 1.5, ובקשת 1.3 יכולה גם להחזיר 0.7. הדיוק בסקייל המשלים אינו מובטח.

noise_scale_precision = {0.5: 0.15, 1.3: 0.2}

qet_job = qesem_function.run(
pubs=[
(
circ,
[avg_magnetization, other_observable],
None,
noise_scale_precision,
)
],
backend_name=backend_name,
options={"max_execution_time": 300},
)
print(qet_job.job_id)
print(qet_job.status())
8195fa58-f037-4651-8715-36ce1cdc5521
DONE
qet_result = qet_job.result()
print("QET noise-scaling results:")

for pub_idx, pub_result in enumerate(qet_result):
print(f"\nPUB {pub_idx}:")
noisy_results = pub_result.metadata["noisy_results"]
print(f" Unmitigated expectation values: {noisy_results.evs}")
print(f" Unmitigated error bars: {noisy_results.stds}")
print(" Results for each observable:")
for circ_idx, circ_results in enumerate(pub_result.metadata["results"]):
print(f" Circuit {circ_idx}:")
for obs_idx, (obs_array, result_dict) in enumerate(circ_results):
print(f" Observable {obs_idx}: {obs_array}")
noise_scaling = result_dict["noise_scaling"]
print(
f" Scaling method: {noise_scaling['scaling_method']}"
)
print(" Results with Readout mitigation (REM):")
for rem_result in sorted(
(
item
for item in noise_scaling["results_with_REM"]
if item["scale"] != 0.0
),
key=lambda item: item["scale"],
):
print(
f" Scale factor {rem_result['scale']}: {rem_result['value']} ± {rem_result['error_bar']}"
)
QET noise-scaling results:

PUB 0:
Unmitigated expectation values: [0.97822857 0.96171429]
Unmitigated error bars: [0.00123812 0.00672958]
Results for each observable:
Circuit 0:
Observable 0: ObservablesArray({'IIIIZ': 0.2, 'IIIZI': 0.2, 'IIZII': 0.2, 'IZIII': 0.2, 'ZIIII': 0.2}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 0.9938730340199383 ± 0.0032116907357568275
Scale factor 0.7: 0.9963976191853445 ± 0.00036300258869586616
Scale factor 1.0: 0.9898115079506586 ± 0.0012525947426560995
Scale factor 1.3: 0.9864667065580341 ± 0.002633221613518526
Scale factor 1.5: 0.9838755527197551 ± 0.002948417797996015
Observable 1: ObservablesArray({'IIIZZ': 1.0, 'ZIIXI': 0.5}, shape=())
Scaling method: QESEM
Results with Readout mitigation (REM):
Scale factor 0.5: 1.0006538544450332 ± 0.002121742014777343
Scale factor 0.7: 1.0004159801523036 ± 0.0021671375357823794
Scale factor 1.0: 0.9898058846339917 ± 0.00690183710903159
Scale factor 1.3: 0.9948946719997267 ± 0.002146532859610311
Scale factor 1.5: 0.9927220368192772 ± 0.0020875057190323882

אחזור הודעות שגיאה​

אם סטטוס עומס העבודה שלך הוא ERROR, השתמש ב-job.result() כדי לקבל את הודעת השגיאה כדלקמן:

# Get the result and truncate for readability
result = sample_job.result()
result_str = str(result)
max_length = 500 # Adjust this value as necessary

if len(result_str) > max_length:
truncated = (
result_str[:max_length]
+ f"... (truncated {len(result_str) - max_length} characters)"
)
else:
truncated = result_str

print(truncated)
PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(2,), dtype=float64>), stds=np.ndarray(<shape=(2,), dtype=float64>), shape=(2,)), metadata={'gate_fidelities': {'CZ': 0.9979444718552628, 'ID1Q': 0.9991994239814883}, 'total_shots': 498600, 'mitigation_shots': 223400, 'transpiled_circs': [{'circuit': 'OPENQASM 3.0;\ninclude "stdgates.inc";\nbit[76] c0;\nqubit[76] q0;\nrx(0) q0[54];\nrx(0) q0[59];\nrx(0) q0[75];\nrz(pi/2) q0[54];\nrz(pi/2) q0[59];\nrz(pi/2) q0[75];\nrx(pi/2) q0[54];\nr... (truncated 3771 characters)

קבלת תמיכה​

צוות התמיכה של Qedma כאן לעזור! אם נתקלת בבעיות כלשהן או יש לך שאלות לגבי שימוש בפונקציית QESEM של Qiskit, אל תהסס לפנות. צוות התמיכה הידידותי והמיומן שלנו מוכן לסייע לך בכל דאגה טכנית או פנייה שיש לך.

תוכל לשלוח אלינו אימייל לכתובת support@qedma.com לקבלת סיוע. כלול כמה שיותר פרטים על הבעיה שאתה חווה כדי לעזור לנו לספק תגובה מהירה ומדויקת. תוכל גם ליצור קשר עם נציג ה-POC הייעודי שלך ב-Qedma באמצעות אימייל או טלפון.

כדי לסייע לנו לטפל בך ביעילות רבה יותר, ספק את המידע הבא כאשר אתה יוצר קשר:

  • תיאור מפורט של הבעיה

  • מזהה העבודה

  • הודעות שגיאה או קודים רלוונטיים

אנחנו מחויבים לספק לך תמיכה מהירה ויעילה כדי להבטיח שתהיה לך החוויה הטובה ביותר עם פונקציית Qiskit שלנו.

אנחנו תמיד שואפים לשפר את המוצר שלנו ומברכים על ההצעות שלך! אם יש לך רעיונות כיצד נוכל לשפר את השירותים או תכונות שתרצה לראות, שלח לנו את מחשבותיך לכתובת support@qedma.com.

הצעדים הבאים​