Aller au contenu principal

Paramètres couramment utilisés pour la transpilation

Versions des packages

Le code de cette page a été développé avec les dépendances suivantes. Nous recommandons d'utiliser ces versions ou des versions plus récentes.

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

Cette page décrit certains des paramètres les plus couramment utilisés pour la transpilation locale. Ces paramètres sont configurés via des arguments passés à generate_preset_pass_manager ou à transpile.

Degré d'approximation

Tu peux utiliser le degré d'approximation pour indiquer à quel point tu veux que le circuit résultant corresponde au circuit souhaité (en entrée). Il s'agit d'un flottant compris dans l'intervalle (0.0 - 1.0), où 0.0 correspond à une approximation maximale et 1.0 (valeur par défaut) correspond à aucune approximation. Des valeurs plus faibles sacrifient la précision de sortie au profit de la facilité d'exécution (c'est-à-dire moins de portes). La valeur par défaut est 1.0.

Lors de la synthèse unitaire à deux qubits (utilisée dans les étapes initiales de tous les niveaux et pour l'étape d'optimisation avec le niveau 3), cette valeur spécifie la fidélité cible de la décomposition en sortie. Autrement dit, quelle quantité d'erreur est introduite lorsqu'une représentation matricielle d'un circuit est convertie en portes discrètes. Si le degré d'approximation est faible (plus d'approximation), le circuit de sortie issu de la synthèse différera davantage de la matrice d'entrée, mais aura aussi probablement moins de portes (car toute opération arbitraire à deux qubits peut être décomposée parfaitement avec au plus trois portes CX) et sera plus facile à exécuter.

Lorsque le degré d'approximation est inférieur à 1.0, des circuits avec une ou deux portes CX peuvent être synthétisés, ce qui entraîne moins d'erreurs liées au matériel, mais davantage liées à l'approximation. Étant donné que CX est la porte la plus coûteuse en termes d'erreur, il peut être avantageux de réduire leur nombre au détriment de la fidélité lors de la synthèse (cette technique a été utilisée pour augmenter le volume quantique sur les appareils IBM® : Validating quantum computers using randomized model circuits).

À titre d'exemple, nous générons un UnitaryGate aléatoire à deux qubits qui sera synthétisé lors de l'étape initiale. Définir approximation_degree à une valeur inférieure à 1.0 peut générer un circuit approximatif. Nous devons également spécifier les basis_gates pour indiquer à la méthode de synthèse quelles portes elle peut utiliser pour la synthèse approximative.

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import random_unitary
from qiskit.transpiler import generate_preset_pass_manager

UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)

qubits = QuantumRegister(2, name="q")
qc = QuantumCircuit(qubits)
qc.append(rand_U, qubits)
pass_manager = generate_preset_pass_manager(
optimization_level=1,
approximation_degree=0.85,
basis_gates=["sx", "rz", "cx"],
)
approx_qc = pass_manager.run(qc)
print(approx_qc.count_ops()["cx"])
2

Cela donne un résultat de 2 car l'approximation nécessite moins de portes CX.

Graine du générateur de nombres aléatoires

Certaines parties du transpiler sont stochastiques, de sorte que des exécutions de transpilation répétées peuvent retourner des résultats différents. Pour obtenir un résultat reproductible, tu peux définir la graine du générateur de nombres pseudoaléatoires à l'aide de l'argument seed_transpiler. Des exécutions répétées avec la même graine retourneront les mêmes résultats.

Exemple :

pass_manager = generate_preset_pass_manager(
optimization_level=1, seed_transpiler=11, basis_gates=["sx", "rz", "cx"]
)
optimized_1 = pass_manager.run(qc)
optimized_1.draw("mpl")

Output of the previous code cell

Layout initial

Avant la transpilation, les qubits contenus dans ton circuit sont des qubits virtuels qui ne correspondent pas nécessairement à des qubits physiques du backend cible. Tu peux spécifier la correspondance initiale entre qubits virtuels et qubits physiques à l'aide de l'argument initial_layout. Note que le layout final peut différer du layout initial, car le transpiler peut permuter les qubits à l'aide de portes swap ou d'autres moyens.

Dans l'exemple ci-dessous, nous construisons un layout initial pour le backend simulé FakeSherbrooke en créant un objet Layout. Notre layout associe le premier qubit de notre circuit au qubit 5 de Sherbrooke, et le second qubit de notre circuit au qubit 6 de Sherbrooke. Note que les qubits physiques sont toujours représentés par des entiers.

from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit.transpiler import Layout

backend = FakeSherbrooke()

a, b = qubits
initial_layout = Layout({a: 5, b: 6})

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Output of the previous code cell

En plus de spécifier un objet Layout, tu peux également passer une liste d'entiers, où le ii-ème élément de la liste contient le qubit physique sur lequel le ii-ème qubit doit être mappé. Par exemple :

initial_layout = [5, 6]

pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, initial_layout=initial_layout
)
transpiled_circ = pass_manager.run(qc)

transpiled_circ.draw("mpl", idle_wires=False)

Output of the previous code cell

Tu peux utiliser la fonction plot_error_map pour générer un diagramme du graphe du dispositif avec les informations d'erreur et les qubits physiques étiquetés. Tu peux également consulter des diagrammes similaires sur la page Compute resources.

from qiskit.visualization import plot_error_map

plot_error_map(backend, figsize=(30, 24))

Output of the previous code cell

Options d'étape et de plugin du transpiler

Ces options ont le suffixe _method. Elles influencent le fonctionnement du transpiler et sont utilisées pour tenter d'obtenir une sortie meilleure, différente ou spécifique de sa part.

  • init_method (str) - Le plugin à utiliser pour l'étape d'initialisation.

  • layout_method (str) - La passe de sélection du layout (trivial, dense, sabre). Il peut également s'agir du nom d'un plugin externe à utiliser pour l'étape de layout.

  • optimization_method (str) - Le plugin à utiliser pour l'étape d'optimisation.

  • routing_method (str) - Nom de la passe de routage (basic, lookahead, default, sabre, none). Il peut également s'agir du nom d'un plugin externe à utiliser pour l'étape de routage.

  • scheduling_method (str) - Nom de la passe d'ordonnancement. Il peut également s'agir du nom d'un plugin externe à utiliser pour l'étape d'ordonnancement.

    • as_soon_as_possible : Ordonnancer les instructions de manière greedy : le plus tôt possible sur une ressource qubit (alias : asap).
    • as_late_as_possible : Ordonnancer les instructions le plus tard possible. C'est-à-dire maintenir les qubits dans l'état fondamental autant que possible (alias : alap).
  • translation_method (str) - Nom de la passe de traduction (unroller, translator, synthesis). Il peut également s'agir du nom d'un plugin externe à utiliser pour l'étape de traduction.

  • unitary_synthesis_method (str) - Le nom de la méthode de synthèse unitaire à utiliser. Par défaut, default est utilisé.

remarque

Pour voir la liste de tous les plugins installés pour une étape donnée, exécute list_stage_plugins("stage_name"). Par exemple, pour voir la liste de tous les plugins installés pour l'étape de routage, exécute list_stage_plugins(routing).

Prochaines étapes