Saltar al contenido principal

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:

  • RZZ(θ)R_{ZZ}(\theta) para 0<θπ/20 \lt \theta \leq \pi/2
  • RX(θ)R_X(\theta) para cualquier θ\theta

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 RZZ(θ)R_{ZZ}(\theta) y RX(θ)R_X(\theta) para un ángulo arbitrario. El uso de la puerta RX(θ)R_X(\theta) 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 RZZ(θ)R_{ZZ}(\theta) 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.

Nota sobre las tasas de error reportadas

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

Salida de la celda de código anterior

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(),
)

Salida de la celda de código anterior

# 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(),
)

Salida de la celda de código anterior

Restricciones de ángulo

Para la puerta de dos qubits RZZ(θ)R_{ZZ}(\theta), solo se pueden ejecutar en hardware IBM Quantum ángulos entre 00 y π/2\pi/2. Si un circuito contiene puertas RZZ(θ)R_{ZZ}(\theta) 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 RZZ(θ)R_{ZZ}(\theta) 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 π/2\pi / 2. Por ejemplo, una puerta RX(θ)R_X(\theta), al transpilarse, debe descomponerse en una serie de puertas RZRZ y X\sqrt{X}, 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 RZZ(θ)R_{ZZ}(\theta), 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")

Salida de la celda de código anterior

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

Salida de la celda de código anterior

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

Salida de la celda de código anterior

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

Salida de la celda de código anterior

Para flujos de trabajo que requieren muchas rotaciones de un solo qubit RX(θ)R_X(\theta) 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 RZZ(θ)R_{ZZ}(\theta) 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:

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

Recomendaciones