Portes fractionnaires
Le code de cette page a été développé en tenant compte des exigences suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.
qiskit[all]~=2.3.1 qiskit-ibm-runtime~=0.45.1
Cette page présente deux nouveaux types de portes pris en charge sur la flotte de QPU IBM Quantum®. Ces portes fractionnaires sont prises en charge par les QPU Heron sous la forme de :
- pour
- pour tout
Cette page présente les cas d'utilisation où la mise en œuvre de portes fractionnaires peut améliorer l'efficacité de vos flux de travail, ainsi que la manière d'utiliser ces portes sur les QPU Quantum à l'adresse IBM.
Comment utiliser les portes fractionnaires
En interne, ces portes fractionnaires fonctionnent en exécutant directement une rotation d' s et d' s pour un angle arbitraire. L'utilisation de la porte peut réduire jusqu'à deux fois la durée et l'erreur des rotations d'un seul qubit à angle arbitraire. L'exécution directe de la rotation de porte d' s évite la décomposition en plusieurs CZGate objets, réduisant ainsi la durée et l'erreur d'un circuit. Cela est particulièrement utile pour les circuits qui contiennent de nombreuses rotations à un ou deux qubits, par exemple lors de la simulation de la dynamique d'un système quantique ou lors de l'utilisation d'une approche variationnelle avec de nombreux paramètres.
Bien que ces types de portes fassent partie de la bibliothèque de portes standard dont un utilisateur QuantumCircuit peut disposer, elles ne peuvent être utilisées que sur certaines QPU d' IBM Quantum, et doivent être chargées avec l'indicateur use_fractional_gates défini sur True (comme indiqué ci-dessous). Cet indicateur garantit que les portes fractionnaires sont incluses dans le backend Target du transcompilateur.
service = QiskitRuntimeService()
backend = service.backend('ibm_torino', use_fractional_gates=True)Cet exemple de code montre comment utiliser les portes fractionnaires dans le contexte d'un flux de travail qui simule la dynamique d'une chaîne d'Ising à l'aide de portes fractionnaires. La durée du circuit est ensuite comparée à celle d'un backend qui n'utilise pas de portes fractionnaires.
La valeur d'erreur signalée dans le site Target d'un backend dont les portes fractionnaires sont activées n'est qu'une copie de la contrepartie de la porte non fractionnaire (qui peut ne pas être la même). En effet, la déclaration des taux d'erreur sur les portes fractionnaires n'est pas encore prise en charge.
Toutefois, étant donné que le temps de grille des portes fractionnaires et non fractionnaires est le même, on peut raisonnablement supposer que leurs taux d'erreur sont comparables, en particulier lorsque la source d'erreur dominante dans un circuit est due à la relaxation.
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")Output:
Spécifiez deux objets backend : l'un avec les portes fractionnaires activées, l'autre avec les portes désactivées, puis transpilez-les tous les deux.
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)Affichez la chronologie du circuit utilisant les deux types de portes.
# 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(),
)Output:
# 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(),
)Output:
Contraintes angulaires
Pour la porte « » à deux qubits, seuls les angles compris entre et peuvent être mis en œuvre sur le matériel IBM Quantum. Si un circuit contient des portes de type « » dont l'angle se situe en dehors de cette plage, le pipeline de transpilation standard corrigera généralement ce problème à l'aide d'une transformation de circuit appropriée (via le pass FoldRzzAngle ). Toutefois, pour toute porte « » contenant un ou plusieurs « Parameters », le transpileur supposera que ces paramètres se verront attribuer des angles compris dans cette plage lors de l'exécution. La tâche échouera si l'une des valeurs des paramètres spécifiés dans l' PUB e transmise au service de calcul IBM Quantum se situe en dehors de cette plage.
Où utiliser les portes fractionnaires
Historiquement, les portes de base disponibles sur les QPU Quantum de IBM sont les suivantes CZ, X, RZ, SX, et **ID**qui ne peuvent pas représenter efficacement les circuits avec des rotations à un ou deux qubits qui ne sont pas des multiples de . Par exemple, une porte , lorsqu'elle est transposée, doit se décomposer en une série de portes et , ce qui crée un circuit avec deux portes de durée finie au lieu d'une.
De même, lorsque des rotations à deux qubits telles qu'une porte sont transposées, la décomposition nécessite deux portes et plusieurs portes à un qubit, ce qui augmente la profondeur du circuit CZ portes et plusieurs portes à qubit unique, ce qui augmente la profondeur du circuit. Ces décompositions sont présentées dans le code suivant.
qc = QuantumCircuit(1)
param = Parameter("θ")
qc.rx(param, 0)
qc.draw("mpl")Output:
# 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)Output:
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")Output:
# 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)Output:
Pour les flux de travail qui nécessitent de nombreuses rotations d'un seul qubit ou de deux qubits (comme dans un ansatz variationnel ou lors de la simulation de l'évolution temporelle de systèmes quantiques), cette contrainte entraîne une croissance rapide de la profondeur du circuit. Cependant, les portes fractionnaires suppriment cette exigence, car les rotations à un ou deux qubits sont exécutées directement, et créent un circuit quantique plus efficace (et donc exempt d'erreurs).
Quand ne pas utiliser les portes fractionnaires
Il est important de noter que les portes fractionnaires constituent une fonctionnalité expérimentale et que le comportement de cet use_fractional_gates indicateur pourrait évoluer à l'avenir. Pour qiskit-ibm-runtime plus d'informations, consultez les notes de mise à jour des nouvelles versions de [nom du logiciel]. Consultez également la documentation de référence de l'API pour QiskitRuntimeService.backend, qui décrit use_fractional_gates.
En outre, le transpondeur Qiskit a une capacité limitée à utiliser dans ses passes d'optimisation. Cela vous oblige à être plus prudent dans la conception et l'optimisation des circuits qui contiennent ces instructions.
Enfin, l'utilisation de portes fractionnaires n'est pas prise en charge :
- Tourbillon de Pauli - toutefois, le tourbillon de mesure avec TREX est pris en charge.
- Annulation probabiliste des erreurs
- Extrapolation à bruit nul (par amplification probabiliste de l'erreur)
Lisez le guide sur les options primitives pour en savoir plus sur la personnalisation des techniques d'atténuation et de suppression des erreurs pour une charge de travail quantique donnée.
Quels backends prennent en charge les portes fractionnaires?
Tous les backends ne prennent pas en charge les portes fractionnaires. Cours service.backends(use_fractional_gates=True) pour trouver ceux qui le font. Avec la sortie de v0.48qiskit-ibm-runtime , vous pouvez également exécuter cette commande pour service.least_busy(fractional_gates=True) trouver le backend le moins sollicité qui prend en charge les portes fractionnaires. Un backend fictif ne prend en charge les portes fractionnaires que si le « véritable » backend correspondant les prend en charge.
Notez que les backends fictifs ne prennent pas en charge les portes fractionnaires par défaut, car celles-ci sont désactivées par défaut. Pour activer les portes fractionnaires sur un backend fictif qui les prend en charge, actualisez sa configuration.
Exemple :
service = QiskitRuntimeService()
fake_backend = FakeBoston()
fake_backend.refresh(service=service, use_fractional_gates=True)Etapes suivantes
- Pour en savoir plus sur la transpilation, voir la page d' introduction à la transpilation.
- En savoir plus sur l' écriture d'une passe de transpilation personnalisée.
- Comprendre comment configurer la prévention des erreurs.