{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "33f4bb3c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Visualizar o tempo de resposta do circuito\"\n",
        "description: \"Visualize a temporização dos circuitos gerados criando uma figura que você pode visualizar, baixar ou ambas as coisas.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mactex, backgroundcolor, lightgreen */}\n",
        "\n",
        "<span id=\"visualize-circuit-timing\" />\n",
        "\n",
        "# Visualizar o tempo de resposta do circuito\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bfada4f0",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido com base nos seguintes requisitos.\n",
        "    Recomendamos usar essas versões ou versões mais recentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.0\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ad24e3a0",
      "metadata": {},
      "source": [
        "Embora a [janela](/docs/guides/visualize-circuit-timing) 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](/docs/guides/classical-feedforward-and-control-flow) 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.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Notas\">\n",
        "  * Esta é uma função experimental. Está em fase de pré-lançamento e, portanto, está sujeito a alterações.\n",
        "  * Esta função se aplica apenas a tarefas do Sampler do Qiskit Runtime.\n",
        "  * 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).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "995a99e8",
      "metadata": {},
      "source": [
        "<span id=\"enable-timing-data-retrieval\" />\n",
        "\n",
        "### Ativar a recuperação de dados de tempo\n",
        "\n",
        "Para habilitar a recuperação de dados de tempo, defina o sinalizador `scheduler_timing` experimental como `True` ao executar o trabalho primitivo.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "ab8c6c23",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\n",
        "    \"execution\": {\n",
        "        \"scheduler_timing\": True,\n",
        "    },\n",
        "}\n",
        "\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "531b2abd",
      "metadata": {},
      "source": [
        "<span id=\"access-the-circuit-timing-data\" />\n",
        "\n",
        "### Acessar os dados de cronometragem do circuito\n",
        "\n",
        "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](#visualize-timings) ”.\n",
        "\n",
        "Use o código a seguir para acessar os dados de tempo do circuito para o primeiro PUB :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b6958d99",
      "metadata": {},
      "outputs": [],
      "source": [
        "job_result = sampler_job.result()\n",
        "circuit_schedule = job_result[0].metadata[\"compilation\"][\"scheduler_timing\"]\n",
        "circuit_schedule_timing = circuit_schedule[\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "20400401",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-raw-timing-data\" />\n",
        "\n",
        "#### Compreender os dados brutos de temporização\n",
        "\n",
        "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.\n",
        "\n",
        "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:\n",
        "\n",
        "* `Branch` - Determina se a instrução está em um fluxo de controle (then / else) ou em um ramo principal.\n",
        "* `Instruction` - A porta lógica e o qubit sobre o qual se vai operar.\n",
        "* `Channel` - O canal ao qual a instrução está sendo atribuída. Pode ser um dos seguintes:\n",
        "  * `Qubit x` - O canal de excitação do qubit *x*.\n",
        "  * `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.\n",
        "* `T0` - A hora de início da aula dentro do horário completo\n",
        "* `Duration` - A duração da instrução, em unidades de *dt* segundos, onde 1 dt = 1 ciclo de agendamento. Você pode descobrir o `dt` valor de um backend usando [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt).\n",
        "* `Pulse` - O tipo de operação por pulsos que está sendo utilizado.\n",
        "\n",
        "Exemplo:\n",
        "\n",
        "```python\n",
        "main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration\n",
        "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\n",
        "...\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d34100f",
      "metadata": {},
      "source": [
        "<span id=\"visualize-timings\" />\n",
        "\n",
        "<span id=\"visualize-the-timings\" />\n",
        "\n",
        "### Visualize os tempos\n",
        "\n",
        "Com o `qiskit-ibm-runtime`v0.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](https://github.com/Qiskit/qiskit-ibm-runtime/blob/3d1bf1e1d49e5123841639fce259859c90ce9314/qiskit_ibm_runtime/visualization/draw_circuit_schedule_timings.py#L26). 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()`](https://plotly.com/python-api-reference/generated/plotly.io.show.html) e [`fig.write_image(\"<path.format>\")`](https://plotly.com/python-api-reference/generated/plotly.io.write_image.html).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "4ad3acfb",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "# Create a figure from the metadata\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule_timing,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2788e992",
      "metadata": {},
      "source": [
        "![Ao passar o mouse sobre o resultado, são exibidas informações como início, fim e duração. ](https://quantum.cloud.ibm.com/docs/images/guides/visualize-circuit-timing/image_1.avif \"Exemplo de uma figura gerada\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "323a7d38",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-generated-figure\" />\n",
        "\n",
        "#### Compreender a figura gerada\n",
        "\n",
        "A imagem dos dados de temporização do circuito gerados por `draw_circuit_schedule_timing` apresenta as seguintes informações:\n",
        "\n",
        "* O eixo X representa o tempo em unidades de *dt* segundos, onde 1 dt = 1 ciclo de agendamento. Você pode descobrir o `dt` valor de um backend usando [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt).\n",
        "* O eixo Y representa o canal (pense nos canais como instrumentos que emitem pulsos).\n",
        "  * `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.\n",
        "  * `Qubit x` - O canal de excitação do qubit x.\n",
        "  * `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.\n",
        "  * `Hub` - Controla a transmissão.\n",
        "\n",
        "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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86af09ca",
      "metadata": {},
      "source": [
        "<span id=\"end-to-end-example\" />\n",
        "\n",
        "### Exemplo de ponta a ponta\n",
        "\n",
        "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.\n",
        "\n",
        "Primeiro, configure o ambiente, defina os circuitos e converta-os para circuitos ISA, e defina e execute os trabalhos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b46908a0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>>  Job ID:    d9bk4smg26ic73dg33fg (DONE)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService\n",
        "from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Create a dynamic circuit\n",
        "\n",
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "qc = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "qc.h(q0)\n",
        "qc.measure(q0, c0)\n",
        "with qc.if_test((c0, 1)):\n",
        "    qc.x(q0)\n",
        "qc.measure(q0, c0)\n",
        "\n",
        "# Convert to an ISA circuit for the given backend\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "# Generate samplers for backend targets\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\"execution\": {\"scheduler_timing\": True}}\n",
        "\n",
        "# Submit jobs\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()\n",
        "\n",
        "print(\n",
        "    f\">>> {' Job ID:':<10}  {sampler_job.job_id()} ({sampler_job.status()})\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1bd5993c",
      "metadata": {},
      "source": [
        "Em seguida, verifique os horários do circuito:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "7e943812",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'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'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get the circuit schedule timing\n",
        "result[0].metadata[\"compilation\"][\"scheduler_timing\"][\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "04db1f41",
      "metadata": {},
      "source": [
        "Por fim, você pode visualizar e salvar a cronometragem:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "9d1901c3",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "circuit_schedule = result[0].metadata[\"compilation\"][\"scheduler_timing\"][\n",
        "    \"timing\"\n",
        "]\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9daa7cf7",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * [Feedforward clássico e fluxo de controle](/docs/guides/classical-feedforward-and-control-flow) (circuitos dinâmicos)\n",
        "  * [Visualizar circuitos](/docs/guides/visualize-circuits)\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}