Pular para o conteúdo principal

Gates fracionários

Versões dos pacotes

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

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

Esta página apresenta dois novos tipos de gates suportados pela frota de QPUs IBM Quantum®. Esses gates fracionários são suportados em QPUs Heron nas seguintes formas:

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

Esta página discute os casos de uso em que a implementação de gates fracionários pode melhorar a eficiência dos seus fluxos de trabalho, além de como usar esses gates em QPUs IBM Quantum.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime

Como usar gates fracionários

Internamente, esses gates fracionários funcionam executando diretamente uma rotação RZZ(θ)R_{ZZ}(\theta) e RX(θ)R_X(\theta) para um ângulo arbitrário. O uso do gate RX(θ)R_X(\theta) pode reduzir a duração e o erro de rotações de um único qubit com ângulo arbitrário em até um fator de dois. A execução direta da rotação do gate RZZ(θ)R_{ZZ}(\theta) evita a decomposição em múltiplos objetos CZGate, reduzindo igualmente a duração e o erro do circuito. Isso é especialmente útil para circuitos que contêm muitas rotações de um e dois qubits, como ao simular a dinâmica de um sistema quântico ou ao usar um ansatz variacional com muitos parâmetros.

Embora esses tipos de gates estejam na biblioteca de gates padrão que um QuantumCircuit pode conter, eles só podem ser usados em QPUs IBM Quantum específicas, e precisam ser carregados com o flag use_fractional_gates definido como True (mostrado abaixo). Esse flag garantirá que os gates fracionários sejam incluídos no Target do backend para o transpilador.

service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)

Este exemplo de código demonstra como usar gates fracionários no contexto de um fluxo de trabalho que simula a dinâmica de uma cadeia de Ising usando gates fracionários. A duração do circuito é então comparada com a de um backend que não usa gates fracionários.

Observação sobre as taxas de erro reportadas

O valor de erro reportado no Target de um backend com gates fracionários habilitados é apenas uma cópia do equivalente do gate não fracionário (que pode não ser o mesmo). Isso ocorre porque o reporte de taxas de erro nos gates fracionários ainda não é suportado.

No entanto, como o tempo de gate dos gates fracionários versus os não fracionários é o mesmo, é uma suposição razoável que suas taxas de erro sejam comparáveis — especialmente quando a principal fonte de erro num circuito é devida ao relaxamento.

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

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

Especifique dois objetos de backend: um com gates fracionários habilitados e o outro com eles desabilitados, e então transpile os dois.

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)

Exiba a linha do tempo do circuito usando os dois tipos de gates.

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

Saída da célula 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(),
)

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

Restrições de ângulo

Para o gate de dois qubits RZZ(θ)R_{ZZ}(\theta), apenas ângulos entre 00 e π/2\pi/2 podem ser executados no hardware IBM Quantum. Se um circuito contiver quaisquer gates RZZ(θ)R_{ZZ}(\theta) com um ângulo fora desse intervalo, o pipeline de transpilação padrão geralmente corrigirá isso com uma transformação de circuito adequada (por meio do passo FoldRzzAngle). No entanto, para qualquer gate RZZ(θ)R_{ZZ}(\theta) que contenha um ou mais Parameters, o transpilador assumirá que esses parâmetros receberão ângulos dentro desse intervalo em tempo de execução. O job falhará se algum dos valores de parâmetro especificados no PUB enviado ao Qiskit Runtime estiver fora desse intervalo.

Onde usar gates fracionários

Historicamente, os gates de base disponíveis nas QPUs IBM Quantum foram CZ, X, RZ, SX e ID, que não conseguem representar eficientemente circuitos com rotações de um e dois qubits que não sejam múltiplos de π/2\pi / 2. Por exemplo, um gate RX(θ)R_X(\theta), quando transpilado, deve ser decomposto em uma série de gates RZRZ e X\sqrt{X}, o que cria um circuito com dois gates de duração finita em vez de um.

Da mesma forma, quando rotações de dois qubits como um gate RZZ(θ)R_{ZZ}(\theta) são transpiladas, a decomposição requer dois gates CZ e vários gates de um único qubit, o que aumenta a profundidade do circuito. Essas decomposições são mostradas no código a seguir.

qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")

Saída da célula 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)

Saída da célula 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")

Saída da célula 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)

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

Para fluxos de trabalho que requerem muitas rotações de um único qubit RX(θ)R_X(\theta) ou de dois qubits (como em um ansatz variacional ou ao simular a evolução temporal de sistemas quânticos), essa restrição faz com que a profundidade do circuito cresça rapidamente. No entanto, os gates fracionários eliminam esse requisito, pois as rotações de um e dois qubits são executadas diretamente, criando um circuito quântico mais eficiente (e, portanto, com supressão de erros).

Quando não usar gates fracionários

É importante notar que os gates fracionários são um recurso experimental e o comportamento do flag use_fractional_gates pode mudar no futuro. Consulte as notas de lançamento para novas versões do Qiskit Runtime para mais informações. Veja também a documentação de referência da API para QiskitRuntimeService.backend, que descreve use_fractional_gates.

Além disso, o transpilador Qiskit tem capacidade limitada de usar RZZ(θ)R_{ZZ}(\theta) em seus passos de otimização. Isso exige que você tenha mais cuidado ao criar e otimizar circuitos que contenham essas instruções.

Por fim, o uso de gates fracionários não é suportado para:

Leia o guia sobre opções de primitivas para saber mais sobre como personalizar as técnicas de mitigação e supressão de erros para uma carga de trabalho quântica específica.

Próximos passos

Recomendações