Ipatupad ang mga dynamic na circuit
Mga bersyon ng package
Ang code sa pahinang ito ay binuo gamit ang mga sumusunod na kinakailangan. Inirerekumenda naming gamitin ang mga bersyong ito o mas bago.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Ang mga dynamic na circuit ay mga makapangyarihang kasangkapan na sa pamamagitan ng mga ito ay maaari mong sukatin ang mga qubit sa kalagitnaan ng isang quantum circuit execution at pagkatapos ay magsagawa ng mga classical logic operation sa loob ng circuit, batay sa resulta ng mga mid-circuit measurement na iyon. Ang prosesong ito ay kilala rin bilang classical feedforward. Habang ito ay mga maagang araw ng pag-unawa kung paano pinakamainam na samantalahin ang mga dynamic na circuit, ang quantum research community ay nakatukoy na ng ilang mga use case, tulad ng mga sumusunod:
- Mahusay na paghahanda ng quantum state, tulad ng GHZ state, W-state (para sa karagdagang impormasyon tungkol sa W-state, sumangguni din sa "State preparation by shallow circuits using feed forward"), at isang malawak na klase ng matrix product state
- Mahusay na long-range entanglement sa pagitan ng mga qubit sa parehong chip sa pamamagitan ng paggamit ng mga shallow circuit
- Mahusay na sampling ng mga circuit na tulad ng IQP
Ang mga pagpapabuti na dala ng mga dynamic na circuit, gayunpaman, ay may mga trade-off. Ang mga mid-circuit measurement at mga classical operation ay karaniwang may mas matagal na oras ng execution kaysa sa mga two-qubit gate, at ang pagtaas na ito sa oras ay maaaring magpawalang-bisa ng mga benepisyo ng nabawasang lalim ng circuit. Samakatuwid, ang pagbabawas ng haba ng mid-circuit measurement ay isang lugar ng pagtuon ng pagpapabuti habang naglalabas ang IBM Quantumยฎ ng bagong bersyon ng mga dynamic na circuit. Para sa iba pang mga paghihigpit kapag gumagamit ng mga dynamic na circuit, tingnan ang talahanayan ng Feature compatibility ng Estimator o Sampler.
Tinutukoy ng OpenQASM 3 specification ang ilang mga istruktura ng control-flow, ngunit kasalukuyan ay sinusuportahan lamang ng Qiskit Runtime ang conditional na pahayag na if. Sa Qiskit SDK, ito ay tumutugma sa method na if_test sa QuantumCircuit. Ang method na ito ay nagbabalik ng isang context manager at karaniwang ginagamit sa isang pahayag na with. Inilalarawan ng gabay na ito kung paano gamitin ang conditional na pahayag na ito.
Ang mga halimbawa ng code sa gabay na ito ay gumagamit ng standard na tagubilin sa sukat para sa mga mid-circuit measurement. Gayunpaman, inirerekomenda na gumamit ka ng tagubilin na MidCircuitMeasure sa halip, kung sinusuportahan ito ng backend. Tingnan ang seksyon ng Mid-circuit measurement para sa mga detalye.
Hanapin ang mga backend na sumusuporta sa mga dynamic na circuitโ
Para mahanap ang lahat ng backend na maa-access ng iyong account at sumusuporta sa mga dynamic na circuit, magpatakbo ng code tulad ng sumusunod. Ipinapalagay ng halimbawang ito na nai-save mo na ang iyong mga kredensyal sa pag-login. Maaari ka ring magtukoy nang tahasan ng mga kredensyal kapag ini-initialize ang iyong Qiskit Runtime service account. Magpapahintulot ito sa iyo na tingnan ang mga backend na available sa isang tiyak na instance o uri ng plano, halimbawa.
- Ang mga backend na available sa account ay nakasalalay sa instance na tinukoy sa mga kredensyal.
- Ang bagong bersyon ng mga dynamic na circuit ay available na sa lahat ng gumagamit sa lahat ng backend. Tingnan ang anunsyo para sa karagdagang detalye.
# 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')>]
Mga mid-circuit measurementโ
Bago ang qiskit-ibm-runtime v0.43.0, ang measure ang nag-iisang tagubilin sa sukat sa Qiskit. Ang mga mid-circuit measurement, gayunpaman, ay may iba't ibang mga kinakailangan sa tuning kaysa sa mga terminal measurement (mga sukat na nagaganap sa dulo ng isang circuit). Halimbawa, kailangan mong isaalang-alang ang tagal ng tagubilin kapag ino-tune ang isang mid-circuit measurement dahil ang mas matagal na mga tagubilin ay nagdudulot ng mas maingay na mga circuit. Hindi mo kailangang isaalang-alang ang tagal ng tagubilin para sa mga terminal measurement dahil walang mga tagubilin pagkatapos ng mga terminal measurement.
Ang tagubilin na MidCircuitMeasure ay nagma-map sa tagubilin na measure_2 na iniulat sa supported_instructions ng backend. Gayunpaman, ang measure_2 ay hindi sinusuportahan sa lahat ng backend. Gamitin ang service.backends(filters=lambda b: "measure_2" in b.supported_instructions) para mahanap ang mga backend na sumusuporta nito. Maaaring magdagdag ng mga bagong sukat sa hinaharap, ngunit hindi ito ginagarantiyahan.
Method na MidCircuitMeasureโ
Sa qiskit-ibm-runtime v0.43.0, ang tagubilin na MidCircuitMeasure ay ipinakilala. Tulad ng iminumungkahi ng pangalan, ito ay isang bagong tagubilin sa sukat na optimized para sa mid-circuit sa IBMยฎ QPU. Habang maaari kang gumamit ng QuantumCircuit.measure para sa isang mid-circuit measurement, dahil sa disenyo nito, ang MidCircuitMeasure ay karaniwang mas magandang pagpipilian. Halimbawa, nagdaragdag ito ng mas kaunting overhead sa iyong circuit kaysa kapag gumagamit ng 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: โโโโโโโโโโโโโโโโโโโ
- Dapat mayroong kahit isang classical register para magamit ang mga sukat.
- Ang Sampler primitive ay nangangailangan ng mga sukat ng circuit. Maaari kang magdagdag ng mga sukat ng circuit sa Estimator primitive, ngunit binabalewala ang mga ito.
Storeโ
Sa qiskit-ibm-runtime bersyon 0.47.0 o mas bago, maaari mong gamitin ang tagubilin na store para i-save ang resulta ng isang classical expression, kung ang expression na iyon ay gagamitin nang paulit-ulit. Ang mga operasyon ay awtomatikong pinara-parallel, na ginagawang mas mahusay ang iyong code sa runtime.
Para sa karagdagang impormasyon, tingnan ang gabay na Classical feedforward and control flow.
Kapag ginamit mo ang store para i-save ang isang value sa isang classical register sa isang tunay na backend, ang value na iyon ay naka-save lamang sa memory sa panahon ng execution at hindi kinokopya o ibinalik sa resulta ng job.
Halimbawa, sa sumusunod na code, ang temp ay may parehong value ng creg sa panahon ng execution, at gumagana ang if_test ayon sa inaasahan. Ngunit pagkatapos matapos ang job, ang temp BitArray na ibinalik sa resulta ng job ay hindi naglalaman ng value ng creg. Ibig sabihin, ang job.result()[0].data.temp ay 0.
creg = ClassicalRegister(3, "c")
temp = ClassicalRegister(3, "temp")
...
qc.store(temp, creg)
with circuit.if_test((temp, 0b001)):
...
Kumpletong halimbawaโ
Ang sumusunod na code ay lumilikha at nagpapatakbo ng isang dynamic na circuit sa IBMยฎ hardware.
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)
Mga limitasyon ng Qiskit Runtimeโ
Maging aware ng mga sumusunod na limitasyon kapag nagpapatakbo ng mga dynamic na circuit sa Qiskit Runtime.
-
Dahil sa limitadong pisikal na memory sa mga control electronics, mayroon ding limitasyon sa bilang ng mga pahayag na
ifat laki ng kanilang mga operand. Ang limitasyong ito ay isang function ng bilang ng mga broadcast at bilang ng mga broadcasted na bit sa isang job (hindi isang circuit).Kapag nagpoproseso ng isang kondisyon na
if, ang data ng sukat ay kailangang ilipat sa control logic para gawin ang pagtatasa na iyon. Ang isang broadcast ay isang paglipat ng natatanging classical data, at ang mga broadcasted na bit ay ang bilang ng mga classical bit na inililipat. Isaalang-alang ang sumusunod: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)) ...Sa nakaraang halimbawa ng code, ang unang dalawang object na
if_testsac0ay itinuturing na isang broadcast dahil ang nilalaman ngc0ay hindi nagbago, at samakatuwid ay hindi na kailangang i-re-broadcast. Angif_testsac1ay isang pangalawang broadcast. Ang una ay nagba-broadcast ng lahat ng tatlong bit sac0at ang pangalawa ay nagba-broadcast ng isang bit lamang, na gumagawa ng kabuuang apat na broadcasted na bit.Kasalukuyan, kung nagba-broadcast ka ng 60 bit bawat beses, ang job ay maaaring magkaroon ng humigit-kumulang 300 broadcast. Kung nagba-broadcast ka ng isang bit lamang bawat beses, gayunpaman, ang job ay maaaring magkaroon ng 2400 broadcast.
-
Ang operand na ginamit sa isang pahayag na
if_testay dapat na 32 o mas kaunting bit. Kaya, kung ikukumpara mo ang isang buongClassicalRegister, ang laki ngClassicalRegisterna iyon ay dapat na 32 o mas kaunting bit. Kung ikukumpara mo lamang ang isang solong bit mula sa isangClassicalRegister, gayunpaman, angClassicalRegisterna iyon ay maaaring may anumang laki (dahil ang operand ay isang bit lamang).Halimbawa, ang "Hindi valid" na code block ay hindi gumagana dahil ang
cray higit sa 32 bit. Maaari mong gamitin ang isang classical register na mas malawak sa 32 bit, gayunpaman, kung sinusubukan mo lamang ang isang bit, tulad ng ipinapakita sa "Valid" na code block.- Hindi 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)):... -
Hindi pinapayagan ang mga nested conditional. Halimbawa, ang sumusunod na code block ay hindi gagana dahil mayroon itong
if_testsa loob ng isa pangif_test:- Hindi 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)):... -
Hindi sinusuportahan ang pagkakaroon ng
reseto mga sukat sa loob ng mga conditional. -
Hindi sinusuportahan ang mga arithmetic operation.
-
Tingnan ang talahanayan ng feature ng OpenQASM 3 para matukoy kung aling mga feature ng OpenQASM 3 ang sinusuportahan sa Qiskit at Qiskit Runtime.
-
Kapag ginamit ang OpenQASM 3 (sa halip na
QuantumCircuit) bilang format ng input para mag-pass ng mga circuit sa mga primitive ng Qiskit Runtime, sinusuportahan lamang ang mga tagubilin na maaaring i-load sa Qiskit. Ang mga classical operation, halimbawa, ay hindi sinusuportahan dahil hindi sila maaaring i-load sa Qiskit. Tingnan ang Mag-import ng OpenQASM 3 program sa Qiskit para sa karagdagang impormasyon. -
Hindi sinusuportahan ang mga tagubilin na
for,while, atswitch.
Gumamit ng mga dynamic na circuit sa Estimatorโ
Dahil hindi sinusuportahan ng Estimator ang mga dynamic na circuit, maaari kang gumamit ng Sampler at bumuo ng iyong sariling mga circuit ng sukat sa halip.
Para tularan ang gawi ng Estimator, sundin ang prosesong ito:
- Grupuhin ang mga term ng lahat ng observable sa isang partition. Maaari itong gawin sa pamamagitan ng paggamit ng
PauliListAPI, halimbawa.talaMaaari mong gamitin ang attribute ng primitive na
BitArraypara kalkulahin ang mga expectation value ng mga ibinigay na observable. - Ipatupad ang isang basis change circuit bawat partition (anumang pagbabago ng batayan ang kailangang gawin para sa bawat partition). Tingnan ang addon utility ng Measurement bases
measurement_basesmodule para sa karagdagang impormasyon. Para sa karagdagang impormasyon, tingnan ang dokumentasyon para sa Qiskit addon utilities package. - Idagdag nang magkasama ang mga resulta para sa bawat partition.
Mga paghihigpitโ
Suriin ang anumang Talahanayan ng feature compatibility para maunawaan ang mga paghihigpit kapag gumagamit ng mga dynamic na circuit. Tandaan na ang compatibility ng feature ay hindi nakasalalay sa primitive.
Mga susunod na hakbangโ
- Matuto kung paano ipatupad ang tumpak na dynamic decoupling sa pamamagitan ng paggamit ng stretch.
- Suriin ang gabay na classical feedforward at control flow.
- Gamitin ang visualization ng circuit schedule para mag-debug at mag-optimize ng iyong mga dynamic na circuit.
- Hindi lahat ng function ay compatible sa mga dynamic na circuit. Tingnan ang seksyon ng feature compatibility para sa Sampler o Executor para sa mga detalye.