Puertas fraccionarias
Versiones de paquetes
El código de esta página fue desarrollado usando los siguientes requisitos. Recomendamos usar estas versiones o más recientes.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Esta página presenta dos tipos de puertas recientemente soportadas en la flota de QPUs de IBM Quantum®. Estas puertas fraccionarias están disponibles en QPUs Heron con las siguientes formas:
- para
- para cualquier
Esta página trata los casos de uso en los que implementar puertas fraccionarias puede mejorar la eficiencia de tus flujos de trabajo, así como la manera de usar estas puertas en QPUs de IBM Quantum.
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
Cómo usar puertas fraccionarias
Internamente, estas puertas fraccionarias funcionan ejecutando directamente una rotación y para un ángulo arbitrario. El uso de la puerta puede reducir la duración y el error en rotaciones de un solo qubit con ángulo arbitrario hasta en un factor de dos. La ejecución directa de la rotación de la puerta evita la descomposición en múltiples objetos CZGate, reduciendo de manera similar la duración y el error de un circuito. Esto es especialmente útil para circuitos que contienen muchas rotaciones de uno y dos qubits, como al simular la dinámica de un sistema cuántico o al usar un ansatz variacional con muchos parámetros.
Si bien estos tipos de puertas están en la biblioteca de puertas estándar que puede poseer un QuantumCircuit, solo se pueden usar en QPUs específicas de IBM Quantum, y deben cargarse con la bandera use_fractional_gates configurada en True (como se muestra a continuación). Esta bandera garantizará que las puertas fraccionarias se incluyan en el Target del backend para el transpilador.
service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)
Este ejemplo de código demuestra cómo usar puertas fraccionarias en el contexto de un flujo de trabajo que simula la dinámica de una cadena de Ising usando puertas fraccionarias. Luego se compara la duración del circuito con un backend que no usa puertas fraccionarias.
El valor de error reportado en el Target de un backend con puertas fraccionarias habilitadas es solo una copia del equivalente de la puerta no fraccionaria (que puede no ser el mismo). Esto se debe a que el reporte de tasas de error en las puertas fraccionarias aún no está soportado.
Sin embargo, dado que el tiempo de puerta de las puertas fraccionarias y no fraccionarias es el mismo, es una suposición razonable que sus tasas de error son comparables — especialmente cuando la fuente dominante de error en un circuito se debe a la relajación.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization.timeline import draw as draw_timeline, IQXSimple
from qiskit_ibm_runtime import QiskitRuntimeService
num_qubits = 5
num_time_steps = 3
rx_angle = 0.1
rzz_angle = 0.1
ising_circuit = QuantumCircuit(num_qubits)
for i in range(num_time_steps):
# rx layer
for q in range(num_qubits):
ising_circuit.rx(rx_angle, q)
for q in range(1, num_qubits - 1, 2):
ising_circuit.rzz(rzz_angle, q, q + 1)
# 2nd rzz layer
for q in range(0, num_qubits - 1, 2):
ising_circuit.rzz(rzz_angle, q, q + 1)
ising_circuit.barrier()
ising_circuit.draw("mpl")
Especifica dos objetos backend: uno con puertas fraccionarias habilitadas y el otro con ellas deshabilitadas; luego transpílalos ambos.
service = QiskitRuntimeService()
backend_fractional = service.backend("ibm_torino", use_fractional_gates=True)
backend_conventional = service.backend(
"ibm_torino", use_fractional_gates=False
)
pm_fractional = generate_preset_pass_manager(
optimization_level=3, backend=backend_fractional, scheduling_method="alap"
)
pm_conventional = generate_preset_pass_manager(
optimization_level=3,
backend=backend_conventional,
scheduling_method="alap",
)
ising_circuit_fractional = pm_fractional.run(ising_circuit)
ising_circuit_conventional = pm_conventional.run(ising_circuit)
Muestra la línea de tiempo del circuito usando los dos tipos de puertas.
# Draw timeline of circuit with conventional gates
draw_timeline(
ising_circuit_conventional,
idle_wires=False,
target=backend_conventional.target,
time_range=(0, 500),
style=IQXSimple(),
)
# Draw timeline of circuit with fractional gates
draw_timeline(
ising_circuit_fractional,
idle_wires=False,
target=backend_fractional.target,
time_range=(0, 500),
style=IQXSimple(),
)
Restricciones de ángulo
Para la puerta de dos qubits , solo se pueden ejecutar en hardware IBM Quantum ángulos entre y . Si un circuito contiene puertas con un ángulo fuera de este rango, el pipeline estándar de transpilación generalmente corregirá esto con una transformación de circuito apropiada (mediante el paso FoldRzzAngle). Sin embargo, para cualquier puerta que contenga uno o más Parameters, el transpilador asumirá que estos parámetros se asignarán con ángulos dentro de este rango en tiempo de ejecución. El trabajo fallará si alguno de los valores de parámetro especificados en el PUB enviado a Qiskit Runtime está fuera de este rango.
Dónde usar puertas fraccionarias
Históricamente, las puertas base disponibles en los QPUs de IBM Quantum han sido CZ, X, RZ, SX e ID, que no pueden representar eficientemente circuitos con rotaciones de uno y dos qubits que no sean múltiplos de . Por ejemplo, una puerta , al transpilarse, debe descomponerse en una serie de puertas y , lo que crea un circuito con dos puertas de duración finita en lugar de una.
De manera similar, cuando se transpilan rotaciones de dos qubits como una puerta , la descomposición requiere dos puertas CZ y varias puertas de un solo qubit, lo que aumenta la profundidad del circuito. Estas descomposiciones se muestran en el siguiente código.
qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")
# Decomposition of an RX(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.backend("ibm_torino")
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
qc = QuantumCircuit(2)
param = Parameter("θ")
qc.rzz(param, 0, 1)
qc.draw("mpl")
# Decomposition of an RZZ(θ) gate using the IBM Quantum QPU basis
service = QiskitRuntimeService()
backend = service.backend("ibm_torino")
optimization_level = 3
pm = generate_preset_pass_manager(optimization_level, backend=backend)
transpiled_circuit = pm.run(qc)
transpiled_circuit.draw("mpl", idle_wires=False)
Para flujos de trabajo que requieren muchas rotaciones de un solo qubit o de dos qubits (como en un ansatz variacional o al simular la evolución temporal de sistemas cuánticos), esta restricción hace que la profundidad del circuito crezca rápidamente. Sin embargo, las puertas fraccionarias eliminan este requisito, ya que las rotaciones de uno y dos qubits se ejecutan directamente, creando un circuito cuántico más eficiente (y por tanto con menor error).
Cuándo no usar puertas fraccionarias
Es importante tener en cuenta que las puertas fraccionarias son una característica experimental y que el comportamiento de la bandera use_fractional_gates puede cambiar en el futuro. Consulta las notas de versión para nuevas versiones de Qiskit Runtime para obtener más información. Consulta también la documentación de referencia de la API para QiskitRuntimeService.backend, que describe use_fractional_gates.
Además, el transpilador de Qiskit tiene capacidad limitada para usar en sus pasos de optimización. Esto requiere que tengas más cuidado al construir y optimizar circuitos que contengan estas instrucciones.
Por último, el uso de puertas fraccionarias no está soportado para:
- Circuitos dinámicos
- Pauli twirling — sin embargo, el twirling de medición con TREX sí está soportado.
- Cancelación probabilística de errores
- Extrapolación de ruido cero (usando amplificación probabilística de errores)
Lee la guía sobre opciones de primitivas para aprender más sobre cómo personalizar las técnicas de mitigación y supresión de errores para una carga de trabajo cuántica determinada.
Siguientes pasos
- Para aprender más sobre la transpilación, consulta la página de introducción a la transpilación.
- Lee sobre cómo escribir un pase de transpilador personalizado.
- Aprende cómo configurar la mitigación de errores para Qiskit Runtime.