انتقل إلى المحتوى الرئيسي
هذا المشروع في مرحلة تجريبية. وجدت خطأ؟ افتح مشكلة على GitHub. لديك سؤال أو فكرة؟ اسأل في Discussions — نحب سماع ملاحظاتك!
كيف جودة الترجمة في هذه الصفحة؟

العتاد الصلب

ملاحظة

Masao Tokunari and Tamiya Onodera (14 June 2024)

هذه الدورة مستندة إلى دورة حضورية قُدِّمت في جامعة طوكيو.

ملف PDF محاضرة هذا الدرس قُسِّم إلى جزأين. تنزيل الجزء الأول وتنزيل الجزء الثاني. لاحظ أن بعض مقتطفات الكود قد تصبح مهجورة لأنها صور ثابتة.

1. مقدمة​

يستكشف هذا الدرس عتاد الحوسبة الكمومية الحديثة.

سنبدأ بالتحقق من بعض الإصدارات واستيراد بعض الحزم ذات الصلة.

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

_needed = {"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")
import statistics

from qiskit_ibm_runtime import QiskitRuntimeService

2. الواجهة الخلفية والهدف​

تُتيح Qiskit واجهة برمجية للحصول على المعلومات الثابتة والديناميكية عن جهاز كمومي. نستخدم نسخة Backend للتفاعل مع الجهاز، والتي تتضمن نسخة Target، وهي نموذج آلة مجرد يلخص الميزات الجوهرية مثل بنية مجموعة التعليمات (ISA) وأي خصائص أو قيود مرتبطة بها. لنستخدم هذه النسخ من Backend للحصول على بعض المعلومات التي تراها في صفحة موارد الحوسبة على منصة IBM Quantum®. أولاً، نُنشئ نسخة Backend للجهاز الذي نهتم به. في ما يلي، نختار "ibm_kyoto" أو "ibm_kawasaki" أو أقل أجهزة Eagle انشغالاً. قد يختلف وصولك إلى وحدات المعالجة الكمومية؛ عدِّل اسم الواجهة الخلفية وفقاً لذلك.

service = QiskitRuntimeService()
# backend = service.backend("ibm_kawasaki") # an Eagle, if you have access to ibm_kawasaki
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
) # Eagle
backend.name
'ibm_strasbourg'

نبدأ ببعض المعلومات الأساسية (الثابتة) عن الجهاز.

print(
f"""
{backend.name}, {backend.num_qubits} qubits
processor type = {backend.processor_type}
basis gates = {backend.basis_gates}
"""
)
ibm_strasbourg, 127 qubits
processor type = {'family': 'Eagle', 'revision': 3}
basis gates = ['ecr', 'id', 'rz', 'sx', 'x']

2.1 تمرين​

جرّب الحصول على المعلومات الأساسية عن جهاز Heron "ibm_strasbourg". جرّب ذلك بنفسك، وقد أضفنا الكود أدناه لتتحقق من إجابتك.

a_heron = service.backend("ibm_strasbourg") # a Heron

# your code here
print(
f"""
{backend.name}, {a_heron.num_qubits} qubits
processor type = {a_heron.processor_type}
basis gates = {a_heron.basis_gates}
"""
)
ibm_strasbourg, 133 qubits
processor type = {'family': 'Heron', 'revision': '1'}
basis gates = ['cz', 'id', 'rz', 'sx', 'x']

2.2 خريطة الاقتران​

نرسم الآن خريطة اقتران الجهاز. كما ترى، العقد هي كيوبتات ذات أرقام. الحواف تشير إلى الأزواج التي يمكن تطبيق بوابة التشابك ثنائية الكيوبت عليها مباشرةً. تُسمى هذه الطوبولوجيا "شبكة السداسي الثقيل".

# This function requires that Graphviz is installed. If you need to install Graphviz
# you can refer to:
# https://graphviz.org/download/#executable-packages for instructions.
try:
fig = backend.coupling_map.draw()
except RuntimeError as ex:
print(ex)
fig

ناتج خلية الكود السابقة

3. خصائص الكيوبت​

جهاز Eagle يحتوي على 127 كيوبت. دعنا نحصل على خصائص بعضها.

for qn in range(backend.num_qubits):
if qn >= 5:
break
print(f"{qn}: {backend.qubit_properties(qn)}")
0: QubitProperties(t1=0.000183686508736532, t2=0.00023613944465408068, frequency=4832100227.116953)
1: QubitProperties(t1=0.00048794378526038294, t2=9.007098375327869e-05, frequency=4736264354.075363)
2: QubitProperties(t1=0.00021247781834456527, t2=7.81037910324034e-05, frequency=4859349851.150393)
3: QubitProperties(t1=0.0002936462084765663, t2=0.00011400214529510604, frequency=4679749549.503852)
4: QubitProperties(t1=0.00044229440258559125, t2=0.0003181648356339447, frequency=4845872064.050596)

لنحسب الوسيط لأزمنة T1 للكيوبتات. قارن النتيجة بالنتيجة المعروضة للجهاز على IBM Quantum Platform.

t1s = [backend.qubit_properties(qq).t1 for qq in range(backend.num_qubits)]
f"Median T1: {(statistics.median(t1s)*10**6):.2f} \u03bcs"
'Median T1: 285.43 μs'

3.1 تمرين​

من فضلك احسب الوسيط لأزمنة T2 للكيوبتات. جرّب ذلك بنفسك، لكن أُضيف الكود أدناه للتحقق من نفسك.

# Your code here

t2s = [backend.qubit_properties(qq).t2 for qq in range(backend.num_qubits)]
f"Median T2: {(statistics.median(t2s)*10**6):.2f} \u03bcs"
'Median T2: 173.10 μs'

3.2 أخطاء البوابة والقراءة​

ننتقل الآن إلى أخطاء البوابة. للبداية، ندرس بنية البيانات لنسخة Target. إنها قاموس مفاتيحه أسماء العمليات.

target = backend.target
target.keys()
dict_keys(['measure', 'id', 'sx', 'delay', 'x', 'for_loop', 'rz', 'if_else', 'ecr', 'reset', 'switch_case'])

قيمها أيضاً قواميس. دعنا نلقي نظرة على بعض عناصر القيمة (القاموس) لعملية 'sx'.

for i, qq in enumerate(target["sx"]):
if i >= 5:
break
print(i, qq, target["sx"][qq])
0 (0,) InstructionProperties(duration=6e-08, error=0.0007401311759115297)
1 (1,) InstructionProperties(duration=6e-08, error=0.0003163759907528654)
2 (2,) InstructionProperties(duration=6e-08, error=0.0003183859004638003)
3 (3,) InstructionProperties(duration=6e-08, error=0.00042235914178831863)
4 (4,) InstructionProperties(duration=6e-08, error=0.011163151923589715)

لنكرر الأمر ذاته لعمليتَي 'ecr' و'measure'.

for i, edge in enumerate(target["ecr"]):
if i >= 5:
break
print(i, edge, target["ecr"][edge])
0 (0, 14) InstructionProperties(duration=6.6e-07, error=0.01486295709788732)
1 (1, 0) InstructionProperties(duration=6.6e-07, error=0.015201590794522601)
2 (2, 1) InstructionProperties(duration=6.6e-07, error=0.00697838102630724)
3 (2, 3) InstructionProperties(duration=6.6e-07, error=0.008075067943986797)
4 (3, 4) InstructionProperties(duration=6.6e-07, error=0.0630164507876913)
for i, qq in enumerate(target["measure"]):
if i >= 5:
break
print(i, qq, target["measure"][qq])
0 (0,) InstructionProperties(duration=1.6e-06, error=0.0078125)
1 (1,) InstructionProperties(duration=1.6e-06, error=0.155029296875)
2 (2,) InstructionProperties(duration=1.6e-06, error=0.057373046875)
3 (3,) InstructionProperties(duration=1.6e-06, error=0.02880859375)
4 (4,) InstructionProperties(duration=1.6e-06, error=0.01318359375)

كما يتضح، أخطاء القراءة تميل إلى أن تكون أكبر من أخطاء العملية ثنائية الكيوبت، والتي بدورها تميل إلى أن تكون أكبر من أخطاء العملية أحادية الكيوبت.

بعد فهم هياكل البيانات، نستطيع الآن حساب القيمة الوسيطة للأخطاء في بوابتَي 'sx' و'ecr'. مجدداً، قارن النتائج بالنتائج المعروضة للجهاز على IBM Quantum Platform.

sx_errors = [inst_prop.error for inst_prop in target["sx"].values()]
f"Median SX error: {(statistics.median(sx_errors)):.3e}"
'Median SX error: 2.277e-04'
ecr_errors = [inst_prop.error for inst_prop in target["ecr"].values()]
f"Median ECR error: {(statistics.median(ecr_errors)):.3e}"
'Median ECR error: 6.895e-03'

4. ملحق​

من أبرز ميزات Qiskit قدراتها في التصور. وتشمل مُصوِّرات الدوائر ومُصوِّرات الحالة والتوزيع ومُصوِّر الهدف. استخدمت النوعَين الأولَين بالفعل في دفاتر Jupyter السابقة. لنستخدم بعض قدرات مُصوِّر الهدف.

from qiskit.visualization import plot_gate_map

plot_gate_map(backend, font_size=14)

ناتج خلية الكود السابقة

from qiskit.visualization import plot_error_map

plot_error_map(backend)

ناتج خلية الكود السابقة

# Check Qiskit version
import qiskit

qiskit.__version__
'2.0.2'