ข้ามไปยังเนื้อหาหลัก

เริ่มต้นใช้งาน Primitive

New execution model, now in beta release

การเปิดตัว beta ของโมเดลการรันใหม่มีให้ใช้งานแล้ว โมเดล directed execution มอบความยืดหยุ่นมากขึ้นในการปรับแต่ง error mitigation workflow ดูรายละเอียดได้ที่คู่มือ Directed execution model

หมายเหตุ

แม้ว่าเอกสารนี้จะใช้ primitive จาก Qiskit Runtime ซึ่งให้ใช้งาน IBM® Backend ได้ แต่ primitive สามารถรันบน provider ใดก็ได้โดยใช้ backend primitives แทน นอกจากนี้ยังสามารถใช้ reference primitive เพื่อรันบน local statevector simulator ดูรายละเอียดได้ที่ การจำลองแบบแม่นยำด้วย Qiskit primitives

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

ขั้นตอนในหัวข้อนี้อธิบายวิธีตั้งค่า primitive สำรวจตัวเลือกที่ใช้กำหนดค่า และเรียกใช้ใน program

Using Fractional Gates

หากต้องการใช้ fractional gates ที่รองรับใหม่ ให้ตั้งค่า use_fractional_gates=True เมื่อขอ Backend จาก instance QiskitRuntimeService ตัวอย่างเช่น:

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

โปรดทราบว่านี่เป็นฟีเจอร์ทดลองและอาจมีการเปลี่ยนแปลงในอนาคต

Package versions

โค้ดในหน้านี้พัฒนาโดยใช้ requirement ดังนี้ แนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า

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

เริ่มต้นใช้งาน Estimator

1. เริ่มต้น account

เนื่องจาก Qiskit Runtime Estimator เป็น managed service จึงต้องเริ่มต้น account ก่อน จากนั้นเลือก QPU ที่ต้องการใช้คำนวณค่า expectation value

ทำตามขั้นตอนใน หัวข้อ Install and set up หากยังไม่มี account

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 อย่างน้อยหนึ่งตัวเป็น input สำหรับ 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 ต้องถูกแปลงให้ใช้เฉพาะ instruction ที่ QPU รองรับ (เรียกว่า Circuit 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 ให้ใช้ parameter mode เพื่อระบุโหมดที่ต้องการรัน ค่าที่เป็นไปได้คือออบเจกต์ batch, session หรือ backend สำหรับโหมดการรันแบบ batch, session และ job ตามลำดับ ดูข้อมูลเพิ่มเติมได้ที่ บทนำสู่โหมดการรัน Qiskit Runtime

from qiskit_ibm_runtime import EstimatorV2 as Estimator

estimator = Estimator(mode=backend)

4. เรียกใช้ Estimator และรับผลลัพธ์

ถัดมา เรียกใช้เมธอด run() เพื่อคำนวณค่า expectation value สำหรับ Circuit และ observable ที่เป็น input Circuit, observable และชุดค่า parameter ที่ไม่บังคับจะถูกส่งเป็น tuple PUB (primitive unified bloc)

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. เริ่มต้น account

เนื่องจาก Qiskit Runtime Sampler เป็น managed service จึงต้องเริ่มต้น account ก่อน จากนั้นเลือก QPU ที่ต้องการใช้คำนวณค่า expectation value

ทำตามขั้นตอนใน หัวข้อ Install and set up หากยังไม่มี account

from qiskit_ibm_runtime import QiskitRuntimeService

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

2. สร้าง Circuit

ต้องมี Circuit อย่างน้อยหนึ่งตัวเป็น input สำหรับ 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 ให้ใช้ parameter mode เพื่อระบุโหมดที่ต้องการรัน ค่าที่เป็นไปได้คือออบเจกต์ batch, session หรือ backend สำหรับโหมดการรันแบบ batch, session และ job ตามลำดับ ดูข้อมูลเพิ่มเติมได้ที่ บทนำสู่โหมดการรัน Qiskit Runtime โปรดทราบว่าผู้ใช้ Open Plan ไม่สามารถส่งงาน session ได้

from qiskit_ibm_runtime import SamplerV2 as Sampler

sampler = Sampler(mode=backend)

4. เรียกใช้ Sampler และรับผลลัพธ์

ถัดมา เรียกใช้เมธอด run() เพื่อสร้าง output Circuit และชุดค่า parameter ที่ไม่บังคับจะถูกส่งเป็น tuple PUB (primitive unified bloc)

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 primitive

ต่างจาก primitive เฉพาะ provider backend primitive เป็น implementation ทั่วไปที่สามารถใช้กับออบเจกต์ backend ใดก็ได้ ตราบเท่าที่ implement interface Backend

Provider บางรายมี primitive ในตัว ดูรายละเอียดได้ที่ Qiskit Ecosystem page

ตัวอย่าง: 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 primitive และ Runtime primitive

  • input และ output ของ qiskit.primitives.BackendSamplerV2 และ qiskit.primitives.BackendEstimatorV2 ใช้รูปแบบ PUB เดียวกับ primitive ใน Qiskit Runtime ดูรายละเอียดได้ที่ Primitive inputs and outputs อย่างไรก็ตาม อาจมีความต่างในฟิลด์ของ metadata ที่ส่งคืน

  • คลาส qiskit.primitives.BackendEstimatorV2 ไม่มี measurement หรือ gate error mitigation implementation สำเร็จรูป เนื่องจาก backend primitive ออกแบบมาเพื่อรันในเครื่องของผู้ใช้

  • คลาส qiskit.primitives.BackendSamplerV2 ต้องการ Backend ที่รองรับตัวเลือก memory

  • interface ของ backend primitive เปิดเผย Options แบบกำหนดเองสำหรับ SamplerV2 และ EstimatorV2 ซึ่งต่างจาก Runtime implementation

ขั้นตอนถัดไป

Recommendations
Source: IBM Quantum docs — updated 27 เม.ย. 2569
English version on doQumentation — updated 7 พ.ค. 2569
This translation based on the English version of 11 มี.ค. 2569