Visualizar o tempo de resposta do circuito
O código desta página foi desenvolvido com base nos seguintes requisitos. Recomendamos usar essas versões ou versões mais recentes.
qiskit[all]~=2.5.0 qiskit-ibm-runtime~=0.47.0
Embora a janela de linha do tempo integrada ao Qiskit seja útil para circuitos estáticos, ela pode não refletir com precisão a temporização de circuitos dinâmicos devido a operações implícitas, como difusão e determinação de ramificação. Como parte do suporte a circuitos dinâmicos, a função Qiskit Runtime retorna informações precisas sobre o tempo de execução do circuito nos resultados da tarefa, quando solicitado.
- Esta é uma função experimental. Está em fase de pré-lançamento e, portanto, está sujeito a alterações.
- Esta função se aplica apenas a tarefas do Sampler do Qiskit Runtime.
- Embora o tempo total de execução do circuito seja informado nos metadados de "compilação", esse NÃO é o tempo utilizado para fins de cobrança (tempo de QPU).
Ativar a recuperação de dados de tempo
Para habilitar a recuperação de dados de tempo, defina o sinalizador scheduler_timing experimental como True ao executar o trabalho 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()Acessar os dados de cronometragem do circuito
Quando solicitado, os dados de tempo de execução do circuito para cada PUB são retornados nos metadados do resultado da tarefa, na seção ["compilation"]["scheduler_timing"]["timing"]. Este campo contém as informações brutas de tempo. Para exibir as informações de tempo, use a ferramenta de visualização integrada, conforme descrito na seção “Visualizar os tempos ”.
Use o código a seguir para acessar os dados de tempo 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"]Compreender os dados brutos de temporização
Embora a visualização dos dados de temporização do circuito por meio do draw_circuit_schedule_timing método seja o caso de uso mais comum, pode ser útil compreender a estrutura dos dados de temporização brutos retornados. Isso pode ajudá-lo, por exemplo, a extrair informações por meio de programação.
Os dados de tempo retornados em ["compilation"]["scheduler_timing"]["timing"] são uma lista de strings. Cada sequência de caracteres 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 ramo principal.Instruction- A porta lógica e o qubit sobre o qual se vai operar.Channel- O canal ao qual a instrução está sendo atribuída. Pode ser um dos seguintes:Qubit x- O canal de excitação do qubit x.AWGRx_y(leitura do gerador de formas de onda arbitrárias) - Utilizado pelos canais de leitura para se comunicarem durante a medição de qubits. Os argumentos x e y correspondem ao ID do instrumento de leitura e ao número do qubit, respectivamente.
T0- A hora de início da aula dentro do horário completoDuration- A duração da instrução, em unidades de dt segundos, onde 1 dt = 1 ciclo de agendamento. Você pode descobrir odtvalor de um backend usandobackend.dt.Pulse- O tipo de operação por pulsos que está sendo utilizado.
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
...Visualize os tempos
Com o qiskit-ibm-runtimev0.43.0 ou versões posteriores, é possível visualizar os tempos de resposta do circuito. Para visualizar os tempos, primeiro é preciso converter os metadados do resultado para fig usando o draw_circuit_schedule_timing método. Este método retorna uma plotly figura, que você pode exibir diretamente, salvar em um arquivo ou fazer as duas coisas. Para obter mais informações sobre os plotly comandos a serem usados, consulte 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")
Compreender a figura gerada
A imagem dos dados de temporização do circuito gerados por draw_circuit_schedule_timing apresenta as seguintes informações:
- O eixo X representa o tempo em unidades de dt segundos, onde 1 dt = 1 ciclo de agendamento. Você pode descobrir o
dtvalor de um backend usandobackend.dt. - O eixo Y representa o canal (pense nos canais como instrumentos que emitem pulsos).
Receive channel- O único canal que não é um instrumento por si só. Trata-se de uma instrução transmitida em todos os canais que fazem parte de um procedimento de comunicação com o hub naquele momento.Qubit x- O canal de excitação do qubit x.AWGRx_y(leitura do gerador de formas de onda arbitrárias) - Utilizado pelos canais de leitura para se comunicarem durante a medição de qubits. Os argumentos x e y correspondem ao ID do instrumento de leitura e ao número do qubit, respectivamente.Hub- Controla a transmissão.
Além disso, cada instrução segue o formato X_Y, em que X é o nome da instrução e Y é o tipo de pulso. Um 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 a porta X aplicado ao qubit 10 às 1161 dt.
Exemplo de ponta a ponta
Este exemplo mostra como ativar a opção, obter as informações de temporização do circuito a partir dos metadados e exibi-las como uma imagem.
Primeiro, configure o ambiente, defina os circuitos e converta-os para circuitos ISA, e defina e execute os trabalhos.
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: d9bk4smg26ic73dg33fg (DONE)
Em seguida, verifique os horários do circuito:
# Get the circuit schedule timing
result[0].metadata["compilation"]["scheduler_timing"]["timing"]Output:
'main,rz_0,Qubit 0,897,0,shift_phase\nmain,sx_0,Qubit 0,897,6,play\nmain,sx_0,Qubit 0,901,0,shift_phase\nmain,rz_0,Qubit 0,903,0,shift_phase\nmain,barrier,Qubit 0,903,0,barrier\nmain,measure_0,Qubit 0,904,180,play\nmain,measure_0,AWGR0_0,1025,205,capture\nmain,barrier,Qubit 0,1431,0,barrier\nmain,broadcast,Hub,1025,406,broadcast\nmain,receive,Receive,1431,7,receive\nthen,x_0,Qubit 0,1446,6,play\nmain,barrier,Qubit 0,1460,0,barrier\nmain,measure_0,Qubit 0,1461,180,play\nmain,measure_0,AWGR0_0,1582,205,capture\nmain,barrier,Qubit 0,1886,0,barrier\nmain,barrier,Qubit 0,1886,0,barrier\nmain,FINI_0,Qubit 0,1887,180,play\nmain,FINI_0,AWGR0_0,2008,205,capture\nmain,FINI_0,Qubit 0,2312,6,play\nmain,FINI_0,Qubit 0,2319,180,play\nmain,FINI_0,AWGR0_0,2440,205,capture\nmain,FINI_0,Qubit 0,2744,6,play\nmain,barrier,Qubit 0,2750,0,barrier\n'
Por fim, você pode visualizar e salvar a cronometragem:
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óximas etapas
- Feedforward clássico e fluxo de controle (circuitos dinâmicos)
- Visualizar circuitos