{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "3a5616bf-6edb-4539-872a-03217649edcb",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"동적 분리용 패스 관리자 생성\"\n",
        "description: \"Qiskit에서 동적 디커플링을 위한 패스 매니저 생성 방법\"\n",
        "---\n",
        "\n",
        "<span id=\"create-a-pass-manager-for-dynamical-decoupling\" />\n",
        "\n",
        "# 동적 분리용 패스 관리자 생성\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a5662d8c-46f8-40a8-92b5-af63c32d303f",
      "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": "1ed6dc8d-b6f2-43dc-bb40-ceec0f311764",
      "metadata": {},
      "source": [
        "이 페이지는 동적 디커플링이라는 오류 억제 기법을 추가하기 위해 [`PadDynamicalDecoupling`](/docs/api/qiskit/qiskit.transpiler.passes.PadDynamicalDecoupling) 패스를 사용하여 *동적 디커플링이라는* 오류 억제 기술을 회로에 추가하는 방법을 설명합니다.\n",
        "\n",
        "동적 디커플링은 유휴 큐비트에 펄스 시퀀스( *동적 디커플링 시퀀스라고* 함)를 추가하여 블로흐 구체 주위를 뒤집어 노이즈 채널의 효과를 상쇄하여 디코히어런스를 억제하는 방식으로 작동합니다. 이러한 펄스 시퀀스는 핵 자기 공명에서 사용되는 리포커싱 펄스와 유사합니다. 자세한 설명은 [양자 엔지니어를 위한 초전도 큐비트 가이드를](https://arxiv.org/abs/1904.06560) 참조하세요.\n",
        "\n",
        "`PadDynamicalDecoupling` 패스는 예약된 회로에서만 작동하고 대상의 기본 게이트가 아닌 게이트를 포함하므로, 반드시 [`ALAPScheduleAnalysis`](/docs/api/qiskit/qiskit.transpiler.passes.ALAPScheduleAnalysis) 및 [`BasisTranslator`](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) 패스도 필요합니다.\n",
        "\n",
        "에서 정보를 `target` `backend` 가져오고, 작업 이름을 로 저장하십시오 `basis_gates` . 동적 디커플링에 사용되는 게이트에 대한 타이밍 정보를 추가하기 위해 를 `target` 수정해야 하기 때문입니다.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  이 예제에서는 의 모의 `FakeSherbrooke``qiskit_ibm_runtime` 백엔드를 사용하지만, Qiskit과 호환되는 실제 또는 모의 백엔드라면 어떤 것이든 사용해 볼 수 있습니다.  결과는 다를 수 있습니다.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "c55c6e3b-4016-4866-b2ec-19793e89d215",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "\n",
        "target = backend.target\n",
        "basis_gates = list(target.operation_names)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b8dfccd9-30c9-48dc-88bc-50af3256f187",
      "metadata": {},
      "source": [
        "예를 들어 `efficient_su2` 회로를 만듭니다. 먼저, 회로를 트랜스파일하고 스케줄링한 후 동적 디커플링 펄스를 추가해야 하므로 회로를 백엔드로 트랜스파일합니다. 동적 디커플링은 양자 회로에 유휴 시간이 많을 때, 즉 다른 큐비트가 활성화되어 있는 동안 사용되지 않는 큐비트가 있을 때 가장 잘 작동하는 경우가 많습니다. 이 회로에서는 두 개의 큐비트 `ecr` 게이트가 순차적으로 적용되기 때문입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "9479a60c-d5d0-45c7-a93e-a2a488ba8985",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/9479a60c-d5d0-45c7-a93e-a2a488ba8985-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "qc = efficient_su2(12, entanglement=\"circular\", reps=1)\n",
        "pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)\n",
        "qc_t = pm.run(qc)\n",
        "qc_t.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d3ab848d-2782-431c-b028-69a46cf94360",
      "metadata": {},
      "source": [
        "동적 디커플링 시퀀스는 아이덴티티를 구성하는 일련의 게이트로, 시간적으로 일정한 간격을 두고 있습니다. 예를 들어, 4개의 게이트로 구성된 XY4 이라는 간단한 시퀀스를 생성하는 것으로 시작하세요.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "368df772-aee7-4b59-b096-a47e5bc94577",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.circuit.library import XGate, YGate\n",
        "\n",
        "X = XGate()\n",
        "Y = YGate()\n",
        "\n",
        "dd_sequence = [X, Y, X, Y]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d5eafd85-6fea-42ac-8bcb-0abf15635456",
      "metadata": {},
      "source": [
        "동적 분리 시퀀스의 규칙적인 타이밍 때문에, 는 기본 게이트가 *아닌* 반면 는 `XGate` 기본 게이트이므로, 에 `target` 대한 정보를 에 `YGate` 추가해야 합니다. 우리는 *선험적으로* 가 와 동일한 지속 `YGate` 시간과 `XGate`오차를 가짐을 알고 있으므로, `target` 에서 해당 속성들을 추출하여 `YGate` 객체들에 다시 적용하면 됩니다. 이것이 또한 가 별도로 `basis_gates` 저장된 이유이기도 합니다. 비록 의 실제 기본 `ibm_fez`게이트는 아니지만, `YGate` 명령어를 `target` 에 추가하고 있기 때문입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "cabac6ca-c845-4c05-8c7d-2940717b3120",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import InstructionProperties\n",
        "\n",
        "y_gate_properties = {}\n",
        "for qubit in range(target.num_qubits):\n",
        "    y_gate_properties.update(\n",
        "        {\n",
        "            (qubit,): InstructionProperties(\n",
        "                duration=target[\"x\"][(qubit,)].duration,\n",
        "                error=target[\"x\"][(qubit,)].error,\n",
        "            )\n",
        "        }\n",
        "    )\n",
        "\n",
        "target.add_instruction(YGate(), y_gate_properties)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d33f64d6-c4e3-4881-a924-f30dfce35106",
      "metadata": {},
      "source": [
        "`efficient_su2` 같은 앤사츠 회로는 매개변수화되어 있으므로 백엔드로 전송되기 전에 바인딩된 값이 있어야 합니다. 여기에서 임의의 매개 변수를 할당합니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "788839cc-9378-4c9d-95fd-df0ec6bc2d64",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "rng = np.random.default_rng(1234)\n",
        "qc_t.assign_parameters(\n",
        "    rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "36d54ded-1786-41c0-9c8a-75f339dbd160",
      "metadata": {},
      "source": [
        "다음으로 사용자 지정 패스를 실행합니다. `PassManager` 를 `ALAPScheduleAnalysis` 및 `PadDynamicalDecoupling` 로 인스턴스화합니다.  규칙적인 간격의 동적 디커플링 시퀀스를 추가하기 전에 `ALAPScheduleAnalysis` 을 먼저 실행하여 양자 회로에 대한 타이밍 정보를 추가합니다. 이 패스는 `.run()` 를 사용하여 회로에서 실행됩니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "334796e7-fb37-42fa-be54-4135b485246b",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.transpiler.passes.scheduling import (\n",
        "    ALAPScheduleAnalysis,\n",
        "    PadDynamicalDecoupling,\n",
        ")\n",
        "\n",
        "dd_pm = PassManager(\n",
        "    [\n",
        "        ALAPScheduleAnalysis(target=target),\n",
        "        PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),\n",
        "    ]\n",
        ")\n",
        "qc_dd = dd_pm.run(qc_t)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0f68880-066c-4586-a27c-5d0f90d674f7",
      "metadata": {},
      "source": [
        "시각화 도구를 사용하여 회로의 [`timeline_drawer`](/docs/api/qiskit/qiskit.visualization.timeline_drawer) 타이밍을 확인하고, 회로 내에 균일한 간격으로 배열된 `XGate` 객체와 `YGate` 객체의 시퀀스가 나타나는지 확인하십시오.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "7a552621-a96f-4bb8-ae9b-4ab5a65bbb64",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/7a552621-a96f-4bb8-ae9b-4ab5a65bbb64-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import timeline_drawer\n",
        "\n",
        "timeline_drawer(qc_dd, idle_wires=False, target=target)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "836a4094-0e55-4028-9e2e-cdf561d27049",
      "metadata": {},
      "source": [
        "마지막으로 `YGate` 는 백엔드의 실제 기준 게이트가 아니므로 `BasisTranslator` 패스를 수동으로 적용하세요(기본 패스는 아니지만 스케줄링 전에 실행되므로 다시 적용해야 합니다). 세션 등가 라이브러리는 트랜스파일러가 인자로 지정된 대로 회로를 기저 게이트로 분해할 수 있도록 하는 회로 등가 라이브러리입니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "f0f4b29d-1c95-47d2-a7ad-8e130eaff74a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/dynamical-decoupling-pass-manager/extracted-outputs/f0f4b29d-1c95-47d2-a7ad-8e130eaff74a-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.equivalence_library import (\n",
        "    SessionEquivalenceLibrary as sel,\n",
        ")\n",
        "from qiskit.transpiler.passes import BasisTranslator\n",
        "\n",
        "qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)\n",
        "qc_dd.draw(\"mpl\", fold=-1, idle_wires=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fafca471-0042-41f8-964c-606b4ee0d5cd",
      "metadata": {},
      "source": [
        "이제 회로에서 `YGate` 객체가 사라졌으며, 게이트 `Delay` 형태의 명시적 타이밍 정보가 존재합니다. 동적 디커플링이 적용된 이 트랜스파일된 회로는 이제 백엔드로 전송할 준비가 되었습니다.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "95fee5f9-9e7d-47db-83c2-309ca03d357a",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## 다음 단계\n",
        "\n",
        "<Admonition type=\"tip\" title=\"권장사항\">\n",
        "  * 직접 패스를 작성하는 대신 `generate_preset_passmanager` 함수를 사용하는 방법을 알아보려면 [번역 기본 설정 및 구성 옵션](defaults-and-configuration-options) 항목부터 시작하세요.\n",
        "  * [Compare 트랜스파일러 설정](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings) 가이드를 시도해 보세요.\n",
        "  * [Transpile API](https://docs.quantum-computing.ibm.com/api/qiskit/transpiler) 문서를 참조하십시오.\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
}