انتقل إلى المحتوى الرئيسي

Sampler مع REST API

تصف الخطوات في هذا الموضوع كيفية تشغيل أحمال العمل وتهيئتها باستخدام REST API، وتوضح كيفية استدعائها في أي برنامج تختاره.

ملاحظة

تستخدم هذه الوثائق وحدة Python requests لتوضيح Qiskit Runtime REST API. غير أن هذا الأسلوب يمكن تنفيذه بأي لغة أو إطار عمل يدعم التعامل مع REST APIs. راجع وثائق مرجع API للتفاصيل.

1. تهيئة الحساب

بما أن Qiskit Runtime Sampler خدمة مُدارة، تحتاج أولًا إلى تهيئة حسابك. ثم يمكنك اختيار الجهاز الذي تريد تشغيل حساباتك عليه.

ابحث عن تفاصيل تهيئة حسابك وعرض الـ Backends المتاحة والتعامل مع الـ Tokens في إعداد استخدام IBM Quantum Platform مع REST API.

2. إنشاء دائرة QASM

تحتاج إلى دائرة كمي واحد على الأقل كإدخال لـ Sampler primitive.

عرِّف Circuit QASM الكمي:

qasm_string='''
OPENQASM 3;
include "stdgates.inc";
qreg q[2];
creg c[2];
x q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
'''

تفترض مقاطع الكود أدناه أن qasm_string قد جرى Transpile إلى سلسلة جديدة resulting_qasm.

3. تشغيل الـ دائرة الكمي باستخدام Sampler V2 API

ملاحظة

تستخدم المهام أدناه Qiskit Runtime V2 primitives. يأخذ SamplerV2 وحدة PUB أو أكثر (primitive unified blocs) كإدخال. كل PUB عبارة عن صف (tuple) يحتوي على دائرة واحدة والبيانات المُبثَّة إليها، والتي يمكن أن تكون معاملات متعددة، ويُعيد نتيجة واحدة لكل PUB.

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm],[resulting_qasm,None,500]]
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

4. التحقق من حالة المهمة والحصول على النتائج

بعد ذلك، مرِّر job_id إلى الـ API:

response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')

المخرجات

>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING

احصل على نتائج المهمة:

response_result= requests.get(url+'/'+job_id+'/results', headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

المخرجات

['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']

5. التعامل مع خيارات Qiskit Runtime

تتيح تقنيات تخفيف الأخطاء للمستخدمين تقليل أخطاء الـ دائرة عبر نمذجة ضوضاء الجهاز وقت التنفيذ. وهذا يؤدي عادةً إلى حمل زائد في المعالجة المسبقة الكمية المتعلقة بتدريب النموذج، وحمل زائد في المعالجة اللاحقة الكلاسيكية لتخفيف الأخطاء في النتائج الخام باستخدام النموذج المُنتَج.

تقنيات تخفيف الأخطاء المدمجة في الـ primitives هي خيارات مرونة متقدمة. لتحديد هذه الخيارات، استخدم خيار resilience_level عند إرسال مهمتك. لا يدعم Sampler V2 تحديد مستويات المرونة. غير أنه يمكنك تشغيل أو إيقاف طرق تخفيف الأخطاء/القمع الفردية.

توضح الأمثلة التالية الخيارات الافتراضية للفصل الديناميكي والـ Twirling. ابحث عن خيارات إضافية وتفاصيل أكثر في موضوع تقنيات تخفيف الأخطاء وقمعها.

الفصل الديناميكي

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"options": {
"dynamical_decoupling": {
"enable": True,
"sequence_type": 'XpXm',
"extra_slack_distribution": 'middle',
"scheduling_method": 'alap',
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

الـ Twirling

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}
job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"options": {
"twirling": {
"enable_gates": True,
"enable_measure": True,
"num_randomizations": "auto",
"shots_per_randomization": "auto",
"strategy": "active-accum",
},
},
}
}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print("Job created:",response.text)
else:
print(f"Error: {response.status_code}")

الـ Circuits ذات المعاملات

1. تهيئة الحساب

بما أن Qiskit Runtime خدمة مُدارة، تحتاج أولًا إلى تهيئة حسابك. ثم يمكنك اختيار الجهاز الذي تريد تشغيل حساباتك عليه.

ابحث عن تفاصيل تهيئة حسابك وعرض الـ Backends المتاحة وإلغاء صلاحية الـ Tokens في هذا الموضوع.

2. تعريف المعاملات

import requests
import qiskit_ibm_runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.qasm3 import dumps
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit import transpile

service = QiskitRuntimeService(channel='ibm_quantum')
backend = service.backend("<SPECIFY BACKEND>")

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)

theta = Parameter('theta')
phi = Parameter('phi')
# In case we want to pass a dictionary:
parameter_values = {'theta': 1.57, 'phi': 3.14}

3. إنشاء دائرة كمي وإضافة Gates ذات معاملات

qc = QuantumCircuit(2)

# Add parameterized gates
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)
qc.measure_all()

# Draw the original circuit
qc.draw('mpl')

# Get an ISA circuit
isa_circuit = pm.run(qc)

4. توليد كود QASM 3

qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)

5. تشغيل الـ دائرة الكمي باستخدام Sampler V2 API

import requests

url = 'https://quantum.cloud.ibm.com/api/v1/jobs'
auth_id = "Bearer <YOUR_BEARER_TOKEN>"
crn = "<SERVICE-CRN>"
backend = "<BACKEND_NAME>"

headers = {
'Content-Type': 'application/json',
'Authorization':auth_id,
'Service-CRN': crn
}

job_input = {
'program_id': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
# # primitive unified blocs (PUBs) containing one circuit each:
#"pubs": [[qasm_str,[1,2],500]],

# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[qasm_str,parameter_values,500]],
}}

response = requests.post(url, headers=headers, json=job_input)

if response.status_code == 200:
job_id = response.json().get('id')
print(f"Job created: {response.text}")
else:
print(f"Error: {response.status_code}")
print(response.text)

6. التحقق من حالة المهمة والحصول على النتائج

بعد ذلك، مرِّر job_id إلى الـ API:

response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')

المخرجات

{'status': 'Completed'}

احصل على نتائج المهمة:

response_result = requests.get(f"{url}/{job_id}/results", headers=headers)

res_dict=response_result.json()

# Get results for the first PUB
counts=res_dict['results'][0]['data']['c']['samples']

print(counts[:20])

المخرجات

['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']

الخطوات التالية

توصيات
  • هناك عدة طرق لتشغيل أحمال العمل حسب احتياجاتك: وضع المهمة، ووضع الـ Session، ووضع الـ Batch. تعلَّم كيفية التعامل مع وضع الـ Session ووضع الـ Batch في موضوع أوضاع التنفيذ. لاحظ أن مستخدمي الخطة المفتوحة لا يمكنهم إرسال مهام Session.
  • تعلَّم كيفية تهيئة حسابك باستخدام REST API.
  • تدرَّب على الـ primitives بالعمل على درس دالة التكلفة في IBM Quantum Learning.
  • تعلَّم كيفية عمل Transpile محليًا في قسم Transpile.