Visualizar o timing do Circuit
Versões dos pacotes
O código desta página foi desenvolvido usando os seguintes requisitos. Recomendamos usar essas versões ou versões mais recentes.
qiskit[all]~=2.4.0
qiskit-ibm-runtime~=0.46.1
Embora o visualizador de linha do tempo integrado ao Qiskit seja útil para Circuits estáticos, ele pode não refletir com precisão o timing de Circuits dinâmicos por causa de operações implícitas como broadcasting e determinação de branch. Como parte do suporte a Circuits dinâmicos, o Qiskit Runtime retorna as informações precisas de timing do circuito nos resultados do job quando solicitado.
- Esta é uma função experimental. Está em status de versão prévia e, portanto, sujeita a alterações.
- Esta função aplica-se apenas a jobs do Sampler do Qiskit Runtime.
- Embora o tempo total do circuito seja retornado nos metadados de "compilação", este NÃO é o tempo usado para cobrança (tempo de QPU).
Habilitar a recuperação de dados de timing
Para habilitar a recuperação de dados de timing, defina o sinalizador experimental scheduler_timing como True ao executar o job da primitiva.
# 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()
Acessar os dados de timing do circuito
Quando solicitados, os dados de timing do circuito para cada PUB são retornados nos metadados do resultado do job, em ["compilation"]["scheduler_timing"]["timing"]. Este campo contém as informações brutas de timing. Para exibir as informações de timing, use a ferramenta de visualização integrada, conforme descrito na seção Visualizar os timings.
Use o código a seguir para acessar os dados de timing do circuito para o primeiro PUB:
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]
Entender os dados brutos de timing
Embora visualizar os dados de timing do circuito usando o método draw_circuit_schedule_timing seja o caso de uso mais comum, pode ser útil entender a estrutura dos dados brutos de timing retornados. Isso pode ajudá-lo, por exemplo, a extrair informações programaticamente.
Os dados de timing retornados em ["compilation"]["scheduler_timing"]["timing"] são uma lista de strings. Cada string representa uma única instrução em algum canal e é separada por vírgulas nos seguintes tipos de dados:
Branch- Determina se a instrução está em um fluxo de controle (then / else) ou em um branch principal.Instruction- O gate e o qubit a operar.Channel- O canal que está sendo atribuído com a instrução. Pode ser um dos seguintes:qubit x- O canal de drive para o qubit x.AWGRx_y(gerador de forma de onda arbitrária de leitura) - Usado por canais de leitura para comunicar quando medir qubits. Os argumentos x e y correspondem ao ID do instrumento de leitura e ao número do qubit, respectivamente.
T0- O tempo de início da instrução dentro do agendamento completoDuration- A duração da instrução, em unidades de dt segundos, onde 1 dt = 1 ciclo de agendamento. Você pode encontrar o valordtde um Backend usandobackend.dt.Pulse- O tipo de operação de pulso sendo usado.
Exemplo:
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 os timings
Com o qiskit-ibm-runtime v0.43.0 ou posterior, você pode visualizar os timings de circuito. Para visualizar os timings, você primeiro precisa converter os metadados do resultado para fig usando o método draw_circuit_schedule_timing. Este método retorna uma figura plotly, que você pode exibir diretamente, salvar em um arquivo ou ambos. Para mais informações sobre os comandos plotly a usar, veja 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")
Entender a figura gerada
A imagem dos dados de timing do circuito gerada por draw_circuit_schedule_timing transmite as seguintes informações:
- O eixo X é o tempo em unidades de dt segundos, onde 1 dt = 1 ciclo de agendamento. Você pode encontrar o valor
dtde um Backend usandobackend.dt. - O eixo Y é o canal (pense nos canais como instrumentos que emitem pulsos).
Receive channel- O único canal que não é um instrumento em si. É uma instrução executada em todos os canais que fazem parte de um procedimento de comunicação com o hub naquele momento.qubit x- O canal de drive para o qubit x.AWGRx_y(gerador de forma de onda arbitrária de leitura) - Usado por canais de leitura para comunicar quando medir qubits. Os argumentos x e y correspondem ao ID do instrumento de leitura e ao número do qubit, respectivamente.Hub- Controla o broadcasting.
Adicionalmente, cada instrução tem o formato X_Y, onde X é o nome da instrução e Y é o tipo de pulso. Um tipo play aplica pulsos de controle e um capture registra o estado do qubit. Você também pode passar o mouse sobre cada instrução para obter mais detalhes. Por exemplo, a figura anterior mostra um pulso de controle para o gate X aplicado ao qubit 10 em 1161 dt.
Exemplo de ponta a ponta
Este exemplo mostra como habilitar a opção, obter as informações de timing do circuito dos metadados e exibi-las como uma imagem.
Primeiro, configure o ambiente, defina os circuitos e converta-os para Circuits ISA, e defina e execute os jobs.
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)
Em seguida, obtenha o timing do agendamento do circuito:
# 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'
Por fim, você pode visualizar e salvar o timing:
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 passos
- Retroalimentação clássica e fluxo de controle (Circuits dinâmicos)
- Visualizar Circuits