Primitives dengan REST API
Langkah-langkah dalam topik ini menerangkan cara menjalankan dan mengkonfigurasi beban kerja primitif dengan REST API, serta menunjukkan cara memanggilnya dalam mana-mana program pilihan anda.
Dokumentasi ini menggunakan modul Python requests untuk mendemonstrasikan Qiskit Runtime REST API. Walau bagaimanapun, aliran kerja ini boleh dilaksanakan menggunakan sebarang bahasa atau rangka kerja yang menyokong REST API. Rujuk dokumentasi rujukan API untuk maklumat lanjut.
Estimator primitive dengan REST APIβ
1. Mulakan akaunβ
Oleh sebab Qiskit Runtime Estimator adalah perkhidmatan terurus, anda perlu memulakan akaun anda terlebih dahulu. Kemudian anda boleh memilih peranti yang ingin digunakan untuk mengira nilai jangkaan.
Cari butiran tentang cara memulakan akaun, melihat Backend yang tersedia, dan membatalkan token dalam topik ini.
2. Cipta Circuit QASMβ
Anda memerlukan sekurang-kurangnya satu Circuit sebagai input kepada primitif Estimator.
Takrifkan Circuit kuantum QASM. Contohnya:
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];
'''
Coretan kod berikut menganggap bahawa qasm_string telah ditranspilkan ke dalam rentetan baru resulting_qasm.
3. Jalankan Circuit kuantum menggunakan Estimator V2 APIβ
Kerja-kerja berikut menggunakan Qiskit Runtime V2 primitives. Kedua-dua SamplerV2 dan EstimatorV2 menerima satu atau lebih primitive unified blocs (PUBs) sebagai input. Setiap PUB ialah tuple yang mengandungi satu Circuit dan data yang disiarkan ke Circuit tersebut, yang boleh terdiri daripada pelbagai observable dan parameter. Setiap PUB mengembalikan satu keputusan.
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': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each.
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
}}
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. Semak status kerja dan dapatkan keputusanβ
Seterusnya, hantar job_id ke API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Output
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edcad
>>> Job Status: JobStatus.RUNNING
Dapatkan keputusan kerja:
response_result= requests.get(url+'/'+job_id+'/results', headers=headers)
res_dict=response_result.json()
estimator_result=res_dict['results']
print(estimator_result)
Output
[{'data': {'evs': 0.7428980350102542, 'stds': 0.029884014518789213, 'ensemble_standard_error': 0.03261147170624149}, 'metadata': {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}}]
5. Bekerja dengan pilihan Runtimeβ
Teknik pengurangan ralat membolehkan pengguna mengurangkan ralat Circuit dengan memodelkan hingar peranti pada masa pelaksanaan. Ini biasanya menghasilkan overhed pra-pemprosesan kuantum berkaitan latihan model, dan overhed pasca-pemprosesan klasik untuk mengurangkan ralat dalam keputusan mentah menggunakan model yang dijana.
Teknik pengurangan ralat yang terbina dalam primitif ialah pilihan resilience lanjutan. Untuk menentukan pilihan ini, gunakan pilihan resilience_level semasa menghantar kerja anda.
Contoh-contoh berikut menunjukkan pilihan lalai untuk dynamical decoupling, twirling, dan TREX + ZNE. Cari lebih banyak pilihan dan butiran lanjut dalam topik Teknik pengurangan dan penindasan ralat.
- TREX + ZNE
- Dynamical Decoupling
- 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': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"options": {
"resilience": {
"measure_mitigation": True,
"zne_mitigation": True,
"zne": {
"extrapolator":["exponential", "linear"],
"noise_factors":[1, 3, 5],
},
},
},
}
}
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}")
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': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"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}")
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': 'estimator',
"backend": backend,
"params": {
"pubs": [ #primitive unified blocs (PUBs) containing one circuit each
[resulting_qasm, # QASM circuit
{"IIZII": 1, "XIZZZ": 2.3}, # Observable
None # parameter values
]]
"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}")
Sampler primitive with REST APIβ
1. Initialize the accountβ
Because Qiskit Runtime Sampler is a managed service, you first need to initialize your account. You can then select the device you want to use to run your calculations on.
Find details on how to initialize your account, view available backends, and invalidate tokens in this topic.
2. Create a QASM circuitβ
You need at least one circuit as the input to the Sampler primitive.
Define a QASM quantum circuit:
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];
'''
Coretan kod yang diberikan di bawah menganggap bahawa qasm_string telah ditranspilkan ke dalam rentetan baru resulting_qasm.
3. Jalankan Circuit kuantum menggunakan Sampler V2 APIβ
Kerja-kerja di bawah menggunakan Qiskit Runtime V2 primitives. Kedua-dua SamplerV2 dan EstimatorV2 menerima satu atau lebih primitive unified blocs (PUBs) sebagai input. Setiap PUB ialah tuple yang mengandungi satu Circuit dan data yang disiarkan ke Circuit tersebut, yang boleh terdiri daripada pelbagai observable dan parameter. Setiap PUB mengembalikan satu keputusan.
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": {
"pubs": [[resulting_qasm],[resulting_qasm,None,500]] # primitive unified blocs (PUBs) containing one circuit each.
}}
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. Semak status kerja dan dapatkan keputusanβ
Seterusnya, hantar job_id ke API:
response_status_singlejob= requests.get(url+'/'+job_id, headers=headers)
response_status_singlejob.json().get('state')
Output
>>> Job ID: 58223448-5100-4dec-a47a-942fb30edced
>>> Job Status: JobStatus.RUNNING
Dapatkan keputusan kerja:
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])
Output
['0x3', '0x0', '0x2', '0x1', '0x0', '0x3', '0x0', '0x3', '0x1', '0x2', '0x2', '0x0', '0x2', '0x0', '0x3', '0x3', '0x2', '0x0', '0x1', '0x0']
5. Bekerja dengan pilihan Runtimeβ
Teknik pengurangan ralat membolehkan pengguna mengurangkan ralat Circuit dengan memodelkan hingar peranti pada masa pelaksanaan. Ini biasanya menghasilkan overhed pra-pemprosesan kuantum berkaitan latihan model, dan overhed pasca-pemprosesan klasik untuk mengurangkan ralat dalam keputusan mentah menggunakan model yang dijana.
Teknik pengurangan ralat yang terbina dalam primitif ialah pilihan resilience lanjutan. Untuk menentukan pilihan ini, gunakan pilihan resilience_level semasa menghantar kerja anda.
Sampler V2 tidak menyokong penentuan tahap resilience. Walau bagaimanapun, anda boleh menghidupkan atau mematikan kaedah pengurangan / penindasan ralat secara individu.
Contoh-contoh berikut menunjukkan pilihan lalai untuk dynamical decoupling dan twirling. Cari lebih banyak pilihan dan butiran lanjut dalam topik Teknik pengurangan dan penindasan ralat.
- Dynamical Decoupling
- 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": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.
"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}")
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": {
"pubs": [[resulting_qasm]], # primitive unified blocs (PUBs) containing one circuit each.
"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}")
Sampler primitive dengan REST API dan circuit berparameterβ
1. Mulakan akaunβ
Oleh sebab Qiskit Runtime adalah perkhidmatan terurus, anda perlu memulakan akaun anda terlebih dahulu. Kemudian anda boleh memilih peranti yang ingin digunakan untuk menjalankan pengiraan anda.
Cari butiran tentang cara memulakan akaun, melihat Backend yang tersedia, dan membatalkan token dalam topik ini.
2. Takrifkan parameterβ
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')
parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary
3. Cipta Circuit kuantum dan tambah Gate berparameterβ
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. Jana kod QASM 3β
qasm_str = dumps(isa_circuit)
print("Generated QASM 3 code:")
print(qasm_str)
5. Jalankan Circuit kuantum menggunakan Sampler V2 APIβ
Kerja-kerja berikut menggunakan Qiskit Runtime V2 primitives. Kedua-dua SamplerV2 dan EstimatorV2 menerima satu atau lebih primitive unified blocs (PUBs) sebagai input. Setiap PUB ialah tuple yang mengandungi satu Circuit dan data yang disiarkan ke Circuit tersebut, yang boleh terdiri daripada pelbagai observable dan parameter. Setiap PUB mengembalikan satu keputusan.
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
#"pubs": [[qasm_str,[1,2],500]], # primitive unified blocs (PUBs) containing one circuit each.
"pubs": [[qasm_str,parameter_values,500]], # primitive unified blocs (PUBs) containing one circuit each.
}}
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. Semak status kerja dan dapatkan keputusanβ
Seterusnya, hantar job_id ke API:
response_status_singlejob = requests.get(f"{url}/{job_id}", headers=headers)
response_status_singlejob.json().get('state')
Output
{'status': 'Completed'}
Dapatkan keputusan kerja:
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])
Output
['0x1', '0x2', '0x1', '0x2', '0x1', '0x2', '0x0', '0x2', '0x1', '0x1', '0x2', '0x2', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1', '0x1']
Langkah seterusnyaβ
- Terdapat beberapa cara untuk menjalankan beban kerja, bergantung pada keperluan anda: mod kerja, mod sesi, dan mod kelompok. Ketahui cara bekerja dengan mod sesi dan mod kelompok dalam topik mod pelaksanaan. Perhatikan bahawa pengguna Pelan Terbuka tidak boleh menghantar kerja sesi.
- Ketahui cara memulakan akaun anda dengan REST API.
- Baca Migrasi ke V2 primitives.
- Berlatih dengan primitives melalui pelajaran Fungsi kos dalam IBM Quantum Learning.
- Ketahui cara transpilasi secara tempatan dalam bahagian Transpile.
- Migrasi ke Qiskit Runtime V2 primitives.