Langkau ke kandungan utama

Suapan balik klasik dan aliran kawalan

Versi pakej

Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan penggunaan versi ini atau yang lebih baharu.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Litar dinamik kini tersedia pada semua Backend

Versi baharu litar dinamik kini tersedia kepada semua pengguna pada semua Backend. Anda boleh menjalankan litar dinamik pada skala utiliti. Lihat pengumuman ini untuk maklumat lanjut.

Litar dinamik ialah alat yang berkuasa yang membolehkan anda mengukur Qubit di tengah-tengah pelaksanaan Circuit kuantum dan kemudian melakukan operasi logik klasik dalam Circuit, berdasarkan keputusan pengukuran mid-Circuit tersebut. Proses ini juga dikenali sebagai suapan balik klasik. Walaupun ini masih peringkat awal dalam memahami cara terbaik memanfaatkan litar dinamik, komuniti penyelidikan kuantum telah mengenal pasti beberapa kes penggunaan, seperti berikut:

Namun, penambahbaikan yang dibawa oleh litar dinamik ini disertai dengan pertukaran. Pengukuran mid-Circuit dan operasi klasik biasanya mempunyai masa pelaksanaan yang lebih lama berbanding Gate dua-Qubit, dan peningkatan masa ini mungkin menghapuskan manfaat daripada kedalaman Circuit yang berkurangan. Oleh itu, mengurangkan panjang pengukuran mid-Circuit menjadi fokus penambahbaikan semasa IBM Quantum® mengeluarkan versi baharu litar dinamik.

Spesifikasi OpenQASM 3 mentakrifkan beberapa struktur aliran kawalan, tetapi Qiskit Runtime pada masa ini hanya menyokong pernyataan if bersyarat. Dalam Qiskit SDK, ini berpadanan dengan kaedah if_test pada QuantumCircuit. Kaedah ini mengembalikan pengurus konteks dan biasanya digunakan dalam pernyataan with. Panduan ini menerangkan cara menggunakan pernyataan bersyarat ini.

nota

Contoh kod dalam panduan ini menggunakan arahan ukur standard untuk pengukuran mid-Circuit. Walau bagaimanapun, adalah disyorkan agar anda menggunakan arahan MidCircuitMeasure sebaliknya, jika Backend menyokongnya. Lihat dokumentasi Pengukuran mid-Circuit untuk butiran.

Pernyataan if​

Pernyataan if digunakan untuk melaksanakan operasi secara bersyarat berdasarkan nilai bit atau daftar klasik.

Dalam contoh di bawah, kami menggunakan Gate Hadamard pada sebuah Qubit dan mengukurnya. Jika hasilnya ialah 1, maka kami menggunakan Gate X pada Qubit tersebut, yang berkesan membalikkannya semula ke keadaan 0. Kemudian kami mengukur Qubit itu sekali lagi. Hasil pengukuran seharusnya ialah 0 dengan kebarangkalian 100%.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister

qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
circuit = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits

circuit.h(q0)
# Use MidCircuitMeasure() if it's supported by the backend.
# circuit.append(MidCircuitMeasure(), [q0], [c0])
circuit.measure(q0, c0)
with circuit.if_test((c0, 1)):
circuit.x(q0)
circuit.measure(q0, c0)
circuit.draw("mpl")

# example output counts: {'0': 1024}

Output of the previous code cell

Pernyataan with boleh diberi sasaran tugasan yang itu sendiri merupakan pengurus konteks yang boleh disimpan dan kemudiannya digunakan untuk mencipta blok else, yang dilaksanakan apabila kandungan blok if tidak dilaksanakan.

Dalam contoh di bawah, kami memulakan daftar dengan dua Qubit dan dua bit klasik. Kami menggunakan Gate Hadamard pada Qubit pertama dan mengukurnya. Jika hasilnya ialah 1, maka kami menggunakan Gate Hadamard pada Qubit kedua; jika tidak, kami menggunakan Gate X pada Qubit kedua. Akhirnya, kami mengukur Qubit kedua juga.

qubits = QuantumRegister(2)
clbits = ClassicalRegister(2)
circuit = QuantumCircuit(qubits, clbits)
(q0, q1) = qubits
(c0, c1) = clbits

circuit.h(q0)
circuit.measure(q0, c0)
with circuit.if_test((c0, 1)) as else_:
circuit.h(q1)
with else_:
circuit.x(q1)
circuit.measure(q1, c1)

circuit.draw("mpl")

# example output counts: {'01': 260, '11': 272, '10': 492}

Output of the previous code cell

Selain daripada bersyarat pada satu bit klasik, adalah juga boleh bersyarat pada nilai daftar klasik yang terdiri daripada beberapa bit.

Dalam contoh di bawah, kami menggunakan Gate Hadamard pada dua Qubit dan mengukurnya. Jika hasilnya ialah 01, iaitu Qubit pertama ialah 1 dan Qubit kedua ialah 0, maka kami menggunakan Gate X pada Qubit ketiga. Akhirnya, kami mengukur Qubit ketiga. Perhatikan bahawa untuk kejelasan, kami memilih untuk menentukan keadaan bit klasik ketiga, iaitu 0, dalam syarat if. Dalam lukisan Circuit, syarat ditunjukkan oleh bulatan pada bit klasik yang dijadikan syarat. Bulatan hitam menunjukkan syarat pada 1, manakala bulatan putih menunjukkan syarat pada 0.

qubits = QuantumRegister(3)
clbits = ClassicalRegister(3)
circuit = QuantumCircuit(qubits, clbits)
(q0, q1, q2) = qubits
(c0, c1, c2) = clbits

circuit.h([q0, q1])
circuit.measure(q0, c0)
circuit.measure(q1, c1)
with circuit.if_test((clbits, 0b001)):
circuit.x(q2)
circuit.measure(q2, c2)

circuit.draw("mpl")

# example output counts: {'101': 269, '011': 260, '000': 252, '010': 243}

Output of the previous code cell

Ungkapan klasik​

Modul ungkapan klasik Qiskit qiskit.circuit.classical mengandungi representasi eksperimentasi operasi masa larian pada nilai klasik semasa pelaksanaan Circuit. Disebabkan had perkakasan, hanya syarat QuantumCircuit.if_test() yang disokong pada masa ini.

Contoh berikut menunjukkan bahawa anda boleh menggunakan pengiraan pariti untuk mencipta keadaan GHZ n-Qubit menggunakan litar dinamik. Pertama, jana n/2n/2 pasangan Bell pada Qubit bersebelahan. Kemudian, sambungkan pasangan-pasangan ini menggunakan lapisan Gate CNOT di antara pasangan. Anda kemudian mengukur Qubit sasaran semua Gate CNOT sebelumnya dan menetapkan semula setiap Qubit yang diukur ke keadaan ∣0⟩\vert 0 \rangle. Anda menggunakan XX pada setiap tapak yang tidak diukur di mana pariti semua bit sebelumnya adalah ganjil. Akhirnya, Gate CNOT digunakan pada Qubit yang diukur untuk memulihkan keterikatan yang hilang dalam pengukuran.

Dalam pengiraan pariti, elemen pertama ungkapan yang dibina melibatkan pengangkatan objek Python mr[0] ke nod Value (lift digunakan untuk menukar objek arbitrari kepada ungkapan klasik). Ini tidak diperlukan untuk mr[1] dan daftar klasik yang mungkin berikutnya, kerana ia adalah input kepada expr.bit_xor, dan sebarang pengangkatan yang diperlukan dilakukan secara automatik dalam kes-kes ini. Ungkapan sedemikian boleh dibina dalam gelung dan konstruk lain.

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.circuit.classical import expr

num_qubits = 8
if num_qubits % 2 or num_qubits < 4:
raise ValueError("num_qubits must be an even integer ≥ 4")
meas_qubits = list(range(2, num_qubits, 2)) # qubits to measure and reset

qr = QuantumRegister(num_qubits, "qr")
mr = ClassicalRegister(len(meas_qubits), "m")
qc = QuantumCircuit(qr, mr)

# Create local Bell pairs
qc.reset(qr)
qc.h(qr[::2])
for ctrl in range(0, num_qubits, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])

# Glue neighboring pairs
for ctrl in range(1, num_qubits - 1, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])

# Measure boundary qubits between pairs,reset to 0
for k, q in enumerate(meas_qubits):
qc.measure(qr[q], mr[k])
qc.reset(qr[q])

# Parity-conditioned X corrections
# Each non-measured qubit gets flipped iff the parity (XOR) of all
# preceding measurement bits is 1
for tgt in range(num_qubits):
if tgt in meas_qubits: # skip measured qubits
continue
# all measurement registers whose physical qubit index < tgt
left_bits = [k for k, q in enumerate(meas_qubits) if q < tgt]
if not left_bits: # skip if list empty
continue

# build XOR-parity expression
parity = expr.lift(
mr[left_bits[0]]
) # lift the first bit to Value so it will be treated like a boolean.
for k in left_bits[1:]:
parity = expr.bit_xor(
mr[k], parity
) # calculate parity with all other bits
with qc.if_test(parity): # Add X if parity is 1
qc.x(qr[tgt])

# Re-entangle measured qubits
for ctrl in range(1, num_qubits - 1, 2):
qc.cx(qr[ctrl], qr[ctrl + 1])
qc.draw(output="mpl", style="iqp", idle_wires=False, fold=-1)

Output of the previous code cell

Cari Backend yang menyokong litar dinamik​

Untuk mencari semua Backend yang boleh diakses oleh akaun anda dan menyokong litar dinamik, jalankan kod seperti berikut. Contoh ini mengandaikan bahawa anda telah menyimpan kelayakan log masuk anda. Anda juga boleh menentukan kelayakan secara eksplisit semasa memulakan akaun perkhidmatan Qiskit Runtime anda. Ini membolehkan anda melihat Backend yang tersedia pada instans atau jenis pelan tertentu, contohnya.

Nota
  • Backend yang tersedia untuk akaun bergantung pada instans yang ditentukan dalam kelayakan.
  • Versi baharu litar dinamik kini tersedia kepada semua pengguna pada semua Backend. Lihat pengumuman ini untuk maklumat lanjut.
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
dc_backends = service.backends(dynamic_circuits=True)
print(dc_backends)
[<IBMBackend('ibm_pittsburgh')>, <IBMBackend('ibm_boston')>, <IBMBackend('ibm_fez')>, <IBMBackend('ibm_miami')>, <IBMBackend('ibm_marrakesh')>, <IBMBackend('ibm_torino')>, <IBMBackend('ibm_kingston')>]

Had Qiskit Runtime​

Sila ambil perhatian kekangan berikut semasa menjalankan litar dinamik dalam Qiskit Runtime.

  • Disebabkan memori fizikal yang terhad pada elektronik kawalan, terdapat juga had pada bilangan pernyataan if dan saiz operannya. Had ini adalah fungsi bilangan siaran dan bilangan bit yang disiarkan dalam sesuatu kerja (bukan Circuit).

    Semasa memproses syarat if, data pengukuran perlu dipindahkan ke logik kawalan untuk membuat penilaian tersebut. Siaran ialah pemindahan data klasik yang unik, dan bit yang disiarkan ialah bilangan bit klasik yang dipindahkan. Pertimbangkan perkara berikut:

    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 kod sebelumnya, dua objek if_test pertama pada c0 dianggap sebagai satu siaran kerana kandungan c0 tidak berubah, dan oleh itu tidak perlu disiarkan semula. if_test pada c1 ialah siaran kedua. Yang pertama menyiarkan kesemua tiga bit dalam c0 dan yang kedua menyiarkan hanya satu bit, menjadikan jumlah empat bit yang disiarkan.

    Pada masa ini, jika anda menyiarkan 60 bit setiap kali, maka kerja boleh mempunyai kira-kira 300 siaran. Jika anda menyiarkan hanya satu bit setiap kali, bagaimanapun, maka kerja boleh mempunyai 2400 siaran.

  • Operan yang digunakan dalam pernyataan if_test mestilah 32 bit atau kurang. Oleh itu, jika anda membandingkan keseluruhan ClassicalRegister, saiz ClassicalRegister itu mestilah 32 bit atau kurang. Namun jika anda hanya membandingkan satu bit dari ClassicalRegister, ClassicalRegister itu boleh bersaiz apa-apa (kerana operannya hanya satu bit).

    Sebagai contoh, blok kod "Tidak sah" tidak berfungsi kerana cr lebih daripada 32 bit. Anda boleh, bagaimanapun, menggunakan daftar klasik yang lebih lebar daripada 32 bit jika anda hanya menguji satu bit, seperti yang ditunjukkan dalam blok kod "Sah".

       cr = ClassicalRegister(50)
    qr = QuantumRegister(50)
    circuit = QuantumCircuit(qr, cr)
    ...
    circ.measure(qr, cr)
    with circ.if_test((cr, 15)):
    ...
  • Bersyarat bersarang tidak dibenarkan. Sebagai contoh, blok kod berikut tidak akan berfungsi kerana ia mempunyai if_test di dalam if_test yang lain:

       c1 = ClassicalRegister(1, "c1")
    c2 = ClassicalRegister(2, "c2")
    ...
    with circ.if_test((c1, 1)):
    with circ.if_test(c2, 1)):
    ...
  • Mempunyai reset atau pengukuran di dalam bersyarat tidak disokong.

  • Operasi aritmetik tidak disokong.

  • Lihat jadual ciri OpenQASM 3 untuk menentukan ciri OpenQASM 3 mana yang disokong pada Qiskit dan Qiskit Runtime.

  • Apabila OpenQASM 3 (berbanding QuantumCircuit) digunakan sebagai format input untuk menghantar Circuit ke primitif Qiskit Runtime, hanya arahan yang boleh dimuatkan ke dalam Qiskit yang disokong. Operasi klasik, sebagai contoh, tidak disokong kerana ia tidak boleh dimuatkan ke dalam Qiskit. Lihat Import atur cara OpenQASM 3 ke dalam Qiskit untuk maklumat lanjut.

  • Arahan for, while, dan switch tidak disokong.

Guna litar dinamik dengan Estimator​

Oleh sebab Estimator tidak menyokong litar dinamik, anda boleh menggunakan Sampler dan membina Circuit pengukuran anda sendiri. Sebagai alternatif, anda boleh menggunakan primitif Executor, yang menyokong litar dinamik.

Untuk meniru tingkah laku Estimator, ikuti proses ini:

  1. Kumpulkan terma semua pemerhatian ke dalam partisi. Ini boleh dilakukan dengan menggunakan API PauliList, sebagai contoh.
    nota

    Anda boleh menggunakan atribut primitif BitArray untuk mengira nilai jangkaan bagi pemerhatian yang diberikan.

  2. Laksanakan satu Circuit perubahan asas per partisi (perubahan asas mana yang perlu dilakukan untuk setiap partisi). Lihat utiliti addon Measurement bases modul measurement_bases untuk maklumat lanjut. Mulakan dengan utiliti.
  3. Tambah semula keputusan untuk setiap partisi.

Langkah seterusnya​

Cadangan
Source: IBM Quantum docs — updated 1 Apr 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of 11 Mac 2026