{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "d53161ce",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Définir le niveau d'optimisation du transpiler\"\n",
        "description: \"Comment définir le niveau d'optimisation pour la transcompilation des circuits quantiques dans 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",
        "# Définir le niveau d'optimisation du 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=\"Versions de package\">\n",
        "    Le code de cette page a été développé en tenant compte des exigences suivantes.\n",
        "    Nous recommandons d'utiliser ces versions ou des versions plus récentes.\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": [
        "Les dispositifs quantiques réels sont sujets au bruit et aux erreurs de porte, de sorte que l'optimisation des circuits pour réduire leur profondeur et le nombre de portes peut améliorer de manière significative les résultats obtenus lors de l'exécution de ces circuits.\n",
        "La fonction [`generate_preset_pass_manager`](/docs/api/qiskit/qiskit.transpiler.generate_preset_pass_manager#qiskit.transpiler.generate_preset_pass_manager) a un argument de position obligatoire, `optimization_level`, qui contrôle l'effort que le transpileur consacre à l'optimisation des circuits. Cet argument peut être un nombre entier prenant l'une des valeurs 0, 1, 2 ou 3.\n",
        "Des niveaux d'optimisation plus élevés génèrent des circuits plus optimisés au prix de temps de compilation plus longs.\n",
        "Le tableau suivant explique les optimisations réalisées avec chaque paramètre.\n",
        "\n",
        "<Table>\n",
        "  <thead>\n",
        "    <Tr>\n",
        "      <Th>Niveau d'optimisation</Th>\n",
        "      <Th>Description</Th>\n",
        "    </Tr>\n",
        "  </thead>\n",
        "\n",
        "  <tbody>\n",
        "    <Tr>\n",
        "      <Td>0</Td>\n",
        "\n",
        "      <Td>\n",
        "        Pas d'optimisation : typiquement utilisé pour la caractérisation du matériel\n",
        "\n",
        "        * Traduction de base\n",
        "        * Disposition/Routage : `TrivialLayout`, où il sélectionne les mêmes numéros de qubits physiques que virtuels et insère des SWAPs pour que cela fonctionne (en utilisant `SabreSwap`)\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>1</Td>\n",
        "\n",
        "      <Td>\n",
        "        Optimisation de la lumière :\n",
        "\n",
        "        * Mise en page/Routage : La mise en page est d'abord tentée avec `TrivialLayout`. Si des SWAP supplémentaires sont nécessaires, une disposition avec un nombre minimum de SWAP est trouvée en utilisant `SabreSwap`, puis `VF2LayoutPostLayout` pour essayer de sélectionner les meilleurs qubits dans le graphe.\n",
        "        * `InverseCancellation`\n",
        "        * 1Q optimisation de la porte\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>2</Td>\n",
        "\n",
        "      <Td>\n",
        "        Optimisation moyenne :\n",
        "\n",
        "        * Mise en page/routage : Optimisation de niveau 1 (sans trivialité) + heuristique optimisée avec une plus grande profondeur de recherche et des essais de la fonction d'optimisation avec une plus grande profondeur de recherche et des essais de la fonction d'optimisation.  Comme `TrivialLayout` n'est pas utilisé, il n'y a pas de tentative d'utiliser les mêmes numéros de qubits physiques et virtuels.\n",
        "        * `CommutativeCancellation`\n",
        "      </Td>\n",
        "    </Tr>\n",
        "\n",
        "    <Tr>\n",
        "      <Td>3</Td>\n",
        "\n",
        "      <Td>\n",
        "        Haute optimisation :\n",
        "\n",
        "        * Optimisation niveau 2 + heuristique optimisée sur l'agencement/le routage avec plus d'efforts/essais\n",
        "        * Resynthèse de blocs à deux qubits à l'aide de la [décomposition KAK de Cartan](https://arxiv.org/abs/quant-ph/0507171).\n",
        "        * Passes brisant l'unité :\n",
        "          * `OptimizeSwapBeforeMeasure`: Déplace les mesures pour éviter les SWAPs\n",
        "          * `RemoveDiagonalGatesBeforeMeasure`: Supprime les portes avant les mesures qui n'auraient pas d'effet sur les mesures\n",
        "      </Td>\n",
        "    </Tr>\n",
        "  </tbody>\n",
        "</Table>\n",
        "\n",
        "<span id=\"optimization-level-in-action\" />\n",
        "\n",
        "## Niveau d'optimisation en action\n",
        "\n",
        "Étant donné que les portes à deux qubits sont généralement la source d'erreurs la plus importante, nous pouvons quantifier approximativement l'\"efficacité matérielle\" de la transpilation en comptant le nombre de portes à deux qubits dans le circuit résultant.\n",
        "Ici, nous allons essayer les différents niveaux d'optimisation sur un circuit d'entrée composé d'un unitaire aléatoire suivi d'une porte 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",
        "  Le backend `FakeSherbrooke` fictif de `qiskit_ibm_runtime` est utilisé dans ces exemples, mais vous pouvez l'essayer sur n'importe quel backend réel ou fictif compatible avec Qiskit.  Vos résultats peuvent varier.\n",
        "</Admonition>\n",
        "\n",
        "Commençons par effectuer la transpilation avec un niveau d'optimisation de 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": [
        "Le circuit transposé comporte six portes ECR à deux qubits.\n",
        "\n",
        "Répéter pour le niveau d'optimisation 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": [
        "Le circuit transposé comporte toujours six portes ECR, mais le nombre de portes à qubit unique a été réduit.\n",
        "\n",
        "Répétez l'opération pour le niveau d'optimisation 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": [
        "Cela donne les mêmes résultats que le niveau d'optimisation 1. Notez que l'augmentation du niveau d'optimisation ne fait pas toujours la différence.\n",
        "\n",
        "Répétez l'opération avec le niveau d'optimisation 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": [
        "Aujourd'hui, il n'y a plus que trois portes ECR. Nous obtenons ce résultat parce qu'au niveau d'optimisation 3, Qiskit tente de resynthétiser des blocs de portes de deux qubits, et que toute porte de deux qubits peut être implémentée en utilisant au plus trois portes ECR. Nous pouvons obtenir encore moins de portes ECR si nous fixons `approximation_degree` à une valeur inférieure à 1, ce qui permet au transpilateur de faire des approximations susceptibles d'introduire une erreur dans la décomposition de la porte (voir [Paramètres couramment utilisés pour la transpilation](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": [
        "Ce circuit ne comporte que deux portes ECR, mais il s'agit d'un circuit approximatif. Pour comprendre en quoi son effet diffère de celui du circuit exact, nous pouvons calculer la fidélité entre l'opérateur unitaire que ce circuit met en œuvre et l'opérateur unitaire exact. Avant d'effectuer le calcul, nous réduisons d'abord le circuit transpilé, qui contient 127 qubits, à un circuit qui ne contient que les qubits actifs, qui sont au nombre de deux.\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": [
        "Le réglage du niveau d'optimisation peut également modifier d'autres aspects du circuit, et pas seulement le nombre de portes ECR. Pour voir des exemples illustrant comment la modification du niveau d'optimisation influe sur la disposition, consultez [la section « Représentation des ordinateurs quantiques](/docs/guides/represent-quantum-computers) ».\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Pour en savoir plus sur la fonction `generate_preset_passmanager` , commencez par la rubrique [Paramètres par défaut et options de configuration de la transpilation](defaults-and-configuration-options).\n",
        "  * Poursuivez votre apprentissage de la transpilation avec le thème des [étapes de la transpilation](transpiler-stages).\n",
        "  * Consultez le guide [Comparer les paramètres du transpiler](/docs/guides/circuit-transpilation-settings).\n",
        "  * Essayez le tutoriel [Construire des codes de répétition](/docs/tutorials/repetition-codes).\n",
        "  * Consultez la [documentation de l'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
}