דלג לתוכן הראשי

Sampler עם REST API

השלבים בנושא זה מסבירים כיצד להריץ ולהגדיר עומסי עבודה עם REST API, ומדגימים כיצד להפעיל אותם בכל תוכנית שתבחר.

הערה

תיעוד זה משתמש במודול requests של Python כדי להדגים את Qiskit Runtime REST API. עם זאת, תהליך עבודה זה ניתן לביצוע באמצעות כל שפה או מסגרת שתומכת בעבודה עם REST APIs. עיין בתיעוד הפניית API לפרטים.

1. אתחול החשבון

מכיוון ש-Qiskit Runtime Sampler הוא שירות מנוהל, קודם צריך לאתחל את החשבון שלך. לאחר מכן אפשר לבחור את המכשיר שרוצים להשתמש בו להרצת החישובים.

מצא פרטים על כיצד לאתחל את החשבון שלך, לצפות ב-backends הזמינים ולעבוד עם tokens בהגדרת שימוש ב-IBM Quantum Platform עם REST API.

2. יצירת מעגל QASM

צריך לפחות Circuit אחד כקלט ל-primitive של Sampler.

הגדר מעגל קוונטי 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

הערה

העבודות להלן משתמשות ב-V2 primitives של Qiskit Runtime. SamplerV2 מקבל PUB (primitive unified bloc) אחד או יותר כקלט. כל 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 אינו תומך בציון רמות חוסן. עם זאת, ניתן להפעיל או לכבות שיטות הפחתת/דיכוי שגיאות בודדות.

הדוגמאות הבאות מדגימות את האפשרויות ברירת המחדל עבור dynamical decoupling ו-twirling. מצא אפשרויות נוספות ופרטים נוספים בנושא טכניקות הפחתת שגיאות ודיכוי שגיאות.

Dynamical decoupling

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}")

מעגלים פרמטריים

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. יצירת מעגל קוונטי והוספת שערים פרמטריים

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']

השלבים הבאים

המלצות
  • יש מספר דרכים להריץ עומסי עבודה, בהתאם לצרכים שלך: מצב job, מצב session ומצב batch. למד כיצד לעבוד עם מצב session ומצב batch בנושא מצבי ההרצה. שים לב שמשתמשי Open Plan לא יכולים להגיש עבודות session.
  • למד כיצד לאתחל את החשבון שלך עם REST API.
  • תרגל עם primitives באמצעות עבודה על שיעור פונקציית עלות בלימוד IBM Quantum.
  • למד כיצד לבצע transpile מקומית בחלק Transpile.