Définir le niveau d'optimisation du transpiler
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.5.1 qiskit-ibm-runtime~=0.47.0
Les dispositifs quantiques réels sont sujets au bruit et aux erreurs de porte, de sorte que l'optimisation des circuits pour réduire leur profondeur et le nombre de portes peut améliorer de manière significative les résultats obtenus lors de l'exécution de ces circuits.
La fonction generate_preset_pass_manager a un argument de position obligatoire, optimization_level, qui contrôle l'effort que le transpileur consacre à l'optimisation des circuits. Cet argument peut être un nombre entier prenant l'une des valeurs 0, 1, 2 ou 3.
Des niveaux d'optimisation plus élevés génèrent des circuits plus optimisés au prix de temps de compilation plus longs.
Le tableau suivant explique les optimisations réalisées avec chaque paramètre.
Niveau d'optimisation | Description |
|---|---|
| 0 | Pas d'optimisation : typiquement utilisé pour la caractérisation du matériel
|
| 1 | Optimisation de la lumière :
|
| 2 | Optimisation moyenne :
|
| 3 | Haute optimisation :
|
Niveau d'optimisation en action
Étant donné que les portes à deux qubits sont généralement la source d'erreurs la plus importante, nous pouvons quantifier approximativement l'"efficacité matérielle" de la transpilation en comptant le nombre de portes à deux qubits dans le circuit résultant. Ici, nous allons essayer les différents niveaux d'optimisation sur un circuit d'entrée composé d'un unitaire aléatoire suivi d'une porte SWAP.
from qiskit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import Operator, random_unitary
UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)
qc = QuantumCircuit(2)
qc.append(rand_U, range(2))
qc.swap(0, 1)
qc.draw("mpl", style="iqp")Output:
Le backend FakeSherbrooke fictif de qiskit_ibm_runtime est utilisé dans ces exemples, mais vous pouvez l'essayer sur n'importe quel backend réel ou fictif compatible avec Qiskit. Vos résultats peuvent varier.
Commençons par effectuer la transpilation avec un niveau d'optimisation de 0.
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
pass_manager = generate_preset_pass_manager(
optimization_level=0, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)Output:
Le circuit transposé comporte six portes ECR à deux qubits.
Répéter pour le niveau d'optimisation 1 :
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend = FakeSherbrooke()
pass_manager = generate_preset_pass_manager(
optimization_level=1, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)Output:
Le circuit transposé comporte toujours six portes ECR, mais le nombre de portes à qubit unique a été réduit.
Répétez l'opération pour le niveau d'optimisation 2 :
pass_manager = generate_preset_pass_manager(
optimization_level=2, backend=backend, seed_transpiler=12345
)
qc_t2_exact = pass_manager.run(qc)
qc_t2_exact.draw("mpl", idle_wires=False)Output:
Cela donne les mêmes résultats que le niveau d'optimisation 1. Notez que l'augmentation du niveau d'optimisation ne fait pas toujours la différence.
Répétez l'opération avec le niveau d'optimisation 3 :
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend, seed_transpiler=12345
)
qc_t3_exact = pass_manager.run(qc)
qc_t3_exact.draw("mpl", idle_wires=False)Output:
Aujourd'hui, il n'y a plus que trois portes ECR. Nous obtenons ce résultat parce qu'au niveau d'optimisation 3, Qiskit tente de resynthétiser des blocs de portes de deux qubits, et que toute porte de deux qubits peut être implémentée en utilisant au plus trois portes ECR. Nous pouvons obtenir encore moins de portes ECR si nous fixons approximation_degree à une valeur inférieure à 1, ce qui permet au transpilateur de faire des approximations susceptibles d'introduire une erreur dans la décomposition de la porte (voir Paramètres couramment utilisés pour la transpilation ) :
pass_manager = generate_preset_pass_manager(
optimization_level=3,
approximation_degree=0.99,
backend=backend,
seed_transpiler=12345,
)
qc_t3_approx = pass_manager.run(qc)
qc_t3_approx.draw("mpl", idle_wires=False)Output:
Ce circuit ne comporte que deux portes ECR, mais il s'agit d'un circuit approximatif. Pour comprendre en quoi son effet diffère de celui du circuit exact, nous pouvons calculer la fidélité entre l'opérateur unitaire que ce circuit met en œuvre et l'opérateur unitaire exact. Avant d'effectuer le calcul, nous réduisons d'abord le circuit transpilé, qui contient 127 qubits, à un circuit qui ne contient que les qubits actifs, qui sont au nombre de deux.
import numpy as np
def trace_to_fidelity_2q(trace: float) -> float:
return (4.0 + trace * trace.conjugate()) / 20.0
# Reduce circuits down to 2 qubits so they are easy to simulate
qc_t3_exact_small = QuantumCircuit.from_instructions(qc_t3_exact)
qc_t3_approx_small = QuantumCircuit.from_instructions(qc_t3_approx)
# Compute the fidelity
exact_fid = trace_to_fidelity_2q(
np.trace(np.dot(Operator(qc_t3_exact_small).adjoint().data, UU))
)
approx_fid = trace_to_fidelity_2q(
np.trace(np.dot(Operator(qc_t3_approx_small).adjoint().data, UU))
)
print(
f"Synthesis fidelity\nExact: {exact_fid:.3f}\nApproximate: {approx_fid:.3f}"
)Output:
Synthesis fidelity
Exact: 1.000+0.000j
Approximate: 0.992+0.000j
Le réglage du niveau d'optimisation peut également modifier d'autres aspects du circuit, et pas seulement le nombre de portes ECR. Pour voir des exemples illustrant comment la modification du niveau d'optimisation influe sur la disposition, consultez la section « Représentation des ordinateurs quantiques ».
Etapes suivantes
- Pour en savoir plus sur la fonction
generate_preset_passmanager, commencez par la rubrique Paramètres par défaut et options de configuration de la transpilation. - Poursuivez votre apprentissage de la transpilation avec le thème des étapes de la transpilation.
- Consultez le guide Comparer les paramètres du transpiler.
- Essayez le tutoriel Construire des codes de répétition.
- Consultez la documentation de l'API Transpile.