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
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:
- Penyediaan keadaan kuantum yang cekap, seperti keadaan GHZ, keadaan-W, (untuk maklumat lanjut tentang keadaan-W, rujuk juga "State preparation by shallow circuits using feed forward") dan kelas luas matrix product states
- Keterikatan jarak jauh yang cekap antara Qubit pada cip yang sama dengan menggunakan Circuit cetek
- Pensampelan cekap litar seperti IQP
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.
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}
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}
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}
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 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 . Anda menggunakan 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)
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.
- 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
ifdan 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_testpertama padac0dianggap sebagai satu siaran kerana kandunganc0tidak berubah, dan oleh itu tidak perlu disiarkan semula.if_testpadac1ialah siaran kedua. Yang pertama menyiarkan kesemua tiga bit dalamc0dan 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_testmestilah 32 bit atau kurang. Oleh itu, jika anda membandingkan keseluruhanClassicalRegister, saizClassicalRegisteritu mestilah 32 bit atau kurang. Namun jika anda hanya membandingkan satu bit dariClassicalRegister,ClassicalRegisteritu boleh bersaiz apa-apa (kerana operannya hanya satu bit).Sebagai contoh, blok kod "Tidak sah" tidak berfungsi kerana
crlebih 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".- Tidak sah
- Sah
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)):
... -
Bersyarat bersarang tidak dibenarkan. Sebagai contoh, blok kod berikut tidak akan berfungsi kerana ia mempunyai
if_testdi dalamif_testyang lain:- Tidak sah
- Sah
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)):
... -
Mempunyai
resetatau 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, danswitchtidak 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:
- Kumpulkan terma semua pemerhatian ke dalam partisi. Ini boleh dilakukan dengan menggunakan API
PauliList, sebagai contoh.notaAnda boleh menggunakan atribut primitif
BitArrayuntuk mengira nilai jangkaan bagi pemerhatian yang diberikan. - Laksanakan satu Circuit perubahan asas per partisi (perubahan asas mana yang perlu dilakukan untuk setiap partisi). Lihat utiliti addon Measurement bases modul
measurement_basesuntuk maklumat lanjut. Mulakan dengan utiliti. - Tambah semula keputusan untuk setiap partisi.
Langkah seterusnya​
- Ketahui cara melaksanakan dynamic decoupling yang tepat dengan menggunakan stretch.
- Ketahui tentang pengukuran mid-Circuit yang lebih pendek yang mengurangkan masa Circuit.
- Guna visualisasi jadual Circuit untuk debug dan optimumkan litar dinamik anda.