Visualizar el tiempo de los circuits
Versiones de paquetes
El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o más recientes.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Aunque el visualizador de línea de tiempo integrado en Qiskit es útil para circuits estáticos, es posible que no refleje con precisión el tiempo de los circuits dinámicos debido a operaciones implícitas como la difusión y la determinación de ramas. Como parte del soporte de circuits dinámicos, Qiskit Runtime devuelve la información precisa de tiempo del circuit dentro de los resultados del trabajo cuando se solicita.
- Esta es una función experimental. Está en estado de versión preliminar y, por lo tanto, está sujeta a cambios.
- Esta función solo aplica a los trabajos de Sampler de Qiskit Runtime.
- Aunque el tiempo total del circuit se devuelve en los metadatos de "compilación", este NO es el tiempo utilizado para la facturación (tiempo de QPU).
Habilitar la recuperación de datos de tiempo
Para habilitar la recuperación de datos de tiempo, establece el indicador experimental scheduler_timing en True al ejecutar el trabajo primitivo.
# 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()
Acceder a los datos de tiempo del circuit
Cuando se solicita, los datos de tiempo del circuit para cada PUB se devuelven en los metadatos del resultado del trabajo, bajo ["compilation"]["scheduler_timing"]["timing"]. Este campo contiene la información de tiempo sin procesar. Para mostrar la información de tiempo, usa la herramienta de visualización integrada, como se describe en la sección Visualizar los tiempos.
Usa el siguiente código para acceder a los datos de tiempo del circuit para el primer PUB:
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]
Comprender los datos de tiempo sin procesar
Aunque visualizar los datos de tiempo del circuit usando el método draw_circuit_schedule_timing es el caso de uso más común, puede ser útil comprender la estructura de los datos de tiempo sin procesar devueltos. Esto podría ayudarte, por ejemplo, a extraer información de forma programática.
Los datos de tiempo devueltos en ["compilation"]["scheduler_timing"]["timing"] son una lista de cadenas. Cada cadena representa una única instrucción en algún canal y está separada por comas en los siguientes tipos de datos:
Branch- Determina si la instrucción está en un flujo de control (entonces / si no) o en una rama principal.Instruction- El gate y el qubit en el que operar.Channel- El canal al que se asigna la instrucción. Puede ser uno de los siguientes:Qubit x- El canal de conducción para el qubit x.AWGRx_y(generador de formas de onda arbitrarias de lectura) - Usado por los canales de lectura para comunicar cuándo se miden los qubits. Los argumentos x e y corresponden al ID del instrumento de lectura y al número de qubit, respectivamente.
T0- El tiempo de inicio de la instrucción dentro del horario completoDuration- La duración de la instrucción, en unidades de segundos dt, donde 1 dt = 1 ciclo de programación. Puedes encontrar el valordtde un backend usandobackend.dt.Pulse- El tipo de operación de pulso que se está utilizando.
Ejemplo:
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
...
Visualizar los tiempos
Con qiskit-ibm-runtime v0.43.0 o posterior, puedes visualizar los tiempos de los circuits. Para visualizar los tiempos, primero debes convertir los metadatos del resultado a fig usando el método draw_circuit_schedule_timing. Este método devuelve una figura plotly, que puedes mostrar directamente, guardar en un archivo o ambas cosas. Para más información sobre los comandos plotly que usar, consulta fig.show() y 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")
Comprender la figura generada
La imagen de los datos de tiempo del circuit producida por draw_circuit_schedule_timing transmite la siguiente información:
- El eje X es el tiempo en unidades de segundos dt, donde 1 dt = 1 ciclo de programación. Puedes encontrar el valor
dtde un backend usandobackend.dt. - El eje Y es el canal (piensa en los canales como instrumentos que emiten pulsos).
Receive channel- El único canal que no es un instrumento por sí mismo. Es una instrucción ejecutada en todos los canales que forman parte de un procedimiento de comunicación con el hub en ese momento.Qubit x- El canal de conducción para el qubit x.AWGRx_y(generador de formas de onda arbitrarias de lectura) - Usado por los canales de lectura para comunicar cuándo se miden los qubits. Los argumentos x e y corresponden al ID del instrumento de lectura y al número de qubit, respectivamente.Hub- Controla la difusión.
Además, cada instrucción tiene el formato X_Y, donde X es el nombre de la instrucción e Y es el tipo de pulso. Un tipo play aplica pulsos de control, y un capture registra el estado del qubit. También puedes pasar el cursor sobre cada instrucción para obtener más detalles. Por ejemplo, la figura anterior muestra un pulso de control para el gate X aplicado al qubit 10 a 1161 dt.
Ejemplo de extremo a extremo
Este ejemplo te muestra cómo habilitar la opción, obtener la información de tiempo del circuit de los metadatos y mostrarla como una imagen.
Primero, configura el entorno, define los circuits y conviértelos a circuits ISA, y define y ejecuta los trabajos.
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)
A continuación, obtén el tiempo del horario del circuit:
# 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'
Finalmente, puedes visualizar y guardar el tiempo:
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")
Próximos pasos
- Retroalimentación clásica y flujo de control (circuits dinámicos)
- Visualizar circuits