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:
- para
- para qualquer
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 e para um ângulo arbitrário. O uso do gate 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 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.
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")
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(),
)
# 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(),
)
Restrições de ângulo
Para o gate de dois qubits , apenas ângulos entre e podem ser executados no hardware IBM Quantum. Se um circuito contiver quaisquer gates 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 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 . Por exemplo, um gate , quando transpilado, deve ser decomposto em uma série de gates e , 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 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")
# 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 fluxos de trabalho que requerem muitas rotações de um único qubit 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 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:
- Circuitos dinâmicos
- Pauli twirling — no entanto, o measurement twirling com TREX é suportado.
- Cancelamento probabilístico de erros
- Extrapolação de ruído zero (usando amplificação probabilística de erros)
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
- Para saber mais sobre transpilação, veja a página de introdução à transpilação.
- Leia sobre como escrever um passo de transpilador personalizado.
- Entenda como configurar a mitigação de erros para o Qiskit Runtime.