{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d53161ce",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Imposta il livello di ottimizzazione del transpiler\"\n",
        "description: \"Come impostare il livello di ottimizzazione per la transpilazione dei circuiti quantistici in Qiskit.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore Cartan's */}\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6f5a4641-5b7f-4841-8bec-60fa44429030",
      "metadata": {},
      "source": [
        "<span id=\"set-transpiler-optimization-level\" />\n",
        "\n",
        "# Imposta il livello di ottimizzazione del transpiler\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "8a1db79c-9bee-4737-b8b5-13155062ca04",
      "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 di questa pagina è stato sviluppato in base ai seguenti requisiti.\n",
        "    Si consiglia di utilizzare queste versioni o versioni 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": "bd9eb973-430c-4450-8de2-c061aa0ff742",
      "metadata": {},
      "source": [
        "I dispositivi quantistici reali sono soggetti a rumore ed errori di gate, quindi l'ottimizzazione dei circuiti per ridurre la profondità e il numero di gate può migliorare significativamente i risultati ottenuti dall'esecuzione di tali circuiti.\n",
        "La funzione [`generate_preset_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager#qiskit.transpiler.generate_preset_pass_manager) ha un argomento posizionale obbligatorio, `optimization_level`, che controlla quanto sforzo il transpiler dedica all'ottimizzazione dei circuiti. Questo argomento può essere un numero intero che assume uno dei valori 0, 1, 2 o 3.\n",
        "Livelli di ottimizzazione più elevati generano circuiti più ottimizzati a scapito di tempi di compilazione più lunghi.\n",
        "La tabella seguente spiega le ottimizzazioni eseguite con ciascuna impostazione.\n",
        "\n",
        "<Table>\n",
        "  <thead>\n",
        "    <Tr>\n",
        "      <Th>Livello di ottimizzazione</Th>\n",
        "      <Th>Descrizione</Th>\n",
        "    </Tr>\n",
        "  </thead>\n",
        "\n",
        "  <tbody>\n",
        "    <Tr>\n",
        "      <Td>0</Td>\n",
        "\n",
        "      <Td>\n",
        "        Nessuna ottimizzazione: tipicamente utilizzato per la caratterizzazione dell'hardware\n",
        "\n",
        "        * Traduzione di base\n",
        "        * Layout/Routing: `TrivialLayout` dove seleziona gli stessi numeri di qubit fisici e virtuali e inserisce degli SWAP per farli funzionare (usando `SabreSwap`)\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>1</Td>\n",
        "\n",
        "      <Td>\n",
        "        Ottimizzazione della luce:\n",
        "\n",
        "        * Layout/Instradamento: Il layout viene prima tentato con `TrivialLayout`. Se sono necessari ulteriori SWAP, si trova un layout con un numero minimo di SWAP usando `SabreSwap`, quindi si usa `VF2LayoutPostLayout` per cercare di selezionare i migliori qubit nel grafo.\n",
        "        * `InverseCancellation`\n",
        "        * 1Q ottimizzazione del gate\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>2</Td>\n",
        "\n",
        "      <Td>\n",
        "        Ottimizzazione media:\n",
        "\n",
        "        * Layout/Instradamento: Ottimizzazione di livello 1 (senza banalità) + euristica ottimizzata con maggiore profondità di ricerca e prove della funzione di ottimizzazione profondità di ricerca e prove della funzione di ottimizzazione.  Poiché non viene utilizzato `TrivialLayout` , non si cerca di utilizzare lo stesso numero di qubit fisici e virtuali.\n",
        "        * `CommutativeCancellation`\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>3</Td>\n",
        "\n",
        "      <Td>\n",
        "        Ottimizzazione elevata:\n",
        "\n",
        "        * Ottimizzazione di livello 2 + euristica ottimizzata su layout/routing con maggiore impegno/trials\n",
        "        * Sintesi di blocchi a due qubit utilizzando [la decomposizione KAK di Cartan](https://arxiv.org/abs/quant-ph/0507171).\n",
        "        * Passaggi di rottura dell'unità:\n",
        "          * `OptimizeSwapBeforeMeasure`: Sposta le misure per evitare gli SWAP\n",
        "          * `RemoveDiagonalGatesBeforeMeasure`: Rimuove le porte prima delle misurazioni che non influiscono su di esse\n",
        "      </Td>\n",
        "    </Tr>\n",
        "  </tbody>\n",
        "</Table>\n",
        "\n",
        "<span id=\"optimization-level-in-action\" />\n",
        "\n",
        "## Livello di ottimizzazione in azione\n",
        "\n",
        "Poiché le porte a due equbit sono tipicamente la fonte più significativa di errori, possiamo quantificare approssimativamente l'\"efficienza hardware\" della transpilazione contando il numero di porte a due equbit nel circuito risultante.\n",
        "Qui proveremo i diversi livelli di ottimizzazione su un circuito di ingresso costituito da un unitario casuale seguito da una porta SWAP.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "81173ebc-8359-48a6-b585-0477907b3b93",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/81173ebc-8359-48a6-b585-0477907b3b93-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit.circuit.library import UnitaryGate\n",
        "from qiskit.quantum_info import Operator, random_unitary\n",
        "\n",
        "UU = random_unitary(4, seed=12345)\n",
        "rand_U = UnitaryGate(UU)\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "qc.append(rand_U, range(2))\n",
        "qc.swap(0, 1)\n",
        "qc.draw(\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "34509d07-7804-46cb-b508-130436d9b01d",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  In questi esempi viene utilizzato il backend `FakeSherbrooke``qiskit_ibm_runtime` fittizio di, ma è possibile provarlo su qualsiasi backend reale o fittizio compatibile con Qiskit.  I tuoi risultati potrebbero essere diversi.\n",
        "</Admonition>\n",
        "\n",
        "Per prima cosa, proviamo a traspilare utilizzando il livello di ottimizzazione 0.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "40cdd173-b437-48b1-8928-741e8411342e",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/40cdd173-b437-48b1-8928-741e8411342e-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=0, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t1_exact = pass_manager.run(qc)\n",
        "qc_t1_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5169cb2-cd2a-40c0-93e5-c526580f84aa",
      "metadata": {},
      "source": [
        "Il circuito transpilato ha sei porte ECR a due qubit.\n",
        "\n",
        "Ripetere l'operazione per il livello di ottimizzazione 1:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "2dab5def-a017-42e9-92d6-e043ac4065b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/2dab5def-a017-42e9-92d6-e043ac4065b2-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t1_exact = pass_manager.run(qc)\n",
        "qc_t1_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "69d5d04b-746f-41c4-92e8-62a7eaffb5b2",
      "metadata": {},
      "source": [
        "Il circuito transpilato ha ancora sei porte ECR, ma il numero di porte a singolo qubit si è ridotto.\n",
        "\n",
        "Ripetere l'operazione per il livello di ottimizzazione 2:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "77d76048-b1e8-4225-b35f-80dc9d458e8d",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/77d76048-b1e8-4225-b35f-80dc9d458e8d-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=2, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t2_exact = pass_manager.run(qc)\n",
        "qc_t2_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4818fb06-88bd-43cb-b23c-eba5a3537e67",
      "metadata": {},
      "source": [
        "Si ottengono così gli stessi risultati del livello di ottimizzazione 1. Si noti che l'aumento del livello di ottimizzazione non sempre fa la differenza.\n",
        "\n",
        "Ripetere nuovamente l'operazione con il livello di ottimizzazione 3:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "4109d0e2-df37-4850-8409-6b860c48595c",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/4109d0e2-df37-4850-8409-6b860c48595c-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=3, backend=backend, seed_transpiler=12345\n",
        ")\n",
        "qc_t3_exact = pass_manager.run(qc)\n",
        "qc_t3_exact.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c9cf6dcf-733f-494f-a571-43d47d3908ce",
      "metadata": {},
      "source": [
        "Ora ci sono solo tre porte ECR. Otteniamo questo risultato perché al livello di ottimizzazione 3, Qiskit cerca di risintetizzare blocchi di porte a due qubit e qualsiasi porta a due qubit può essere implementata utilizzando al massimo tre porte ECR. Si può ottenere un numero ancora minore di porte ECR se si imposta `approximation_degree` a un valore inferiore a 1, consentendo al transpiler di effettuare approssimazioni che possono introdurre qualche errore nella decomposizione delle porte (vedere [Parametri comunemente usati per la transpilazione](common-parameters#approximation-degree) ):\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "bf239116-b8bb-42aa-a27a-89206d9e108a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/set-optimization/extracted-outputs/bf239116-b8bb-42aa-a27a-89206d9e108a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=3,\n",
        "    approximation_degree=0.99,\n",
        "    backend=backend,\n",
        "    seed_transpiler=12345,\n",
        ")\n",
        "qc_t3_approx = pass_manager.run(qc)\n",
        "qc_t3_approx.draw(\"mpl\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "247f60a9-b0ad-4e83-85ea-008dc808267f",
      "metadata": {},
      "source": [
        "Questo circuito ha solo due porte ECR, ma è un circuito approssimativo. Per capire in che modo il suo effetto differisce dal circuito esatto, possiamo calcolare la fedeltà tra l'operatore unitario che questo circuito implementa e l'operatore unitario esatto. Prima di eseguire il calcolo, riduciamo il circuito transpilato, che contiene 127 qubit, a un circuito che contiene solo i qubit attivi, che sono due.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "56988ecd-8a78-42ca-90eb-fc956674c64d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Synthesis fidelity\n",
            "Exact: 1.000+0.000j\n",
            "Approximate: 0.992+0.000j\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "\n",
        "def trace_to_fidelity_2q(trace: float) -> float:\n",
        "    return (4.0 + trace * trace.conjugate()) / 20.0\n",
        "\n",
        "\n",
        "# Reduce circuits down to 2 qubits so they are easy to simulate\n",
        "qc_t3_exact_small = QuantumCircuit.from_instructions(qc_t3_exact)\n",
        "qc_t3_approx_small = QuantumCircuit.from_instructions(qc_t3_approx)\n",
        "\n",
        "# Compute the fidelity\n",
        "exact_fid = trace_to_fidelity_2q(\n",
        "    np.trace(np.dot(Operator(qc_t3_exact_small).adjoint().data, UU))\n",
        ")\n",
        "approx_fid = trace_to_fidelity_2q(\n",
        "    np.trace(np.dot(Operator(qc_t3_approx_small).adjoint().data, UU))\n",
        ")\n",
        "print(\n",
        "    f\"Synthesis fidelity\\nExact: {exact_fid:.3f}\\nApproximate: {approx_fid:.3f}\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "382f6ffc-1d17-4c4b-8ea1-2f828c705793",
      "metadata": {
        "jp-MarkdownHeadingCollapsed": true
      },
      "source": [
        "La regolazione del livello di ottimizzazione può modificare anche altri aspetti del circuito, non solo il numero di porte ECR. Per alcuni esempi di come la modifica del livello di ottimizzazione influisca sulla struttura, consultare [la sezione \"Rappresentazione dei computer quantistici\"](/docs/guides/represent-quantum-computers).\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Passi successivi\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Suggerimenti\">\n",
        "  * Per saperne di più sulla funzione `generate_preset_passmanager` , iniziare con l'argomento [Impostazioni predefinite e opzioni di configurazione della transpilazione](defaults-and-configuration-options).\n",
        "  * Continuate a conoscere la transpilazione con l'argomento [Stadi del transpiler](transpiler-stages).\n",
        "  * Prova la guida [Confronta le impostazioni del transpiler](/docs/guides/circuit-transpilation-settings).\n",
        "  * Provate l'esercitazione sui [codici di ripetizione degli edifici](/docs/tutorials/repetition-codes).\n",
        "  * Consulta [la documentazione dell'API Transpile](/docs/api/qiskit/transpiler).\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
}