Przejdź do głównej treści
Ten projekt jest w wersji beta. Znalazłeś błąd? Otwórz zgłoszenie na GitHub. Masz pytanie lub pomysł? Zapytaj w Discussions — chętnie poznamy Twoją opinię!
Jak oceniasz jakość tłumaczenia tej strony?

Estimator z REST API

Package versions

Kod na tej stronie został opracowany z użyciem następujących wersji pakietów. 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.

uwaga

Ta dokumentacja wykorzystuje moduł Python requests do zademonstrowania 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ż 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ą prymitywów IBM Quantum. Zarówno Sampler, jak i Estimator przyjmują jeden lub więcej prymitywnych zunifikowanych bloków (PUB) jako dane wejściowe. Każdy PUB to krotka zawierająca jeden obwód oraz dane rozgłaszane do tego obwodu, którymi mogą 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. Praca z opcjami​

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​

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​

Rekomendacje
  • Istnieje kilka sposobów uruchamiania obciążeń, w zależności od potrzeb: job mode, session mode i batch mode. Dowiedz się, jak pracować z session mode i batch mode w temacie dotyczącym trybów wykonywania. Pamiętaj, że użytkownicy planu Open nie mogą przesyłać zadań w session mode.
  • 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.