{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "5b6cbc5d-14d4-40c6-a702-0ce635c483d8",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Representa los ordenadores cuánticos para el transpilador\"\n",
        "description: \"Aprende sobre mapas de acoplamiento, puertas básicas y errores del procesador para la transpilación\"\n",
        "---\n",
        "\n",
        "<span id=\"represent-quantum-computers-for-the-transpiler\" />\n",
        "\n",
        "# Representa los ordenadores cuánticos para el transpilador\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aed00912-17af-4e4c-8639-77957b314b98",
      "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=\"Versiones del paquete\">\n",
        "    El código de esta página se ha desarrollado teniendo en cuenta los siguientes requisitos.\n",
        "    Recomendamos utilizar estas versiones o versiones más recientes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.0\n",
        "    qiskit-ibm-runtime~=0.47.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9dbd70a7-3353-4286-aa6b-3547d7894f58",
      "metadata": {},
      "source": [
        "Para convertir un circuito abstracto en un circuito ISA que pueda ejecutarse en una QPU (unidad de procesamiento cuántico) específica, el transpilador necesita cierta información sobre la QPU. Esta información se encuentra en dos lugares: el objeto `BackendV2` (o legado `BackendV1`) al que planea enviar trabajos, y el atributo `Target` del backend.\n",
        "\n",
        "* El [`Target`](/docs/api/qiskit/qiskit.transpiler.Target) contiene todas las restricciones relevantes de un dispositivo, como el conjunto de instrucciones que admite, la conectividad de qubits y la información sobre pulsos o sincronización.\n",
        "* El [`Backend`](/docs/api/qiskit/qiskit.providers.BackendV2) posee un `Target` por defecto, contiene información adicional, como el [`InstructionScheduleMap`](/docs/api/qiskit/1.4/qiskit.pulse.InstructionScheduleMap), y proporciona la interfaz para enviar trabajos de circuitos cuánticos.\n",
        "\n",
        "También puedes proporcionar explícitamente información para que el transpilador la utilice, por ejemplo, si tienes un caso de uso específico, o si crees que esta información ayudará al transpilador a generar un circuito más optimizado.\n",
        "\n",
        "La precisión con la que el transpilador produce el circuito más adecuado para un hardware específico depende de la información que `Target` o `Backend` tengan sobre sus restricciones.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Como muchos de los algoritmos de transpilación subyacentes son estocásticos, no hay garantía de que se encuentre un circuito mejor.\n",
        "</Admonition>\n",
        "\n",
        "En esta página se muestran varios ejemplos de cómo pasar información de la QPU al transpilador.\n",
        "\n",
        "<span id=\"default-config\" />\n",
        "\n",
        "<span id=\"default-configuration\" />\n",
        "\n",
        "## Configuración predeterminada\n",
        "\n",
        "El uso más sencillo del transpilador es proporcionar toda la información de la QPU mediante `Backend` o `Target`. Para entender mejor cómo funciona el transpilador, construye un circuito y transpílalo con información diferente, como se indica a continuación.\n",
        "\n",
        "Importar las bibliotecas necesarias e instanciar la QPU: Para convertir un circuito abstracto en un circuito ISA que pueda ejecutarse en un procesador específico, el transpilador necesita cierta información sobre el procesador.  Normalmente, esta información se almacena en el archivo [`Backend`](/docs/api/qiskit/qiskit.providers.Backend#backend) o [`Target`](/docs/api/qiskit/qiskit.transpiler.Target#target) proporcionado al transpilador, y no se necesita más información. Sin embargo, también puedes proporcionar explícitamente información para que el transpilador la utilice, por ejemplo, si tienes un caso de uso específico, o si crees que esta información ayudará al transpilador a generar un circuito más optimizado.\n",
        "\n",
        "En este tema se muestran varios ejemplos de cómo pasar información al transpilador.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  En estos ejemplos se utiliza el destino del backend `qiskit_ibm_runtime`[`FakeSherbrooke`](/docs/api/qiskit-ibm-runtime/fake-provider-fake-sherbrooke#fakesherbrooke) simulado.  Sin embargo, puedes probarlo en cualquier backend real o simulado compatible con Qiskit.  Tus resultados pueden ser diferentes.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "a52d0681-5436-4d7a-8d45-9832472e59ca",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit_ibm_runtime.fake_provider import FakeSherbrooke\n",
        "\n",
        "backend = FakeSherbrooke()\n",
        "target = backend.target"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4064b5ad-8a3a-462b-ae30-29576230c084",
      "metadata": {},
      "source": [
        "El circuito de ejemplo utiliza una instancia de [`efficient_su2`](/docs/api/qiskit/qiskit.circuit.library.efficient_su2) de la biblioteca de circuitos de Qiskit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "97f9acc1-ac53-4025-b413-485777932a9b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/97f9acc1-ac53-4025-b413-485777932a9b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.circuit.library import efficient_su2\n",
        "\n",
        "qc = efficient_su2(12, entanglement=\"circular\", reps=1)\n",
        "\n",
        "qc.draw(\"mpl\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "id": "b133229c-0146-4feb-a366-548d175b858e",
      "metadata": {},
      "source": [
        "Este ejemplo utiliza la configuración predeterminada para transpilar a la `backend`'s `target`, que proporciona toda la información necesaria para convertir el circuito a uno que se ejecutará en el backend.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "4b81fb9d-d199-45c5-b119-c1f0b973afe9",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/4b81fb9d-d199-45c5-b119-c1f0b973afe9-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 3,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler import generate_preset_pass_manager\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1, target=target, seed_transpiler=12345\n",
        ")\n",
        "qc_t_target = pass_manager.run(qc)\n",
        "qc_t_target.draw(\"mpl\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "2ad3848d",
      "metadata": {},
      "source": [
        "Este ejemplo se utiliza en secciones posteriores de este tema para ilustrar que el mapa de acoplamiento y el conjunto de instrucciones compatibles son los datos esenciales que se deben transmitir al transpilador para lograr una construcción óptima del circuito. La QPU normalmente puede seleccionar ajustes predeterminados para otra información que no se transmite, como la sincronización y la programación.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "956f1b7a-80b4-4cda-9ecf-6057f560deb9",
      "metadata": {},
      "source": [
        "<span id=\"coupling-map\" />\n",
        "\n",
        "## Mapa de acoplamiento\n",
        "\n",
        "El mapa de acoplamiento es un gráfico que muestra qué qubits están conectados y, por tanto, tienen puertas de dos qubits entre ellos. A veces este gráfico es direccional, lo que significa que las puertas de dos qubits sólo pueden ir en una dirección. Sin embargo, el transpilador siempre puede invertir la dirección de una puerta añadiendo puertas adicionales de un solo qubit. Un circuito cuántico abstracto siempre puede representarse en este grafo, aunque su conectividad sea limitada, introduciendo puertas SWAP para desplazar la información cuántica.\n",
        "\n",
        "Los qubits de nuestros circuitos abstractos se denominan *qubits virtuales* y los del mapa de acoplamiento son *qubits físicos*. El transpilador proporciona una correspondencia entre qubits virtuales y físicos. Uno de los primeros pasos de la transpilación, la fase de *maquetación*, realiza este mapeo.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Aunque la etapa de enrutamiento está entrelazada con la etapa de *diseño* -que selecciona los qubits reales- por defecto, este tema las trata como etapas separadas para simplificar. La combinación de enrutamiento y disposición se denomina *mapeo de qubits*.  Obtenga más información sobre estas etapas en el tema [Etapas del transpilador](transpiler-stages).\n",
        "</Admonition>\n",
        "\n",
        "Pase el argumento de la palabra clave `coupling_map` para ver su efecto en el transpilador:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "ec354bee-e06b-42ea-a117-6c1a9308ca73",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/ec354bee-e06b-42ea-a117-6c1a9308ca73-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 4,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "coupling_map = target.build_coupling_map()\n",
        "\n",
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345\n",
        ")\n",
        "qc_t_cm_lv0 = pass_manager.run(qc)\n",
        "qc_t_cm_lv0.draw(\"mpl\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0d3fe7d4-3a40-423d-975f-b4de6613efe9",
      "metadata": {},
      "source": [
        "Como se muestra arriba, se insertaron varias compuertas SWAP (cada una formada por tres compuertas CX), lo que provocará muchos errores en los dispositivos actuales. Para ver qué qubits están seleccionados en la topología qubit real, utilice `plot_circuit_layout` de Qiskit Visualizations:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "9be74535-ed36-4d51-afeb-ee53c3f8a046",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/9be74535-ed36-4d51-afeb-ee53c3f8a046-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_circuit_layout\n",
        "\n",
        "plot_circuit_layout(qc_t_cm_lv0, backend, view=\"physical\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "633744e3-b9e7-4333-ac7b-0089f28e9c27",
      "metadata": {},
      "source": [
        "Esto demuestra que nuestros qubits virtuales 0-11 se mapearon trivialmente a la línea de qubits físicos 0-11. Volvamos al valor por defecto (`optimization_level=1`), que utiliza `VF2Layout` si se requiere algún enrutamiento.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "8035fd05-f7cd-4151-b19a-4968202246e6",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/8035fd05-f7cd-4151-b19a-4968202246e6-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 6,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345\n",
        ")\n",
        "qc_t_cm_lv1 = pass_manager.run(qc)\n",
        "qc_t_cm_lv1.draw(\"mpl\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "217c75f4-4c86-46bb-9a34-b451ff4743ef",
      "metadata": {},
      "source": [
        "Ahora no hay puertas SWAP insertadas y los qubits físicos seleccionados son los mismos cuando se utiliza la clase `target` .\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "25d9fac3-abda-4b2d-81b4-351dc0772722",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/25d9fac3-abda-4b2d-81b4-351dc0772722-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.visualization import plot_circuit_layout\n",
        "\n",
        "plot_circuit_layout(qc_t_cm_lv1, backend, view=\"physical\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "db62df0f",
      "metadata": {},
      "source": [
        "Ahora la disposición es en anillo.  Como esta disposición respeta la conectividad del circuito, no hay puertas SWAP, lo que proporciona un circuito mucho mejor para la ejecución.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f62e0541",
      "metadata": {},
      "source": [
        "<span id=\"supported-instructions\" />\n",
        "\n",
        "## Instrucciones compatibles\n",
        "\n",
        "Cada ordenador cuántico admite un conjunto limitado de instrucciones.  Cada puerta del circuito debe traducirse a los elementos de este conjunto. Este conjunto debe estar formado por puertas de uno y dos qubits que proporcionen un conjunto de puertas universal, lo que significa que cualquier operación cuántica puede descomponerse en esas puertas.  Esto lo realiza [BasisTranslator](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) y se `basis_gates` puede especificar como argumento clave para el transpilador con el fin de proporcionar esta información.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "4445ff03",
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "['x', 'switch_case', 'for_loop', 'rz', 'sx', 'measure', 'id', 'ecr', 'delay', 'reset', 'if_else']\n"
          ]
        }
      ],
      "source": [
        "basis_gates = list(target.operation_names)\n",
        "print(basis_gates)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6e9aed06",
      "metadata": {},
      "source": [
        "Las puertas de un solo qubit predeterminadas en `FakeSherbrooke` son `rz`, `x`, y `sx`, y la puerta de dos qubits predeterminada es `ecr` (resonancia cruzada con eco). Las puertas CX se construyen a partir de `ecr` puertas, por lo que en algunas QPU `ecr` se especifica como la puerta de base de dos qubits, mientras que en otras `cx` es la opción predeterminada. La `ecr` puerta es la parte *que se entrelaza* de la `cx` puerta. Además de las puertas de control, también hay instrucciones `delay` `measurement` y.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Las QPU tienen puertas básicas predeterminadas, pero puedes elegir las puertas que desees, siempre y cuando proporciones la instrucción o añadas puertas de pulso (consulta [Crear pasadas del transpilador](/docs/guides/custom-transpiler-pass) ) Las puertas básicas predeterminadas son aquellas para las que se han realizado calibraciones en la QPU, por lo que no es necesario proporcionar más puertas de instrucción/pulso. Por ejemplo, en algunas QPU `cx` es la puerta predeterminada de dos qubits y `ecr` en otras. Consulte la lista de posibles [puertas y operaciones nativas](/docs/guides/qpu-information#native-gates) para obtener más detalles.\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "313e4743",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/313e4743-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 9,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1,\n",
        "    coupling_map=coupling_map,\n",
        "    basis_gates=basis_gates,\n",
        "    seed_transpiler=12345,\n",
        ")\n",
        "qc_t_cm_bg = pass_manager.run(qc)\n",
        "qc_t_cm_bg.draw(\"mpl\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b0195ba6",
      "metadata": {},
      "source": [
        "Tenga en cuenta que los `CXGate` objetos se han descompuesto en `ecr` puertas y puertas de base de un solo qubit.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb3f5aff-3ca2-4688-a59e-da05c724ef09",
      "metadata": {},
      "source": [
        "<span id=\"device-error-rates\" />\n",
        "\n",
        "## Tasas de error del dispositivo\n",
        "\n",
        "La clase `Target` puede contener información sobre las tasas de error de las operaciones en el dispositivo.\n",
        "Por ejemplo, el siguiente código recupera las propiedades de la puerta de resonancia cruzada con eco (ECR) entre el qubit 1 y el 0 (nótese que la puerta ECR es direccional):\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "38aa1eca-a6aa-4db9-af36-66289e2059d2",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)"
            ]
          },
          "execution_count": 10,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "target[\"ecr\"][(1, 0)]"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "90cca3a8-ca25-4795-a22f-57ba6d8cfcaa",
      "metadata": {},
      "source": [
        "La salida muestra la duración de la puerta (en segundos) y su tasa de error. Para revelar la información de error al transpilador, construya un modelo de destino con `basis_gates` y `coupling_map` y rellénelo con los valores de error del backend `FakeSherbrooke`.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "e92c39d7-4aab-4657-aa9a-1b8b5788cb58",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler import Target\n",
        "from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp\n",
        "\n",
        "err_targ = Target.from_configuration(\n",
        "    basis_gates=basis_gates,\n",
        "    coupling_map=coupling_map,\n",
        "    num_qubits=target.num_qubits,\n",
        "    custom_name_mapping={\n",
        "        \"if_else\": IfElseOp,\n",
        "        \"switch_case\": SwitchCaseOp,\n",
        "        \"for_loop\": ForLoopOp,\n",
        "    },\n",
        ")\n",
        "\n",
        "for i, (op, qargs) in enumerate(target.instructions):\n",
        "    if op.name in basis_gates:\n",
        "        err_targ[op.name][qargs] = target.instruction_properties(i)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "433f2772-b397-42ab-b3a5-a44a85192f3c",
      "metadata": {},
      "source": [
        "Transpile con nuestro nuevo objetivo `err_targ` como objetivo:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "f1e270c4-e2cc-487e-a050-4180bc321b0b",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<Image src=\"/docs/images/guides/represent-quantum-computers/extracted-outputs/f1e270c4-e2cc-487e-a050-4180bc321b0b-0.svg\" alt=\"Output of the previous code cell\" />"
            ]
          },
          "execution_count": 12,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "pass_manager = generate_preset_pass_manager(\n",
        "    optimization_level=1, target=err_targ, seed_transpiler=12345\n",
        ")\n",
        "qc_t_cm_bg_et = pass_manager.run(qc)\n",
        "qc_t_cm_bg_et.draw(\"mpl\", idle_wires=False, fold=-1)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f8b516be-805d-4d0b-92f9-44d3fbe3b51f",
      "metadata": {},
      "source": [
        "Dado que el objetivo incluye información de error, el paso `VF2PostLayout` intenta encontrar los qubits óptimos a utilizar, dando como resultado el mismo circuito que se encontró originalmente con los mismos qubits físicos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e815a158-c77a-4e82-bebe-1710d0ae4f1f",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximos pasos\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendaciones\">\n",
        "  * Comprender [la configuración predeterminada y las opciones de configuración de Transpilation](defaults-and-configuration-options).\n",
        "  * Revise el tema [Parámetros más utilizados para la transpilación](common-parameters).\n",
        "  * Prueba la guía [de configuración del transpilador Compare](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings).\n",
        "  * Consulte la [documentación de la API de Transpile](/docs/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": 5
}