{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "5b6cbc5d-14d4-40c6-a702-0ce635c483d8",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Representar computadores quânticos para o transpiler\"\n",
        "description: \"Aprenda sobre mapas de acoplamento, portas básicas e erros do processador para transpilagem\"\n",
        "---\n",
        "\n",
        "<span id=\"represent-quantum-computers-for-the-transpiler\" />\n",
        "\n",
        "# Representar computadores quânticos para o transpiler\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=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido usando os seguintes requisitos.\n",
        "    Recomendamos o uso dessas versões ou de versões mais recentes.\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 converter um circuito abstrato em um circuito ISA que possa ser executado em uma QPU (unidade de processamento quântico) específica, o transpilador precisa de determinadas informações sobre a QPU. Essas informações são encontradas em dois locais: o objeto `BackendV2` (ou `BackendV1` herdado) para o qual você planeja enviar trabalhos e o atributo `Target` do backend.\n",
        "\n",
        "* O [`Target`](/docs/api/qiskit/qiskit.transpiler.Target) contém todas as restrições relevantes de um dispositivo, tais como o conjunto de instruções suportadas, conectividade qubit e informações de pulso ou temporização.\n",
        "* O [`Backend`](/docs/api/qiskit/qiskit.providers.BackendV2) possui um `Target` por padrão, contém informações adicionais — como o [`InstructionScheduleMap`](/docs/api/qiskit/1.4/qiskit.pulse.InstructionScheduleMap)— e fornece a interface para enviar tarefas de circuito quântico.\n",
        "\n",
        "Você também pode fornecer explicitamente informações para o transpilador usar, por exemplo, se você tiver um caso de uso específico ou se acreditar que essas informações ajudarão o transpilador a gerar um circuito mais otimizado.\n",
        "\n",
        "A precisão com que o transpilador produz o circuito mais adequado para um hardware específico depende da quantidade de informações que o `Target` ou `Backend` tem sobre suas restrições.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Como muitos dos algoritmos de transpilação subjacentes são estocásticos, não há garantia de que um circuito melhor será encontrado.\n",
        "</Admonition>\n",
        "\n",
        "Esta página apresenta vários exemplos de como passar informações da QPU para o transpilador.\n",
        "\n",
        "<span id=\"default-config\" />\n",
        "\n",
        "<span id=\"default-configuration\" />\n",
        "\n",
        "## Configuração padrão\n",
        "\n",
        "O uso mais simples do transpilador é fornecer todas as informações do QPU por meio do `Backend` ou `Target`. Para entender melhor como o transpilador funciona, construa um circuito e transpile-o com informações diferentes, como segue.\n",
        "\n",
        "Importe as bibliotecas necessárias e instancie a QPU: Para converter um circuito abstrato em um circuito ISA que possa ser executado em um processador específico, o transpilador precisa de determinadas informações sobre o processador.  Normalmente, essas informações são armazenadas no arquivo [`Backend`](/docs/api/qiskit/qiskit.providers.Backend#backend) ou [`Target`](/docs/api/qiskit/qiskit.transpiler.Target#target) fornecido ao transpilador, e nenhuma outra informação é necessária. No entanto, você também pode fornecer explicitamente informações para o transpilador usar, por exemplo, se tiver um caso de uso específico ou se acreditar que essas informações ajudarão o transpilador a gerar um circuito mais otimizado.\n",
        "\n",
        "Este tópico apresenta vários exemplos de como passar informações para o transpiler.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Esses exemplos utilizam o alvo do backend `qiskit_ibm_runtime`[`FakeSherbrooke`](/docs/api/qiskit-ibm-runtime/fake-provider-fake-sherbrooke#fakesherbrooke) simulado.  No entanto, você pode testá-lo em qualquer backend real ou simulado compatível com o Qiskit.  Seus resultados podem 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": [
        "O circuito de exemplo usa uma instância de [`efficient_su2`](/docs/api/qiskit/qiskit.circuit.library.efficient_su2) da biblioteca de circuitos do 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 exemplo usa configurações padrão para transpilar para o site `backend` `target`, que fornece todas as informações necessárias para converter o circuito em um que será executado no 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 exemplo é usado nas seções posteriores deste tópico para ilustrar que o mapa de acoplamento e o conjunto de instruções suportadas são as informações essenciais a serem passadas ao transpilador para a construção ideal do circuito. A QPU geralmente pode selecionar configurações padrão para outras informações que não são transmitidas, como temporização e programação.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "956f1b7a-80b4-4cda-9ecf-6057f560deb9",
      "metadata": {},
      "source": [
        "<span id=\"coupling-map\" />\n",
        "\n",
        "## Mapa de acoplamento\n",
        "\n",
        "O mapa de acoplamento é um gráfico que mostra quais qubits estão conectados e, portanto, têm portas de dois qubits entre eles. Às vezes, esse gráfico é direcional, o que significa que as portas de dois qubits só podem ir em uma direção. No entanto, o transpilador sempre pode inverter a direção de uma porta adicionando portas adicionais de um único qubit. Um circuito quântico abstrato sempre pode ser representado nesse gráfico, mesmo que sua conectividade seja limitada, com a introdução de portas SWAP para mover as informações quânticas.\n",
        "\n",
        "Os qubits de nossos circuitos abstratos são chamados de *qubits virtuais* e os do mapa de acoplamento são *qubits físicos*. O transpilador fornece um mapeamento entre qubits virtuais e físicos. Uma das primeiras etapas da transpilação, o estágio de *layout*, realiza esse mapeamento.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  Embora o estágio de roteamento esteja entrelaçado com o estágio de *layout* - que seleciona os qubits reais - por padrão, este tópico os trata como estágios separados para simplificar. A combinação de roteamento e layout é chamada de *mapeamento de qubit*.  Saiba mais sobre esses estágios no tópico [Estágios do Transpiler](transpiler-stages).\n",
        "</Admonition>\n",
        "\n",
        "Passe o argumento da palavra-chave `coupling_map` para ver seu efeito no 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 mostrado acima, várias portas SWAP foram inseridas (cada uma consistindo em três portas CX), o que causará muitos erros nos dispositivos atuais. Para ver quais qubits estão selecionados na topologia real do qubit, use o site `plot_circuit_layout` do 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": [
        "Isso mostra que nossos qubits virtuais 0-11 foram trivialmente mapeados para a linha de qubits físicos 0-11. Vamos voltar ao padrão (`optimization_level=1`), que usa `VF2Layout` se for necessário algum roteamento.\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": [
        "Agora não há portas SWAP inseridas e os qubits físicos selecionados são os mesmos quando se usa a classe `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": [
        "Agora o layout está em um anel.  Como esse layout respeita a conectividade do circuito, não há portas SWAP, o que proporciona um circuito muito melhor para a execução.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f62e0541",
      "metadata": {},
      "source": [
        "<span id=\"supported-instructions\" />\n",
        "\n",
        "## Instruções suportadas\n",
        "\n",
        "Todo computador quântico suporta um conjunto limitado de instruções.  Cada porta do circuito deve ser traduzida para os elementos deste conjunto. Este conjunto deve consistir em portas de um e dois qubits que fornecem um conjunto de portas universal, o que significa que qualquer operação quântica pode ser decomposta nessas portas.  Isso é feito pelo [BasisTranslator](/docs/api/qiskit/qiskit.transpiler.passes.BasisTranslator) e `basis_gates` pode ser especificado como um argumento de palavra-chave para o transpiler para fornecer essas informações.\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": [
        "As portas padrão de um qubit no `FakeSherbrooke` são `rz`, `x`, e `sx`, e a porta padrão de dois qubits é `ecr` (ressonância cruzada com eco). As portas CX são construídas a partir de `ecr` portas, de modo que, em algumas QPUs, `ecr` é especificada como a porta de base de dois qubits, enquanto em outras `cx` é a predefinição. O `ecr` portão é a parte *que se entrelaça* do `cx` portão. Além das portas de controle, há também as `delay``measurement` instruções e.\n",
        "\n",
        "<Admonition type=\"note\">\n",
        "  As QPUs têm portas básicas padrão, mas você pode escolher as portas que desejar, desde que forneça a instrução ou adicione portas de pulso (consulte [Criar passagens do transpiler](/docs/guides/custom-transpiler-pass) ) Os portões básicos padrão são aqueles para os quais foram feitas calibrações na QPU, portanto, não é necessário fornecer mais portões de instrução/pulso. Por exemplo, em algumas QPUs, `cx` é o portão padrão de dois qubits e, `ecr` em outras,. Consulte a lista de [portas e operações nativas](/docs/guides/qpu-information#native-gates) possíveis para obter mais detalhes.\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": [
        "Observe que os `CXGate` objetos foram decompostos em `ecr` portas e portas de base de qubit único.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb3f5aff-3ca2-4688-a59e-da05c724ef09",
      "metadata": {},
      "source": [
        "<span id=\"device-error-rates\" />\n",
        "\n",
        "## Taxas de erro do dispositivo\n",
        "\n",
        "A classe `Target` pode conter informações sobre as taxas de erro das operações no dispositivo.\n",
        "Por exemplo, o código a seguir recupera as propriedades da porta de ressonância cruzada ecoada (ECR) entre o qubit 1 e 0 (observe que a porta ECR é direcional):\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": [
        "A saída exibe a duração da porta (em segundos) e sua taxa de erro. Para revelar informações de erro ao transpilador, crie um modelo de destino com `basis_gates` e `coupling_map` acima e preencha-o com valores de erro do 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 com nosso novo alvo `err_targ` como alvo:\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": [
        "Como o alvo inclui informações de erro, a passagem `VF2PostLayout` tenta encontrar os qubits ideais a serem usados, resultando no mesmo circuito que foi originalmente encontrado com os mesmos qubits físicos.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e815a158-c77a-4e82-bebe-1710d0ae4f1f",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Entenda [as configurações padrão e as opções de configuração do Transpilation](defaults-and-configuration-options).\n",
        "  * Revise o tópico [Parâmetros comumente usados para transpilação](common-parameters).\n",
        "  * Experimente o guia [Comparar configurações do transpiler](/docs/guides/circuit-transpilation-settings#compare-transpiler-settings).\n",
        "  * Consulte [a documentação da API 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
}