{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f4e55284-8bd6-4cb2-b044-11816cba1e2d",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Executar tarefas em lote\"\n",
        "description: \"Como executar tarefas de computação quântica em modo batch usando o Qiskit Runtime.\"\n",
        "---\n",
        "\n",
        "<span id=\"run-jobs-in-a-batch\" />\n",
        "\n",
        "# Executar tarefas em lote\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=\"Versões do pacote\">\n",
        "    O código nesta página foi desenvolvido utilizando os seguintes requisitos.\n",
        "    Recomendamos usar essas versões ou mais recentes.\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": [
        "Use o modo em lote para enviar vários trabalhos primitivos simultaneamente. A seguir, exemplos de como trabalhar com lotes.\n",
        "\n",
        "<span id=\"set-up-to-use-batches\" />\n",
        "\n",
        "## Configurar para usar lotes\n",
        "\n",
        "Antes de iniciar um lote, você deve [configurar Qiskit Runtime](/docs/guides/install-qiskit) e inicializá-lo como um serviço:\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",
        "## Abrir um lote\n",
        "\n",
        "Você pode abrir um lote de tempo de execução usando o gerenciador de contexto `with Batch(...)` ou inicializando a classe `Batch` classe. Ao iniciar um lote, você deve especificar uma QPU passando um objeto `backend` .  O lote começa quando seu primeiro trabalho inicia a execução.\n",
        "\n",
        "**Classe de lote**\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": [
        "**Gerenciador de contexto**\n",
        "\n",
        "O gerenciador de contexto abre e fecha automaticamente o lote.\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",
        "## Comprimento do lote\n",
        "\n",
        "Você pode definir o tempo máximo de vida (TTL) do lote com o parâmetro `max_time` . Isso deve exceder o tempo de execução do trabalho mais longo. Esse cronômetro começa quando o lote é iniciado.  Quando o valor é atingido, o lote é fechado.  Todos os trabalhos que estiverem em execução serão concluídos, mas os trabalhos que ainda estiverem na fila falharão.\n",
        "\n",
        "```python\n",
        "with Batch(backend=backend, max_time=\"25m\"):\n",
        "  ...\n",
        "```\n",
        "\n",
        "Há também um valor de tempo de vida interativo (TTL interativo) que não pode ser configurado (1 minuto para todos os planos).  Se nenhum trabalho em lote estiver enfileirado nessa janela, o lote será temporariamente desativado.\n",
        "\n",
        "Valores TTL máximos padrão:\n",
        "\n",
        "| Tipo de instância     | Padrão TTL máximo |\n",
        "| --------------------- | ----------------- |\n",
        "| Todos os planos pagos | 8 horas           |\n",
        "| Aberta                | 10 minutos        |\n",
        "\n",
        "Para determinar o TTL máximo ou o TTL interativo de um lote, siga as instruções em [Determinar detalhes do lote](#batch-details) e procure o valor `max_time` ou `interactive_timeout` , respectivamente.\n",
        "\n",
        "<span id=\"close\" />\n",
        "\n",
        "<span id=\"close-a-batch\" />\n",
        "\n",
        "## Fechar um lote\n",
        "\n",
        "Um lote é fechado automaticamente quando sai do gerenciador de contexto. Quando o gerenciador de contexto de lote é encerrado, o lote é colocado no status \"Em andamento, não aceitando novos trabalhos\". Isso significa que o lote termina de processar todos os trabalhos em execução ou em fila até que o valor máximo de TTL seja atingido. Após a conclusão de todos os trabalhos, o lote é imediatamente fechado. Não é possível enviar trabalhos para um lote fechado.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "05868749-5c03-4540-b780-3e151054e4cf",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  O código a seguir exige que você forneça suas próprias informações, como os PUBs do Estimador e do Amostrador, além de um 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",
        "  Se não estiver usando um gerenciador de contexto, feche manualmente o lote.  Se você deixar o lote aberto e enviar mais trabalhos para ele posteriormente, é possível que o TTL máximo seja atingido antes que os trabalhos subsequentes comecem a ser executados, fazendo com que eles sejam cancelados. Você pode fechar um lote assim que terminar de enviar trabalhos a ele. Quando um lote é fechado com `batch.close()`, ele não aceita mais novos trabalhos, mas os trabalhos já enviados ainda serão executados até a conclusão e seus resultados poderão ser recuperados.\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",
        "## Determine os detalhes do lote\n",
        "\n",
        "Para obter uma visão geral abrangente da configuração e do status de um lote, incluindo seu TTL interativo e máximo, use o site `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",
        "## Reconfigure tarefas para processamento paralelo\n",
        "\n",
        "Há várias maneiras de reconfigurar seus trabalhos para aproveitar o processamento paralelo proporcionado pelo batching. O exemplo a seguir mostra como você pode dividir uma longa lista de circuitos em vários trabalhos e executá-los como um lote para aproveitar o processamento paralelo.\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",
        "  Se você definir `backend=backend` em um primitivo, o programa será executado no modo de tarefa, mesmo que esteja dentro de um contexto de lote ou sessão. A configuração `backend=backend` está obsoleta a partir do Qiskit Runtime v0.24.0.  Em vez disso, use o `mode` parâmetro.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Experimente um exemplo no tutorial “[Combinar opções de mitigação de erros com a primitiva Estimator](/docs/tutorials/combine-error-mitigation-techniques) ”.\n",
        "  * Consulte a referência [da Batch API](/docs/api/qiskit-ibm-runtime/batch#batch).\n",
        "  * Entenda os [limites da tarefa](/docs/guides/job-limits) ao enviar uma tarefa para uma QPU do IBM®.\n",
        "  * Consulte [as perguntas frequentes sobre os modos de execução](/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
}