Saltar al contenido principal

Parámetros de uso común para la transpilación

Versiones de paquetes

El código de esta página fue desarrollado con los siguientes requisitos. Se recomienda usar estas versiones o superiores.

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

Esta página describe algunos de los parámetros más utilizados para la transpilación local. Estos parámetros se configuran mediante argumentos de generate_preset_pass_manager o transpile.

Grado de aproximación

Puedes usar el grado de aproximación para especificar qué tan cerca quieres que el circuito resultante coincida con el circuito deseado (de entrada). Es un número de punto flotante en el rango (0.0 - 1.0), donde 0.0 es la máxima aproximación y 1.0 (valor por defecto) significa sin aproximación. Los valores más bajos intercambian precisión en la salida por facilidad de ejecución (es decir, menos puertas). El valor predeterminado es 1.0.

En la síntesis unitaria de dos qubits (utilizada en las etapas iniciales de todos los niveles y en la etapa de optimización con nivel 3), este valor especifica la fidelidad objetivo de la descomposición de salida. Es decir, cuánto error se introduce cuando una representación matricial de un circuito se convierte a puertas discretas. Si el grado de aproximación es menor (más aproximación), el circuito de salida de la síntesis diferirá más de la matriz de entrada, pero probablemente tendrá menos puertas (ya que cualquier operación arbitraria de dos qubits puede descomponerse perfectamente con a lo sumo tres puertas CX) y será más fácil de ejecutar.

Cuando el grado de aproximación es menor que 1.0, pueden sintetizarse circuitos con una o dos puertas CX, lo que reduce el error proveniente del hardware pero aumenta el error por aproximación. Como CX es la puerta más costosa en términos de error, puede ser beneficioso reducir su cantidad a costa de la fidelidad en la síntesis (esta técnica se usó para aumentar el volumen cuántico en dispositivos IBM®: Validating quantum computers using randomized model circuits).

Como ejemplo, generamos una UnitaryGate aleatoria de dos qubits que será sintetizada en la etapa inicial. Establecer approximation_degree en un valor menor que 1.0 puede generar un circuito aproximado. También debemos especificar basis_gates para que el método de síntesis sepa qué puertas puede usar en la síntesis 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

El resultado es 2 porque la aproximación requiere menos puertas CX.

Semilla del generador de números aleatorios

Algunas partes del transpilador son estocásticas, por lo que ejecuciones repetidas pueden devolver resultados distintos. Para obtener un resultado reproducible, puedes establecer la semilla del generador de números pseudoaleatorios con el argumento seed_transpiler. Las ejecuciones repetidas con la misma semilla siempre devuelven los mismos resultados.

Ejemplo:

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")

Output of the previous code cell

Distribución inicial

Antes de la transpilación, los qubits de tu circuito son qubits virtuales que no necesariamente corresponden a qubits físicos del backend de destino. Puedes especificar la asignación inicial de qubits virtuales a qubits físicos mediante el argumento initial_layout. Ten en cuenta que la distribución final de qubits puede diferir de la inicial, ya que el transpilador puede permutar qubits usando puertas swap u otros mecanismos.

En el ejemplo siguiente, construimos una distribución inicial para el backend simulado FakeSherbrooke creando un objeto Layout. Nuestra distribución asigna el primer qubit del circuito al qubit 5 de Sherbrooke, y el segundo qubit del circuito al qubit 6 de Sherbrooke. Ten en cuenta que los qubits físicos siempre se representan con enteros.

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)

Output of the previous code cell

Además de especificar un objeto Layout, también puedes pasar una lista de enteros, donde el ii-ésimo elemento de la lista contiene el qubit físico al que debe asignarse el ii-ésimo qubit. Por ejemplo:

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)

Output of the previous code cell

Puedes usar la función plot_error_map para generar un diagrama del grafo del dispositivo con información de errores y con los qubits físicos etiquetados. También puedes ver diagramas similares en la página de Recursos de cómputo.

from qiskit.visualization import plot_error_map

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

Output of the previous code cell

Opciones de etapas y plugins del transpilador

Estas opciones tienen el sufijo _method. Influyen en el funcionamiento del transpilador y se utilizan para intentar obtener una salida mejor, diferente o específica de él.

  • init_method (str) - El plugin a usar en la etapa de inicialización.

  • layout_method (str) - El paso de selección de distribución (trivial, dense, sabre). También puede ser el nombre de un plugin externo a usar en la etapa de distribución.

  • optimization_method (str) - El plugin a usar en la etapa de optimización.

  • routing_method (str) - Nombre del paso de enrutamiento (basic, lookahead, default, sabre, none). También puede ser el nombre de un plugin externo a usar en la etapa de enrutamiento.

  • scheduling_method (str) - Nombre del paso de planificación temporal. También puede ser el nombre de un plugin externo a usar en la etapa de planificación.

    • as_soon_as_possible: Planifica las instrucciones de forma greedy: lo antes posible en un recurso de qubit (alias: asap).
    • as_late_as_possible: Planifica las instrucciones tarde. Es decir, mantiene los qubits en el estado fundamental cuando es posible (alias: alap).
  • translation_method (str) - Nombre del paso de traducción (unroller, translator, synthesis). También puede ser el nombre de un plugin externo a usar en la etapa de traducción.

  • unitary_synthesis_method (str) - El nombre del método de síntesis unitaria a usar. Por defecto se usa default.

nota

Para ver la lista de todos los plugins instalados para una etapa determinada, ejecuta list_stage_plugins("stage_name"). Por ejemplo, para ver los plugins instalados para la etapa de enrutamiento, ejecuta list_stage_plugins(routing).

Próximos pasos