Pular para o conteúdo principal

Parâmetros mais usados na transpilação

Versões dos pacotes

O código nesta página foi desenvolvido com os seguintes requisitos. Recomendamos usar estas versões ou versões mais recentes.

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

Esta página descreve alguns dos parâmetros mais usados na transpilação local. Esses parâmetros são configurados como argumentos de generate_preset_pass_manager ou transpile.

Grau de aproximação

Você pode usar o grau de aproximação para especificar o quão próximo você deseja que o circuito resultante seja do circuito desejado (de entrada). Trata-se de um número de ponto flutuante no intervalo (0,0 – 1,0), em que 0,0 representa aproximação máxima e 1,0 (padrão) representa nenhuma aproximação. Valores menores trocam precisão na saída por facilidade de execução (ou seja, menos portas). O valor padrão é 1,0.

Na síntese unitária de dois qubits (usada nas etapas iniciais de todos os níveis e na etapa de otimização com nível de otimização 3), esse valor especifica a fidelidade alvo da decomposição de saída. Ou seja, quanto de erro é introduzido quando uma representação matricial de um circuito é convertida em portas discretas. Se o grau de aproximação for um valor menor (mais aproximação), o circuito de saída da síntese diferirá mais da matriz de entrada, mas provavelmente terá menos portas (porque qualquer operação arbitrária de dois qubits pode ser decomposta perfeitamente com no máximo três portas CX) e será mais fácil de executar.

Quando o grau de aproximação é menor que 1,0, circuitos com uma ou duas portas CX podem ser sintetizados, resultando em menos erro proveniente do hardware, mas mais erro proveniente da aproximação. Como a porta CX é a mais custosa em termos de erro, pode ser benéfico reduzir a quantidade delas ao custo da fidelidade na síntese (essa técnica foi usada para aumentar o volume quântico em dispositivos IBM®: Validating quantum computers using randomized model circuits).

Como exemplo, geramos um UnitaryGate aleatório de dois qubits que será sintetizado na etapa inicial. Definir o approximation_degree com um valor menor que 1,0 pode gerar um circuito aproximado. É necessário também especificar os basis_gates para informar ao método de síntese quais portas ele pode usar na síntese aproximada.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import random_unitary
from qiskit.transpiler import generate_preset_pass_manager

UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)

qubits = QuantumRegister(2, name="q")
qc = QuantumCircuit(qubits)
qc.append(rand_U, qubits)
pass_manager = generate_preset_pass_manager(
optimization_level=1,
approximation_degree=0.85,
basis_gates=["sx", "rz", "cx"],
)
approx_qc = pass_manager.run(qc)
print(approx_qc.count_ops()["cx"])
2

Isso produz uma saída 2 porque a aproximação exige menos portas CX.

Semente do gerador de números aleatórios

Algumas partes do transpilador são estocásticas, portanto execuções repetidas de transpilação podem retornar resultados diferentes. Para obter um resultado reproduzível, você pode definir a semente do gerador de números pseudoaleatórios usando o argumento seed_transpiler. Execuções repetidas com a mesma semente retornarão os mesmos resultados.

Exemplo:

pass_manager = generate_preset_pass_manager(
optimization_level=1, seed_transpiler=11, basis_gates=["sx", "rz", "cx"]
)
optimized_1 = pass_manager.run(qc)
optimized_1.draw("mpl")

Saída da célula de código anterior

Layout inicial

Antes da transpilação, os qubits contidos no seu circuito são qubits virtuais que não correspondem necessariamente a qubits físicos no backend alvo. Você pode especificar o mapeamento inicial de qubits virtuais para qubits físicos usando o argumento initial_layout. Note que o layout final de qubits pode diferir do layout inicial, pois o transpilador pode permutar qubits usando portas de swap ou outros meios.

No exemplo abaixo, construímos um layout inicial para o backend simulado FakeSherbrooke criando um objeto Layout. Nosso layout mapeia o primeiro qubit do nosso circuito para o qubit 5 de Sherbrooke, e o segundo qubit do nosso circuito para o qubit 6 de Sherbrooke. Note que qubits físicos são sempre representados por inteiros.

from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit.transpiler import Layout

backend = FakeSherbrooke()

a, b = qubits
initial_layout = Layout({a: 5, b: 6})

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Saída da célula de código anterior

Além de especificar um objeto Layout, você também pode passar uma lista de inteiros, em que o ii-ésimo elemento da lista contém o qubit físico para o qual o ii-ésimo qubit deve ser mapeado. Por exemplo:

initial_layout = [5, 6]

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Saída da célula de código anterior

Você pode usar a função plot_error_map para gerar um diagrama do grafo do dispositivo com informações de erro e com os qubits físicos identificados. Você também pode ver diagramas semelhantes na página de Recursos de computação.

from qiskit.visualization import plot_error_map

plot_error_map(backend, figsize=(30, 24))

Saída da célula de código anterior

Opções de estágio e plugin do transpilador

Essas opções têm o sufixo _method. Elas influenciam o funcionamento do transpilador e são usadas para tentar obter uma saída melhor, diferente ou específica do transpilador.

  • init_method (str) - O plugin a ser usado na etapa de inicialização.

  • layout_method (str) - O passo de seleção de layout (trivial, dense, sabre). Também pode ser o nome de um plugin externo a ser usado na etapa de layout.

  • optimization_method (str) - O plugin a ser usado na etapa de otimização.

  • routing_method (str) - Nome do passo de roteamento (basic, lookahead, default, sabre, none). Também pode ser o nome de um plugin externo a ser usado na etapa de roteamento.

  • scheduling_method (str) - Nome do passo de escalonamento. Também pode ser o nome de um plugin externo a ser usado na etapa de escalonamento.

    • as_soon_as_possible: Escalonar instruções de forma gulosa: o mais cedo possível em um recurso de qubit (alias: asap).
    • as_late_as_possible: Escalonar instruções tarde. Ou seja, manter os qubits no estado fundamental sempre que possível (alias: alap).
  • translation_method (str) - Nome do passo de tradução (unroller, translator, synthesis). Também pode ser o nome de um plugin externo a ser usado na etapa de tradução.

  • unitary_synthesis_method (str) - O nome do método de síntese unitária a ser usado. Por padrão, é usado o método default.

nota

Para ver uma lista de todos os plugins instalados para uma determinada etapa, execute list_stage_plugins("stage_name"). Por exemplo, se você quiser ver uma lista de todos os plugins instalados para a etapa de roteamento, execute list_stage_plugins(routing).

Próximos passos