{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "f4e55284-8bd6-4cb2-b044-11816cba1e2d",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"배치로 작업을 실행하다\"\n",
        "description: \"IBM Quantum 컴퓨트 서비스를 사용하여 양자 컴퓨팅 작업을 배치 모드로 실행하는 방법.\"\n",
        "---\n",
        "\n",
        "<span id=\"run-jobs-in-a-batch\" />\n",
        "\n",
        "# 배치로 작업을 실행하다\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=\"패키지 버전\">\n",
        "    이 페이지의 코드는 다음 요구 사항을 사용하여 개발되었습니다.\n",
        "    이 버전 또는 그 이상의 버전을 사용하는 것을 권장합니다.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.2\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "388d0a36-0a7c-4b60-8607-4e535f8adf2c",
      "metadata": {},
      "source": [
        "배치 모드를 사용하여 여러 개의 기본 작업을 동시에 제출할 수 있습니다. 다음은 일괄 처리 작업의 예입니다.\n",
        "\n",
        "<span id=\"set-up-to-use-batches\" />\n",
        "\n",
        "## 배치 사용 설정\n",
        "\n",
        "배치를 시작하기 전에, [IBM Quantum 컴퓨트 클라이언트를 설정하고](/docs/guides/install-qiskit) 서비스로 초기화해야 합니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "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",
        "## 배치를 열기\n",
        "\n",
        "컨텍스트 관리자 `with Batch(...)` 를 사용하거나 런타임 배치를 열거나 `Batch` 클래스를 초기화할 수 있습니다. 배치를 시작할 때 `backend` 개체를 전달하여 QPU를 지정해야 합니다.  배치는 첫 번째 작업이 실행을 시작할 때 시작됩니다.\n",
        "\n",
        "**배치 클래스**\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "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": [
        "**컨텍스트 관리자**\n",
        "\n",
        "컨텍스트 관리자가 자동으로 배치를 열고 닫습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "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",
        "## 배치 길이\n",
        "\n",
        "`max_time` 매개 변수를 사용하여 배치의 최대 라이브 시간(TTL)을 정의할 수 있습니다. 이는 가장 긴 작업의 실행 시간을 초과해야 합니다. 이 타이머는 배치가 시작될 때 시작됩니다.  이 값에 도달하면 배치가 닫힙니다.  실행 중인 모든 작업은 완료되지만 여전히 대기 중인 작업은 실패합니다.\n",
        "\n",
        "```python\n",
        "with Batch(backend=backend, max_time=\"25m\"):\n",
        "  ...\n",
        "```\n",
        "\n",
        "또한 구성할 수 없는 대화형 TTL(대화형 실시간 시간) 값(모든 요금제의 경우 1분)도 있습니다.  해당 기간 내에 대기 중인 배치 작업이 없으면 배치가 일시적으로 비활성화됩니다.\n",
        "\n",
        "기본 최대 TTL 값입니다:\n",
        "\n",
        "| 인스턴스 유형   | 기본 최대 TTL |\n",
        "| --------- | --------- |\n",
        "| 모든 유료 요금제 | 8시간       |\n",
        "| 열기        | 10분       |\n",
        "\n",
        "배치의 최대 TTL 또는 대화형 TTL을 확인하려면 [배치 세부 정보 확인의](#batch-details) 지침에 따라 각각 `max_time` 또는 `interactive_timeout` 값을 찾습니다.\n",
        "\n",
        "<span id=\"close\" />\n",
        "\n",
        "<span id=\"close-a-batch\" />\n",
        "\n",
        "## 배치 닫기\n",
        "\n",
        "배치가 컨텍스트 관리자를 종료하면 자동으로 닫힙니다. 배치 컨텍스트 관리자를 종료하면 배치가 '진행 중, 새 작업 수락 안 함' 상태가 됩니다. 즉, 배치가 최대 TTL 값에 도달할 때까지 실행 중이거나 대기 중인 모든 작업의 처리를 완료합니다. 모든 작업이 완료되면 배치가 즉시 닫힙니다. 닫힌 배치에는 작업을 제출할 수 없습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "05868749-5c03-4540-b780-3e151054e4cf",
      "metadata": {},
      "source": [
        "<Admonition type=\"note\">\n",
        "  다음 코드를 사용하려면 Estimator 및 Sampler PUB와 같은 정보와 백엔드를 직접 지정해야 합니다.\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",
        "  컨텍스트 관리자를 사용하지 않는 경우에는 수동으로 배치를 닫습니다.  배치를 열어 두었다가 나중에 더 많은 작업을 제출하면 후속 작업이 실행되기 전에 최대 TTL에 도달하여 작업이 취소될 수 있습니다. 작업 제출을 완료하는 즉시 배치를 닫을 수 있습니다. `batch.close()` 으로 배치가 종료되면 더 이상 새 작업을 수락하지 않지만 이미 제출된 작업은 완료될 때까지 계속 실행되며 그 결과를 검색할 수 있습니다.\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=156>), shape=(3, 2)), metadata={'circuit_metadata': {}})], metadata={'execution': {'execution_spans': ExecutionSpans([DoubleSliceSpan(<start='2026-09-01 07:46:49', stop='2026-09-01 07:46:56', 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",
        "## 배치 세부 정보 결정\n",
        "\n",
        "대화형 및 최대 TTL을 포함하여 배치의 구성 및 상태에 대한 종합적인 개요를 보려면 `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': '947aa097-9055-42d4-9e58-ad1c2cdd9d5a', 'backend_name': 'ibm_marrakesh', '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",
        "## 병렬 처리를 위해 작업을 재구성하십시오\n",
        "\n",
        "일괄 처리에서 제공하는 병렬 처리 기능을 활용하도록 작업을 재구성하는 방법에는 여러 가지가 있습니다. 다음 예는 긴 회로 목록을 여러 작업으로 분할하고 일괄 처리로 실행하여 병렬 처리의 이점을 활용하는 방법을 보여 줍니다.\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",
        "  원시 명령어에서 를 `backend=backend` 설정하면, 배치 또는 세션 컨텍스트 내부에 있더라도 프로그램은 작업 모드로 실행됩니다. Qiskit Runtime 부터 설정(Setting) `backend=backend` 은 더 이상 사용되지 않습니다. v0.24.0.  대신 `mode` 매개변수를 사용하십시오.\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * [‘오류 완화 옵션을 Estimator 기본 요소와 결합하기](/docs/tutorials/combine-error-mitigation-techniques) ’ 튜토리얼의 예제를 직접 해보세요.\n",
        "  * [배치 API](/docs/api/qiskit-ibm-runtime/batch#batch) 참조를 검토하세요.\n",
        "  * IBM® QPU로 작업을 전송할 때 [작업 제한](/docs/guides/job-limits) 사항을 숙지하십시오.\n",
        "  * [실행 모드](/docs/guides/execution-modes-faq) 검토 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
}