Przejdź do głównej treści

Prymitywy z REST API

Kroki opisane w tym temacie pokazują, jak uruchamiać i konfigurować obciążenia prymitywów za pomocą REST API, oraz demonstrują, jak wywoływać je w dowolnym programie według własnego wyboru.

uwaga

Ta dokumentacja wykorzystuje moduł Python requests do zademonstrowania Qiskit Runtime REST API. Jednak ten przepływ pracy można wykonać przy użyciu dowolnego języka lub frameworka obsługującego REST API. Szczegółowe informacje znajdziesz w dokumentacji referencyjnej API.

Estimator primitive z REST API

1. Zainicjuj konto

Ponieważ Qiskit Runtime Estimator jest usługą zarządzaną, najpierw musisz zainicjować swoje konto. Następnie możesz wybrać urządzenie, którego chcesz użyć do obliczenia wartości oczekiwanej.

Szczegóły dotyczące inicjowania konta, przeglądania dostępnych Backend-ów i unieważniania tokenów znajdziesz w tym temacie.

2. Utwórz Circuit QASM

Potrzebujesz co najmniej jednego Circuit jako danych wejściowych dla prymitywu Estimator.

Zdefiniuj Circuit kwantowy QASM. Na przykład:

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

Poniższe fragmenty kodu zakładają, że qasm_string został poddany transpilacji do nowego ciągu znaków resulting_qasm.

3. Uruchom Circuit kwantowy za pomocą Estimator V2 API

uwaga

Poniższe zadania używają Qiskit Runtime V2 primitives. Zarówno SamplerV2, jak i EstimatorV2 przyjmują jeden lub więcej primitive unified bloców (PUB) jako dane wejściowe. Każdy PUB to krotka zawierająca jeden Circuit oraz dane rozgłaszane do tego Circuit, co może obejmować wiele obserwowalnych i parametrów. Każdy PUB zwraca wynik.

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. Sprawdź status zadania i pobierz wyniki

Następnie przekaż job_id do 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

Pobierz wyniki zadania:

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. Pracuj z opcjami Runtime

Techniki łagodzenia błędów pozwalają użytkownikom minimalizować błędy Circuit poprzez modelowanie szumów urządzenia w czasie wykonywania. Zazwyczaj wiąże się to z kwantowym narzutem przetwarzania wstępnego związanym z trenowaniem modelu oraz klasycznym narzutem przetwarzania końcowego służącym do łagodzenia błędów w surowych wynikach przy użyciu wygenerowanego modelu.

Techniki łagodzenia błędów wbudowane w prymitywy to zaawansowane opcje odporności. Aby określić te opcje, użyj opcji resilience_level podczas przesyłania zadania.

Poniższe przykłady demonstrują domyślne opcje dla dynamicznego odsprzęgania, twirling-u i TREX + ZNE. Więcej opcji i szczegółów znajdziesz w temacie Techniki łagodzenia i tłumienia błędów.

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

Prymityw Sampler z REST API

1. Zainicjalizuj konto

Ponieważ Qiskit Runtime Sampler jest usługą zarządzaną, najpierw musisz zainicjalizować swoje konto. Następnie możesz wybrać urządzenie, na którym chcesz wykonywać obliczenia.

Szczegóły dotyczące inicjalizacji konta, przeglądania dostępnych Backend-ów oraz unieważniania tokenów znajdziesz w tym temacie.

2. Utwórz Circuit QASM

Potrzebujesz co najmniej jednego Circuit jako wejścia do prymitywu Sampler.

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

Poniższe fragmenty kodu zakładają, że qasm_string został przetranspilowany do nowego ciągu znaków resulting_qasm.

3. Uruchom kwantowy Circuit za pomocą API Sampler V2

uwaga

Poniższe zadania korzystają z prymitywów Qiskit Runtime V2. Zarówno SamplerV2, jak i EstimatorV2 przyjmują jeden lub więcej prymitywnych bloków zunifikowanych (PUB) jako wejście. Każdy PUB to krotka zawierająca jeden Circuit oraz dane rozgłaszane do tego Circuit, którymi może być wiele obserwabli i parametrów. Każdy PUB zwraca wynik.

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. Sprawdź status zadania i pobierz wyniki

Następnie przekaż job_id do API:

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

Wynik

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

Pobierz wyniki zadania:

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

Wynik

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

5. Praca z opcjami Runtime

Techniki mitygacji błędów pozwalają użytkownikom ograniczać błędy Circuit przez modelowanie szumów urządzenia w czasie wykonania. Zazwyczaj wiąże się to z narzutem przetwarzania wstępnego związanym z trenowaniem modelu oraz narzutem przetwarzania klasycznego służącym do mitygacji błędów w surowych wynikach przy użyciu wygenerowanego modelu.

Techniki mitygacji błędów wbudowane w prymitywy to zaawansowane opcje odporności. Aby je określić, użyj opcji resilience_level podczas przesyłania zadania. Sampler V2 nie obsługuje określania poziomów odporności. Możesz jednak włączać lub wyłączać poszczególne metody mitygacji / tłumienia błędów.

Poniższe przykłady przedstawiają domyślne opcje dynamicznego odsprzęgania i twirling-u. Więcej opcji i szczegółów znajdziesz w temacie Techniki mitygacji i tłumienia błędów.

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

Primitive Sampler z REST API i parametryzowanymi Circuit

1. Zainicjuj konto

Ponieważ Qiskit Runtime jest usługą zarządzaną, najpierw musisz zainicjować swoje konto. Następnie możesz wybrać urządzenie, na którym chcesz wykonywać obliczenia.

Szczegółowe informacje na temat inicjowania konta, przeglądania dostępnych Backend oraz unieważniania tokenów znajdziesz w tym temacie.

2. Zdefiniuj parametry

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. Utwórz Circuit kwantowy i dodaj sparametryzowane Gate

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. Wygeneruj kod QASM 3

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

5. Uruchom Circuit kwantowy za pomocą API Sampler V2

uwaga

Poniższe zadania korzystają z prymitywów Qiskit Runtime V2. Zarówno SamplerV2, jak i EstimatorV2 przyjmują jeden lub więcej primitive unified blocs (PUB) jako dane wejściowe. Każdy PUB to krotka zawierająca jeden Circuit oraz dane rozgłaszane do tego Circuit, które mogą obejmować wiele obserwabli i parametrów. Każdy PUB zwraca wynik.

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. Sprawdź status zadania i pobierz wyniki

Następnie przekaż job_id do API:

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

Wynik

{'status': 'Completed'}

Pobierz wyniki zadania:

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

Wynik

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

Następne kroki

Rekomendacje