{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "33f4bb3c",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"회로 타이밍 시각화\"\n",
        "description: \"생성된 회로의 타이밍을 시각화하여, 확인하거나 다운로드할 수 있는(혹은 둘 다 가능한) 도표를 생성합니다.\"\n",
        "---\n",
        "\n",
        "{/* cspell:ignore mactex, backgroundcolor, lightgreen */}\n",
        "\n",
        "<span id=\"visualize-circuit-timing\" />\n",
        "\n",
        "# 회로 타이밍 시각화\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "bfada4f0",
      "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": "ad24e3a0",
      "metadata": {},
      "source": [
        "Qiskit에 내장된 [타임라인 드로](/docs/guides/visualize-circuit-timing) 어는 정적 회로에는 유용하지만, 브로드캐스팅이나 분기 결정과 같은 암시적 연산으로 인해 [동적](/docs/guides/classical-feedforward-and-control-flow) 회로의 타이밍을 정확하게 반영하지 못할 수도 있습니다. 동적 회로 지원의 일환으로, IBM Quantum 컴퓨트 서비스는 요청 시 작업 결과 내에 정확한 회로 타이밍 정보를 반환합니다.\n",
        "\n",
        "<Admonition type=\"note\" title=\"참고\">\n",
        "  * 이 기능은 실험적인 기능입니다. 현재는 미리보기 버전으로 제공되고 있으므로 내용이 변경될 수 있습니다.\n",
        "  * 이 기능은 ‘ IBM Quantum ’ 샘플러 작업에만 적용됩니다.\n",
        "  * \"컴파일\" 메타데이터에는 전체 회로 실행 시간이 표시되지만, 이는 청구용 시간(QPU 시간)이 아닙니다.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "995a99e8",
      "metadata": {},
      "source": [
        "<span id=\"enable-timing-data-retrieval\" />\n",
        "\n",
        "### 타이밍 데이터 가져오기 활성화\n",
        "\n",
        "타이밍 데이터 검색을 활성화하려면, 기본 작업 실행 시 실험용 `scheduler_timing``True` 플래그를 로 설정하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "ab8c6c23",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "qc = QuantumCircuit(2)\n",
        "qc.h(0)\n",
        "qc.cx(0, 1)\n",
        "qc.measure_all()\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\n",
        "    \"execution\": {\n",
        "        \"scheduler_timing\": True,\n",
        "    },\n",
        "}\n",
        "\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "531b2abd",
      "metadata": {},
      "source": [
        "<span id=\"access-the-circuit-timing-data\" />\n",
        "\n",
        "### 회로 타이밍 데이터에 접근하기\n",
        "\n",
        "요청 시, 각 PUB 에 대한 회로 타이밍 데이터가 작업 결과 메타데이터의. `[\"compilation\"][\"scheduler_timing\"][\"timing\"]`아래에 반환됩니다. 이 필드에는 원시 타이밍 정보가 포함되어 있습니다. 타이밍 정보를 표시하려면 [‘타이밍](#visualize-timings) 시각화’ 섹션에 설명된 대로 내장된 시각화 도구를 사용하십시오.\n",
        "\n",
        "다음 코드를 사용하여 첫 번째 PUB 의 서킷 타이밍 데이터에 액세스하세요:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "b6958d99",
      "metadata": {},
      "outputs": [],
      "source": [
        "job_result = sampler_job.result()\n",
        "circuit_schedule = job_result[0].metadata[\"compilation\"][\"scheduler_timing\"]\n",
        "circuit_schedule_timing = circuit_schedule[\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "20400401",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-raw-timing-data\" />\n",
        "\n",
        "#### 원시 타이밍 데이터 이해하기\n",
        "\n",
        "이 `draw_circuit_schedule_timing` 메서드를 사용하여 회로 타이밍 데이터를 시각화하는 것이 가장 일반적인 사용 사례이지만, 반환되는 원시 타이밍 데이터의 구조를 이해하는 것도 유용할 수 있습니다. 예를 들어, 이를 통해 프로그래밍 방식으로 정보를 추출하는 데 도움이 될 수 있습니다.\n",
        "\n",
        "에서 반환되는 타이밍 `[\"compilation\"][\"scheduler_timing\"][\"timing\"]` 데이터는 문자열 목록입니다. 각 문자열은 특정 채널의 단일 명령어를 나타내며, 쉼표로 구분된 다음 데이터 유형들로 구성됩니다:\n",
        "\n",
        "* `Branch` - 해당 명령어가 제어 흐름(then / else)에 속하는지, 아니면 메인 분기에 속하는지 판단합니다.\n",
        "* `Instruction` - 게이트와 연산을 수행할 큐비트.\n",
        "* `Channel` - 해당 명령어로 할당되는 채널. 다음 중 하나일 수 있습니다.\n",
        "  * `Qubit x` - 큐비트 *x* 의 구동 채널.\n",
        "  * `AWGRx_y` (임의 파형 발생기 표시값) - 큐비트 측정 시 표시 채널 간의 통신에 사용됩니다. *x* 및 *y* 인수는 각각 판독 기기 ID와 큐비트 번호에 해당합니다.\n",
        "* `T0` - 전체 일정 내 수업 시작 시간\n",
        "* `Duration` - 명령어의 실행 시간( *dt* 초 단위), 여기서 1 dt = 1 스케줄링 사이클. ... [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt)를 사용하여 백엔드의 값을 `dt` 확인할 수 있습니다.\n",
        "* `Pulse` - 사용 중인 펄스 작동 방식.\n",
        "\n",
        "예:\n",
        "\n",
        "```python\n",
        "main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration\n",
        "main,reset_0,Qubit 0,7,64,play # A reset instruction on the main branch on qubit 0 at time 7 with duration 64 and a play operation\n",
        "...\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9d34100f",
      "metadata": {},
      "source": [
        "<span id=\"visualize-timings\" />\n",
        "\n",
        "<span id=\"visualize-the-timings\" />\n",
        "\n",
        "### 시간대를 시각화하세요\n",
        "\n",
        "v0.43.0 이상 `qiskit-ibm-runtime` 버전에서는 회로 타이밍을 시각화할 수 있습니다. 타이밍을 시각화하려면 먼저 결과 메타데이터를 로 `fig` 변환해야 [`draw_circuit_schedule_timing` 메서드](https://github.com/Qiskit/qiskit-ibm-runtime/blob/3d1bf1e1d49e5123841639fce259859c90ce9314/qiskit_ibm_runtime/visualization/draw_circuit_schedule_timings.py#L26) 합니다. 이 메서드는 그림을 `plotly` 반환하며, 이를 직접 표시하거나 파일에 저장하거나, 두 가지 모두 수행할 수 있습니다.  사용할 `plotly` 명령어에 대한 자세한 내용은 및 을 [`fig.show()`](https://plotly.com/python-api-reference/generated/plotly.io.show.html)[`fig.write_image(\"<path.format>\")`](https://plotly.com/python-api-reference/generated/plotly.io.write_image.html) 참조하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "4ad3acfb",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "# Create a figure from the metadata\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule_timing,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2788e992",
      "metadata": {},
      "source": [
        "![출력 결과 위에 마우스를 올리면 시작 시간, 종료 시간, 소요 시간 등의 정보가 표시됩니다.](https://quantum.cloud.ibm.com/docs/images/guides/visualize-circuit-timing/image_1.avif \" 생성된 그림의 예시\")\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "323a7d38",
      "metadata": {},
      "source": [
        "<span id=\"understand-the-generated-figure\" />\n",
        "\n",
        "#### 생성된 그림을 이해하기\n",
        "\n",
        "에서 출력되는 회로 타이밍 데이터의 `draw_circuit_schedule_timing` 이미지는 다음과 같은 정보를 전달합니다:\n",
        "\n",
        "* X축은 *dt* 초 단위의 시간이며, 여기서 1 dt = 1 스케줄링 사이클입니다. ... [`backend.dt`](/docs/api/qiskit/qiskit.providers.BackendV2#dt)를 사용하여 백엔드의 값을 `dt` 확인할 수 있습니다.\n",
        "* Y축은 채널입니다(채널을 펄스를 방출하는 장치라고 생각하시면 됩니다).\n",
        "  * `Receive channel` - 악기 그 자체는 아니지만, 유일한 채널입니다. 이는 당시 허브와 통신 절차를 수행 중인 모든 채널에서 전송되는 명령입니다.\n",
        "  * `Qubit x` - 큐비트 x의 구동 채널.\n",
        "  * `AWGRx_y` (임의 파형 발생기 표시값) - 큐비트 측정 시 표시 채널 간의 통신에 사용됩니다. *x* 및 *y* 인수는 각각 판독 기기 ID와 큐비트 번호에 해당합니다.\n",
        "  * `Hub` - 방송을 제어합니다.\n",
        "\n",
        "또한, 각 명령어는 *X\\_Y* 형식을 따르며, 여기서 *X는* 명령어 이름이고 *Y는* 펄스 유형입니다. A는 `play` 제어 펄스를 가하고, B는 큐비트의 `capture` 상태를 기록합니다. 각 지침 위에 마우스를 올리면 자세한 내용을 확인할 수 있습니다. 예를 들어, 앞 그림은 1161 dt 시점에 큐비트 10에 적용된 X 게이트용 제어 펄스를 보여줍니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "86af09ca",
      "metadata": {},
      "source": [
        "<span id=\"end-to-end-example\" />\n",
        "\n",
        "### 엔드-투-엔드 예제\n",
        "\n",
        "이 예제는 해당 옵션을 활성화하고, 메타데이터에서 회로 타이밍 정보를 가져와 이미지로 표시하는 방법을 보여줍니다.\n",
        "\n",
        "먼저 환경을 설정하고, 회로를 정의하여 ISA 회로로 변환한 다음, 작업을 정의하고 실행합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "b46908a0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            ">>>  Job ID:    dab83qbvpcac73ddf510 (DONE)\n"
          ]
        }
      ],
      "source": [
        "from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService\n",
        "from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(operational=True, simulator=False)\n",
        "\n",
        "# Create a dynamic circuit\n",
        "\n",
        "qubits = QuantumRegister(1)\n",
        "clbits = ClassicalRegister(1)\n",
        "qc = QuantumCircuit(qubits, clbits)\n",
        "(q0,) = qubits\n",
        "(c0,) = clbits\n",
        "\n",
        "qc.h(q0)\n",
        "qc.measure(q0, c0)\n",
        "with qc.if_test((c0, 1)):\n",
        "    qc.x(q0)\n",
        "qc.measure(q0, c0)\n",
        "\n",
        "# Convert to an ISA circuit for the given backend\n",
        "\n",
        "pm = generate_preset_pass_manager(backend=backend, optimization_level=1)\n",
        "isa_circuit = pm.run(qc)\n",
        "\n",
        "# Generate samplers for backend targets\n",
        "sampler = SamplerV2(backend)\n",
        "sampler.options.experimental = {\"execution\": {\"scheduler_timing\": True}}\n",
        "\n",
        "# Submit jobs\n",
        "sampler_job = sampler.run([isa_circuit])\n",
        "result = sampler_job.result()\n",
        "\n",
        "print(\n",
        "    f\">>> {' Job ID:':<10}  {sampler_job.job_id()} ({sampler_job.status()})\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1bd5993c",
      "metadata": {},
      "source": [
        "다음으로, 경기 일정을 확인하세요:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "7e943812",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'main,rz_0,Qubit 0,1393,0,shift_phase\\nmain,sx_0,Qubit 0,1393,9,play\\nmain,sx_0,Qubit 0,1397,0,shift_phase\\nmain,rz_0,Qubit 0,1402,0,shift_phase\\nmain,barrier,Qubit 0,1402,0,barrier\\nmain,measure_0,Qubit 0,1402,64,play\\nmain,measure_0,Qubit 0,1466,108,play\\nmain,measure_0,AWGR0_0,1523,325,capture\\nmain,measure_0,Qubit 0,1574,64,play\\nmain,measure_0,Qubit 0,1638,64,play\\nmain,barrier,Qubit 0,2049,0,barrier\\nmain,broadcast,Hub,1523,526,broadcast\\nmain,receive,Receive,2049,7,receive\\nthen,x_0,Qubit 0,2064,9,play\\nmain,barrier,Qubit 0,2082,0,barrier\\nmain,measure_0,Qubit 0,2082,64,play\\nmain,measure_0,Qubit 0,2146,108,play\\nmain,measure_0,AWGR0_0,2203,325,capture\\nmain,measure_0,Qubit 0,2254,64,play\\nmain,measure_0,Qubit 0,2318,64,play\\nmain,barrier,Qubit 0,2753,0,barrier\\nmain,barrier,Qubit 0,2753,0,barrier\\nmain,FINI_0,Qubit 0,2753,64,play\\nmain,FINI_0,Qubit 0,2817,108,play\\nmain,FINI_0,AWGR0_0,2874,325,capture\\nmain,FINI_0,Qubit 0,2925,64,play\\nmain,FINI_0,Qubit 0,2989,64,play\\nmain,FINI_0,Qubit 0,3424,9,play\\nmain,FINI_0,Qubit 0,3433,64,play\\nmain,FINI_0,Qubit 0,3497,108,play\\nmain,FINI_0,AWGR0_0,3554,325,capture\\nmain,FINI_0,Qubit 0,3605,64,play\\nmain,FINI_0,Qubit 0,3669,64,play\\nmain,FINI_0,Qubit 0,4104,9,play\\nmain,barrier,Qubit 0,4113,0,barrier\\n'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Get the circuit schedule timing\n",
        "result[0].metadata[\"compilation\"][\"scheduler_timing\"][\"timing\"]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "04db1f41",
      "metadata": {},
      "source": [
        "마지막으로, 타이밍을 시각화하고 저장할 수 있습니다:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "9d1901c3",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing\n",
        "\n",
        "circuit_schedule = result[0].metadata[\"compilation\"][\"scheduler_timing\"][\n",
        "    \"timing\"\n",
        "]\n",
        "fig = draw_circuit_schedule_timing(\n",
        "    circuit_schedule=circuit_schedule,\n",
        "    included_channels=None,\n",
        "    filter_readout_channels=False,\n",
        "    filter_barriers=False,\n",
        "    width=1000,\n",
        ")\n",
        "\n",
        "# Uncomment the following line to display the figure\n",
        "# fig.show(renderer=\"notebook\")\n",
        "\n",
        "# Save to a file\n",
        "# fig.write_html(\"scheduler_timing.html\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9daa7cf7",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * [고전적인 피드포워드 및 제어 흐름](/docs/guides/classical-feedforward-and-control-flow) (동적 회로)\n",
        "  * [회로 시각화하기](/docs/guides/visualize-circuits)\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
}