{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f4e55284-8bd6-4cb2-b044-11816cba1e2d",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Exécuter des tâches par lots\"\n",
        "description: \"Comment exécuter des tâches de calcul quantique en mode batch à l'aide du service de calcul d' IBM Quantum.\"\n",
        "---\n",
        "\n",
        "<span id=\"run-jobs-in-a-batch\" />\n",
        "\n",
        "# Exécuter des tâches par lots\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "3f77b9f7-7967-45ad-a68b-3db6e0d36456",
      "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 figurant sur cette page a été développé selon les exigences suivantes.\n",
        "    Nous recommandons d'utiliser ces versions ou des versions plus récentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.3.0\n",
        "    qiskit-ibm-runtime~=0.43.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "388d0a36-0a7c-4b60-8607-4e535f8adf2c",
      "metadata": {},
      "source": [
        "Utilisez le mode batch pour soumettre plusieurs travaux primitifs simultanément. Les exemples suivants illustrent l'utilisation des lots.\n",
        "\n",
        "<span id=\"set-up-to-use-batches\" />\n",
        "\n",
        "## Configurer pour utiliser des lots\n",
        "\n",
        "Avant de lancer un traitement par lots, vous devez [configurer le client Compute d’ IBM Quantum](/docs/guides/install-qiskit), puis l’initialiser en tant que service :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "340d9d45-9ec0-473f-bf17-9dc7eb0804ed",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    Batch,\n",
        "    SamplerV2 as Sampler,\n",
        "    EstimatorV2 as Estimator,\n",
        "    Executor,\n",
        ")\n",
        "\n",
        "\n",
        "service = QiskitRuntimeService()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fc80a9fa-ffc1-419f-be98-ef36b73eda9a",
      "metadata": {},
      "source": [
        "<span id=\"open-a-batch\" />\n",
        "\n",
        "## Ouvrir un lot\n",
        "\n",
        "Vous pouvez ouvrir un lot d'exécution en utilisant le gestionnaire de contexte `with Batch(...)` ou en initialisant la classe `Batch` classe. Lorsque vous démarrez un lot, vous devez spécifier une QPU en transmettant un objet `backend` .  Le lot démarre lorsque son premier travail commence à être exécuté.\n",
        "\n",
        "**Classe de lots**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "02e53d53-3410-4e07-9c02-c582b97e15e1",
      "metadata": {},
      "outputs": [],
      "source": [
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "batch = Batch(backend=backend)\n",
        "estimator = Estimator(mode=batch)\n",
        "sampler = Sampler(mode=batch)\n",
        "executor = Executor(mode=batch)\n",
        "# Close the batch because no context manager was used.\n",
        "batch.close()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "ad0927c2-cbba-4392-bced-fddcde738521",
      "metadata": {},
      "source": [
        "**Gestionnaire de contexte**\n",
        "\n",
        "Le gestionnaire de contexte ouvre et ferme automatiquement le lot.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "fe96e5dd-8237-458d-8657-dd0f71c65f8a",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime import (\n",
        "    Batch,\n",
        "    SamplerV2 as Sampler,\n",
        "    EstimatorV2 as Estimator,\n",
        "    Executor,\n",
        ")\n",
        "\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "with Batch(backend=backend):\n",
        "    estimator = Estimator()\n",
        "    sampler = Sampler()\n",
        "    executor = Executor()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "285f7538-3abd-4940-bca1-b1a61bc25bd5",
      "metadata": {},
      "source": [
        "<span id=\"specify-batch-length\" />\n",
        "\n",
        "<span id=\"batch-length\" />\n",
        "\n",
        "## Longueur du lot\n",
        "\n",
        "Le paramètre `max_time` permet de définir la durée maximale de vie du lot (TTL). Cette durée doit être supérieure à la durée d'exécution du travail le plus long. Cette minuterie démarre lorsque le lot démarre.  Lorsque la valeur est atteinte, le lot est clôturé.  Les tâches en cours d'exécution se terminent, mais celles qui sont encore en file d'attente échouent.\n",
        "\n",
        "```python\n",
        "with Batch(backend=backend, max_time=\"25m\"):\n",
        "  ...\n",
        "```\n",
        "\n",
        "Il existe également une valeur TTL interactive qui ne peut pas être configurée (1 minute pour tous les plans).  Si aucun travail par lot n'est mis en file d'attente dans cette fenêtre, le lot est temporairement désactivé.\n",
        "\n",
        "Valeurs maximales par défaut du TTL :\n",
        "\n",
        "| Type d'instance        | Défaut Maximum TTL |\n",
        "| ---------------------- | ------------------ |\n",
        "| Tous les plans payants | 8 heures           |\n",
        "| Ouvrir                 | 10 minutes         |\n",
        "\n",
        "Pour déterminer le TTL maximum ou le TTL interactif d'un lot, suivez les instructions de la section [Déterminer les détails du lot](#batch-details) et recherchez la valeur `max_time` ou `interactive_timeout` , respectivement.\n",
        "\n",
        "<span id=\"close\" />\n",
        "\n",
        "<span id=\"close-a-batch\" />\n",
        "\n",
        "## Fermer un lot\n",
        "\n",
        "Un lot se ferme automatiquement lorsqu'il quitte le gestionnaire de contexte. Lorsque le gestionnaire de contexte de lot est quitté, le lot est placé dans l'état \"En cours, n'acceptant pas de nouveaux travaux\". Cela signifie que le lot termine le traitement de tous les travaux en cours ou en file d'attente jusqu'à ce que la valeur maximale du TTL soit atteinte. Lorsque tous les travaux sont terminés, le lot est immédiatement clôturé. Il n'est pas possible de soumettre des travaux à un lot fermé.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "05868749-5c03-4540-b780-3e151054e4cf",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  Le code suivant nécessite que vous fournissiez vos propres informations, telles que les PUB de l'estimateur et de l'échantillonneur, ainsi qu'un backend.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "39fa154b-d5f2-411f-8953-367bd5e3c879",
      "metadata": {},
      "outputs": [],
      "source": [
        "with Batch(backend=backend) as batch:\n",
        "    estimator = Estimator()\n",
        "    sampler = Sampler()\n",
        "    job1 = estimator.run([estimator_pub])\n",
        "    job2 = sampler.run([sampler_pub])\n",
        "\n",
        "# The batch is no longer accepting jobs but the submitted job will run to completion.\n",
        "result = job1.result()\n",
        "result2 = job2.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "92515062-ec5e-41a1-8969-59e78c448b1f",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\">\n",
        "  Si vous n'utilisez pas de gestionnaire de contexte, fermez manuellement le lot.  Si vous laissez le lot ouvert et que vous y soumettez d'autres travaux ultérieurement, il est possible que le TTL maximal soit atteint avant que les travaux suivants ne commencent à s'exécuter, ce qui entraînera leur annulation. Vous pouvez fermer un lot dès que vous avez fini de lui soumettre des travaux. Lorsqu'un lot est fermé à l'aide de `batch.close()`, il n'accepte plus de nouveaux travaux, mais les travaux déjà soumis continueront à être exécutés jusqu'à leur achèvement et leurs résultats pourront être récupérés.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "d1cb86c0-b397-47a9-ad93-055aa71ca327",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Result1: PrimitiveResult([PubResult(data=DataBin(evs=np.ndarray(<shape=(3, 2), dtype=float64>), stds=np.ndarray(<shape=(3, 2), dtype=float64>), ensemble_standard_error=np.ndarray(<shape=(3, 2), dtype=float64>), shape=(3, 2)), metadata={'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32})], metadata={'dynamical_decoupling': {'enable': False, 'sequence_type': 'XX', 'extra_slack_distribution': 'middle', 'scheduling_method': 'alap'}, 'twirling': {'enable_gates': False, 'enable_measure': True, 'num_randomizations': 'auto', 'shots_per_randomization': 'auto', 'interleave_randomizations': True, 'strategy': 'active-accum'}, 'resilience': {'measure_mitigation': True, 'zne_mitigation': False, 'pec_mitigation': False}, 'version': 2})\n",
            "Result2: PrimitiveResult([SamplerPubResult(data=DataBin(meas=BitArray(<shape=(3, 2), num_shots=4096, num_bits=2>), meas0=BitArray(<shape=(3, 2), num_shots=4096, num_bits=133>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-02-15 07:58:55', stop='2026-02-15 07:59:02', size=24576>)])}, 'version': 2})\n"
          ]
        }
      ],
      "source": [
        "batch = Batch(backend=backend)\n",
        "\n",
        "# If using qiskit-ibm-runtime earlier than 0.24.0, change `mode=` to `batch=`\n",
        "estimator = Estimator(mode=batch)\n",
        "sampler = Sampler(mode=batch)\n",
        "job1 = estimator.run([estimator_pub])\n",
        "job2 = sampler.run([sampler_pub])\n",
        "print(f\"Result1: {job1.result()}\")\n",
        "print(f\"Result2: {job2.result()}\")\n",
        "\n",
        "# Manually close the batch. Running and queued jobs will run to completion.\n",
        "batch.close()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9594105f-b003-43ee-9a5f-5cf3d6410887",
      "metadata": {},
      "source": [
        "<span id=\"batch-details\" />\n",
        "\n",
        "<span id=\"determine-batch-details\" />\n",
        "\n",
        "## Déterminer les détails du lot\n",
        "\n",
        "Pour obtenir une vue d'ensemble de la configuration et de l'état d'un lot, y compris son TTL interactif et maximal, utilisez l'adresse `batch.details() method`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "8a21ca0e-0373-456c-879f-9bcddda5289a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "{'id': '970fe01d-d2cf-45f0-b32b-f886b987a462', 'backend_name': 'ibm_torino', 'interactive_timeout': 1, 'max_time': 28800, 'active_timeout': 28800, 'state': 'open', 'accepting_jobs': True, 'last_job_started': None, 'last_job_completed': None, 'started_at': None, 'closed_at': None, 'activated_at': None, 'mode': 'batch', 'usage_time': None}\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    batch,\n",
        "    SamplerV2 as Sampler,\n",
        ")\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "with Batch(backend=backend) as batch:\n",
        "    print(batch.details())"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "cbdc7521-7b4c-4e02-a24d-2b5ca0a11abe",
      "metadata": {},
      "source": [
        "<span id=\"partition\" />\n",
        "\n",
        "<span id=\"reconfigure-jobs-for-parallel-processing\" />\n",
        "\n",
        "## Reconfigurer les tâches pour le traitement parallèle\n",
        "\n",
        "Il existe de nombreuses façons de reconfigurer vos travaux pour tirer parti du traitement parallèle offert par la mise en lots. L'exemple suivant montre comment vous pouvez diviser une longue liste de circuits en plusieurs tâches et les exécuter en tant que lot pour tirer parti du traitement parallèle.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "31ae3a23-e8bd-4dcd-86c1-10f6d7b5cee4",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime import SamplerV2 as Sampler, Batch\n",
        "from qiskit.circuit.random import random_circuit\n",
        "\n",
        "max_circuits = 100\n",
        "circuits = [pm.run(random_circuit(5, 5)) for _ in range(5 * max_circuits)]\n",
        "for circuit in circuits:\n",
        "    circuit.measure_active()\n",
        "all_partitioned_circuits = []\n",
        "for i in range(0, len(circuits), max_circuits):\n",
        "    all_partitioned_circuits.append(circuits[i : i + max_circuits])\n",
        "jobs = []\n",
        "start_idx = 0\n",
        "\n",
        "with Batch(backend=backend):\n",
        "    sampler = Sampler()\n",
        "    for partitioned_circuits in all_partitioned_circuits:\n",
        "        job = sampler.run(partitioned_circuits)\n",
        "        jobs.append(job)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5d4420f8-9c8d-4953-8561-1b0bdb8372eb",
      "metadata": {},
      "source": [
        "<Admonition type=\"caution\">\n",
        "  Si vous définissez `backend=backend` dans une primitive, le programme est exécuté en mode tâche, même s'il se trouve dans un contexte de lot ou de session. Le paramètre `backend=backend` est obsolète depuis Qiskit Runtime v0.24.0.  Utilisez plutôt le `mode` paramètre.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Etapes suivantes\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recommandations\">\n",
        "  * Essayez l'exemple proposé dans le tutoriel «[ Combiner les options d'atténuation des erreurs avec la primitive Estimator](/docs/tutorials/combine-error-mitigation-techniques) ».\n",
        "  * Consultez la référence de l' [API Batch](/docs/api/qiskit-ibm-runtime/batch#batch).\n",
        "  * Comprendre [les limites des](/docs/guides/job-limits) tâches lors de l'envoi d'une tâche vers une unité de traitement de calcul (QPU) d' IBM®.\n",
        "  * Consultez [la FAQ sur les modes d'exécution](/docs/guides/execution-modes-faq).\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
}