Lewati ke konten utama

Primitives dengan REST API

Langkah-langkah dalam topik ini menjelaskan cara menjalankan dan mengonfigurasi beban kerja primitives dengan REST API, serta mendemonstrasikan cara memanggilnya di program apa pun yang kamu pilih.

catatan

Dokumentasi ini menggunakan modul Python requests untuk mendemonstrasikan Qiskit Runtime REST API. Namun, alur kerja ini bisa dijalankan menggunakan bahasa atau framework apa pun yang mendukung REST API. Lihat dokumentasi referensi API untuk detailnya.

Estimator primitive dengan REST API​

1. Inisialisasi akun​

Karena Qiskit Runtime Estimator adalah layanan terkelola, kamu perlu menginisialisasi akun terlebih dahulu. Setelah itu, kamu bisa memilih perangkat yang ingin digunakan untuk menghitung nilai ekspektasi.

Temukan detail cara menginisialisasi akun, melihat Backend yang tersedia, dan membatalkan token di topik ini.

2. Buat Circuit QASM​

Kamu membutuhkan setidaknya satu Circuit sebagai input untuk primitive Estimator.

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

Cuplikan kode berikut mengasumsikan bahwa qasm_string telah ditranspilasi ke string baru resulting_qasm.

3. Jalankan Circuit kuantum menggunakan Estimator V2 API​

catatan

Job-job berikut menggunakan Qiskit Runtime V2 primitives. Baik SamplerV2 maupun EstimatorV2 menerima satu atau lebih primitive unified blocs (PUBs) sebagai input. Setiap PUB adalah tuple yang berisi satu Circuit dan data yang disiarkan ke Circuit tersebut, yang bisa berupa beberapa observabel dan parameter. Setiap PUB mengembalikan satu hasil.

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. Periksa status job dan dapatkan hasilnya​

Selanjutnya, masukkan 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 hasil job:

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 opsi Runtime​

Teknik mitigasi error memungkinkan pengguna mengurangi error pada Circuit dengan memodelkan noise perangkat saat eksekusi berlangsung. Hal ini biasanya menghasilkan overhead pra-pemrosesan kuantum terkait pelatihan model, serta overhead pasca-pemrosesan klasikal untuk mengurangi error pada hasil mentah menggunakan model yang dihasilkan.

Teknik mitigasi error yang sudah terintegrasi ke dalam primitives adalah opsi resilience tingkat lanjut. Untuk menentukan opsi-opsi ini, gunakan opsi resilience_level saat mengirimkan job kamu.

Contoh-contoh berikut mendemonstrasikan opsi default untuk dynamical decoupling, twirling, dan TREX + ZNE. Temukan lebih banyak opsi dan detail lebih lanjut di topik Teknik mitigasi dan supresi error.

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

Sampler primitive with REST API​

1. Initialize the account​

Karena Qiskit Runtime Sampler adalah layanan terkelola, kamu harus menginisialisasi akunmu terlebih dahulu. Kemudian kamu dapat memilih perangkat yang ingin kamu gunakan untuk menjalankan perhitungan.

Lihat detail tentang cara menginisialisasi akun, melihat backend yang tersedia, dan menonaktifkan token di topik ini.

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

The code snippets given below assume that the qasm_string has been transpiled to a new string resulting_qasm.

3. Run the quantum circuit using Sampler V2 API​

catatan

The jobs below use Qiskit Runtime V2 primitives. Both SamplerV2 and EstimatorV2 take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.

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. Check job status and get results​

Next, pass the job_id to the 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

Get job results:

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. Work with Runtime options​

Teknik mitigasi error memungkinkan kamu untuk mengurangi error circuit dengan memodelkan noise perangkat pada saat eksekusi. Ini biasanya menghasilkan overhead pra-pemrosesan kuantum yang terkait dengan pelatihan model, dan overhead pasca-pemrosesan klasik untuk mengurangi error dalam hasil mentah menggunakan model yang dihasilkan.

Teknik mitigasi error yang terintegrasi dalam primitive adalah opsi resilience tingkat lanjut. Untuk menentukan opsi ini, gunakan opsi resilience_level saat mengirimkan job. Sampler V2 tidak mendukung penentuan tingkat resilience. Namun, kamu dapat mengaktifkan atau menonaktifkan metode mitigasi/penekanan error secara individual.

Contoh berikut menunjukkan opsi default untuk dynamical decoupling dan twirling. Lihat opsi lain dan detail lebih lanjut di topik Teknik mitigasi dan penekanan error.

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

Sampler primitive with REST API and parameterized circuits​

1. Initialize the account​

Karena Qiskit Runtime adalah layanan terkelola, kamu harus menginisialisasi akunmu terlebih dahulu. Kemudian kamu dapat memilih perangkat yang ingin kamu gunakan untuk menjalankan perhitungan.

Lihat detail tentang cara menginisialisasi akun, melihat backend yang tersedia, dan menonaktifkan token di topik ini.

2. Define parameters​

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. Create a quantum circuit and add parameterized 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. Generate QASM 3 code​

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

5. Run the quantum circuit using Sampler V2 API​

catatan

The following jobs use Qiskit Runtime V2 primitives. Both SamplerV2 and EstimatorV2 take one or more primitive unified blocs (PUBs) as the input. Each PUB is a tuple that contains one circuit and the data broadcasted to that circuit, which can be multiple observables and parameters. Each PUB returns a result.

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. Check job status and get results​

Next, pass the job_id to the API:

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

Output

{'status': 'Completed'}

Get job results:

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 selanjutnya​

Rekomendasi