Eksekusi dynamic circuit
Versi paket
Kode di halaman ini dikembangkan menggunakan persyaratan berikut. Kami menyarankan menggunakan versi ini atau yang lebih baru.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Dynamic circuit adalah alat yang powerful yang dengannya kamu bisa mengukur qubit di tengah eksekusi quantum circuit dan kemudian melakukan operasi logika klasik di dalam circuit, berdasarkan hasil pengukuran mid-circuit tersebut. Proses ini juga dikenal sebagai classical feedforward. Meskipun masih awal dalam memahami cara terbaik memanfaatkan dynamic circuit, komunitas riset kuantum telah mengidentifikasi sejumlah kasus penggunaan, seperti berikut:
- Persiapan state kuantum yang efisien, seperti state GHZ, W-state (untuk informasi lebih lanjut tentang W-state, lihat juga "State preparation by shallow circuits using feed forward"), dan kelas luas matrix product states
- Entanglement jarak jauh yang efisien antara qubit di chip yang sama menggunakan circuit dangkal
- Pengambilan sampel circuit mirip-IQP yang efisien
Peningkatan yang dibawa oleh dynamic circuit ini, bagaimanapun, memiliki trade-off. Pengukuran mid-circuit dan operasi klasik biasanya memiliki waktu eksekusi yang lebih lama daripada gate dua-qubit, dan peningkatan waktu ini mungkin membatalkan manfaat dari pengurangan kedalaman circuit. Karena itu, mengurangi durasi pengukuran mid-circuit adalah area fokus perbaikan saat IBM Quantumยฎ merilis versi baru dynamic circuit. Untuk batasan lain saat menggunakan dynamic circuit, lihat tabel kompatibilitas fitur Estimator atau Sampler.
Spesifikasi OpenQASM 3 mendefinisikan sejumlah struktur alur kontrol, tetapi Qiskit Runtime saat ini hanya mendukung pernyataan if kondisional. Di Qiskit SDK, ini sesuai dengan metode if_test pada QuantumCircuit. Metode ini mengembalikan context manager dan biasanya digunakan dalam pernyataan with. Panduan ini menjelaskan cara menggunakan pernyataan kondisional ini.
Contoh kode dalam panduan ini menggunakan instruksi measure standar untuk pengukuran mid-circuit. Namun, disarankan kamu menggunakan instruksi MidCircuitMeasure sebagai gantinya, jika backend mendukungnya. Lihat bagian Pengukuran mid-circuit untuk detailnya.
Temukan backend yang mendukung dynamic circuitโ
Untuk menemukan semua backend yang bisa diakses akunmu dan mendukung dynamic circuit, jalankan kode seperti berikut. Contoh ini mengasumsikan kamu telah menyimpan kredensial login-mu. Kamu juga bisa secara eksplisit menentukan kredensial saat menginisialisasi akun layanan Qiskit Runtime-mu. Ini memungkinkan kamu melihat backend yang tersedia pada instansi atau tipe plan tertentu, misalnya.
- Backend yang tersedia untuk akun bergantung pada instansi yang ditentukan dalam kredensial.
- Versi baru dynamic circuit sekarang tersedia untuk semua pengguna di semua backend. Lihat pengumumannya untuk detail lebih lanjut.
# Added by doQumentation โ required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
# This cell is hidden from users. It hides all those "...instance was not set..." warnings.
import warnings
warnings.filterwarnings("ignore", message=".*Instance was not set*")
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
dc_backends = service.backends(dynamic_circuits=True)
print(dc_backends)
[<IBMBackend('ibm_pittsburgh')>, <IBMBackend('ibm_kingston')>, <IBMBackend('ibm_marrakesh')>, <IBMBackend('ibm_fez')>, <IBMBackend('ibm_boston')>]
Pengukuran mid-circuitโ
Sebelum qiskit-ibm-runtime v0.43.0, measure adalah satu-satunya instruksi pengukuran di Qiskit. Pengukuran mid-circuit, bagaimanapun, memiliki persyaratan penyetelan yang berbeda dari pengukuran terminal (pengukuran yang terjadi di akhir circuit). Misalnya, kamu perlu mempertimbangkan durasi instruksi saat menyetel pengukuran mid-circuit karena instruksi yang lebih lama menyebabkan circuit yang lebih berisik. Kamu tidak perlu mempertimbangkan durasi instruksi untuk pengukuran terminal karena tidak ada instruksi setelah pengukuran terminal.
Instruksi MidCircuitMeasure memetakan ke instruksi measure_2 yang dilaporkan dalam supported_instructions backend. Namun, measure_2 tidak didukung di semua backend. Gunakan service.backends(filters=lambda b: "measure_2" in b.supported_instructions) untuk menemukan backend yang mendukungnya. Pengukuran baru mungkin ditambahkan di masa depan, tetapi ini tidak dijamin.
Metode MidCircuitMeasureโ
Di qiskit-ibm-runtime v0.43.0, instruksi MidCircuitMeasure diperkenalkan. Seperti namanya, ini adalah instruksi pengukuran baru yang dioptimalkan untuk mid-circuit pada QPU IBMยฎ. Meskipun kamu bisa menggunakan QuantumCircuit.measure untuk pengukuran mid-circuit, karena desainnya, MidCircuitMeasure biasanya merupakan pilihan yang lebih baik. Misalnya, ini menambahkan overhead yang lebih sedikit ke circuit-mu daripada menggunakan QuantumCircuit.measure.
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime.circuit import MidCircuitMeasure
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, dynamic_circuits=True
)
circ = QuantumCircuit(2, 2)
circ.x(0)
circ.append(MidCircuitMeasure(), [0], [0])
# circ.measure([0], [0])
# circ.measure_all()
print(circ.draw(cregbundle=False))
โโโโโโโโโโโโโโโโโโโ
q_0: โค X โโค0 โ
โโโโโโ โ
q_1: โโโโโโค Measure_2 โ
โ โ
c_0: โโโโโโก0 โ
โโโโโโโโโโโโโโ
c_1: โโโโโโโโโโโโโโโโโโโ
- Harus ada setidaknya satu classical register untuk menggunakan pengukuran.
- Primitif Sampler memerlukan pengukuran circuit. Kamu bisa menambahkan pengukuran circuit dengan primitif Estimator, tetapi pengukuran tersebut diabaikan.
Storeโ
Dengan qiskit-ibm-runtime versi 0.47.0 atau lebih baru, kamu bisa menggunakan instruksi store untuk menyimpan hasil ekspresi klasik, jika ekspresi tersebut akan digunakan berulang kali. Operasi diparalelkan secara otomatis, membuat kode-mu jauh lebih efisien saat runtime.
Untuk informasi lebih lanjut, lihat panduan Classical feedforward and control flow.
Ketika kamu menggunakan store untuk menyimpan nilai ke classical register pada backend nyata, nilai tersebut hanya disimpan di memori selama eksekusi dan tidak disalin atau dikembalikan dalam hasil job.
Misalnya, dalam kode berikut, temp memiliki nilai yang sama dengan creg selama eksekusi, dan if_test bekerja seperti yang diharapkan. Tetapi setelah job selesai, temp BitArray yang dikembalikan dalam hasil job tidak mengandung nilai creg. Artinya, job.result()[0].data.temp adalah 0.
creg = ClassicalRegister(3, "c")
temp = ClassicalRegister(3, "temp")
...
qc.store(temp, creg)
with circuit.if_test((temp, 0b001)):
...
Contoh lengkapโ
Kode berikut membuat dan menjalankan dynamic circuit pada hardware IBMยฎ.
from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, dynamic_circuits=True
)
# Create a dynamic circuit
qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
qc = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits
qc.h(q0)
qc.measure(q0, c0)
with qc.if_test((c0, 1)):
qc.x(q0)
qc.measure(q0, c0)
# Convert to an ISA circuit for the given backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Generate samplers for backend targets
sampler = SamplerV2(backend)
# Submit jobs
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
print(
f">>> {' Job ID:':<10} {sampler_job.job_id()} ({sampler_job.status()})"
)
>>> Job ID: d88cakp789is7391vq0g (DONE)
Batasan Qiskit Runtimeโ
Perhatikan batasan-batasan berikut saat menjalankan dynamic circuit di Qiskit Runtime.
-
Karena keterbatasan memori fisik pada elektronik kontrol, ada juga batas jumlah pernyataan
ifdan ukuran operandnya. Batas ini merupakan fungsi dari jumlah broadcast dan jumlah bit yang di-broadcast dalam sebuah job (bukan circuit).Saat memproses kondisi
if, data pengukuran perlu ditransfer ke logika kontrol untuk membuat evaluasi tersebut. Broadcast adalah transfer data klasik yang unik, dan bit yang di-broadcast adalah jumlah bit klasik yang ditransfer. Pertimbangkan berikut ini:c0 = ClassicalRegister(3)c1 = ClassicalRegister(5)...with circuit.if_test((c0, 1)) ...with circuit.if_test((c0, 3)) ...with circuit.if_test((c1[2], 1)) ...Dalam contoh kode sebelumnya, dua objek
if_testpertama padac0dianggap satu broadcast karena kontenc0tidak berubah, dan karenanya tidak perlu di-broadcast ulang.if_testpadac1adalah broadcast kedua. Yang pertama mem-broadcast semua tiga bit dalamc0dan yang kedua mem-broadcast hanya satu bit, membuat total empat bit yang di-broadcast.Saat ini, jika kamu mem-broadcast 60 bit setiap kali, maka job dapat memiliki sekitar 300 broadcast. Jika kamu mem-broadcast hanya satu bit setiap kali, bagaimanapun, maka job dapat memiliki 2400 broadcast.
-
Operand yang digunakan dalam pernyataan
if_testharus 32 bit atau kurang. Jadi, jika kamu membandingkan seluruhClassicalRegister, ukuranClassicalRegistertersebut harus 32 bit atau kurang. Jika kamu hanya membandingkan satu bit dariClassicalRegister, bagaimanapun,ClassicalRegistertersebut bisa berukuran berapa saja (karena operandnya hanya satu bit).Misalnya, blok kode "Tidak valid" tidak berfungsi karena
crlebih dari 32 bit. Namun, kamu bisa menggunakan classical register yang lebih lebar dari 32 bit jika kamu hanya menguji satu bit, seperti yang ditunjukkan dalam blok kode "Valid".- Tidak valid
- Valid
cr = ClassicalRegister(50)qr = QuantumRegister(50)circuit = QuantumCircuit(qr, cr)...circ.measure(qr, cr)with circ.if_test((cr, 15)):...cr = ClassicalRegister(50)qr = QuantumRegister(50)circuit = QuantumCircuit(qr, cr)...circ.measure(qr, cr)with circ.if_test((cr[5], 1)):... -
Kondisional bersarang tidak diizinkan. Misalnya, blok kode berikut tidak akan berfungsi karena memiliki
if_testdi dalamif_testlain:- Tidak valid
- Valid
c1 = ClassicalRegister(1, "c1")c2 = ClassicalRegister(2, "c2")...with circ.if_test((c1, 1)):with circ.if_test(c2, 1)):...cr = ClassicalRegister(2)...with circuit.if_test((cr, 0b11)):... -
Memiliki
resetatau pengukuran di dalam kondisional tidak didukung. -
Operasi aritmatika tidak didukung.
-
Lihat tabel fitur OpenQASM 3 untuk menentukan fitur OpenQASM 3 mana yang didukung di Qiskit dan Qiskit Runtime.
-
Ketika OpenQASM 3 (bukannya
QuantumCircuit) digunakan sebagai format input untuk meneruskan circuit ke primitif Qiskit Runtime, hanya instruksi yang dapat dimuat ke dalam Qiskit yang didukung. Operasi klasik, misalnya, tidak didukung karena tidak bisa dimuat ke dalam Qiskit. Lihat Impor program OpenQASM 3 ke dalam Qiskit untuk informasi lebih lanjut. -
Instruksi
for,while, danswitchtidak didukung.
Gunakan dynamic circuit dengan Estimatorโ
Karena Estimator tidak mendukung dynamic circuit, kamu bisa menggunakan Sampler dan membangun circuit pengukuranmu sendiri.
Untuk mereplikasi perilaku Estimator, ikuti proses ini:
- Kelompokkan term-term dari semua observable ke dalam sebuah partisi. Ini bisa dilakukan menggunakan API
PauliList, misalnya.catatanKamu bisa menggunakan atribut primitif
BitArrayuntuk menghitung nilai ekspektasi dari observable yang diberikan. - Eksekusi satu circuit perubahan basis per partisi (perubahan basis apa pun yang perlu dilakukan untuk setiap partisi). Lihat modul
measurement_basesaddon utility Measurement bases untuk informasi lebih lanjut. Untuk informasi lebih lanjut, lihat dokumentasi untuk paket Qiskit addon utilities. - Tambahkan kembali hasil untuk setiap partisi.
Pembatasanโ
Tinjau tabel kompatibilitas fitur apapun untuk memahami pembatasan saat menggunakan dynamic circuit. Perhatikan bahwa kompatibilitas fitur tidak bergantung pada primitif.
Langkah selanjutnyaโ
- Pelajari cara mengimplementasikan dynamical decoupling yang akurat menggunakan stretch.
- Tinjau panduan classical feedforward dan alur kontrol.
- Gunakan visualisasi jadwal circuit untuk men-debug dan mengoptimalkan dynamic circuit-mu.
- Tidak semua fungsi kompatibel dengan dynamic circuit. Periksa bagian kompatibilitas fitur untuk Sampler atau Executor untuk detailnya.