Przejdź do głównej treści

Sampler z REST API

Kroki opisane w tym temacie opisują, jak uruchamiać i konfigurować obciążenia robocze za pomocą REST API, i demonstrują, jak wywoływać je w dowolnym wybranym programie.

uwaga

Ta dokumentacja używa modułu Python requests do demonstracji REST API Qiskit Runtime. Jednak ten przepływ pracy można wykonać za pomocą dowolnego języka lub struktury obsługującej pracę z REST API. Szczegółowe informacje znajdziesz w dokumentacji referencyjnej API.

1. Zainicjuj konto

Ponieważ Qiskit Runtime Sampler 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 inicjalizacji konta, przeglądania dostępnych backendów i pracy z tokenami znajdziesz w Konfiguracja do używania IBM Quantum Platform z REST API.

2. Utwórz obwód QASM

Do prymitywu Sampler potrzebujesz co najmniej jednego obwodu jako danych wejściowych.

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

Fragmenty kodu podane poniżej zakładają, że qasm_string został transpilowany do nowego ciągu znaków resulting_qasm.

3. Uruchom obwód kwantowy za pomocą Sampler V2 API

uwaga

Poniższe zadania używają prymitywów Qiskit Runtime V2. SamplerV2 przyjmuje jeden lub więcej primitive unified bloc (PUB) jako dane wejściowe. Każdy PUB to krotka zawierająca jeden obwód i dane rozgłoszone do tego obwodu, które mogą obejmować wiele parametrów, i zwraca jeden wynik na 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": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm],[resulting_qasm,None,500]]
}}

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

Dane wyjściowe

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

Dane wyjściowe

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

5. Praca z opcjami Qiskit Runtime

Techniki łagodzenia błędów pozwalają użytkownikom łagodzić błędy obwodu poprzez modelowanie szumu urządzenia w czasie wykonania. Zazwyczaj skutkuje to kwantowym narzutem przetwarzania wstępnego związanym ze szkoleniem modelu oraz klasycznym narzutem przetwarzania końcowego w celu ł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. Sampler V2 nie obsługuje określania poziomów odporności. Możesz jednak włączyć lub wyłączyć poszczególne metody łagodzenia/tłumienia błędów.

Poniższe przykłady demonstrują domyślne opcje dynamicznego odsprzęgania i twirlingowania. Więcej opcji i szczegółów znajdziesz w temacie Techniki łagodzenia i tłumienia błędów.

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': 'sampler',
"backend": backend,
"params": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"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}")

Twirlingowanie

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": {
# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[resulting_qasm]],
"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}")

Sparametryzowane obwody

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

3. Utwórz obwód kwantowy i dodaj sparametryzowane bramki

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 obwód kwantowy za pomocą Sampler 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': 'sampler',
"backend": backend,
"params": {
# Choose one option: direct parameter transfer or through a dictionary
# # primitive unified blocs (PUBs) containing one circuit each:
#"pubs": [[qasm_str,[1,2],500]],

# primitive unified blocs (PUBs) containing one circuit each:
"pubs": [[qasm_str,parameter_values,500]],
}}

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

Dane wyjściowe

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

Dane wyjściowe

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

Następne kroki

Zalecenia
  • Istnieje kilka sposobów uruchamiania obciążeń roboczych w zależności od potrzeb: tryb zadania, tryb sesji i tryb wsadowy. Dowiedz się, jak pracować z trybem sesji i trybem wsadowym w temacie o trybach wykonania. Pamiętaj, że użytkownicy planu Open nie mogą przesyłać zadań sesji.
  • Dowiedz się, jak zainicjować swoje konto za pomocą REST API.
  • Ćwicz z prymitywami, pracując przez lekcję funkcji kosztu w IBM Quantum Learning.
  • Dowiedz się, jak transpilować lokalnie w sekcji Transpilacja.