Estimator z REST API
Package versions
Kod na tej stronie został opracowany przy użyciu następujących wymagań. Zalecamy używanie tych wersji lub nowszych.
qiskit[all]~=2.3.0
Kroki opisane w tym temacie pokazują, jak uruchamiać i konfigurować obciążenia za pomocą REST API, oraz demonstrują, jak wywoływać je w dowolnym programie według własnego wyboru.
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.
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
Poniższe zadania używają prymitywów Qiskit Runtime V2. 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 obwód oraz dane rozgłaszane do tego obwód, 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': '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')
Wynik
>>> 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)
Wynik
[{'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.
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}")
Dynamiczne odsprzęganie
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}")
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": {
"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}")
Parametryzowane 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óły dotyczące inicjowania konta, przeglądania dostępnych Backend-ów i 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ą Estimator 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': 'estimator',
"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
- Istnieje kilka sposobów uruchamiania obciążeń, w zależności od potrzeb: tryb zadania, tryb Session i tryb wsadowy. Dowiedz się, jak pracować z trybem Session i trybem wsadowym w temacie dotyczącym trybów wykonywania. Pamiętaj, że użytkownicy planu Open nie mogą przesyłać zadań w trybie Session.
- Dowiedz się, jak zainicjować konto za pomocą REST API.
- Ćwicz z prymitywami, realizując lekcję dotyczącą funkcji kosztu w IBM Quantum® Learning.
- Dowiedz się, jak Transpilować lokalnie, korzystając z sekcji Transpile.