Перейти до основного вмісту

Примітиви з REST API

Кроки в цій темі описують, як запускати та налаштовувати примітивні робочі навантаження за допомогою REST API, і демонструють, як викликати їх у будь-якій програмі на твій вибір.

примітка

Ця документація використовує модуль Python requests для демонстрації Qiskit Runtime REST API. Однак цей робочий процес можна виконати будь-якою мовою або фреймворком, що підтримує роботу з REST API. Деталі дивись у довідковій документації API.

Примітив Estimator з REST API

1. Ініціалізація акаунту

Оскільки Qiskit Runtime Estimator — це керований сервіс, спочатку потрібно ініціалізувати свій акаунт. Після цього ти зможеш обрати пристрій, який хочеш використовувати для обчислення очікуваних значень.

Деталі про те, як ініціалізувати акаунт, переглянути доступні бекенди та анулювати токени, читай у цій темі.

2. Створення QASM-схеми

Потрібна хоча б одна схема як вхідні дані для примітива Estimator.

Визнач квантову схему 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 було транспільовано в новий рядок resulting_qasm.

3. Запуск квантової схеми за допомогою API Estimator V2

примітка

Наступні завдання використовують примітиви Qiskit Runtime V2. І SamplerV2, і EstimatorV2 приймають один або кілька примітивних уніфікованих блоків (PUB) як вхідні дані. Кожен PUB — це кортеж, що містить одну схему і дані, які транслюються на цю схему (кілька спостережуваних і параметрів). Кожен 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': '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. Перевірка статусу завдання та отримання результатів

Далі передай 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-942fb30edcad
>>> Job Status: JobStatus.RUNNING

Отримання результатів завдання:

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

res_dict=response_result.json()

estimator_result=res_dict['results']
print(estimator_result)

Вивід

[{'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. Робота з параметрами Runtime

Техніки пом'якшення помилок дозволяють користувачам зменшувати помилки схем, моделюючи шум пристрою на момент виконання. Зазвичай це призводить до накладних витрат на квантову попередню обробку, пов'язаних із навчанням моделі, та класичних накладних витрат на подальшу обробку для зменшення помилок у сирих результатах за допомогою згенерованої моделі.

Техніки пом'якшення помилок, вбудовані в примітиви, є розширеними параметрами стійкості. Щоб задати ці параметри, використовуй опцію resilience_level під час відправки завдання.

Наступні приклади демонструють параметри за замовчуванням для динамічного розв'язання, твірлінгу та TREX + ZNE. Більше параметрів і детальну інформацію дивись у темі Техніки пом'якшення та придушення помилок.

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 з REST API

1. Ініціалізація акаунту

Оскільки Qiskit Runtime Sampler — це керований сервіс, спочатку потрібно ініціалізувати свій акаунт. Після цього ти зможеш обрати пристрій, який хочеш використовувати для своїх обчислень.

Деталі про те, як ініціалізувати акаунт, переглянути доступні бекенди та анулювати токени, читай у цій темі.

2. Створення QASM-схеми

Потрібна хоча б одна схема як вхідні дані для примітива 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 було транспільовано в новий рядок resulting_qasm.

3. Запуск квантової схеми за допомогою API Sampler V2

примітка

Наступні завдання використовують примітиви Qiskit Runtime V2. І SamplerV2, і EstimatorV2 приймають один або кілька примітивних уніфікованих блоків (PUB) як вхідні дані. Кожен PUB — це кортеж, що містить одну схему і дані, які транслюються на цю схему (кілька спостережуваних і параметрів). Кожен 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": {
"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. Перевірка статусу завдання та отримання результатів

Далі передай 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. Робота з параметрами Runtime

Техніки пом'якшення помилок дозволяють користувачам зменшувати помилки схем, моделюючи шум пристрою на момент виконання. Зазвичай це призводить до накладних витрат на квантову попередню обробку, пов'язаних із навчанням моделі, та класичних накладних витрат на подальшу обробку для зменшення помилок у сирих результатах за допомогою згенерованої моделі.

Техніки пом'якшення помилок, вбудовані в примітиви, є розширеними параметрами стійкості. Щоб задати ці параметри, використовуй опцію resilience_level під час відправки завдання. Sampler V2 не підтримує вказання рівнів стійкості. Однак ти можеш вмикати або вимикати окремі методи пом'якшення/придушення помилок.

Наступні приклади демонструють параметри за замовчуванням для динамічного розв'язання та твірлінгу. Більше параметрів і детальну інформацію дивись у темі Техніки пом'якшення та придушення помилок.

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 з REST API і параметризованими схемами

1. Ініціалізація акаунту

Оскільки Qiskit Runtime — це керований сервіс, спочатку потрібно ініціалізувати свій акаунт. Після цього ти зможеш обрати пристрій, який хочеш використовувати для своїх обчислень.

Деталі про те, як ініціалізувати акаунт, переглянути доступні бекенди та анулювати токени, читай у цій темі.

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')
parameter_values = {'theta': 1.57, 'phi': 3.14} # In case we want to pass a dictionary

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. Запуск квантової схеми за допомогою API Sampler V2

примітка

Наступні завдання використовують примітиви Qiskit Runtime V2. І SamplerV2, і EstimatorV2 приймають один або кілька примітивних уніфікованих блоків (PUB) як вхідні дані. Кожен PUB — це кортеж, що містить одну схему і дані, які транслюються на цю схему (кілька спостережуваних і параметрів). Кожен 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": {
# 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. Перевірка статусу завдання та отримання результатів

Далі передай 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']

Наступні кроки

Рекомендації