Gates fracionários
Versões de pacotes
O código nesta página foi desenvolvido usando os seguintes requisitos. Recomendamos usar essas versões ou mais recentes.
qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0
Esta página apresenta dois novos tipos de Gate com suporte na frota de QPUs do IBM Quantum®. Esses Gates fracionários têm suporte em QPUs Heron na forma de:
- 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 — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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_name = service.least_busy(operational=True, simulator=False).name
backend_fractional = service.backend(backend_name, use_fractional_gates=True)
backend_conventional = service.backend(
backend_name, 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 IBM Quantum Compute Service 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.least_busy(operational=True, simulator=False)
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.least_busy(operational=True, simulator=False)
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 exigem muitas rotações de qubit único ou rotações 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 removem esse requisito, porque 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 de qiskit-ibm-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:
- 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.
Quais backends suportam gates fracionários?
Nem todos os backends suportam gates fracionários. Execute service.backends(use_fractional_gates=True) para encontrar os que suportam. Com o lançamento do qiskit-ibm-runtime v0.48, você também pode executar service.least_busy(fractional_gates=True) para encontrar o backend menos ocupado que suporta gates fracionários. Um backend fake suporta gates fracionários apenas se o backend "real" relacionado os suportar.
Observe que os backends fake não suportam gates fracionários por padrão, já que os gates fracionários são desabilitados por padrão. Para habilitar gates fracionários em um backend fake que os suporte, atualize sua configuração.
Example:
service = QiskitRuntimeService()
fake_backend = FakeBoston()
fake_backend.refresh(service=service, use_fractional_gates=True)
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.