{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "797fe94d-93a3-4a7b-8d60-0706d5ab21d5",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"트랜스파일러 설정 비교\"\n",
        "description: \"회로를 생성하고, 트랜스파일링하고, 제출하는 전체 과정을 통해 트랜스파일링 파이프라인을 살펴보세요.\"\n",
        "---\n",
        "\n",
        "<span id=\"compare-transpiler-settings\" />\n",
        "\n",
        "# 트랜스파일러 설정 비교\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d403684a-9dc5-433b-a788-789881878d6c",
      "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": "a6affcc2-72f4-4f06-8c4c-fc52715b0285",
      "metadata": {},
      "source": [
        "트랜스파일러 설정에 따라 회로에 적용되는 최적화 방식이 달라지며, 이는 대개 기존 처리 시간이 늘어나는 대가를 치르게 됩니다. 이 가이드에서는 다양한 설정의 성능을 테스트하는 방법을 보여주기 위해 회로를 생성하고, 트랜스파일링하고, 제출하는 전체 과정을 단계별로 안내합니다.\n",
        "\n",
        "같은 설정이 한 회로의 성능은 향상시킬 수 있지만, 다른 회로의 성능은 저해할 수도 있다는 점에 유의하십시오. 실제 하드웨어에서 실행하기 전에 변환된 회로를 반드시 점검하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "39f9c961-c52d-46fc-a2aa-464462474b56",
      "metadata": {},
      "source": [
        "<span id=\"set-up-and-create-sample-circuit\" />\n",
        "\n",
        "## 샘플 회로 설정 및 구성\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "790b4934-ae24-4e69-be9f-d82ae639a5e6",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Create circuit to test transpiler on\n",
        "from qiskit import QuantumCircuit\n",
        "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import grover_operator, DiagonalGate\n",
        "\n",
        "# Use Statevector object to calculate the ideal output\n",
        "from qiskit.quantum_info import Statevector\n",
        "from qiskit.visualization import plot_histogram\n",
        "from qiskit.transpiler import PassManager\n",
        "\n",
        "from qiskit.circuit.library import XGate\n",
        "from qiskit.quantum_info import hellinger_fidelity"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe0a4958-b406-4fe4-9415-38a772ad152c",
      "metadata": {},
      "source": [
        "트랜스파일러가 최적화를 시도할 수 있도록 작은 회로를 생성하십시오. 이 예제는 상태를 표시하는 오라클을 사용하여 그로버 `111`알고리즘을 수행하는 회로를 생성합니다. 다음으로, 나중에 비교하기 위해 이상적인 분포(완벽한 양자 컴퓨터에서 무한히 반복 실행했을 때 측정될 것으로 예상되는 결과)를 시뮬레이션합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "4ac958d4-b9b5-4939-a359-a9edca7ddb6a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/4ac958d4-b9b5-4939-a359-a9edca7ddb6a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "oracle = DiagonalGate([1] * 7 + [-1])\n",
        "qc = QuantumCircuit(3)\n",
        "qc.h([0, 1, 2])\n",
        "qc = qc.compose(grover_operator(oracle))\n",
        "\n",
        "qc.draw(output=\"mpl\", style=\"iqp\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "6313186e-bc40-432e-9ada-8594d6a26d55",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/6313186e-bc40-432e-9ada-8594d6a26d55-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ideal_distribution = Statevector.from_instruction(qc).probabilities_dict()\n",
        "\n",
        "plot_histogram(ideal_distribution)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "964ca1e0-d1c9-40ed-bcf1-babc50f847ed",
      "metadata": {},
      "source": [
        "<span id=\"transpile\" />\n",
        "\n",
        "## 트랜스파일\n",
        "\n",
        "다음으로, QPU용 회로를 트랜스파일합니다. 트랜스파일러의 성능을 (최저 `0` )로 설정했을 때와 `3` (최고 `optimization_level` )로 설정했을 때를 비교하게 됩니다. 최저 최적화 수준은 회로가 장치에서 실행되도록 필요한 최소한의 작업만 수행합니다. 회로의 큐비트를 장치의 큐비트에 매핑하고 모든 2-큐비트 연산을 가능하게 하기 위해 스왑 게이트를 추가합니다. 최상위 최적화 수준은 훨씬 더 지능적이며, 전체 게이트 수를 줄이기 위해 다양한 기법을 활용합니다. 다중 큐비트 게이트는 오류율이 높고 큐비트는 시간이 지남에 따라 디코히어런스를 일으키므로, 회로가 짧을수록 더 나은 결과를 얻을 수 있을 것이다.\n",
        "\n",
        "<Admonition type=\"important\">\n",
        "  이 예제는 ‘ IBM Quantum® ’ 하드웨어를 사용하지만, Qiskit과 호환되는 모든 QPU에서 실행해 볼 수 있습니다.  결과는 다를 수 있습니다.\n",
        "</Admonition>\n",
        "\n",
        "다음 셀은 두 값 모두에 대해 `qc``optimization_level` 트랜스파일링을 수행하고, 2큐비트 게이트의 개수를 출력하며, 트랜스파일링된 회로를 리스트에 추가합니다. 일부 트랜스파일러 알고리즘은 무작위화되므로 재현성을 위해 시드를 설정합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "61181ac0-3f89-417f-a31e-9430f63e670b",
      "metadata": {},
      "outputs": [],
      "source": [
        "# Use IBM Quantum Compute Service to run jobs on hardware\n",
        "from qiskit_ibm_runtime import (\n",
        "    QiskitRuntimeService,\n",
        "    SamplerV2 as Sampler,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "c3062a60-1cdc-46e7-8eb3-efc62a1396bd",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'ibm_fez'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Select the backend with the fewest number of jobs in the queue\n",
        "service = QiskitRuntimeService()\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=127\n",
        ")\n",
        "backend.name"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "2a3ebe8c-e47d-4440-b004-f47f6af826f0",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Two-qubit gates (optimization_level=0):  21\n",
            "Two-qubit gates (optimization_level=3):  12\n"
          ]
        }
      ],
      "source": [
        "# Need to add measurements to the circuit\n",
        "qc.measure_all()\n",
        "\n",
        "# Find the correct two-qubit gate\n",
        "twoQ_gates = set([\"ecr\", \"cz\", \"cx\"])\n",
        "for gate in backend.basis_gates:\n",
        "    if gate in twoQ_gates:\n",
        "        twoQ_gate = gate\n",
        "\n",
        "circuits = []\n",
        "for optimization_level in [0, 3]:\n",
        "    pm = generate_preset_pass_manager(\n",
        "        optimization_level, backend=backend, seed_transpiler=0\n",
        "    )\n",
        "    t_qc = pm.run(qc)\n",
        "    print(\n",
        "        f\"Two-qubit gates (optimization_level={optimization_level}): \",\n",
        "        t_qc.count_ops()[twoQ_gate],\n",
        "    )\n",
        "    circuits.append(t_qc)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "99928d6b-a7e7-40c9-b59c-104fc430b57c",
      "metadata": {},
      "source": [
        "CNOT은 일반적으로 오류율이 높기 때문에, 로 트랜스파일된 회로는 훨씬 `optimization_level=3` 더 우수한 성능을 발휘할 것이다.\n",
        "\n",
        "성능을 향상시킬 수 있는 또 다른 방법은 유휴 상태의 큐비트에 일련의 게이트를 적용하는 [동적 디커플링을](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) 활용하는 것입니다. 이를 통해 환경과의 원치 않는 상호작용을 일부 차단할 수 있습니다. 다음 셀은 로 변환된 회로에 동적 디커플링을 `optimization_level=3` 추가하고 이를 목록에 추가합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "b20ebca3-4adb-4a95-9f6a-bb4cbd836daf",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.transpiler.passes.scheduling import (\n",
        "    ASAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "# Get gate durations so the transpiler knows how long each operation takes\n",
        "durations = backend.target.durations()\n",
        "\n",
        "# This is the sequence we'll apply to idling qubits\n",
        "dd_sequence = [XGate(), XGate()]\n",
        "\n",
        "# Run scheduling and dynamic decoupling passes on circuit\n",
        "pm = PassManager(\n",
        "    [\n",
        "        ASAPScheduleAnalysis(durations),\n",
        "        PadDynamicalDecoupling(durations, dd_sequence),\n",
        "    ]\n",
        ")\n",
        "circ_dd = pm.run(circuits[1])\n",
        "\n",
        "# Add this new circuit to our list\n",
        "circuits.append(circ_dd)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "c1c91fbd-acfe-413e-a6c9-ad97f4dd5543",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/c1c91fbd-acfe-413e-a6c9-ad97f4dd5543-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "circ_dd.draw(output=\"mpl\", style=\"iqp\", idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5bcc75c7-8af0-4862-8e3c-ec4d06aed1f1",
      "metadata": {},
      "source": [
        "<span id=\"execute-the-circuit\" />\n",
        "\n",
        "## 회로 실행하기\n",
        "\n",
        "이제 다양한 설정으로 변환된 회로 목록이 준비되었습니다. 다음으로, 샘플러 프리미티브를 사용하여 이 회로들을 실행하고 결과를 에 저장하세요 `result`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "c1b36384-fd9b-4e24-a399-32d35fc6fa5b",
      "metadata": {},
      "outputs": [],
      "source": [
        "sampler = Sampler(backend)\n",
        "job = sampler.run(\n",
        "    [(circuit) for circuit in circuits],  # sample all three circuits\n",
        "    shots=8000,\n",
        ")\n",
        "result = job.result()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c85b4da4-592f-45a6-87a2-a8f2d3415576",
      "metadata": {},
      "source": [
        "<span id=\"view-results\" />\n",
        "\n",
        "## 뷰 결과\n",
        "\n",
        "마지막으로, 장치 실험 결과를 이상 분포와 비교하여 그래프로 나타내십시오. 게이트 수가 적기 때문에 의 결과가 이상적인 `optimization_level=3` 분포에 더 가깝고, 동적 디커플링 덕분에 의 `optimization_level=3 + dd` 결과가 더욱 이상적인 분포에 가깝다는 것을 확인할 수 있습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "9e86132d-a8b2-40db-af42-53042dfa108b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/circuit-transpilation-settings/extracted-outputs/9e86132d-a8b2-40db-af42-53042dfa108b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "binary_prob = [\n",
        "    {\n",
        "        k: v / res.data.meas.num_shots\n",
        "        for k, v in res.data.meas.get_counts().items()\n",
        "    }\n",
        "    for res in result\n",
        "]\n",
        "plot_histogram(\n",
        "    binary_prob + [ideal_distribution],\n",
        "    bar_labels=False,\n",
        "    legend=[\n",
        "        \"optimization_level=0\",\n",
        "        \"optimization_level=3\",\n",
        "        \"optimization_level=3 + dd\",\n",
        "        \"ideal distribution\",\n",
        "    ],\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "47a9eec8-7b31-4b2d-a291-559ddfd7a36b",
      "metadata": {},
      "source": [
        "각 결과 집합과 이상적 분포 사이의 [헬링거 충실도를](/docs/api/qiskit/quantum_info) 계산하여 이를 확인할 수 있습니다(값이 높을수록 좋으며, 1은 완벽한 충실도를 의미합니다).\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "d2b5e797-176b-48b9-ac2b-ba73abe9300f",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.717\n",
            "0.982\n",
            "0.981\n"
          ]
        }
      ],
      "source": [
        "for prob in binary_prob:\n",
        "    print(f\"{hellinger_fidelity(prob, ideal_distribution):.3f}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1b5b7bb9-eedb-45eb-a4cf-9b7708cbbb3e",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * 다음과 같은 고급 트랜스파일링 리소스를 살펴보세요:\n",
        "\n",
        "    * [사용자 정의 트랜스파일러 패스 작성](/docs/guides/custom-transpiler-pass)\n",
        "    * [사용자 정의 백엔드를 대상으로 빌드 및 트랜스파일하기](/docs/guides/custom-backend)\n",
        "    * [트랜스파일러 플러그인 설치 및 사용](/docs/guides/transpiler-plugins)\n",
        "\n",
        "  * 제공되는 [튜토리얼](/docs/tutorials) 을 살펴보세요.\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
}