דלג לתוכן הראשי

תחילת העבודה עם primitives

מודל הרצה חדש, עכשיו בגרסת בטא

גרסת הבטא של מודל הרצה חדש זמינה כעת. מודל ההרצה המכוון מספק גמישות רבה יותר בהתאמה אישית של תהליך העבודה לצמצום שגיאות. ראה את המדריך Directed execution model לקבלת מידע נוסף.

הערה

בעוד שתיעוד זה משתמש ב-primitives מ-Qiskit Runtime, המאפשרים שימוש ב-backends של IBM®, ניתן להריץ את ה-primitives על כל ספק על ידי שימוש ב-backend primitives במקום. בנוסף, ניתן להשתמש ב-primitives של reference להרצה על סימולטור statevector מקומי. ראה Exact simulation with Qiskit primitives לפרטים.

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

השלבים בנושא זה מתארים כיצד להגדיר primitives, לחקור את האפשרויות הזמינות לקונפיגורציה שלהם, ולהפעיל אותם בתוכנית.

שימוש ב-Fractional Gates

כדי להשתמש ב-fractional gates הנתמכים החדשים, הגדר use_fractional_gates=True בעת בקשת Backend מ-QiskitRuntimeService. לדוגמה:

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

שים לב שזוהי תכונה ניסיונית ועשויה להשתנות בעתיד.

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

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 ו-observable

אתה צריך לפחות Circuit אחד ו-observable אחד כקלט ל-Estimator primitive.

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 וה-observable צריכים להיות מומרים לשימוש רק בהוראות הנתמכות על ידי ה-QPU (המכונות מעגלים של ארכיטקטורת מערכת הוראות (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 עבור מצבי הרצה של אצווה, סשן ועבודה, בהתאמה. לקבלת מידע נוסף, ראה Introduction to Qiskit Runtime execution modes.

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. הפעלת ה-Estimator וקבלת תוצאות

בשלב הבא, הפעל את המתודה run() לחישוב ערכי ציפייה עבור ה-Circuits וה-observables שהוזנו. ה-Circuit, ה-observable וערכי הפרמטרים האופציונליים מוזנים כ-tuples של 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 primitive.

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 עבור מצבי הרצה של אצווה, סשן ועבודה, בהתאמה. לקבלת מידע נוסף, ראה Introduction to Qiskit Runtime execution modes. שים לב שמשתמשי Open Plan אינם יכולים לשלוח עבודות סשן.

from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

4. הפעלת ה-Sampler וקבלת תוצאות

בשלב הבא, הפעל את המתודה run() ליצירת הפלט. ה-Circuit וערכי הפרמטרים האופציונליים מוזנים כ-tuples של 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 primitives

בניגוד ל-primitives ספציפיים לספק, backend primitives הם מימושים גנריים שניתן להשתמש בהם עם כל אובייקט backend שרירותי, כל עוד הוא מממש את ממשק Backend.

חלק מהספקים מממשים primitives באופן ילידי. ראה את דף 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)

דמיון והבדלים בין backend ל-Runtime primitives

צעדים הבאים

המלצות