{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "8fe3ca32",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Hardware del sistema\"\n",
        "description: \"Esta lección explora el hardware moderno de computación cuántica. Se basa en un curso presencial impartido en la Universidad de Tokio.\"\n",
        "---\n",
        "\n",
        "<span id=\"hardware\" />\n",
        "\n",
        "# Hardware del sistema\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Masao Tokunari y Tamiya Onodera (14 de junio de 2024)\n",
        "\n",
        "  Este curso se basa en un curso presencial impartido en la Universidad de Tokio.\n",
        "\n",
        "  El pdf de esta lección está dividido en dos partes. [Descargue la parte 1](https://ibm.ent.box.com/public/static/ruz8wf353hncenmaywjlfjilflaumnzt.zip) y [descargue la parte 2](https://ibm.ent.box.com/public/static/tg8vv00ern2bmxmm033xt9oe0fcvwamc.zip). Tenga en cuenta que algunos fragmentos de código podrían quedar obsoletos, ya que se trata de imágenes estáticas.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e0cf0747",
      "metadata": {},
      "source": [
        "<span id=\"1-introduction\" />\n",
        "\n",
        "## 1. Introducción\n",
        "\n",
        "Esta lección explora el hardware moderno de la computación cuántica.\n",
        "\n",
        "Empezaremos verificando algunas versiones e importando algunos paquetes relevantes.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "798d0ab4-34f5-4c64-83f0-02ef5149e6f3",
      "metadata": {},
      "outputs": [],
      "source": [
        "import statistics\n",
        "\n",
        "from qiskit_ibm_runtime import QiskitRuntimeService"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2cc2f2a3-947f-439b-b683-911539f1e6f2",
      "metadata": {},
      "source": [
        "<span id=\"2-backend-and-target\" />\n",
        "\n",
        "## 2. Backend y objetivo\n",
        "\n",
        "Qiskit proporciona una API para obtener la información, tanto estática como dinámica, sobre un dispositivo cuántico. Utilizamos una instancia Backend para interactuar con un dispositivo, que incluye una instancia Target, un modelo abstracto de máquina que resume las características pertinentes, como su arquitectura de conjunto de instrucciones (ISA) y cualquier propiedad o restricción asociada a ella.\n",
        "Utilicemos estas instancias backend para obtener parte de la información que se ve en la página [Recursos informáticos](/computers) en IBM Quantum® Platform.   En primer lugar, creamos una instancia de backend para un dispositivo de interés.  A continuación, elegimos \"ibm\\_kyoto\", \"ibm\\_kawasaki\" o la máquina Eagle menos ocupada. Su acceso a las QPU puede diferir; actualice el nombre del backend en consecuencia.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b92ad1bf-6ad4-420c-8a3a-5bfc488d5923",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'ibm_strasbourg'"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "service = QiskitRuntimeService()\n",
        "# backend = service.backend(\"ibm_kawasaki\") # an Eagle, if you have access to ibm_kawasaki\n",
        "backend = service.least_busy(\n",
        "    operational=True, simulator=False, min_num_qubits=127\n",
        ")  # Eagle\n",
        "backend.name"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "c082da02-fcc5-4506-b4fe-9015e99e63dc",
      "metadata": {},
      "source": [
        "Empezamos con información básica (estática) sobre el dispositivo.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "33c39786-d44a-47bb-8245-72eb6b97e394",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "ibm_strasbourg, 127 qubits\n",
            "processor type = {'family': 'Eagle', 'revision': 3} \n",
            "basis gates = ['ecr', 'id', 'rz', 'sx', 'x']\n",
            "\n"
          ]
        }
      ],
      "source": [
        "print(\n",
        "    f\"\"\"\n",
        "{backend.name}, {backend.num_qubits} qubits\n",
        "processor type = {backend.processor_type}\n",
        "basis gates = {backend.basis_gates}\n",
        "\"\"\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "31675447-1a26-4168-a038-09cc7535e037",
      "metadata": {},
      "source": [
        "<span id=\"21-exercise\" />\n",
        "\n",
        "### 2.1 Ejercicio\n",
        "\n",
        "Intenta obtener la información básica sobre un dispositivo Heron, \"ibm\\_strasbourg\". Pruébalo por tu cuenta, pero a continuación se ha añadido un código para que lo compruebes tú mismo.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "f29afd7e-af40-4cd5-bc0e-a864663a616d",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "\n",
            "ibm_strasbourg, 133 qubits\n",
            "processor type = {'family': 'Heron', 'revision': '1'} \n",
            "basis gates = ['cz', 'id', 'rz', 'sx', 'x']\n",
            "\n"
          ]
        }
      ],
      "source": [
        "a_heron = service.backend(\"ibm_strasbourg\")  # a Heron\n",
        "\n",
        "# your code here\n",
        "print(\n",
        "    f\"\"\"\n",
        "{backend.name}, {a_heron.num_qubits} qubits\n",
        "processor type = {a_heron.processor_type}\n",
        "basis gates = {a_heron.basis_gates}\n",
        "\"\"\"\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "08fef064-3fc6-4c27-9288-a2e3aa7f5d08",
      "metadata": {},
      "source": [
        "<span id=\"22-coupling-map\" />\n",
        "\n",
        "### 2.2 Mapa de acoplamiento\n",
        "\n",
        "Ahora dibujamos el mapa de acoplamiento del dispositivo. Como puedes ver, los nodos son qubits que están numerados. Los bordes indican los pares a los que se puede aplicar directamente la puerta de enredo de 2 qubits.  La topología se denomina \"celosía de hexágonos pesados\".\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "51b87458-a5e8-4e77-a34d-39fe425a5f01",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/51b87458-a5e8-4e77-a34d-39fe425a5f01-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 8,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# This function requires that Graphviz is installed. If you need to install Graphviz\n",
        "# you can refer to:\n",
        "# https://graphviz.org/download/#executable-packages for instructions.\n",
        "try:\n",
        "    fig = backend.coupling_map.draw()\n",
        "except RuntimeError as ex:\n",
        "    print(ex)\n",
        "fig"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "881a5350-282c-4a89-b9e2-ac6bf61c6571",
      "metadata": {},
      "source": [
        "<span id=\"3-qubit-properties\" />\n",
        "\n",
        "## 3. Propiedades del qubit\n",
        "\n",
        "El dispositivo Eagle tiene 127 qubits.   Obtengamos las propiedades de algunos de ellos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "9bcb9ce2-5ea8-487b-a7ac-a2956e8cbc34",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0: QubitProperties(t1=0.000183686508736532, t2=0.00023613944465408068, frequency=4832100227.116953)\n",
            "1: QubitProperties(t1=0.00048794378526038294, t2=9.007098375327869e-05, frequency=4736264354.075363)\n",
            "2: QubitProperties(t1=0.00021247781834456527, t2=7.81037910324034e-05, frequency=4859349851.150393)\n",
            "3: QubitProperties(t1=0.0002936462084765663, t2=0.00011400214529510604, frequency=4679749549.503852)\n",
            "4: QubitProperties(t1=0.00044229440258559125, t2=0.0003181648356339447, frequency=4845872064.050596)\n"
          ]
        }
      ],
      "source": [
        "for qn in range(backend.num_qubits):\n",
        "    if qn >= 5:\n",
        "        break\n",
        "    print(f\"{qn}: {backend.qubit_properties(qn)}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "be601762",
      "metadata": {},
      "source": [
        "Calculemos la mediana de los tiempos T1 de los qubits.   Compare el resultado con el mostrado para el dispositivo en [IBM Quantum Platform.](/)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "e8f398b2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median T1: 285.43 μs'"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "t1s = [backend.qubit_properties(qq).t1 for qq in range(backend.num_qubits)]\n",
        "f\"Median T1: {(statistics.median(t1s)*10**6):.2f} \\u03bcs\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "01695904-2cb2-4f1d-9396-82cc94429d81",
      "metadata": {},
      "source": [
        "<span id=\"31-exercise\" />\n",
        "\n",
        "### 3.1 Ejercicio\n",
        "\n",
        "Pease calcular la mediana de T2 tiempos de los qubits. Pruébalo por tu cuenta, pero a continuación se ha añadido un código para que lo compruebes tú mismo.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "49fbe7a4-3dea-442f-ae3f-e82df93d406a",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median T2: 173.10 μs'"
            ]
          },
          "execution_count": 11,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Your code here\n",
        "\n",
        "t2s = [backend.qubit_properties(qq).t2 for qq in range(backend.num_qubits)]\n",
        "f\"Median T2: {(statistics.median(t2s)*10**6):.2f} \\u03bcs\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7bdf8873-359e-4b03-98af-ede989a4a96d",
      "metadata": {},
      "source": [
        "<span id=\"32-gate-and-readout-errors\" />\n",
        "\n",
        "### 3.2 Errores de puerta y lectura\n",
        "\n",
        "Pasemos ahora a los errores de puerta. Para empezar, estudiamos la estructura de datos de la instancia objetivo. Es un diccionario cuyas claves son los nombres de las operaciones.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "c9188662",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "dict_keys(['measure', 'id', 'sx', 'delay', 'x', 'for_loop', 'rz', 'if_else', 'ecr', 'reset', 'switch_case'])"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "target = backend.target\n",
        "target.keys()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "46e3a8ac-65dc-4973-bd72-820676727f4e",
      "metadata": {},
      "source": [
        "Sus valores también son diccionarios.  Veamos algunos de los elementos del valor (diccionario) para la operación \"sx\".\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "c9b30ede-c00f-4e18-bb72-3bfc06e6afa5",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0,) InstructionProperties(duration=6e-08, error=0.0007401311759115297)\n",
            "1 (1,) InstructionProperties(duration=6e-08, error=0.0003163759907528654)\n",
            "2 (2,) InstructionProperties(duration=6e-08, error=0.0003183859004638003)\n",
            "3 (3,) InstructionProperties(duration=6e-08, error=0.00042235914178831863)\n",
            "4 (4,) InstructionProperties(duration=6e-08, error=0.011163151923589715)\n"
          ]
        }
      ],
      "source": [
        "for i, qq in enumerate(target[\"sx\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, qq, target[\"sx\"][qq])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5a322b40-bbf0-4b54-a151-9ba52f7bffe1",
      "metadata": {},
      "source": [
        "Hagamos lo mismo con las operaciones \"ecr\" y \"measure\".\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "f9cac843-4789-4ca3-84bd-0a4c165820a9",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0, 14) InstructionProperties(duration=6.6e-07, error=0.01486295709788732)\n",
            "1 (1, 0) InstructionProperties(duration=6.6e-07, error=0.015201590794522601)\n",
            "2 (2, 1) InstructionProperties(duration=6.6e-07, error=0.00697838102630724)\n",
            "3 (2, 3) InstructionProperties(duration=6.6e-07, error=0.008075067943986797)\n",
            "4 (3, 4) InstructionProperties(duration=6.6e-07, error=0.0630164507876913)\n"
          ]
        }
      ],
      "source": [
        "for i, edge in enumerate(target[\"ecr\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, edge, target[\"ecr\"][edge])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "af36138a",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 (0,) InstructionProperties(duration=1.6e-06, error=0.0078125)\n",
            "1 (1,) InstructionProperties(duration=1.6e-06, error=0.155029296875)\n",
            "2 (2,) InstructionProperties(duration=1.6e-06, error=0.057373046875)\n",
            "3 (3,) InstructionProperties(duration=1.6e-06, error=0.02880859375)\n",
            "4 (4,) InstructionProperties(duration=1.6e-06, error=0.01318359375)\n"
          ]
        }
      ],
      "source": [
        "for i, qq in enumerate(target[\"measure\"]):\n",
        "    if i >= 5:\n",
        "        break\n",
        "    print(i, qq, target[\"measure\"][qq])"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5d0c106a-3641-42ed-9230-7dc6dbd47252",
      "metadata": {},
      "source": [
        "Como puede verse, los errores de lectura tienden a ser mayores que los de la operación de 2 qubits, que a su vez tienden a ser mayores que los de la operación de 1 qubit.\n",
        "\n",
        "Una vez comprendidas las estructuras de datos, estamos preparados para calcular los errores medios de las puertas 'sx' y 'ecr'. De nuevo, compare los resultados con los mostrados para el dispositivo en la [plataforma IBM Quantum.](/)\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "b239d726",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median SX error: 2.277e-04'"
            ]
          },
          "execution_count": 16,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "sx_errors = [inst_prop.error for inst_prop in target[\"sx\"].values()]\n",
        "f\"Median SX error: {(statistics.median(sx_errors)):.3e}\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "8003f34b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'Median ECR error: 6.895e-03'"
            ]
          },
          "execution_count": 17,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "ecr_errors = [inst_prop.error for inst_prop in target[\"ecr\"].values()]\n",
        "f\"Median ECR error: {(statistics.median(ecr_errors)):.3e}\""
      ]
    },
    {
      "cell_type": "markdown",
      "id": "695ee4bd",
      "metadata": {},
      "source": [
        "<span id=\"4-appendix\" />\n",
        "\n",
        "## 4. Apéndice\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b538e8b5",
      "metadata": {},
      "source": [
        "Una de las características más populares de Qiskit es su capacidad de visualización. Incluye visualizadores de circuitos, de estados y de distribución, y de objetivos.   Ya has utilizado los dos primeros en los cuadernos jupyter anteriores.   Utilicemos algunas capacidades del visualizador de destino.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "97fead46",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/97fead46-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 22,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_gate_map\n",
        "\n",
        "plot_gate_map(backend, font_size=14)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "c9e05530",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/learning/images/courses/utility-scale-quantum-computing/hardware/extracted-outputs/c9e05530-0.avif\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 23,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_error_map\n",
        "\n",
        "plot_error_map(backend)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "22a48124-e6b4-4144-bee1-f01fa4c7ccbb",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "'2.0.2'"
            ]
          },
          "execution_count": 24,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "# Check Qiskit version\n",
        "import qiskit\n",
        "\n",
        "qiskit.__version__"
      ]
    },
    {
      "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"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "state": {},
        "version_major": 2,
        "version_minor": 0
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}