Vizualizează temporizarea circuitelor
Versiuni de pachete
Codul de pe această pagină a fost dezvoltat folosind următoarele cerințe. Recomandăm să folosești aceste versiuni sau mai noi.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Deși instrumentul de desenare a liniei de timp integrat în Qiskit este util pentru circuitele statice, este posibil să nu reflecte cu acuratețe temporizarea circuitelor dinamice din cauza operațiilor implicite, cum ar fi broadcasting-ul și determinarea ramurilor. Ca parte a suportului pentru circuitele dinamice, Qiskit Runtime returnează informațiile exacte de temporizare a circuitelor în rezultatele job-ului atunci când este solicitat.
- Aceasta este o funcție experimentală. Se află în stare de previzualizare și este, prin urmare, supusă modificărilor.
- Această funcție se aplică numai job-urilor Qiskit Runtime Sampler.
- Deși timpul total al circuitului este returnat în metadatele „compilation", acesta NU este timpul utilizat pentru facturare (timp QPU).
Activează recuperarea datelor de temporizare
Pentru a activa recuperarea datelor de temporizare, setează flag-ul experimental scheduler_timing la True când rulezi job-ul primitiv.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
sampler = SamplerV2(backend)
sampler.options.experimental = {
"execution": {
"scheduler_timing": True,
},
}
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
Accesează datele de temporizare ale circuitului
Când este solicitat, datele de temporizare ale circuitului pentru fiecare PUB sunt returnate în metadatele rezultatului job-ului, sub ["compilation"]["scheduler_timing"]["timing"]. Acest câmp conține informațiile brute de temporizare. Pentru a afișa informațiile de temporizare, folosește instrumentul de vizualizare integrat, după cum este descris în secțiunea Vizualizează temporizările.
Folosește următorul cod pentru a accesa datele de temporizare ale circuitului pentru primul PUB:
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]
Înțelege datele brute de temporizare
Deși vizualizarea datelor de temporizare ale circuitului prin metoda draw_circuit_schedule_timing este cel mai frecvent caz de utilizare, ar putea fi util să înțelegi structura datelor brute de temporizare returnate. Acest lucru te-ar putea ajuta, de exemplu, să extragi informații programatic.
Datele de temporizare returnate în ["compilation"]["scheduler_timing"]["timing"] reprezintă o listă de șiruri de caractere. Fiecare șir reprezintă o singură instrucțiune pe un canal și este separat prin virgulă în următoarele tipuri de date:
Branch- Determină dacă instrucțiunea se află într-un flux de control (then / else) sau într-o ramură principală.Instruction- Poarta și qubit-ul pe care se operează.Channel- Canalul căruia i se atribuie instrucțiunea. Poate fi unul dintre următoarele:Qubit x- Canalul de drive pentru qubit-ul x.AWGRx_y(generator de forme de undă arbitrare readout) - Folosit de canalele de readout pentru a comunica la măsurarea qubiților. Argumentele x și y corespund ID-ului instrumentului de readout și, respectiv, numărului qubit-ului.
T0- Timpul de start al instrucțiunii în cadrul programului completDuration- Durata instrucțiunii, în unități de dt secunde, unde 1 dt = 1 ciclu de programare. Poți găsi valoareadta unui backend folosindbackend.dt.Pulse- Tipul operației de puls utilizate.
Exemplu:
main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration
main,reset_0,Qubit 0,7,64,play # A reset instruction on the main branch on qubit 0 at time 7 with duration 64 and a play operation
...
Vizualizează temporizările
Cu qiskit-ibm-runtime v0.43.0 sau mai nou, poți vizualiza temporizările circuitelor. Pentru a vizualiza temporizările, trebuie mai întâi să convertești metadatele rezultatelor în fig folosind metoda draw_circuit_schedule_timing. Această metodă returnează o figură plotly, pe care o poți afișa direct, salva într-un fișier sau ambele. Pentru mai multe informații despre comenzile plotly de utilizat, consultă fig.show() și fig.write_image("<path.format>").
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
# Create a figure from the metadata
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule_timing,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")
Înțelege figura generată
Imaginea datelor de temporizare ale circuitului, ieșite de draw_circuit_schedule_timing, transmite următoarele informații:
- Axa X reprezintă timpul în unități de dt secunde, unde 1 dt = 1 ciclu de programare. Poți găsi valoarea
dta unui backend folosindbackend.dt. - Axa Y reprezintă canalul (gândește-te la canale ca la instrumente care emit pulsuri).
Receive channel- Singurul canal care nu este un instrument în sine. Este o instrucțiune redată pe toate canalele care fac parte dintr-o procedură de comunicare cu hub-ul în acel moment.Qubit x- Canalul de drive pentru qubit-ul x.AWGRx_y(generator de forme de undă arbitrare readout) - Folosit de canalele de readout pentru a comunica la măsurarea qubiților. Argumentele x și y corespund ID-ului instrumentului de readout și, respectiv, numărului qubit-ului.Hub- Controlează broadcasting-ul.
În plus, fiecare instrucțiune are formatul X_Y, unde X este numele instrucțiunii și Y este tipul de puls. Un tip play aplică pulsuri de control, iar un capture înregistrează starea qubit-ului. Poți, de asemenea, să treci cu cursorul peste fiecare instrucțiune pentru a obține mai multe detalii. De exemplu, figura anterioară arată un puls de control pentru poarta X aplicat qubit-ului 10 la 1161 dt.
Exemplu complet end-to-end
Acest exemplu îți arată cum să activezi opțiunea, să obții informațiile de temporizare ale circuitului din metadate și să le afișezi ca imagine.
Mai întâi, configurează mediul, definește circuitele și convertește-le în circuite ISA, și definește și rulează job-urile.
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)
# 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)
sampler.options.experimental = {"execution": {"scheduler_timing": True}}
# 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: d8287kugbeec73alfbug (DONE)
Apoi, obține temporizarea programului circuitului:
# Get the circuit schedule timing
result[0].metadata["compilation"]["scheduler_timing"]["timing"]
'main,rz_0,Qubit 0,1365,0,shift_phase\nmain,sx_0,Qubit 0,1365,9,play\nmain,sx_0,Qubit 0,1369,0,shift_phase\nmain,rz_0,Qubit 0,1374,0,shift_phase\nmain,barrier,Qubit 0,1374,0,barrier\nmain,measure_0,Qubit 0,1374,64,play\nmain,measure_0,Qubit 0,1438,108,play\nmain,measure_0,AWGR0_0,1485,360,capture\nmain,measure_0,Qubit 0,1546,64,play\nmain,measure_0,Qubit 0,1610,64,play\nmain,barrier,Qubit 0,2046,0,barrier\nmain,broadcast,Hub,1485,561,broadcast\nmain,receive,Receive,2046,7,receive\nthen,x_0,Qubit 0,2061,9,play\nmain,barrier,Qubit 0,2079,0,barrier\nmain,measure_0,Qubit 0,2079,64,play\nmain,measure_0,Qubit 0,2143,108,play\nmain,measure_0,AWGR0_0,2190,360,capture\nmain,measure_0,Qubit 0,2251,64,play\nmain,measure_0,Qubit 0,2315,64,play\nmain,barrier,Qubit 0,2725,0,barrier\nmain,barrier,Qubit 0,2725,0,barrier\n'
În final, poți vizualiza și salva temporizarea:
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
circuit_schedule = result[0].metadata["compilation"]["scheduler_timing"][
"timing"
]
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")
Pașii următori
- Feedforward clasic și flux de control (circuite dinamice)
- Vizualizează circuitele