Visualizza i tempi del circuito
Il codice presente in questa pagina è stato sviluppato sulla base dei seguenti requisiti. Si consiglia di utilizzare queste versioni o quelle più recenti.
qiskit[all]~=2.5.1 qiskit-ibm-runtime~=0.47.0
Sebbene il pannello temporale integrato in Qiskit sia utile per i circuiti statici, potrebbe non riflettere con precisione la temporizzazione dei circuiti dinamici a causa di operazioni implicite quali la trasmissione e la determinazione dei rami. Nell’ambito del supporto ai circuiti dinamici, il servizio di elaborazione “ IBM Quantum ” restituisce, su richiesta, informazioni precise sui tempi dei circuiti all’interno dei risultati del processo.
- Questa è una funzione sperimentale. Si tratta di una versione di anteprima e, pertanto, è soggetta a modifiche.
- Questa funzione si applica esclusivamente ai processi di campionamento di IBM Quantum.
- Sebbene il tempo totale di esecuzione del circuito sia riportato nei metadati "compilation", NON si tratta del tempo utilizzato ai fini della fatturazione (tempo QPU).
Abilita il recupero dei dati temporali
Per abilitare il recupero dei dati temporali, impostare il flag scheduler_timing sperimentale su True durante l'esecuzione del processo primitivo.
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()Accedere ai dati relativi ai tempi del circuito
Se richiesto, i dati relativi ai tempi di esecuzione del circuito per ciascun « PUB » vengono restituiti nei metadati dei risultati del processo, alla voce ["compilation"]["scheduler_timing"]["timing"]. Questo campo contiene le informazioni di temporizzazione grezze. Per visualizzare le informazioni relative ai tempi, utilizzare lo strumento di visualizzazione integrato, come descritto nella sezione "Visualizzazione dei tempi ".
Utilizza il codice seguente per accedere ai dati relativi ai tempi del circuito per il primo PUB :
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]Comprendere i dati grezzi relativi alla temporizzazione
Sebbene la visualizzazione dei dati temporali del circuito tramite il draw_circuit_schedule_timing metodo sia l'applicazione più comune, potrebbe essere utile comprendere la struttura dei dati temporali grezzi restituiti. Questo potrebbe aiutarti, ad esempio, a estrarre informazioni in modo automatico.
I dati temporali restituiti in ["compilation"]["scheduler_timing"]["timing"] sono un elenco di stringhe. Ogni stringa rappresenta una singola istruzione su un determinato canale ed è suddivisa, separata da virgole, nei seguenti tipi di dati:
Branch- Determina se l'istruzione si trova in un flusso di controllo (then / else) o in un ramo principale.Instruction- Il gate e il qubit su cui operare.Channel- Il canale a cui viene assegnato il comando. Può essere uno dei seguenti valori:Qubit x- Il canale di pilotaggio per il qubit x.AWGRx_y(Lettura del generatore di forme d'onda arbitrarie) - Utilizzata dai canali di lettura per comunicare durante la misurazione dei qubit. Gli argomenti x e y corrispondono rispettivamente all'ID dello strumento di lettura e al numero del qubit.
T0- L'orario di inizio della lezione nell'orario completoDuration- La durata dell'istruzione, espressa in unità di dt secondi, dove 1 dt = 1 ciclo di schedulazione. È possibile trovare ildtvalore di un backend utilizzandobackend.dt.Pulse- Il tipo di funzionamento a impulsi utilizzato.
Esempio:
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
...Visualizza i tempi
Con qiskit-ibm-runtimev0.43.0 o versioni successive, è possibile visualizzare i tempi dei circuiti. Per visualizzare i tempi, devi prima convertire i metadati dei risultati fig utilizzando il draw_circuit_schedule_timing metodo. Questo metodo restituisce plotly un'immagine che è possibile visualizzare direttamente, salvare su un file o entrambe le cose. Per ulteriori informazioni sui comandi plotly da utilizzare, consultare fig.show() e 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")
Comprendere il grafico generato
L'immagine dei dati temporali del circuito generati da draw_circuit_schedule_timing fornisce le seguenti informazioni:
- L'asse X rappresenta il tempo in unità di dt secondi, dove 1 dt = 1 ciclo di schedulazione. È possibile trovare il
dtvalore di un backend utilizzandobackend.dt. - L'asse Y rappresenta il canale (si pensi ai canali come a strumenti che emettono impulsi).
Receive channel- L'unico canale che non è uno strumento a sé stante. Si tratta di un comando trasmesso su tutti i canali che in quel momento fanno parte di una procedura di comunicazione con l'hub.Qubit x- Il canale di pilotaggio per il qubit x.AWGRx_y(Lettura del generatore di forme d'onda arbitrarie) - Utilizzata dai canali di lettura per comunicare durante la misurazione dei qubit. Gli argomenti x e y corrispondono rispettivamente all'ID dello strumento di lettura e al numero del qubit.Hub- Gestisce la trasmissione.
Inoltre, ogni istruzione ha il formato X_Y, dove X è il nome dell'istruzione e Y è il tipo di impulso. Uno play genera impulsi di controllo, mentre l'altro capture registra lo stato del qubit. Puoi anche passare il mouse su ciascuna istruzione per visualizzare ulteriori dettagli. Ad esempio, la figura precedente mostra un impulso di controllo per il gate X applicato al qubit 10 al tempo 1161 dt.
Esempio end-to-end
Questo esempio mostra come abilitare l'opzione, recuperare le informazioni sui tempi del circuito dai metadati e visualizzarle sotto forma di immagine.
Per prima cosa, configurare l'ambiente, definire i circuiti e convertirli in circuiti ISA, quindi definire ed eseguire i lavori.
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()})"
)Output:
>>> Job ID: d9mqmk7urbec73e67nng (DONE)
A questo punto, controlla gli orari delle gare:
# Get the circuit schedule timing
result[0].metadata["compilation"]["scheduler_timing"]["timing"]Output:
'main,rz_0,Qubit 0,1393,0,shift_phase\nmain,sx_0,Qubit 0,1393,9,play\nmain,sx_0,Qubit 0,1397,0,shift_phase\nmain,rz_0,Qubit 0,1402,0,shift_phase\nmain,barrier,Qubit 0,1402,0,barrier\nmain,measure_0,Qubit 0,1402,64,play\nmain,measure_0,Qubit 0,1466,108,play\nmain,measure_0,AWGR0_0,1523,325,capture\nmain,measure_0,Qubit 0,1574,64,play\nmain,measure_0,Qubit 0,1638,64,play\nmain,barrier,Qubit 0,2049,0,barrier\nmain,broadcast,Hub,1523,526,broadcast\nmain,receive,Receive,2049,7,receive\nthen,x_0,Qubit 0,2064,9,play\nmain,barrier,Qubit 0,2082,0,barrier\nmain,measure_0,Qubit 0,2082,64,play\nmain,measure_0,Qubit 0,2146,108,play\nmain,measure_0,AWGR0_0,2203,325,capture\nmain,measure_0,Qubit 0,2254,64,play\nmain,measure_0,Qubit 0,2318,64,play\nmain,barrier,Qubit 0,2753,0,barrier\nmain,barrier,Qubit 0,2753,0,barrier\nmain,FINI_0,Qubit 0,2753,64,play\nmain,FINI_0,Qubit 0,2817,108,play\nmain,FINI_0,AWGR0_0,2874,325,capture\nmain,FINI_0,Qubit 0,2925,64,play\nmain,FINI_0,Qubit 0,2989,64,play\nmain,FINI_0,Qubit 0,3424,9,play\nmain,FINI_0,Qubit 0,3433,64,play\nmain,FINI_0,Qubit 0,3497,108,play\nmain,FINI_0,AWGR0_0,3554,325,capture\nmain,FINI_0,Qubit 0,3605,64,play\nmain,FINI_0,Qubit 0,3669,64,play\nmain,FINI_0,Qubit 0,4104,9,play\nmain,barrier,Qubit 0,4113,0,barrier\n'
Infine, puoi visualizzare e salvare la sequenza temporale:
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")Passi successivi
- Feedforward classico e flusso di controllo (circuiti dinamici)
- Visualizza i circuiti