انتقل إلى المحتوى الرئيسي

ابدأ مع الأوليات (Primitives)

نموذج تنفيذ جديد، متاح الآن في إصدار تجريبي (بيتا)

الإصدار التجريبي لنموذج التنفيذ الجديد متاح الآن. يوفر نموذج التنفيذ الموجَّه مرونةً أكبر عند تخصيص سير عمل تخفيف الأخطاء لديك. راجع دليل نموذج التنفيذ الموجَّه للمزيد من المعلومات.

ملاحظة

رغم أن هذه الوثائق تستخدم الأوليات من Qiskit Runtime التي تتيح لك استخدام backend من IBM®، يمكن تشغيل الأوليات مع أي مزوّد باستخدام أوليات backend عوضًا عن ذلك. بالإضافة إلى ذلك، يمكنك استخدام الأوليات المرجعية للتشغيل على محاكي statevector محلي. راجع المحاكاة الدقيقة مع أوليات Qiskit لمزيد من التفاصيل.

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

تصف الخطوات في هذا الموضوع كيفية إعداد الأوليات، واستكشاف الخيارات التي يمكنك استخدامها لتهيئتها، واستدعائها في برنامجك.

استخدام البوابات الكسرية (Fractional Gates)

لاستخدام البوابات الكسرية المدعومة حديثًا، عيّن use_fractional_gates=True عند طلب backend من نسخة 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. إنشاء دائرة ومؤثِّر (Observable)

تحتاج إلى دائرة واحدة على الأقل ومؤثِّر واحد على الأقل كمدخلات لأولية 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...', ...]

يجب تحويل الدائرة والمؤثِّر ليستخدما فقط التعليمات التي تدعمها وحدة المعالجة الكمية (يُشار إليها بدوائر معمارية مجموعة التعليمات (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() لحساب قيم التوقع للدوائر والمؤثِّرات المُدخَلة. تُدخَل الدائرة والمؤثِّر ومجموعات قيم المعاملات الاختيارية كصِيَغ كتلة أولية موحدة (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)

تحتاج إلى دائرة واحدة على الأقل كمدخل لأولية 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.

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() لتوليد المخرجات. تُدخَل الدائرة ومجموعات قيم المعاملات الاختيارية كصِيَغ كتلة أولية موحدة (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 هي تطبيقات عامة يمكن استخدامها مع أي كائن backend اعتباطي، طالما أنه يُنفِّذ واجهة Backend.

بعض المزوِّدين يُطبِّقون الأوليات بصورة أصلية. راجع صفحة نظام Qiskit البيئي لمزيد من التفاصيل.

مثال: 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

الخطوات التالية

توصيات