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

Початок роботи з примітивами

Нова модель виконання — зараз у бета-релізі

Бета-версія нової моделі виконання вже доступна. Направлена модель виконання забезпечує більшу гнучкість при налаштуванні робочого процесу пом'якшення помилок. Дивись посібник Directed execution model для отримання додаткової інформації.

примітка

Хоча ця документація використовує примітиви з Qiskit Runtime, які дозволяють використовувати бекенди IBM®, примітиви можна запускати з будь-яким провайдером за допомогою бекенд-примітивів. Крім того, ти можеш використовувати reference-примітиви для запуску на локальному симуляторі стейт-вектора. Дивись Точна симуляція з примітивами Qiskit для деталей.

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime

Кроки в цьому розділі описують, як налаштувати примітиви, дослідити параметри їх конфігурації та викликати їх у програмі.

Використання дробових гейтів

Щоб скористатися новими підтримуваними дробовими гейтами, встанови use_fractional_gates=True при запиті бекенду з екземпляра QiskitRuntimeService. Наприклад:

service = QiskitRuntimeService()
fractional_gate_backend = service.least_busy(use_fractional_gates=True)

Зауважте, що це експериментальна функція, яка може змінитися в майбутньому.

Версії пакетів

Код на цій сторінці розроблено з використанням наведених нижче вимог. Рекомендуємо використовувати ці або новіші версії.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

Початок роботи з Estimator

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

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

Виконай кроки з теми встановлення та налаштування, якщо акаунт ще не налаштовано.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

print(backend.name)
ibm_torino

2. Створення Circuit та спостережуваної величини

Тобі потрібен щонайменше один Circuit і одна спостережувана величина як вхідні дані для примітиву Estimator.

from qiskit.circuit.library import qaoa_ansatz
from qiskit.quantum_info import SparsePauliOp

entanglement = [tuple(edge) for edge in backend.coupling_map.get_edges()]
observable = SparsePauliOp.from_sparse_list(
[("ZZ", [i, j], 0.5) for i, j in entanglement],
num_qubits=backend.num_qubits,
)
circuit = qaoa_ansatz(observable, reps=2)
# the circuit is parametrized, so we will define the parameter values for execution
param_values = [0.1, 0.2, 0.3, 0.4]

print(f">>> Observable: {observable.paulis}")
>>> Observable: ['IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...',
'IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...', ...]

Circuit і спостережувана величина мають бути перетворені так, щоб використовувати лише інструкції, підтримувані QPU (відомі як схеми instruction set architecture (ISA)). Для цього скористаємося Transpiler.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")
>>> Circuit ops (ISA): OrderedDict([('rz', 3826), ('sx', 1601), ('cz', 968)])

3. Ініціалізація Qiskit Runtime Estimator

Під час ініціалізації Estimator використовуй параметр mode, щоб вказати режим роботи. Можливі значення — batch, session або об'єкти backend для режимів пакетного, сеансового та одиночного виконання відповідно. Для отримання додаткової інформації дивись Введення у режими виконання Qiskit Runtime.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. Виклик Estimator та отримання результатів

Далі виклич метод run(), щоб обчислити очікувані значення для вхідних схем і спостережуваних величин. Circuit, спостережувана величина та необов'язкові набори значень параметрів передаються у вигляді кортежів primitive unified bloc (PUB).

job = estimator.run([(isa_circuit, isa_observable, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")
>>> Job ID: d5k96c4jt3vs73ds5smg
>>> Job Status: QUEUED
result = job.result()
print(f">>> {result}")
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
>>> PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(), dtype=float64>), stds=np.ndarray(<shape=(), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(), dtype=float64>)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})
> Expectation value: 25.8930784649363
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Початок роботи з Sampler

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

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

Виконай кроки з теми встановлення та налаштування, якщо акаунт ще не налаштовано.

from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)

2. Створення Circuit

Тобі потрібен щонайменше один Circuit як вхідні дані для примітиву Sampler.

import numpy as np
from qiskit.circuit.library import efficient_su2

circuit = efficient_su2(127, entanglement="linear")
circuit.measure_all()
# The circuit is parametrized, so we will define the parameter values for execution
param_values = np.random.rand(circuit.num_parameters)

Використай Transpiler, щоб отримати ISA Circuit.

from qiskit.transpiler import generate_preset_pass_manager

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
print(f">>> Circuit ops (ISA): {isa_circuit.count_ops()}")
>>> Circuit ops (ISA): OrderedDict([('sx', 3089), ('rz', 3036), ('cz', 1092), ('measure', 127), ('barrier', 1)])

3. Ініціалізація Qiskit Runtime Sampler

Під час ініціалізації Sampler використовуй параметр mode, щоб вказати режим роботи. Можливі значення — batch, session або об'єкти backend для режимів пакетного, сеансового та одиночного виконання відповідно. Для отримання додаткової інформації дивись Введення у режими виконання Qiskit Runtime. Зверни увагу, що користувачі Open Plan не можуть надсилати задачі в режимі сеансу.

from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

4. Виклик Sampler та отримання результатів

Далі виклич метод run(), щоб отримати результати. Circuit і необов'язкові набори значень параметрів передаються у вигляді кортежів primitive unified bloc (PUB).

job = sampler.run([(isa_circuit, param_values)])
print(f">>> Job ID: {job.job_id()}")
print(f">>> Job Status: {job.status()}")
>>> Job ID: d5k96rsjt3vs73ds5tig
>>> Job Status: QUEUED
result = job.result()

# Get results for the first (and only) PUB
pub_result = result[0]
print(
f"First ten results for the 'meas' output register: {pub_result.data.meas.get_bitstrings()[:10]}"
)
First ten results for the 'meas' output register: ['0101001101010000011001110001011000010010001100001000100110011111011110000010110001101000110011101010000100011011000110101111000', '0100111000000100110001100100000101111000111001101000110111101110110010010100001101001111001010011101010000010011000110000010001', '0101111101111111010011010101000000110100000010000010011101100011100011001100000100100001000101000000100001010101010011001101100', '1100110101111111001110010000010100101010101010001000001100100110011111010000000010001000110111010000010101100000100000110111001', '0010000001111001111010100100010111101000101000100000101100001000011100000100011010110110100011100110001001110110111101010011000', '0101110000001000100100010010100100111000010100000000010010000000010110010010000110000001110110010100000111001110100100111101100', '0100011111101001000111110011011101101101110101110001010111011101111110011101001000000001110000011110000101010000001010000100000', '0001010101011000110100000100111111100001011000111110000011000111001101010000010001001100000110000000100000110101010010101110010', '0100011010001110011110000110100101100100101001001111010100100101010100010000000010100000101010110010000000001000010101011111110', '0000011000000111000001000101111111110110101100110000001100010010011101011100001010000100011010001010001101000000000000010001001']

Початок роботи з бекенд-примітивами

На відміну від примітивів, специфічних для провайдера, бекенд-примітиви — це загальні реалізації, які можна використовувати з довільним об'єктом backend, якщо він реалізує інтерфейс Backend.

Деякі провайдери реалізують примітиви нативно. Дивись сторінку Qiskit Ecosystem для деталей.

Приклад: BackendEstimator

from qiskit.primitives import BackendEstimatorV2
from <some_qiskit_provider> import QiskitProvider

provider = QiskitProvider()
backend = provider.get_backend('backend_name')
estimator = BackendEstimatorV2(backend)

Приклад: BackendSampler

from qiskit.primitives import BackendSamplerV2
from <some_qiskit_provider> import QiskitProvider

provider = QiskitProvider()
backend = provider.get_backend('backend_name')
sampler = BackendSamplerV2(backend)

Схожість та відмінності між бекенд-примітивами та Runtime-примітивами

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

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