{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "58b1f0a7-d62e-4f71-ba01-b8f0beaeeb83",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"Criar um plugin transpiler\"\n",
        "description: \"Como criar um plug-in transpilador Qiskit para compartilhar seu código de transpilagem com a comunidade Qiskit.\"\n",
        "---\n",
        "\n",
        "<span id=\"create-a-transpiler-plugin\" />\n",
        "\n",
        "# Criar um plugin transpiler\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5ec7b7a4-5318-4422-ab3d-c88cee551eaa",
      "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",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a7f87a76-b7a1-4dbb-ad45-55ff63c4665b",
      "metadata": {},
      "source": [
        "Criar um [plug-in de trans](transpiler-plugins) pilação é uma ótima maneira de compartilhar seu código de transpilação com a comunidade Qiskit mais ampla, permitindo que outros usuários se beneficiem da funcionalidade que você desenvolveu. Obrigado por seu interesse em contribuir com a comunidade Qiskit!\n",
        "\n",
        "Antes de criar um plug-in de transpilador, você precisa decidir que tipo de plug-in é apropriado para a sua situação. Há três tipos de plug-ins de transpiladores:\n",
        "\n",
        "* [**Plug-in de estágio Transpiler**](/docs/api/qiskit/transpiler_plugins). Escolha essa opção se estiver definindo um gerenciador de passagens que possa ser substituído por um dos [6 estágios](transpiler-stages) de um gerenciador de passagens predefinido.\n",
        "* [**Plug-in de síntese unitária**](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin). Escolha essa opção se o seu código de transpilação receber como entrada uma matriz unitária (representada como uma matriz Numpy) e gerar uma descrição de um circuito quântico que implemente essa unitária.\n",
        "* [**Plug-in de síntese de alto nível**](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin). Escolha essa opção se o seu código de transpilação receber como entrada um \"objeto de alto nível\", como um operador de Clifford ou uma função linear, e gerar uma descrição de um circuito quântico que implemente esse objeto de alto nível. Os objetos de alto nível são representados por subclasses da classe [Operation](/docs/api/qiskit/qiskit.circuit.Operation).\n",
        "\n",
        "Depois de determinar o tipo de plug-in a ser criado, siga estas etapas para criar o plug-in:\n",
        "\n",
        "1. Crie uma subclasse da classe de plug-in abstrata apropriada:\n",
        "   * [PassManagerStagePlugin](/docs/api/qiskit/qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin) para um plug-in de estágio de transpilador,\n",
        "   * [UnitarySynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin) para um plug-in de síntese unitária, e\n",
        "   * [HighLevelSynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin) para um plug-in de síntese de alto nível.\n",
        "2. Exponha a classe como um [ponto de entrada do setuptools](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) nos metadados do pacote, geralmente editando o arquivo `pyproject.toml`, `setup.cfg` ou `setup.py` do seu pacote Python.\n",
        "\n",
        "Não há limite para o número de plug-ins que um único pacote pode definir, mas cada plug-in deve ter um nome exclusivo. O próprio Qiskit SDK inclui vários plug-ins, cujos nomes também são reservados. Os nomes reservados são:\n",
        "\n",
        "* Plug-ins de estágio do Transpiler: Consulte [esta tabela](/docs/api/qiskit/transpiler_plugins#plugin-stages).\n",
        "* Plug-ins de síntese unitária: `default`, `aqc`, `sk`\n",
        "* Plug-ins de síntese de alto nível:\n",
        "\n",
        "| Classe de operação                                                                         | Nome da operação  | Nomes reservados                                  |\n",
        "| ------------------------------------------------------------------------------------------ | ----------------- | ------------------------------------------------- |\n",
        "| [Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford#clifford)                         | `clifford`        | `default`, `ag`, `bm`, `greedy`, `layers`, `lnn`  |\n",
        "| [LinearFunction](/docs/api/qiskit/qiskit.circuit.library.LinearFunction#linearfunction)    | `linear_function` | `default`, `kms`, `pmh`                           |\n",
        "| [PermutationGate](/docs/api/qiskit/qiskit.circuit.library.PermutationGate#permutationgate) | `permutation`     | `default`, `kms`, `basic`, `acg`, `token_swapper` |\n",
        "\n",
        "Nas próximas seções, mostraremos exemplos dessas etapas para os diferentes tipos de plug-ins. Nesses exemplos, presumimos que estamos criando um pacote Python chamado `my_qiskit_plugin`. Para obter informações sobre a criação de pacotes Python, consulte [este tutorial](https://packaging.python.org/en/latest/tutorials/packaging-projects/) no site Python.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4519c0dc-2bcd-48f4-8522-435b72efdb40",
      "metadata": {},
      "source": [
        "<span id=\"example-create-a-transpiler-stage-plugin\" />\n",
        "\n",
        "## Exemplo: Criar um plugin de etapa transpiler\n",
        "\n",
        "Neste exemplo, criamos um plug-in de estágio do transpilador para o estágio `layout` (consulte [Estágios do transpilador](transpiler-stages) para obter uma descrição dos 6 estágios do pipeline de transpilação integrado do Qiskit).\n",
        "Nosso plug-in simplesmente executa [VF2Layout](/docs/api/qiskit/qiskit.transpiler.passes.VF2Layout) por um número de tentativas que depende do nível de otimização solicitado.\n",
        "\n",
        "Primeiro, criamos uma subclasse de [PassManagerStagePlugin](/docs/api/qiskit/qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin). Há um método que precisamos implementar, chamado [`pass_manager`](/docs/api/qiskit/qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePlugin#pass_manager). Esse método recebe como entrada um [PassManagerConfig](/docs/api/qiskit/qiskit.transpiler.PassManagerConfig) e retorna o gerenciador de passes que estamos definindo. O objeto PassManagerConfig armazena informações sobre o backend de destino, como o mapa de acoplamento e as portas de base.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "f90299d9-5026-424c-b528-6d0defdddb54",
      "metadata": {},
      "outputs": [],
      "source": [
        "# This import is needed for python versions prior to 3.10\n",
        "from __future__ import annotations\n",
        "\n",
        "from qiskit.transpiler import PassManager\n",
        "from qiskit.transpiler.passes import VF2Layout\n",
        "from qiskit.transpiler.passmanager_config import PassManagerConfig\n",
        "from qiskit.transpiler.preset_passmanagers import common\n",
        "from qiskit.transpiler.preset_passmanagers.plugin import (\n",
        "    PassManagerStagePlugin,\n",
        ")\n",
        "\n",
        "\n",
        "class MyLayoutPlugin(PassManagerStagePlugin):\n",
        "    def pass_manager(\n",
        "        self,\n",
        "        pass_manager_config: PassManagerConfig,\n",
        "        optimization_level: int | None = None,\n",
        "    ) -> PassManager:\n",
        "        layout_pm = PassManager(\n",
        "            [\n",
        "                VF2Layout(\n",
        "                    coupling_map=pass_manager_config.coupling_map,\n",
        "                    properties=pass_manager_config.backend_properties,\n",
        "                    max_trials=optimization_level * 10 + 1,\n",
        "                    target=pass_manager_config.target,\n",
        "                )\n",
        "            ]\n",
        "        )\n",
        "        layout_pm += common.generate_embed_passmanager(\n",
        "            pass_manager_config.coupling_map\n",
        "        )\n",
        "        return layout_pm"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d7666879-14bc-479c-a91b-56a800897073",
      "metadata": {},
      "source": [
        "Agora, expomos o plug-in adicionando um ponto de entrada em nossos metadados do pacote Python.\n",
        "Aqui, supomos que a classe que definimos está exposta em um módulo chamado `my_qiskit_plugin`, por exemplo, ao ser importada no arquivo `__init__.py` do módulo `my_qiskit_plugin` .\n",
        "Editamos o arquivo `pyproject.toml`, `setup.cfg` ou `setup.py` do nosso pacote (dependendo do tipo de arquivo que você escolheu para armazenar os metadados do projeto Python ):\n",
        "\n",
        "<Tabs>\n",
        "  <TabItem value=\"package-table-toml\" label=\"pyproject.toml\" default>\n",
        "    ```toml\n",
        "    [project.entry-points.\"qiskit.transpiler.layout\"]\n",
        "    \"my_layout\" = \"my_qiskit_plugin:MyLayoutPlugin\"\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-cfg\" label=\"setup.cfg\">\n",
        "    ```ini\n",
        "    [options.entry_points]\n",
        "    qiskit.transpiler.layout =\n",
        "        my_layout = my_qiskit_plugin:MyLayoutPlugin\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-py\" label=\"setup.py\">\n",
        "    ```python\n",
        "    from setuptools import setup\n",
        "\n",
        "    setup(\n",
        "        # ...,\n",
        "        entry_points={\n",
        "            'qiskit.transpiler.layout': [\n",
        "                'my_layout = my_qiskit_plugin:MyLayoutPlugin',\n",
        "            ]\n",
        "        }\n",
        "    )\n",
        "    ```\n",
        "  </TabItem>\n",
        "</Tabs>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5c5edd30",
      "metadata": {},
      "source": [
        "Consulte a [tabela de estágios do plug-in do transpiler](/docs/api/qiskit/transpiler_plugins#stage-table) para obter os pontos de entrada e as expectativas de cada estágio do transpiler.\n",
        "\n",
        "Para verificar se o seu plug-in foi detectado com êxito pelo Qiskit, instale o pacote do plug-in e siga as instruções em [Plug-ins do Transpiler](transpiler-plugins#list-available-transpiler-stage-plugins) para listar os plug-ins instalados e verifique se o seu plug-in aparece na lista:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "04b07ec3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "['default', 'dense', 'sabre', 'trivial']"
            ]
          },
          "execution_count": 2,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler.preset_passmanagers.plugin import list_stage_plugins\n",
        "\n",
        "list_stage_plugins(\"layout\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "d62c4edb",
      "metadata": {},
      "source": [
        "Se o nosso plug-in de exemplo estivesse instalado, o nome `my_layout` apareceria nessa lista.\n",
        "\n",
        "Se quiser usar um estágio de transpilador integrado como ponto de partida para seu plug-in de estágio de transpilador, você poderá obter o gerenciador de passes para um estágio de transpilador integrado usando [PassManagerStagePluginManager](/docs/api/qiskit/qiskit.transpiler.preset_passmanagers.plugin.PassManagerStagePluginManager#passmanagerstagepluginmanager). A célula de código a seguir mostra como fazer isso para obter o estágio de otimização integrada para o nível de otimização 3.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "f4d578d6",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.transpiler.preset_passmanagers.plugin import (\n",
        "    PassManagerStagePluginManager,\n",
        ")\n",
        "\n",
        "# Initialize the plugin manager\n",
        "plugin_manager = PassManagerStagePluginManager()\n",
        "\n",
        "# Here we create a pass manager config to use as an example.\n",
        "# Instead, you should use the pass manager config that you already received as input\n",
        "# to the pass_manager method of your PassManagerStagePlugin.\n",
        "pass_manager_config = PassManagerConfig()\n",
        "\n",
        "# Obtain the desired built-in transpiler stage\n",
        "optimization = plugin_manager.get_passmanager_stage(\n",
        "    \"optimization\", \"default\", pass_manager_config, optimization_level=3\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "fe3a1a6c-5aa2-4f00-9bdd-45598717be1d",
      "metadata": {},
      "source": [
        "<span id=\"example-create-a-unitary-synthesis-plugin\" />\n",
        "\n",
        "## Exemplo: Criar um plugin de síntese unitária\n",
        "\n",
        "Neste exemplo, criaremos um plug-in de síntese unitária que simplesmente usa a passagem de transpilação [UnitarySynthesis](/docs/api/qiskit/qiskit.transpiler.passes.UnitarySynthesis#unitarysynthesis) transpilação integrada para sintetizar uma porta. É claro que seu próprio plug-in fará algo mais interessante do que isso.\n",
        "\n",
        "A classe [UnitarySynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin) define a interface e o contrato para plug-ins de síntese unitária plug-ins. O método principal é [`run`](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin#run), que recebe como entrada uma matriz Numpy que armazena uma matriz unitária e retorna um [DAGCircuit](/docs/api/qiskit/qiskit.dagcircuit.DAGCircuit) que representa o circuito sintetizado a partir dessa matriz unitária.\n",
        "Além do método `run` , há vários métodos de propriedade que precisam ser definidos.\n",
        "Consulte [UnitarySynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin) para obter a documentação de todas as propriedades necessárias.\n",
        "\n",
        "Vamos criar nossa subclasse UnitarySynthesisPlugin :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "6bc1011c-b15d-4210-973b-d9d530ece880",
      "metadata": {},
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "from qiskit.circuit import QuantumCircuit, QuantumRegister\n",
        "from qiskit.converters import circuit_to_dag\n",
        "from qiskit.dagcircuit.dagcircuit import DAGCircuit\n",
        "from qiskit.quantum_info import Operator\n",
        "from qiskit.transpiler.passes import UnitarySynthesis\n",
        "from qiskit.transpiler.passes.synthesis.plugin import UnitarySynthesisPlugin\n",
        "\n",
        "\n",
        "class MyUnitarySynthesisPlugin(UnitarySynthesisPlugin):\n",
        "    @property\n",
        "    def supports_basis_gates(self):\n",
        "        # Returns True if the plugin can target a list of basis gates\n",
        "        return True\n",
        "\n",
        "    @property\n",
        "    def supports_coupling_map(self):\n",
        "        # Returns True if the plugin can synthesize for a given coupling map\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_natural_direction(self):\n",
        "        # Returns True if the plugin supports a toggle for considering\n",
        "        # directionality of 2-qubit gates\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_pulse_optimize(self):\n",
        "        # Returns True if the plugin can optimize pulses during synthesis\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_gate_lengths(self):\n",
        "        # Returns True if the plugin can accept information about gate lengths\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_gate_errors(self):\n",
        "        # Returns True if the plugin can accept information about gate errors\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_gate_lengths_by_qubit(self):\n",
        "        # Returns True if the plugin can accept information about gate lengths\n",
        "        # (The format of the input differs from supports_gate_lengths)\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def supports_gate_errors_by_qubit(self):\n",
        "        # Returns True if the plugin can accept information about gate errors\n",
        "        # (The format of the input differs from supports_gate_errors)\n",
        "        return False\n",
        "\n",
        "    @property\n",
        "    def min_qubits(self):\n",
        "        # Returns the minimum number of qubits the plugin supports\n",
        "        return None\n",
        "\n",
        "    @property\n",
        "    def max_qubits(self):\n",
        "        # Returns the maximum number of qubits the plugin supports\n",
        "        return None\n",
        "\n",
        "    @property\n",
        "    def supported_bases(self):\n",
        "        # Returns a dictionary of supported bases for synthesis\n",
        "        return None\n",
        "\n",
        "    def run(self, unitary: np.ndarray, **options) -> DAGCircuit:\n",
        "        basis_gates = options[\"basis_gates\"]\n",
        "        synth_pass = UnitarySynthesis(basis_gates, min_qubits=3)\n",
        "        qubits = QuantumRegister(3)\n",
        "        circuit = QuantumCircuit(qubits)\n",
        "        circuit.append(Operator(unitary).to_instruction(), qubits)\n",
        "        dag_circuit = synth_pass.run(circuit_to_dag(circuit))\n",
        "        return dag_circuit"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6daebf1b-aa38-44a8-bf62-eea96838e95f",
      "metadata": {},
      "source": [
        "Se você achar que as entradas disponíveis para o [`run`](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.UnitarySynthesisPlugin#run) são insuficientes para seus objetivos, [abra um problema](https://github.com/Qiskit/qiskit/issues/new/choose) explicando seus requisitos. As alterações na interface do plug-in, como a inclusão de entradas opcionais adicionais, serão feitas de forma compatível com as versões anteriores, de modo que não exijam alterações nos plug-ins existentes.\n",
        "\n",
        "<Admonition type=\"note\" title=\"Nota\">\n",
        "  Todos os métodos prefixados com `supports_` são reservados em uma classe derivada de `UnitarySynthesisPlugin` como parte da interface. Você não deve definir nenhum método `supports_*` personalizado em uma subclasse que não esteja definido na classe abstrata.\n",
        "</Admonition>\n",
        "\n",
        "Agora, expomos o plug-in adicionando um ponto de entrada em nossos metadados do pacote Python.\n",
        "Aqui, supomos que a classe que definimos está exposta em um módulo chamado `my_qiskit_plugin`, por exemplo, ao ser importada no arquivo `__init__.py` do módulo `my_qiskit_plugin` .\n",
        "Editamos o arquivo `pyproject.toml`, `setup.cfg` ou `setup.py` do nosso pacote:\n",
        "\n",
        "<Tabs>\n",
        "  <TabItem value=\"package-table-toml\" label=\"pyproject.toml\" default>\n",
        "    ```toml\n",
        "    [project.entry-points.\"qiskit.unitary_synthesis\"]\n",
        "    \"my_unitary_synthesis\" = \"my_qiskit_plugin:MyUnitarySynthesisPlugin\"\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-cfg\" label=\"setup.cfg\">\n",
        "    ```ini\n",
        "    [options.entry_points]\n",
        "    qiskit.unitary_synthesis =\n",
        "        my_unitary_synthesis = my_qiskit_plugin:MyUnitarySynthesisPlugin\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-py\" label=\"setup.py\">\n",
        "    ```python\n",
        "    from setuptools import setup\n",
        "\n",
        "    setup(\n",
        "        # ...,\n",
        "        entry_points={\n",
        "            'qiskit.unitary_synthesis': [\n",
        "                'my_unitary_synthesis = my_qiskit_plugin:MyUnitarySynthesisPlugin',\n",
        "            ]\n",
        "        }\n",
        "    )\n",
        "    ```\n",
        "  </TabItem>\n",
        "</Tabs>\n",
        "\n",
        "Como antes, se o seu projeto usar `setup.cfg` ou `setup.py` em vez de `pyproject.toml`, consulte a [documentação do setuptools](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) para saber como adaptar essas linhas à sua situação.\n",
        "\n",
        "Para verificar se o seu plug-in foi detectado com êxito pelo Qiskit, instale o pacote do plug-in e siga as instruções em [Plug-ins do Transpiler](transpiler-plugins#list-available-unitary-synthesis-plugins) para listar os plug-ins instalados e verifique se o seu plug-in aparece na lista:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "31bfaf30",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "['aqc', 'clifford', 'default', 'gridsynth', 'sk']"
            ]
          },
          "execution_count": 5,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler.passes.synthesis import unitary_synthesis_plugin_names\n",
        "\n",
        "unitary_synthesis_plugin_names()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4faf2d51",
      "metadata": {},
      "source": [
        "Se o nosso plug-in de exemplo estivesse instalado, o nome `my_unitary_synthesis` apareceria nessa lista.\n",
        "\n",
        "Para acomodar plug-ins de síntese unitária que expõem várias opções, a interface do plug-in tem uma opção para que os usuários forneçam um dicionário de configuração. Isso será passado para o método `run` por meio do argumento da palavra-chave `options` . Se o seu plug-in tiver essas opções de configuração, você deverá documentá-las claramente.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "651c863d-41d9-41f4-a133-b392dae2f363",
      "metadata": {},
      "source": [
        "<span id=\"example-create-a-high-level-synthesis-plugin\" />\n",
        "\n",
        "## Exemplo: Criar um plug-in de síntese de alto nível\n",
        "\n",
        "Neste exemplo, criaremos um plug-in de síntese de alto nível que simplesmente usa a função [synth\\_clifford\\_bm](/docs/api/qiskit/synthesis#synth_clifford_bm) integrada para sintetizar um operador Clifford.\n",
        "\n",
        "A classe [HighLevelSynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin) define a interface e o contrato para plug-ins de síntese de alto nível. O método principal é [`run`](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin#run).\n",
        "O argumento posicional `high_level_object` é uma [operação](/docs/api/qiskit/qiskit.circuit.Operation) que representa o objeto de \"alto nível\" a ser sintetizado. Por exemplo, pode ser um [LinearFunction](/docs/api/qiskit/qiskit.circuit.library.LinearFunction) ou um [Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford).\n",
        "Os seguintes argumentos de palavra-chave estão presentes:\n",
        "\n",
        "* `target` especifica o backend de destino, permitindo que o plug-in acesse todas as informações específicas do destino, como o mapa de acoplamento, o conjunto de portas suportado e assim por diante\n",
        "* `coupling_map` especifica apenas o mapa de acoplamento e só é usado quando `target` não é especificado.\n",
        "* `qubits` especifica a lista de qubits sobre os quais o objeto de objeto de alto nível é definido, caso a síntese seja feita no circuito físico.\n",
        "  Um valor de `None` indica que o layout ainda não foi escolhido e que os qubits físicos no alvo ou no mapa de acoplamento em que essa operação está operando ainda não foram determinados.\n",
        "* `options`um dicionário de configuração de forma livre para opções específicas do plug-in. Se o seu plug-in tiver essas opções de configuração, você deve documentá-las claramente.\n",
        "\n",
        "O método `run` retorna um [QuantumCircuit](/docs/api/qiskit/qiskit.circuit.QuantumCircuit) que representa o circuito sintetizado a partir desse objeto de alto nível.\n",
        "Também é permitido retornar `None`, indicando que o plug-in não consegue sintetizar o objeto de alto nível fornecido.\n",
        "A síntese real de objetos de alto nível é realizada pelo [HighLevelSynthesis](/docs/api/qiskit/qiskit.transpiler.passes.HighLevelSynthesis) passagem do transpilador.\n",
        "\n",
        "Além do método `run` , há vários métodos de propriedade que precisam ser definidos.\n",
        "Consulte [HighLevelSynthesisPlugin](/docs/api/qiskit/qiskit.transpiler.passes.synthesis.plugin.HighLevelSynthesisPlugin) para obter a documentação de todas as propriedades necessárias.\n",
        "\n",
        "Vamos definir nossa subclasse HighLevelSynthesisPlugin :\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "3c0e59d4-85b0-4157-824b-b1f6220e83ad",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit.synthesis import synth_clifford_bm\n",
        "from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPlugin\n",
        "\n",
        "\n",
        "class MyCliffordSynthesisPlugin(HighLevelSynthesisPlugin):\n",
        "    def run(\n",
        "        self,\n",
        "        high_level_object,\n",
        "        coupling_map=None,\n",
        "        target=None,\n",
        "        qubits=None,\n",
        "        **options,\n",
        "    ) -> QuantumCircuit:\n",
        "        if high_level_object.num_qubits <= 3:\n",
        "            return synth_clifford_bm(high_level_object)\n",
        "        else:\n",
        "            return None"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1285dbfd-04ce-494b-8a01-a58040035dbd",
      "metadata": {},
      "source": [
        "Esse plug-in sintetiza objetos do tipo [Clifford](/docs/api/qiskit/qiskit.quantum_info.Clifford) que têm no máximo 3 qubits, usando o método `synth_clifford_bm` .\n",
        "\n",
        "Agora, expomos o plug-in adicionando um ponto de entrada em nossos metadados do pacote Python.\n",
        "Aqui, supomos que a classe que definimos está exposta em um módulo chamado `my_qiskit_plugin`, por exemplo, ao ser importada no arquivo `__init__.py` do módulo `my_qiskit_plugin` .\n",
        "Editamos o arquivo `pyproject.toml`, `setup.cfg` ou `setup.py` do nosso pacote:\n",
        "\n",
        "<Tabs>\n",
        "  <TabItem value=\"package-table-toml\" label=\"pyproject.toml\" default>\n",
        "    ```toml\n",
        "    [project.entry-points.\"qiskit.synthesis\"]\n",
        "    \"clifford.my_clifford_synthesis\" = \"my_qiskit_plugin:MyCliffordSynthesisPlugin\"\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-cfg\" label=\"setup.cfg\">\n",
        "    ```ini\n",
        "    [options.entry_points]\n",
        "    qiskit.synthesis =\n",
        "        clifford.my_clifford_synthesis = my_qiskit_plugin:MyCliffordSynthesisPlugin\n",
        "    ```\n",
        "  </TabItem>\n",
        "\n",
        "  <TabItem value=\"package-table-py\" label=\"setup.py\">\n",
        "    ```python\n",
        "    from setuptools import setup\n",
        "\n",
        "    setup(\n",
        "        # ...,\n",
        "        entry_points={\n",
        "            'qiskit.synthesis': [\n",
        "                'clifford.my_clifford_synthesis = my_qiskit_plugin:MyCliffordSynthesisPlugin',\n",
        "            ]\n",
        "        }\n",
        "    )\n",
        "    ```\n",
        "  </TabItem>\n",
        "</Tabs>\n",
        "\n",
        "O `name` consiste em duas partes separadas por um ponto (`.`):\n",
        "\n",
        "* O nome do tipo de [operação](/docs/api/qiskit/qiskit.circuit.Operation) que o plug-in sintetiza (neste caso, `clifford`). Observe que essa cadeia de caracteres corresponde ao atributo [`name`](/docs/api/qiskit/qiskit.circuit.Operation#name) da classe Operation, e não ao nome da classe em si.\n",
        "* O nome do plug-in (nesse caso, `special`).\n",
        "\n",
        "Como antes, se o seu projeto usar `setup.cfg` ou `setup.py` em vez de `pyproject.toml`, consulte a [documentação do setuptools](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) para saber como adaptar essas linhas à sua situação.\n",
        "\n",
        "Para verificar se o seu plug-in foi detectado com êxito pelo Qiskit, instale o pacote do plug-in e siga as instruções em [Plug-ins do Transpiler](transpiler-plugins#list-available-high-level-synthesis-plugins) para listar os plug-ins instalados e verifique se o seu plug-in aparece na lista:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "fbe1f265",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "['ag', 'bm', 'default', 'greedy', 'layers', 'lnn', 'rb_default']"
            ]
          },
          "execution_count": 7,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "from qiskit.transpiler.passes.synthesis import (\n",
        "    high_level_synthesis_plugin_names,\n",
        ")\n",
        "\n",
        "high_level_synthesis_plugin_names(\"clifford\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1e86f49",
      "metadata": {},
      "source": [
        "Se o nosso plug-in de exemplo estivesse instalado, o nome `my_clifford_synthesis` apareceria nessa lista.\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a48c2d0b-c402-4b83-ae2e-42c33fe1720e",
      "metadata": {},
      "source": [
        "<Admonition type=\"tip\" title=\"Recomendação\">\n",
        "  * [Envie seu plug-in para o ecossistema Qiskit!](https://github.com/Qiskit/ecosystem?tab=readme-ov-file#how-to-join)\n",
        "  * Confira os [tutoriais](/docs/tutorials) para ver exemplos de transpilação e execução de circuitos quânticos.\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
}