{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "cdc8dc1e-0cff-46c1-94d0-97456d278e27",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Écrivez votre premier programme Qiskit Serverless\"\n",
        "description: \"Comment créer un programme de transpilation parallèle et le déployer sur IBM Quantum Platform afin de l'utiliser comme service distant réutilisable.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mypath  */}\n",
        "\n",
        "<span id=\"write-your-first-qiskit-serverless-program\" />\n",
        "\n",
        "# Écrivez votre premier programme Qiskit Serverless\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b6d632cb-d884-4963-9c8d-8f3a3acd8a7d",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "<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]~=1.3.1\n",
        "    qiskit-ibm-runtime~=0.34.0\n",
        "    qiskit-aer~=0.15.1\n",
        "    qiskit-serverless~=0.18.1\n",
        "    qiskit-ibm-catalog~=0.2\n",
        "    qiskit-addon-sqd~=0.8.1\n",
        "    qiskit-addon-utils~=0.1.0\n",
        "    qiskit-addon-mpf~=0.2.0\n",
        "    qiskit-addon-aqc-tensor~=0.1.2\n",
        "    qiskit-addon-obp~=0.1.0\n",
        "    scipy~=1.15.0\n",
        "    pyscf~=2.8.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1cc46aeb-aff6-4fab-9d78-69f2bfe98d98",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  **Qiskit Serverless est en cours de mise à niveau et ses fonctionnalités évoluent rapidement.** Pendant cette phase de développement, vous trouverez les notes de mise à jour et la documentation la plus récente sur la page [Qiskit ServerlessGitHub](https://qiskit.github.io/qiskit-serverless/index.html).\n",
        "</Admonition>\n",
        "\n",
        "Cet exemple montre comment utiliser `qiskit-serverless` des outils pour créer un programme de transpilation parallèle, puis comment le `qiskit-ibm-catalog` déployer sur IBM Quantum Platform afin de l'utiliser comme service distant réutilisable.\n",
        "\n",
        "<span id=\"workflow-overview\" />\n",
        "\n",
        "## Présentation du flux de travail\n",
        "\n",
        "1. Créer un répertoire local et vider le fichier programme (`./source_files/transpile_remote.py`)\n",
        "2. Ajoutez à votre programme du code qui, une fois téléchargé sur Qiskit Serverless, compilera un circuit\n",
        "3. Utilisez `qiskit-ibm-catalog` pour vous authentifier sur Qiskit Serverless\n",
        "4. Téléchargez le programme sur Qiskit Serverless\n",
        "\n",
        "Une fois votre programme téléchargé, vous pouvez l'exécuter pour transcompiler le circuit en suivant le guide «[ Exécuter à distance votre première charge de travail Qiskit Serverless](/docs/guides/serverless-run-first-workload) ».\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cad16f43-8548-4849-a4b8-09059a8b747c",
      "metadata": {},
      "source": [
        "<span id=\"example-remote-transpilation-with-qiskit-serverless\" />\n",
        "\n",
        "## Exemple : transpilation à distance avec Qiskit Serverless\n",
        "\n",
        "Cet exemple vous guide tout au long de la création et de l'enrichissement d'un fichier de programme qui, une fois téléchargé sur Qiskit Serverless, transpilera un `circuit` en fonction d'un donné `backend` et d'une cible `optimization_level`.\n",
        "\n",
        "<Admonition type=\"tip\">\n",
        "  Qiskit Serverless nécessite la mise en place des fichiers `.py` de votre charge de travail dans un répertoire dédié. La structure suivante est un exemple de bonne pratique :\n",
        "\n",
        "  ```text\n",
        "  serverless_program\n",
        "  ├── program_uploader.ipynb\n",
        "  └── source_files\n",
        "      ├── transpile_remote.py\n",
        "      └── *.py\n",
        "  ```\n",
        "</Admonition>\n",
        "\n",
        "Serverless télécharge le contenu d'un répertoire spécifique (dans cet exemple, le `source_files` répertoire) pour l'exécuter à distance. Une fois ces paramètres configurés, vous pouvez les ajuster `transpile_remote.py` pour récupérer les données d'entrée et renvoyer les données de sortie.\n",
        "\n",
        "<span id=\"create-the-directory-and-an-empty-program-file\" />\n",
        "\n",
        "### Créez le répertoire et un fichier de programme vide\n",
        "\n",
        "Commencez par créer un répertoire nommé `source_files`, puis créez un fichier programme dans ce répertoire, de sorte que son chemin d'accès soit `./source_files/transpile_remote.py`. Voici le fichier que vous devrez télécharger sur Qiskit Serverless.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a9b3fb7d-abd6-4a3e-b9b1-b21202d8db6d",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-your-program-file\" />\n",
        "\n",
        "### Ajoutez du code à votre fichier de programme\n",
        "\n",
        "Insérez le code suivant dans votre fichier de programme, puis enregistrez-le.\n",
        "\n",
        "<Admonition type=\"caution\">\n",
        "  Si vous exécutez les cellules de code localement dans un notebook, vous verrez apparaître la [commande ](https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-writefile)`%%writefile` magique. L'exécution de cellules à l'aide de cette commande spéciale permet de les enregistrer sur le disque plutôt que de les exécuter.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "214eb803-d1fa-4ac0-b955-8b24717086f4",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This cell is hidden from users, it creates a new folder\n",
        "from pathlib import Path\n",
        "\n",
        "Path(\"./source_files\").mkdir(exist_ok=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "64722041-22ed-42bd-8d83-d8e9f5e5b55b",
      "metadata": {
        "editable": true,
        "slideshow": {
          "slide_type": ""
        },
        "tags": []
      },
      "outputs": [],
      "source": [
        "%%writefile ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "def transpile_remote(circuit, optimization_level, backend):\n",
        "    \"\"\"Transpiles an abstract circuit into an ISA circuit for a given backend.\"\"\"\n",
        "    pass_manager = generate_preset_pass_manager(\n",
        "        optimization_level=optimization_level,\n",
        "\t\tbackend=backend\n",
        "    )\n",
        "    isa_circuit = pass_manager.run(circuit)\n",
        "    return isa_circuit"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7e80b5bb-0f76-43d1-a68c-97b4b22cc88a",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-get-program-arguments\" />\n",
        "\n",
        "### Ajouter du code pour récupérer les arguments du programme\n",
        "\n",
        "Ajoutez maintenant le code suivant à votre fichier de programme; il permet de définir les arguments du programme.\n",
        "\n",
        "Votre site initial `transpile_remote.py` comporte trois entrées : `circuits`, `backend_name`, et `optimization_level`. Serverless est actuellement limité à l'acceptation d'entrées et de sorties sérialisables. Pour cette raison, vous ne pouvez pas transmettre directement `backend` , vous devez donc utiliser `backend_name` comme chaîne de caractères.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6819379b-d7b2-4fda-9e6b-459eec748a79",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit_serverless import get_arguments, save_result, distribute_task, get\n",
        "\n",
        "# Get program arguments\n",
        "arguments = get_arguments()\n",
        "circuits = arguments.get(\"circuits\")\n",
        "backend_name = arguments.get(\"backend_name\")\n",
        "optimization_level = arguments.get(\"optimization_level\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5ae9fb12-f06f-4f7d-8f37-1d872285deab",
      "metadata": {},
      "source": [
        "<span id=\"add-code-that-calls-the-backend\" />\n",
        "\n",
        "### Ajouter le code qui appelle le backend\n",
        "\n",
        "Ajoutez le code suivant à votre fichier de programme, qui appelle votre backend avec `QiskitRuntimeService`.\n",
        "\n",
        "Le code suivant part du principe que vous avez déjà suivi la procédure pour enregistrer vos identifiants à l'aide de `QiskitRuntimeService.save_account`, et chargera votre compte par défaut enregistré, sauf indication contraire de votre part. Pour plus d'informations, consultez les sections « [Enregistrer vos identifiants de connexion ](/docs/guides/save-credentials)» et « [Initialiser votre compte IBM Quantum Compute Service](/docs/guides/initialize-account) ».\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "4b0c7d24-9b87-4e00-bb1d-f82aa967cb1d",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.backend(backend_name)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "61e7cb3b-6d62-4b68-817a-39c0c1d95a9b",
      "metadata": {},
      "source": [
        "<span id=\"add-code-to-transpile\" />\n",
        "\n",
        "### Ajouter du code à transcompiler\n",
        "\n",
        "Pour finir, ajoutez le code suivant à votre fichier de programme. Ce code traite tous `transpile_remote()` les éléments `circuits` transmis et renvoie le `transpiled_circuits` résultat :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "041e7f85-e9e8-424d-8694-d54316225cc4",
      "metadata": {},
      "outputs": [],
      "source": [
        "%%writefile --append ./source_files/transpile_remote.py\n",
        "# If you include the preceding `%%writefile` command (visible only when you read this\n",
        "# locally in a notebook), running this cell saves to disk rather than executing the code.\n",
        "\n",
        "# Each circuit is being transpiled and will populate the array\n",
        "results = [\n",
        "    transpile_remote(circuit, 1, backend)\n",
        "    for circuit in circuits\n",
        "]\n",
        "\n",
        "save_result({\n",
        "    \"transpiled_circuits\": results\n",
        "})"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "dac118ab-e447-4ddd-a5f8-d13e3953db76",
      "metadata": {},
      "source": [
        "<span id=\"upload-to-qiskit-serverless\" />\n",
        "\n",
        "<span id=\"authenticate-to-qiskit-serverless\" />\n",
        "\n",
        "### Se connecter à Qiskit Serverless\n",
        "\n",
        "Utilisez `qiskit-ibm-catalog` pour vous connecter à `QiskitServerless` à l'aide de votre clé API (vous pouvez utiliser votre clé `QiskitRuntimeService` API actuelle ou en créer une nouvelle sur le [tableau de bord de l' IBM Quantum Platform]() ).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "8d1385c3-09a5-42c6-a5bc-53f686d8410e",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_catalog import QiskitServerless, QiskitFunction\n",
        "\n",
        "# Authenticate to the remote cluster and submit the pattern for remote execution\n",
        "serverless = QiskitServerless()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a0f64820-5fb1-41b9-9cb4-5095d0b5db43",
      "metadata": {},
      "source": [
        "<span id=\"run-code-to-upload\" />\n",
        "\n",
        "### Exécuter le code pour effectuer le téléchargement\n",
        "\n",
        "Exécutez le code suivant pour télécharger le programme. Qiskit Serverless compresse le contenu de `working_dir` (dans ce cas, `source_files`) en un fichier `tar`, qui est ensuite téléchargé puis supprimé. Ce paramètre `entrypoint` indique le fichier exécutable principal du programme à lancer pour « Qiskit Serverless ».\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "c1cdd46d-71e9-4711-a09b-6eca569ede6a",
      "metadata": {},
      "outputs": [],
      "source": [
        "transpile_remote_demo = QiskitFunction(\n",
        "    title=\"transpile_remote_serverless\",\n",
        "    entrypoint=\"transpile_remote.py\",\n",
        "    working_dir=\"./source_files/\",\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "8b675d04-bde8-4b3d-b9e5-99982ef742e1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(transpile_remote_serverless)"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "serverless.upload(transpile_remote_demo)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3a840c18-3010-4d05-91cb-592e2692c1d7",
      "metadata": {},
      "source": [
        "<span id=\"verify-upload\" />\n",
        "\n",
        "### Vérifier le téléchargement\n",
        "\n",
        "Pour vérifier si le téléchargement s'est bien déroulé, utilisez `serverless.list()`, comme dans le code suivant :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "afaa3935-adf7-4b28-a8f0-583a82bbe3f1",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "QiskitFunction(transpile_remote_serverless)"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get program from serverless.list() that matches the title of the one we uploaded\n",
        "next(\n",
        "    program\n",
        "    for program in serverless.list()\n",
        "    if program.title == \"transpile_remote_serverless\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a416b143-6f70-49dc-ab2f-ad66f042cab1",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"info\" title=\"Recommandations\">\n",
        "  * Découvrez comment transmettre des paramètres et exécuter votre programme à distance dans la rubrique «[ Exécuter votre première charge de travail Qiskit Serverless à distance](/docs/guides/serverless-run-first-workload) ».\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": 4
}