{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "33f4bb3c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Visualizza i tempi del circuito\"\n",
        "description: \"Visualizza la sequenza temporale dei circuiti generati creando un grafico che puoi visualizzare, scaricare o entrambe le cose.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mactex, backgroundcolor, lightgreen */}\n",
        "\n",
        "<span id=\"visualize-circuit-timing\" />\n",
        "\n",
        "# Visualizza i tempi del 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=\"Versioni del pacchetto\">\n",
        "    Il codice presente in questa pagina è stato sviluppato sulla base dei seguenti requisiti.\n",
        "    Si consiglia di utilizzare queste versioni o quelle più recenti.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ad24e3a0",
      "metadata": {},
      "source": [
        "Sebbene il [pannello temporale](/docs/guides/visualize-circuit-timing) integrato in Qiskit sia utile per i circuiti statici, potrebbe non riflettere con precisione la temporizzazione dei [circuiti dinamici](/docs/guides/classical-feedforward-and-control-flow) 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.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Note\">\n",
        "  * Questa è una funzione sperimentale. Si tratta di una versione di anteprima e, pertanto, è soggetta a modifiche.\n",
        "  * Questa funzione si applica esclusivamente ai processi di campionamento di IBM Quantum.\n",
        "  * 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).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "995a99e8",
      "metadata": {},
      "source": [
        "<span id=\"enable-timing-data-retrieval\" />\n",
        "\n",
        "### Abilita il recupero dei dati temporali\n",
        "\n",
        "Per abilitare il recupero dei dati temporali, impostare il flag `scheduler_timing` sperimentale su `True` durante l'esecuzione del processo 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",
        "### Accedere ai dati relativi ai tempi del circuito\n",
        "\n",
        "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](#visualize-timings) \".\n",
        "\n",
        "Utilizza il codice seguente per accedere ai dati relativi ai tempi del circuito per il primo 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",
        "#### Comprendere i dati grezzi relativi alla temporizzazione\n",
        "\n",
        "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.\n",
        "\n",
        "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:\n",
        "\n",
        "* `Branch` - Determina se l'istruzione si trova in un flusso di controllo (then / else) o in un ramo principale.\n",
        "* `Instruction` - Il gate e il qubit su cui operare.\n",
        "* `Channel` - Il canale a cui viene assegnato il comando. Può essere uno dei seguenti valori:\n",
        "  * `Qubit x` - Il canale di pilotaggio per il qubit *x*.\n",
        "  * `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.\n",
        "* `T0` - L'orario di inizio della lezione nell'orario completo\n",
        "* `Duration` - La durata dell'istruzione, espressa in unità di *dt* secondi, dove 1 dt = 1 ciclo di schedulazione. È possibile trovare il `dt` valore di un backend utilizzando [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt).\n",
        "* `Pulse` - Il tipo di funzionamento a impulsi utilizzato.\n",
        "\n",
        "Esempio:\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",
        "### Visualizza i tempi\n",
        "\n",
        "Con `qiskit-ibm-runtime`v0.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](https://github.com/Qiskit/qiskit-ibm-runtime/blob/3d1bf1e1d49e5123841639fce259859c90ce9314/qiskit_ibm_runtime/visualization/draw_circuit_schedule_timings.py#L26). 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()`](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": [
        "![Passando il mouse sull'output vengono visualizzate informazioni quali l'ora di inizio, l'ora di fine e la durata.](https://quantum.cloud.ibm.com/docs/images/guides/visualize-circuit-timing/image_1.avif \" Esempio di una figura generata\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "323a7d38",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-generated-figure\" />\n",
        "\n",
        "#### Comprendere il grafico generato\n",
        "\n",
        "L'immagine dei dati temporali del circuito generati da `draw_circuit_schedule_timing` fornisce le seguenti informazioni:\n",
        "\n",
        "* L'asse X rappresenta il tempo in unità di *dt* secondi, dove 1 dt = 1 ciclo di schedulazione. È possibile trovare il `dt` valore di un backend utilizzando [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt).\n",
        "* L'asse Y rappresenta il canale (si pensi ai canali come a strumenti che emettono impulsi).\n",
        "  * `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.\n",
        "  * `Qubit x` - Il canale di pilotaggio per il qubit x.\n",
        "  * `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.\n",
        "  * `Hub` - Gestisce la trasmissione.\n",
        "\n",
        "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.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86af09ca",
      "metadata": {},
      "source": [
        "<span id=\"end-to-end-example\" />\n",
        "\n",
        "### Esempio end-to-end\n",
        "\n",
        "Questo esempio mostra come abilitare l'opzione, recuperare le informazioni sui tempi del circuito dai metadati e visualizzarle sotto forma di immagine.\n",
        "\n",
        "Per prima cosa, configurare l'ambiente, definire i circuiti e convertirli in circuiti ISA, quindi definire ed eseguire i lavori.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b46908a0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>>  Job ID:    d9mqmk7urbec73e67nng (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": [
        "A questo punto, controlla gli orari delle gare:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "7e943812",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'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'"
            ]
          },
          "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": [
        "Infine, puoi visualizzare e salvare la sequenza temporale:\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",
        "## Passi successivi\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Suggerimenti\">\n",
        "  * [Feedforward classico e flusso di controllo](/docs/guides/classical-feedforward-and-control-flow) (circuiti dinamici)\n",
        "  * [Visualizza i circuiti](/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
}