Lewati ke konten utama

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:

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.

catatan

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.

Catatan
  • 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.

catatan

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: โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
Catatan penting
  • 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.

catatan

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 if dan 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_test pertama pada c0 dianggap satu broadcast karena konten c0 tidak berubah, dan karenanya tidak perlu di-broadcast ulang. if_test pada c1 adalah broadcast kedua. Yang pertama mem-broadcast semua tiga bit dalam c0 dan 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_test harus 32 bit atau kurang. Jadi, jika kamu membandingkan seluruh ClassicalRegister, ukuran ClassicalRegister tersebut harus 32 bit atau kurang. Jika kamu hanya membandingkan satu bit dari ClassicalRegister, bagaimanapun, ClassicalRegister tersebut bisa berukuran berapa saja (karena operandnya hanya satu bit).

    Misalnya, blok kode "Tidak valid" tidak berfungsi karena cr lebih 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".

    cr = ClassicalRegister(50)
    qr = QuantumRegister(50)
    circuit = QuantumCircuit(qr, cr)
    ...
    circ.measure(qr, cr)
    with circ.if_test((cr, 15)):
    ...
  • Kondisional bersarang tidak diizinkan. Misalnya, blok kode berikut tidak akan berfungsi karena memiliki if_test di dalam if_test lain:

    c1 = ClassicalRegister(1, "c1")
    c2 = ClassicalRegister(2, "c2")
    ...
    with circ.if_test((c1, 1)):
    with circ.if_test(c2, 1)):
    ...
  • Memiliki reset atau 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, dan switch tidak 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:

  1. Kelompokkan term-term dari semua observable ke dalam sebuah partisi. Ini bisa dilakukan menggunakan API PauliList, misalnya.
    catatan

    Kamu bisa menggunakan atribut primitif BitArray untuk menghitung nilai ekspektasi dari observable yang diberikan.

  2. Eksekusi satu circuit perubahan basis per partisi (perubahan basis apa pun yang perlu dilakukan untuk setiap partisi). Lihat modul measurement_bases addon utility Measurement bases untuk informasi lebih lanjut. Untuk informasi lebih lanjut, lihat dokumentasi untuk paket Qiskit addon utilities.
  3. 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โ€‹

Rekomendasi