Skip to main content
IBM Quantum Platform

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 :

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

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' RZZ(θ)R_{ZZ}(\theta) s et d' RX(θ)R_X(\theta) s pour un angle arbitraire. L'utilisation de la porte RX(θ)R_X(\theta) 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' RZZ(θ)R_{ZZ}(\theta) 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.

Note sur les taux d'erreur déclarés

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:

Output of the previous code cell

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:

Output of the previous code cell
# 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:

Output of the previous code cell

Contraintes angulaires

Pour la porte « RZZ(θ)R_{ZZ}(\theta) » à deux qubits, seuls les angles compris entre 00 et π/2\pi/2 peuvent être mis en œuvre sur le matériel IBM Quantum. Si un circuit contient des portes de type « RZZ(θ)R_{ZZ}(\theta) » 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 « RZZ(θ)R_{ZZ}(\theta) » 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 π/2\pi / 2. Par exemple, une porte RX(θ)R_X(\theta), lorsqu'elle est transposée, doit se décomposer en une série de portes RZRZ et X\sqrt{X}, 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 RZZ(θ)R_{ZZ}(\theta) 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:

Output of the previous code cell
# 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:

Output of the previous code cell
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:

Output of the previous code cell
# 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:

Output of the previous code cell

Pour les flux de travail qui nécessitent de nombreuses rotations d'un seul qubit RX(θ)R_X(\theta) 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 RZZ(θ)R_{ZZ}(\theta) 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 :

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

Recommandations
Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.