Classical feedforward at control flow (dynamic circuits)
Package versions
Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na kinakailangan. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago pa.
qiskit[all]~=2.4.0
Ang dynamic circuits ay makapangyarihang mga tool na maaari mong gamitin para sukatin ang mga qubit sa gitna ng pagpapatakbo ng quantum circuit at pagkatapos ay magsagawa ng mga classical logic operation sa loob ng circuit, batay sa resulta ng mga mid-circuit na pagsukat. Ang prosesong ito ay kilala rin bilang classical feedforward. Bagama't maaga pa lamang ang pag-unawa kung paano pinakamabuti na mapagsamantalahan ang dynamic circuits, ang komunidad ng quantum research ay nakakilala 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, tingnan din ang "State preparation by shallow circuits using feed forward"), at isang malawak na klase ng matrix product states
- Mahusay na long-range entanglement sa pagitan ng mga qubit sa parehong chip sa pamamagitan ng paggamit ng mga mababaw na circuit
- Mahusay na sampling ng IQP-like circuits
if statementβ
Ginagamit ang if statement para magsagawa ng mga operasyon nang kondisyonal batay sa halaga ng isang classical bit o register.
Sa halimbawa sa ibaba, nag-aaplay kami ng Hadamard gate sa isang qubit at sinusukat ito. Kung ang resulta ay 1, nag-aaplay kami ng X gate sa qubit, na may epektong ibabalik ito sa estado na 0. Pagkatapos ay sinusukat namin ang qubit muli. Ang nagreresultang kinalabasan ng pagsukat ay dapat na 0 na may 100% na posibilidad.
# Added by doQumentation β required packages for this notebook
!pip install -q qiskit
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
circuit = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits
circuit.h(q0)
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}
Ang with statement ay maaaring bigyan ng assignment target na isa ring context manager na maaaring i-store at pagkatapos ay gamitin para lumikha ng else block, na isinasagawa tuwing ang mga nilalaman ng if block ay hindi isinasagawa.
Sa halimbawa sa ibaba, nagpapasimula kami ng mga register na may dalawang qubit at dalawang classical bit. Nag-aaplay kami ng Hadamard gate sa unang qubit at sinusukat ito. Kung ang resulta ay 1, nag-aaplay kami ng Hadamard gate sa pangalawang qubit; kung hindi, nag-aaplay kami ng X gate sa pangalawang qubit. Sa wakas, sinusukat namin ang pangalawang qubit din.
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}
Bukod sa pag-condition sa isang classical bit, posible rin ang pag-condition sa halaga ng isang classical register na binubuo ng maraming bit.
Sa halimbawa sa ibaba, nag-aaplay kami ng Hadamard gate sa dalawang qubit at sinusukat ang mga ito. Kung ang resulta ay 01, iyon ay, ang unang qubit ay 1 at ang pangalawang qubit ay 0, nag-aaplay kami ng X gate sa ikatlong qubit. Sa wakas, sinusukat namin ang ikatlong qubit. Tandaan na para sa kalinawan, pinili naming tukuyin ang estado ng ikatlong classical bit, na 0, sa kondisyon ng if. Sa drawing ng circuit, ang kondisyon ay ipinahiwatig ng mga bilog sa mga classical bit na kina-condition. Ang isang solidong bilog ay nagpapahiwatig ng pag-condition sa 1, habang ang isang bilog na may balangkas ay nagpapahiwatig ng pag-condition sa 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}
Mga classical expressionβ
Ang Qiskit classical expression module na qiskit.circuit.classical ay naglalaman ng eksplorasyon na representasyon ng mga runtime operation sa mga classical value sa panahon ng pagpapatakbo ng circuit. Dahil sa mga limitasyon ng hardware, ang mga kondisyon ng QuantumCircuit.if_test() lamang ang kasalukuyang sinusuportahan.
Ang sumusunod na halimbawa ay nagpapakita na maaari mong gamitin ang pagkalkula ng parity para lumikha ng n-qubit GHZ state gamit ang dynamic circuits. Una, gumawa ng Bell pairs sa mga katabing qubit. Pagkatapos, idikit ang mga pares na ito gamit ang isang layer ng CNOT gate sa pagitan ng mga pares. Pagkatapos ay susukat ng mga target qubit ng lahat ng naunang CNOT gate at iri-reset ang bawat nasukat na qubit sa estado . Mag-aaplay ka ng sa bawat hindi nasukat na site kung saan ang parity ng lahat ng naunang bit ay kakaiba. Sa wakas, mga CNOT gate ang ilalapat sa mga nasukat na qubit para muling maitatag ang entanglement na nawala sa pagsukat.
Sa pagkalkula ng parity, ang unang elemento ng nabuong expression ay kinabibilangan ng pag-lift ng Python object na mr[0] sa isang Value node (lift ay ginagamit para gawing mga classical expression ang mga arbitrary na object). Hindi ito kinakailangan para sa mr[1] at sa posibleng susunod na classical register, dahil sila ay mga input sa expr.bit_xor, at ang anumang kinakailangang pag-lift ay awtomatikong ginagawa sa mga kasong ito. Ang mga ganitong expression ay maaaring itayo sa mga loop at iba pang mga construct.
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)
Mga susunod na hakbangβ
- Alamin kung paano mag-implement ng tumpak na dynamic decoupling sa pamamagitan ng paggamit ng stretch.
- Gamitin ang circuit schedule visualization para i-debug at i-optimize ang iyong mga dynamic circuit.
- I-execute ang mga dynamic circuit.