Representar computadoras cuánticas para el transpilador
Versiones de paquetes
El código de esta página fue desarrollado con los siguientes requisitos. Recomendamos usar estas versiones o más recientes.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
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 el legado BackendV1) al que planeas enviar trabajos, y el atributo Target del backend.
- El
Targetcontiene todas las restricciones relevantes de un dispositivo, como sus puertas base nativas, la conectividad de qubits e información de pulsos o temporización. - El
Backendposee unTargetde forma predeterminada, contiene información adicional — como elInstructionScheduleMap, y proporciona la interfaz para enviar trabajos de circuitos cuánticos.
También puedes proporcionar información explícitamente para que la use el transpilador; por ejemplo, si tienes un caso de uso específico o si crees que dicha información ayudará al transpilador a generar un circuito más optimizado.
La precisión con la que el transpilador produce el circuito más adecuado para un hardware específico depende de cuánta información tenga el Target o el Backend sobre sus restricciones.
Dado que muchos de los algoritmos de transpilación subyacentes son estocásticos, no hay garantía de que se encuentre un circuito mejor.
Esta página muestra varios ejemplos de cómo pasar información de la QPU al transpilador. Estos ejemplos usan el target del backend simulado FakeSherbrooke.
Configuración predeterminada
El uso más sencillo del transpilador consiste en proporcionar toda la información de la QPU mediante el Backend o el Target. Para entender mejor cómo funciona el transpilador, construye un circuito y transpílalo con distintas configuraciones de información, tal como se muestra a continuación.
Importa las bibliotecas necesarias e instancia la QPU:
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
target = backend.target
El circuito de ejemplo utiliza una instancia de efficient_su2 de la biblioteca de circuitos de Qiskit.
from qiskit.circuit.library import efficient_su2
qc = efficient_su2(12, entanglement="circular", reps=1)
qc.draw("mpl")
Este ejemplo usa la configuración predeterminada para transpilar al target del backend, que proporciona toda la información necesaria para convertir el circuito en uno que se ejecutará en el backend.
from qiskit.transpiler import generate_preset_pass_manager
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=target, seed_transpiler=12345
)
qc_t_target = pass_manager.run(qc)
qc_t_target.draw("mpl", idle_wires=False, fold=-1)
Este ejemplo se utiliza en secciones posteriores de este tema para ilustrar que el mapa de acoplamiento y las puertas base son las piezas de información esenciales que se deben pasar al transpilador para una construcción óptima del circuito. La QPU generalmente puede seleccionar configuraciones predeterminadas para otra información que no se pasa, como la temporización y la planificación.
Mapa de acoplamiento
El mapa de acoplamiento es un grafo que muestra qué qubits están conectados y, por tanto, tienen puertas de dos qubits entre ellos. A veces este grafo es direccional, lo que significa que las puertas de dos qubits solo pueden ir en un sentido. 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, incluso si su conectividad es limitada, introduciendo puertas SWAP para mover la información cuántica.
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. Una de las primeras etapas en la transpilación, la etapa de layout, realiza esta correspondencia.
Aunque la etapa de enrutamiento está entrelazada con la etapa de layout — que selecciona los qubits reales —, de forma predeterminada, este tema las trata como etapas separadas por simplicidad. La combinación de enrutamiento y layout se denomina mapeo de qubits. Obtén más información sobre estas etapas en el tema Etapas del transpilador.
Pasa el argumento de palabra clave coupling_map para ver su efecto en el transpilador:
coupling_map = target.build_coupling_map()
pass_manager = generate_preset_pass_manager(
optimization_level=0, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv0 = pass_manager.run(qc)
qc_t_cm_lv0.draw("mpl", idle_wires=False, fold=-1)
Como se muestra arriba, se insertaron varias puertas SWAP (cada una formada por tres puertas CX), lo que causará muchos errores en los dispositivos actuales. Para ver qué qubits se seleccionan en la topología real de qubits, usa plot_circuit_layout de las Visualizaciones de Qiskit:
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv0, backend, view="physical")
Esto muestra que nuestros qubits virtuales 0-11 se mapearon de forma trivial a la línea de qubits físicos 0-11. Volvamos al valor predeterminado (optimization_level=1), que usa VF2Layout si se requiere algún enrutamiento.
pass_manager = generate_preset_pass_manager(
optimization_level=1, coupling_map=coupling_map, seed_transpiler=12345
)
qc_t_cm_lv1 = pass_manager.run(qc)
qc_t_cm_lv1.draw("mpl", idle_wires=False, fold=-1)
Ahora no se han insertado puertas SWAP y los qubits físicos seleccionados son los mismos que cuando se usa la clase target.
from qiskit.visualization import plot_circuit_layout
plot_circuit_layout(qc_t_cm_lv1, backend, view="physical")
Ahora el layout tiene forma de anillo. Dado que este layout respeta la conectividad del circuito, no hay puertas SWAP, lo que proporciona un circuito mucho mejor para la ejecución.
Puertas base
Cada computadora cuántica admite un conjunto de instrucciones limitado, llamado sus puertas base. 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 dichas puertas. Esto lo realiza el BasisTranslator, y las puertas base pueden especificarse como argumento de palabra clave al transpilador para proporcionar esta información.
basis_gates = list(target.operation_names)
print(basis_gates)
['sx', 'switch_case', 'x', 'if_else', 'measure', 'for_loop', 'delay', 'ecr', 'id', 'reset', 'rz']
Las puertas predeterminadas de un solo qubit en ibm_sherbrooke son rz, x y sx, y la puerta predeterminada de dos qubits es ecr (echoed cross-resonance). Las puertas CX se construyen a partir de puertas ecr, por lo que en algunas QPUs ecr se especifica como la puerta base de dos qubits, mientras que en otras cx es la predeterminada. La puerta ecr es la parte entrelazante de la puerta cx. Además de las puertas de control, también hay instrucciones de delay y medición (measurement).
Las QPUs tienen puertas base predeterminadas, pero puedes elegir las puertas que quieras, siempre que proporciones la instrucción o añadas puertas de pulso (consulta Crear passes del transpilador.). Las puertas base predeterminadas son aquellas para las que se han realizado calibraciones en la QPU, por lo que no es necesario proporcionar instrucciones o puertas de pulso adicionales. Por ejemplo, en algunas QPUs cx es la puerta predeterminada de dos qubits y ecr en otras. Consulta la lista de posibles puertas y operaciones nativas para más detalles.
pass_manager = generate_preset_pass_manager(
optimization_level=1,
coupling_map=coupling_map,
basis_gates=basis_gates,
seed_transpiler=12345,
)
qc_t_cm_bg = pass_manager.run(qc)
qc_t_cm_bg.draw("mpl", idle_wires=False, fold=-1)
Observa que los objetos CXGate se han descompuesto en puertas ecr y puertas base de un solo qubit.
Tasas de error del dispositivo
La clase Target puede contener información sobre las tasas de error para las operaciones en el dispositivo.
Por ejemplo, el siguiente código recupera las propiedades de la puerta echoed cross-resonance (ECR) entre el qubit 1 y el 0 (ten en cuenta que la puerta ECR es direccional):
target["ecr"][(1, 0)]
InstructionProperties(duration=5.333333333333332e-07, error=0.007494257741828603)
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, construye un modelo target con las basis_gates y el coupling_map de arriba y rellénalo con valores de error del backend FakeSherbrooke.
from qiskit.transpiler import Target
from qiskit.circuit.controlflow import IfElseOp, SwitchCaseOp, ForLoopOp
err_targ = Target.from_configuration(
basis_gates=basis_gates,
coupling_map=coupling_map,
num_qubits=target.num_qubits,
custom_name_mapping={
"if_else": IfElseOp,
"switch_case": SwitchCaseOp,
"for_loop": ForLoopOp,
},
)
for i, (op, qargs) in enumerate(target.instructions):
if op.name in basis_gates:
err_targ[op.name][qargs] = target.instruction_properties(i)
Transpila con nuestro nuevo target err_targ como target:
pass_manager = generate_preset_pass_manager(
optimization_level=1, target=err_targ, seed_transpiler=12345
)
qc_t_cm_bg_et = pass_manager.run(qc)
qc_t_cm_bg_et.draw("mpl", idle_wires=False, fold=-1)
Dado que el target incluye información de error, el paso VF2PostLayout intenta encontrar los qubits óptimos a utilizar, lo que resulta en el mismo circuito que se encontró originalmente con los mismos qubits físicos.
Próximos pasos
- Comprende las Configuraciones predeterminadas y opciones de configuración de la transpilación.
- Revisa el tema Parámetros de uso común para la transpilación.
- Prueba la guía Comparar configuraciones del transpilador.
- Consulta la Documentación de la API de Transpile.