Introduction au service de transpilation Qiskit alimenté par l'IA
Utilisation estimée du QPU : aucune (REMARQUE : ce tutoriel n'exécute pas de tâches car il est axé sur la transpilation)
Contexte
Le service de transpilation Qiskit alimenté par l'IA (QTS) introduit des optimisations basées sur l'apprentissage automatique dans les passes de routage et de synthèse. Ces modes IA ont été conçus pour surmonter les limites de la transpilation traditionnelle, en particulier pour les circuits à grande échelle et les topologies matérielles complexes.
Depuis juillet 2025, le Transpiler Service a été migré vers la nouvelle plateforme IBM Quantum® et n'est plus disponible. Pour les dernières mises à jour concernant le statut du Transpiler Service, veuillez consulter la documentation du service de transpilation. Vous pouvez toujours utiliser le transpileur IA localement, de manière similaire à la transpilation standard de Qiskit. Remplacez simplement generate_preset_pass_manager() par generate_ai_pass_manager(). Cette fonction construit un gestionnaire de passes qui intègre les passes de routage et de synthèse alimentées par l'IA directement dans votre flux de transpilation local.
Fonctionnalités clés des passes IA
-
Passes de routage : le routage alimenté par l'IA peut ajuster dynamiquement les chemins des qubits en fonction du circuit et du backend spécifiques, réduisant le besoin de portes SWAP excessives.
AIRouting: sélection de la disposition et routage du circuit
-
Passes de synthèse : les techniques d'IA optimisent la décomposition des portes multi-qubits, minimisant le nombre de portes à deux qubits, qui sont généralement plus sujettes aux erreurs.
AICliffordSynthesis: synthèse de portes CliffordAILinearFunctionSynthesis: synthèse de circuits à fonction linéaireAIPermutationSynthesis: synthèse de circuits de permutationAIPauliNetworkSynthesis: synthèse de circuits de réseau de Pauli (disponible uniquement dans le Qiskit Transpiler Service, pas en environnement local)
-
Comparaison avec la transpilation traditionnelle : le transpileur standard de Qiskit est un outil robuste capable de traiter efficacement un large éventail de circuits quantiques. Cependant, lorsque les circuits augmentent en taille ou que les configurations matérielles deviennent plus complexes, les passes IA peuvent apporter des gains d'optimisation supplémentaires. En utilisant des modèles appris pour le routage et la synthèse, le QTS affine davantage les dispositions des circuits et réduit la surcharge pour les tâches quantiques complexes ou à grande échelle.
Ce tutoriel évalue les modes IA en utilisant à la fois les passes de routage et de synthèse, en comparant les résultats à la transpilation traditionnelle afin de mettre en évidence les gains de performance offerts par l'IA.
Pour plus de détails sur les passes IA disponibles, consultez la documentation des passes IA.
Pourquoi utiliser l'IA pour la transpilation de circuits quantiques ?
À mesure que les circuits quantiques augmentent en taille et en complexité, les méthodes de transpilation traditionnelles peinent à optimiser les dispositions et à réduire efficacement le nombre de portes. Les circuits plus grands, en particulier ceux impliquant des centaines de qubits, imposent des défis significatifs au routage et à la synthèse en raison des contraintes des dispositifs, de la connectivité limitée et des taux d'erreur des qubits.
C'est là que la transpilation alimentée par l'IA offre une solution potentielle. En exploitant les techniques d'apprentissage automatique, le transpileur alimenté par l'IA de Qiskit peut prendre des décisions plus intelligentes concernant le routage des qubits et la synthèse des portes, conduisant à une meilleure optimisation des circuits quantiques à grande échelle.
Résultats de benchmarking en bref

Dans les tests de benchmarking, le transpileur IA a systématiquement produit des circuits moins profonds et de meilleure qualité par rapport au transpileur standard de Qiskit. Pour ces tests, nous avons utilisé la stratégie par défaut du gestionnaire de passes de Qiskit, configurée avec [generate_preset_passmanager]. Bien que cette stratégie par défaut soit souvent efficace, elle peut rencontrer des difficultés avec des circuits plus grands ou plus complexes. En revanche, les passes alimentées par l'IA ont obtenu une réduction moyenne de 24 % du nombre de portes à deux qubits et une réduction de 36 % de la profondeur du circuit pour les grands circuits (plus de 100 qubits) lors de la transpilation vers la topologie heavy-hex du matériel IBM Quantum. Pour plus d'informations sur ces benchmarks, consultez ce blog.
Ce tutoriel explore les principaux avantages des passes IA et comment elles se comparent aux méthodes traditionnelles.
# Added by doQumentation — installs packages not in the Binder environment
%pip install -q qiskit-ibm-transpiler
# This cell is hidden from users;
# it just disables a linting rule.
# ruff: noqa: F811
Prérequis
Avant de commencer ce tutoriel, assurez-vous que les éléments suivants sont installés :
- Qiskit SDK v1.0 ou ultérieur, avec le support de visualisation
- Qiskit Runtime (
pip install qiskit-ibm-runtime) v0.22 ou ultérieur - Qiskit IBM® Transpiler avec le mode local IA (
pip install 'qiskit-ibm-transpiler[ai-local-mode]')
Configuration
from qiskit import QuantumCircuit
from qiskit.circuit.library import efficient_su2, PermutationGate
from qiskit.synthesis.qft import synth_qft_full
from qiskit.circuit.random import random_circuit, random_clifford_circuit
from qiskit.transpiler import generate_preset_pass_manager, CouplingMap
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_transpiler import generate_ai_pass_manager
from qiskit.synthesis.permutation import (
synth_permutation_depth_lnn_kms,
synth_permutation_basic,
)
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import time
import logging
seed = 42
# Used for generating permutation circuits in part two for comparison
def generate_permutation_circuit(width, pattern):
circuit = QuantumCircuit(width)
circuit.append(
PermutationGate(pattern=pattern),
qargs=range(width),
)
return circuit
# Creates a Bernstein-Vazirani circuit given the number of qubits
def create_bv_circuit(num_qubits):
qc = QuantumCircuit(num_qubits, num_qubits - 1)
qc.x(num_qubits - 1)
qc.h(qc.qubits)
for i in range(num_qubits - 1):
qc.cx(i, num_qubits - 1)
qc.h(qc.qubits[:-1])
return qc
# Transpile a circuit with a given pass manager and return metrics
def transpile_with_metrics(pass_manager, circuit):
start = time.time()
qc_out = pass_manager.run(circuit)
elapsed = time.time() - start
depth_2q = qc_out.depth(lambda x: x.operation.num_qubits == 2)
gate_count = qc_out.size()
return qc_out, {
"depth_2q": depth_2q,
"gate_count": gate_count,
"time_s": elapsed,
}
# Used for collecting metrics for part 3 of synthesis methods
def synth_transpile_with_metrics(qc, pm, pattern_id, method):
start = time.time()
qc = pm.run(qc)
elapsed = time.time() - start
return {
"Pattern": pattern_id,
"Method": method,
"Depth (2Q)": qc.depth(lambda x: x.operation.num_qubits == 2),
"Gates": qc.size(),
"Time (s)": elapsed,
}
# Ignore logs like "INFO:qiskit_ibm_transpiler.wrappers.ai_local_synthesis:Running Linear Functions AI synthesis on local mode"
logging.getLogger(
"qiskit_ibm_transpiler.wrappers.ai_local_synthesis"
).setLevel(logging.WARNING)
Partie I. Patterns Qiskit
Voyons maintenant comment utiliser le service de transpilation IA avec un circuit quantique simple, en utilisant les patterns Qiskit. L'essentiel est de créer un PassManager avec generate_ai_pass_manager() au lieu du generate_preset_pass_manager() standard.
Étape 1 : Mapper les entrées classiques vers un problème quantique
Dans cette section, nous testerons le transpileur IA sur le circuit efficient_su2, un ansatz efficace en matériel largement utilisé. Ce circuit est particulièrement pertinent pour les algorithmes quantiques variationnels (par exemple, VQE) et les tâches d'apprentissage automatique quantique, ce qui en fait un cas de test idéal pour évaluer les performances de transpilation.
Le circuit efficient_su2 se compose de couches alternées de rotations mono-qubit et de portes d'intrication comme les CNOT. Ces couches permettent une exploration flexible de l'espace d'états quantiques tout en maintenant une profondeur de portes gérable. En optimisant ce circuit, nous visons à réduire le nombre de portes, améliorer la fidélité et minimiser le bruit. Cela en fait un candidat idéal pour tester l'efficacité du transpileur IA.
# For our transpilation, we will use a large circuit of 101 qubits
qc = efficient_su2(90, entanglement="circular", reps=1).decompose()
# Draw a smaller version of the circuit to get a visual representation
qc_small = efficient_su2(5, entanglement="circular", reps=1).decompose()
qc_small.draw(output="mpl")
Étape 2 : Optimiser le problème pour l'exécution sur matériel quantique
Choisir un backend
Pour cet exemple, nous sélectionnons le backend IBM Quantum opérationnel le moins occupé qui n'est pas un simulateur et possède au moins 100 qubits :
Remarque : Comme le backend le moins occupé peut changer au fil du temps, différents dispositifs peuvent être sélectionnés pour différentes exécutions. Les propriétés spécifiques aux dispositifs, telles que les cartes de couplage, peuvent entraîner des différences dans les circuits transpilés.
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=100
)
cm = backend.coupling_map
print(f"Using backend: {backend.name}")
Using backend: ibm_torino
Créer les gestionnaires de passes IA et traditionnel
Pour évaluer l'efficacité du transpileur IA, nous effectuerons deux exécutions de transpilation. Premièrement, nous transpilerons le circuit en utilisant le transpileur IA. Ensuite, nous effectuerons une comparaison en transpilant le même circuit sans le transpileur IA, en utilisant les méthodes traditionnelles. Les deux processus de transpilation utiliseront la même carte de couplage du backend choisi et le niveau d'optimisation défini à 3 pour une comparaison équitable.
Ces deux méthodes reflètent l'approche standard pour créer des instances de PassManager afin de transpiler des circuits dans Qiskit.
pm_ai = generate_ai_pass_manager(
optimization_level=3,
ai_optimization_level=3,
coupling_map=cm,
include_ai_synthesis=True, # used for part 3 when comparing synthesis methods
)
pm_no_ai = generate_preset_pass_manager(
optimization_level=3,
coupling_map=cm,
seed_transpiler=seed, # note that the AI pass manager does not currently support seeding
)
Transpilez les circuits et enregistrez les temps.
# Transpile using standard (non-AI) pass manager
_, metrics_no_ai = transpile_with_metrics(pm_no_ai, qc)
print(
f"Standard transpilation: Depth (2q) {metrics_no_ai['depth_2q']}, "
f"Gate count {metrics_no_ai['gate_count']}, Time {metrics_no_ai['time_s']}"
)
# Transpile using AI pass manager
_, metrics_ai = transpile_with_metrics(pm_ai, qc)
print(
f"AI transpilation : Depth (2q) {metrics_ai['depth_2q']}, "
f"Gate count {metrics_ai['gate_count']}, Time {metrics_ai['time_s']}"
)
Standard transpilation: Depth (2q) 95, Gate count 458, Time 0.04650712013244629
AI transpilation : Depth (2q) 90, Gate count 456, Time 0.9342479705810547
Dans ce test, nous comparons les performances du transpileur IA et de la méthode de transpilation standard sur le circuit efficient_su2. Le transpileur IA obtient une profondeur de circuit notablement plus faible tout en maintenant un nombre de portes similaire.
-
Profondeur du circuit : Le transpileur IA produit un circuit avec une profondeur à deux qubits plus faible. Cela est attendu, car les passes IA sont entraînées pour optimiser la profondeur en apprenant les schémas d'interaction entre qubits et en exploitant la connectivité matérielle plus efficacement que les heuristiques basées sur des règles.
-
Nombre de portes : Le nombre total de portes reste similaire entre les deux méthodes. Cela correspond aux attentes puisque la transpilation standard basée sur SABRE minimise explicitement le nombre de swaps, qui domine la surcharge en portes. Le transpileur IA, en revanche, privilégie la profondeur globale et peut occasionnellement échanger quelques portes supplémentaires contre un chemin d'exécution plus court.
-
Temps de transpilation : Le transpileur IA prend plus de temps à s'exécuter que la méthode standard. Cela est dû au coût computationnel supplémentaire de l'invocation des modèles appris lors du routage et de la synthèse. En revanche, le transpileur basé sur SABRE est désormais significativement plus rapide après avoir été réécrit et optimisé en Rust, offrant un routage heuristique hautement efficace à grande échelle.
Il est important de noter que ces résultats sont basés sur un seul circuit. Pour obtenir une compréhension complète de la façon dont le transpileur IA se compare aux méthodes traditionnelles, il est nécessaire de tester une variété de circuits. Les performances du QTS peuvent varier considérablement en fonction du type de circuit optimisé. Pour une comparaison plus large, consultez les benchmarks ci-dessus ou visitez le blog.
Étape 3 : Exécuter en utilisant les primitives Qiskit
Comme ce tutoriel se concentre sur la transpilation, aucune expérience ne sera exécutée sur le dispositif quantique. L'objectif est de tirer parti des optimisations de l'étape 2 pour obtenir un circuit transpilé avec une profondeur ou un nombre de portes réduit.
Étape 4 : Post-traiter et retourner le résultat dans le format classique souhaité
Puisqu'il n'y a pas d'exécution pour ce notebook, il n'y a pas de résultats à post-traiter.
Partie II. Analyser et évaluer les circuits transpilés
Dans cette section, nous montrerons comment analyser le circuit transpilé et le comparer de manière plus détaillée à la version originale. Nous nous concentrerons sur des métriques telles que la profondeur du circuit, le nombre de portes et le temps de transpilation pour évaluer l'efficacité de l'optimisation. De plus, nous discuterons de la façon dont les résultats peuvent différer selon les types de circuits, offrant des perspectives sur les performances plus larges du transpileur dans différents scénarios.
# Circuits to benchmark
seed = 42
circuits = [
{
"name": "Random",
"qc": random_circuit(num_qubits=30, depth=10, seed=seed),
},
{
"name": "Clifford",
"qc": random_clifford_circuit(
num_qubits=40, num_gates=200, seed=seed
),
},
{
"name": "QFT",
"qc": synth_qft_full(num_qubits=20, do_swaps=False).decompose(),
},
{
"name": "BV",
"qc": create_bv_circuit(40),
},
]
results = []
# Run the transpilation for each circuit and store the results
for circuit in circuits:
qc_no_ai, metrics_no_ai = transpile_with_metrics(pm_no_ai, circuit["qc"])
qc_ai, metrics_ai = transpile_with_metrics(pm_ai, circuit["qc"])
print("Completed transpilation for", circuit["name"])
results.append(
{
"Circuit": circuit["name"],
"Depth 2Q (No AI)": metrics_no_ai["depth_2q"],
"Gate Count (No AI)": metrics_no_ai["gate_count"],
"Time (No AI)": metrics_no_ai["time_s"],
"Depth 2Q (AI)": metrics_ai["depth_2q"],
"Gate Count (AI)": metrics_ai["gate_count"],
"Time (AI)": metrics_ai["time_s"],
}
)
df = pd.DataFrame(results)
df
Completed transpilation for Random
Completed transpilation for Clifford
Completed transpilation for QFT
Completed transpilation for BV
Circuit Depth 2Q (No AI) Gate Count (No AI) Time (No AI) \
0 Random 37 221 0.039347
1 Clifford 36 232 0.036633
2 QFT 165 924 0.077458
3 BV 65 155 0.024993
Depth 2Q (AI) Gate Count (AI) Time (AI)
0 24 181 0.773718
1 43 267 1.097431
2 130 913 3.660771
3 70 155 0.345522
Réduction moyenne en pourcentage pour chaque métrique. Les valeurs positives représentent des améliorations, les négatives des dégradations.
# Average reduction from non-AI to AI transpilation as a percentage
avg_reduction_depth = (
(df["Depth 2Q (No AI)"] - df["Depth 2Q (AI)"]).mean()
/ df["Depth 2Q (No AI)"].mean()
* 100
)
avg_reduction_gates = (
(df["Gate Count (No AI)"] - df["Gate Count (AI)"]).mean()
/ df["Gate Count (No AI)"].mean()
* 100
)
avg_reduction_time = (
(df["Time (No AI)"] - df["Time (AI)"]).mean()
/ df["Time (No AI)"].mean()
* 100
)
print(f"Average reduction in depth: {avg_reduction_depth:.2f}%")
print(f"Average reduction in gate count: {avg_reduction_gates:.2f}%")
print(f"Average reduction in transpilation time: {avg_reduction_time:.2f}%")
Average reduction in depth: 11.88%
Average reduction in gate count: 1.04%
Average reduction in transpilation time: -3193.95%
fig, axs = plt.subplots(1, 3, figsize=(21, 6))
df.plot(
x="Circuit",
y=["Depth 2Q (No AI)", "Depth 2Q (AI)"],
kind="bar",
ax=axs[0],
)
axs[0].set_title("Circuit Depth Comparison")
axs[0].set_ylabel("Depth")
axs[0].set_xlabel("Circuit")
axs[0].tick_params(axis="x", rotation=45)
df.plot(
x="Circuit",
y=["Gate Count (No AI)", "Gate Count (AI)"],
kind="bar",
ax=axs[1],
)
axs[1].set_title("Gate Count Comparison")
axs[1].set_ylabel("Gate Count")
axs[1].set_xlabel("Circuit")
axs[1].tick_params(axis="x", rotation=45)
df.plot(x="Circuit", y=["Time (No AI)", "Time (AI)"], kind="bar", ax=axs[2])
axs[2].set_title("Time Comparison")
axs[2].set_ylabel("Time (seconds)")
axs[2].set_xlabel("Circuit")
axs[2].tick_params(axis="x", rotation=45)
fig.suptitle(
"Benchmarking AI transpilation vs Non-AI transpilation for various circuits"
)
plt.tight_layout()
plt.show()

Les performances du transpileur IA varient considérablement en fonction du type de circuit optimisé. Dans certains cas, il obtient des réductions notables de la profondeur du circuit et du nombre de portes par rapport au transpileur standard. Cependant, ces améliorations s'accompagnent souvent d'une augmentation substantielle du temps d'exécution.
Pour certains types de circuits, le transpileur IA peut donner des résultats légèrement meilleurs en termes de profondeur du circuit, mais peut aussi entraîner une augmentation du nombre de portes et une pénalité significative en temps d'exécution. Ces observations suggèrent que les avantages du transpileur IA ne sont pas uniformes pour tous les types de circuits. Au contraire, son efficacité dépend des caractéristiques spécifiques du circuit, le rendant plus adapté à certains cas d'utilisation qu'à d'autres.
Quand les utilisateurs devraient-ils choisir la transpilation alimentée par l'IA ?
Le transpileur alimenté par l'IA de Qiskit excelle dans les scénarios où les méthodes de transpilation traditionnelles rencontrent des difficultés, en particulier avec les circuits quantiques à grande échelle et complexes. Pour les circuits impliquant des centaines de qubits ou ceux ciblant du matériel avec des cartes de couplage complexes, le transpileur IA offre une optimisation supérieure en termes de profondeur du circuit, de nombre de portes et d'efficacité du temps d'exécution. Dans les tests de benchmarking, il a systématiquement surpassé les méthodes traditionnelles, produisant des circuits significativement moins profonds et réduisant le nombre de portes, ce qui est essentiel pour améliorer les performances et atténuer le bruit sur du matériel quantique réel.
Les utilisateurs devraient envisager la transpilation alimentée par l'IA lorsqu'ils travaillent avec :
- Des circuits de grande taille où les méthodes traditionnelles ne parviennent pas à gérer efficacement l'échelle.
- Des topologies matérielles complexes où des défis de connectivité et de routage des dispositifs se posent.
- Des applications sensibles aux performances où la réduction de la profondeur du circuit et l'amélioration de la fidélité sont primordiales.
Partie III. Explorer la synthèse de réseaux de permutation alimentée par l'IA
Les réseaux de permutation sont fondamentaux en informatique quantique, en particulier pour les systèmes contraints par des topologies restreintes. Ces réseaux facilitent les interactions à longue portée en échangeant dynamiquement les qubits pour imiter une connectivité tout-à-tout sur du matériel à connectivité limitée. De telles transformations sont essentielles pour implémenter des algorithmes quantiques complexes sur les dispositifs à court terme, où les interactions s'étendent souvent au-delà des voisins les plus proches.
Dans cette section, nous mettons en évidence la synthèse de réseaux de permutation comme un cas d'utilisation convaincant du transpileur alimenté par l'IA de Qiskit. Plus précisément, la passe AIPermutationSynthesis exploite l'optimisation pilotée par l'IA pour générer des circuits efficaces pour les tâches de permutation de qubits. En revanche, les approches de synthèse génériques peinent souvent à équilibrer le nombre de portes et la profondeur du circuit, en particulier dans les scénarios avec des interactions denses entre qubits ou lors de tentatives d'atteindre une connectivité complète.
Nous allons parcourir un exemple de patterns Qiskit présentant la synthèse d'un réseau de permutation pour obtenir une connectivité tout-à-tout pour un ensemble de qubits. Nous comparerons les performances de AIPermutationSynthesis aux méthodes de synthèse standard de Qiskit. Cet exemple démontrera comment le transpileur IA optimise pour une profondeur de circuit et un nombre de portes plus faibles, mettant en évidence ses avantages dans les flux de travail quantiques pratiques. Pour activer la passe de synthèse IA, nous utiliserons la fonction generate_ai_pass_manager() avec le paramètre include_ai_synthesis défini sur True.
Étape 1 : Mapper les entrées classiques vers un problème quantique
Pour représenter un problème de permutation classique sur un ordinateur quantique, nous commençons par définir la structure des circuits quantiques. Pour cet exemple :
-
Initialisation du circuit quantique : Nous allouons 27 qubits pour correspondre au backend que nous utiliserons, qui possède 27 qubits.
-
Application des permutations : Nous générons dix motifs de permutation aléatoires (
pattern_1àpattern_10) en utilisant une graine fixe pour la reproductibilité. Chaque motif de permutation est appliqué à un circuit quantique distinct (qc_1àqc_10). -
Décomposition du circuit : Chaque opération de permutation est décomposée en ensembles de portes natifs compatibles avec le matériel quantique cible. Nous analysons la profondeur et le nombre de portes à deux qubits (portes non locales) pour chaque circuit décomposé.
Les résultats fournissent un aperçu de la complexité de la représentation des problèmes de permutation classiques sur un dispositif quantique, démontrant les besoins en ressources pour différents motifs de permutation.
# Parameters
width = 27
num_circuits = 10
# Set random seed
np.random.seed(seed)
# Generate random patterns and circuits
patterns = [
np.random.permutation(width).tolist() for _ in range(num_circuits)
]
circuits = {
f"qc_{i}": generate_permutation_circuit(width, pattern)
for i, pattern in enumerate(patterns, start=1)
}
# Display one of the circuits
circuits["qc_1"].decompose(reps=3).draw(output="mpl", fold=-1)

Étape 2 : Optimiser le problème pour l'exécution sur matériel quantique
Dans cette étape, nous procédons à l'optimisation en utilisant les passes de synthèse IA.
Pour les passes de synthèse IA, le PassManager ne nécessite que la carte de couplage du backend. Cependant, il est important de noter que toutes les cartes de couplage ne sont pas compatibles ; seules celles sur lesquelles la passe AIPermutationSynthesis a été entraînée fonctionneront. Actuellement, la passe AIPermutationSynthesis prend en charge des blocs de tailles 65, 33 et 27 qubits. Pour cet exemple, nous utilisons un QPU de 27 qubits.
Pour comparaison, nous évaluerons les performances de la synthèse IA par rapport aux méthodes de synthèse de permutation génériques de Qiskit, notamment :
-
synth_permutation_depth_lnn_kms: cette méthode synthétise un circuit de permutation pour une architecture linéaire au plus proche voisin (LNN) en utilisant l'algorithme de Kutin, Moulton et Smithline (KMS). Elle garantit un circuit avec une profondeur d'au plus et une taille d'au plus , où la profondeur et la taille sont mesurées en termes de portes SWAP. -
synth_permutation_basic: il s'agit d'une implémentation directe qui synthétise les circuits de permutation sans imposer de contraintes de connectivité ni d'optimisation pour des architectures spécifiques. Elle sert de référence pour comparer les performances avec des méthodes plus avancées.
Chacune de ces méthodes représente une approche distincte de la synthèse de réseaux de permutation, fournissant un benchmark complet par rapport aux méthodes alimentées par l'IA.
Pour plus de détails sur les méthodes de synthèse dans Qiskit, consultez la documentation de l'API Qiskit. Définissez la carte de couplage représentant le QPU de 27 qubits.
coupling_map = [
[1, 0],
[2, 1],
[3, 2],
[3, 5],
[4, 1],
[6, 7],
[7, 4],
[7, 10],
[8, 5],
[8, 9],
[8, 11],
[11, 14],
[12, 10],
[12, 13],
[12, 15],
[13, 14],
[16, 14],
[17, 18],
[18, 15],
[18, 21],
[19, 16],
[19, 22],
[20, 19],
[21, 23],
[23, 24],
[25, 22],
[25, 24],
[26, 25],
]
CouplingMap(coupling_map).draw()

Transpilez chacun des circuits de permutation en utilisant les passes de synthèse IA et les méthodes de synthèse génériques.
results = []
pm_no_ai_synth = generate_preset_pass_manager(
coupling_map=cm,
optimization_level=1, # set to 1 since we are using the synthesis methods
)
# Transpile and analyze all circuits
for i, (qc_name, qc) in enumerate(circuits.items(), start=1):
pattern = patterns[i - 1] # Get the corresponding pattern
qc_depth_lnn_kms = synth_permutation_depth_lnn_kms(pattern)
qc_basic = synth_permutation_basic(pattern)
# AI synthesis
results.append(
synth_transpile_with_metrics(
qc.decompose(reps=3),
pm_ai,
qc_name,
"AI",
)
)
# Depth-LNN-KMS Method
results.append(
synth_transpile_with_metrics(
qc_depth_lnn_kms.decompose(reps=3),
pm_no_ai_synth,
qc_name,
"Depth-LNN-KMS",
)
)
# Basic Method
results.append(
synth_transpile_with_metrics(
qc_basic.decompose(reps=3),
pm_no_ai_synth,
qc_name,
"Basic",
)
)
results_df = pd.DataFrame(results)
Enregistrez les métriques (profondeur, nombre de portes, temps) pour chaque circuit après la transpilation.
# Calculate averages for each metric
average_metrics = results_df.groupby("Method")[
["Depth (2Q)", "Gates", "Time (s)"]
].mean()
average_metrics = average_metrics.round(3) # Round to two decimal places
print("\n=== Average Metrics ===")
print(average_metrics)
# Identify the best non-AI method based on least average depth
non_ai_methods = [
method for method in results_df["Method"].unique() if method != "AI"
]
best_non_ai_method = average_metrics.loc[non_ai_methods][
"Depth (2Q)"
].idxmin()
print(
f"\nBest Non-AI Method (based on least average depth): {best_non_ai_method}"
)
# Compare AI to the best non-AI method
ai_metrics = average_metrics.loc["AI"]
best_non_ai_metrics = average_metrics.loc[best_non_ai_method]
comparison = {
"Metric": ["Depth (2Q)", "Gates", "Time (s)"],
"AI": [
ai_metrics["Depth (2Q)"],
ai_metrics["Gates"],
ai_metrics["Time (s)"],
],
best_non_ai_method: [
best_non_ai_metrics["Depth (2Q)"],
best_non_ai_metrics["Gates"],
best_non_ai_metrics["Time (s)"],
],
"Improvement (AI vs Best Non-AI)": [
ai_metrics["Depth (2Q)"] - best_non_ai_metrics["Depth (2Q)"],
ai_metrics["Gates"] - best_non_ai_metrics["Gates"],
ai_metrics["Time (s)"] - best_non_ai_metrics["Time (s)"],
],
}
comparison_df = pd.DataFrame(comparison)
print("\n=== Comparison of AI vs Best Non-AI Method ===")
comparison_df
=== Average Metrics ===
Depth (2Q) Gates Time (s)
Method
AI 23.9 82.8 0.248
Basic 29.8 91.0 0.012
Depth-LNN-KMS 70.8 531.6 0.017
Best Non-AI Method (based on least average depth): Basic
=== Comparison of AI vs Best Non-AI Method ===
Metric AI Basic Improvement (AI vs Best Non-AI)
0 Depth (2Q) 23.900 29.800 -5.900
1 Gates 82.800 91.000 -8.200
2 Time (s) 0.248 0.012 0.236
Les résultats démontrent que le transpileur IA surpasse toutes les autres méthodes de synthèse de Qiskit pour cet ensemble de circuits de permutation aléatoires. Les principales conclusions comprennent :
- Profondeur : le transpileur IA atteint la profondeur moyenne la plus faible, indiquant une optimisation supérieure des dispositions de circuits.
- Nombre de portes : il réduit significativement le nombre de portes par rapport aux autres méthodes, améliorant la fidélité et l'efficacité d'exécution.
- Temps de transpilation : toutes les méthodes s'exécutent très rapidement à cette échelle, les rendant pratiques à utiliser. Cependant, le transpileur IA présente une augmentation notable du temps d'exécution par rapport aux méthodes traditionnelles en raison de la complexité des modèles IA utilisés.
Ces résultats établissent le transpileur IA comme l'approche la plus efficace pour ce benchmark, en particulier pour l'optimisation de la profondeur et du nombre de portes. Tracez les résultats pour comparer les performances des passes de synthèse IA par rapport aux méthodes de synthèse génériques.
methods = results_df["Method"].unique()
fig, axs = plt.subplots(1, 3, figsize=(18, 5))
# Pivot the DataFrame and reorder columns to ensure AI is first
pivot_depth = results_df.pivot(
index="Pattern", columns="Method", values="Depth (2Q)"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_gates = results_df.pivot(
index="Pattern", columns="Method", values="Gates"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_time = results_df.pivot(
index="Pattern", columns="Method", values="Time (s)"
)[["AI", "Depth-LNN-KMS", "Basic"]]
pivot_depth.plot(kind="bar", ax=axs[0], legend=False)
axs[0].set_title("Circuit Depth Comparison")
axs[0].set_ylabel("Depth")
axs[0].set_xlabel("Pattern")
axs[0].tick_params(axis="x", rotation=45)
pivot_gates.plot(kind="bar", ax=axs[1], legend=False)
axs[1].set_title("2Q Gate Count Comparison")
axs[1].set_ylabel("Number of 2Q Gates")
axs[1].set_xlabel("Pattern")
axs[1].tick_params(axis="x", rotation=45)
pivot_time.plot(
kind="bar", ax=axs[2], legend=True, title="Legend"
) # Show legend on the last plot
axs[2].set_title("Time Comparison")
axs[2].set_ylabel("Time (seconds)")
axs[2].set_xlabel("Pattern")
axs[2].tick_params(axis="x", rotation=45)
fig.suptitle(
"Benchmarking AI Synthesis Methods vs Non-AI Synthesis Methods For Random Permutations Circuits",
fontsize=16,
y=1,
)
plt.tight_layout()
plt.show()

Ce graphique met en évidence les résultats individuels pour chaque circuit (qc_1 à qc_10) à travers les différentes méthodes de synthèse :
Bien que ces résultats soulignent l'efficacité du transpileur IA pour les circuits de permutation, il est important de noter ses limitations. La méthode de synthèse IA n'est actuellement disponible que pour certaines cartes de couplage, ce qui peut restreindre son applicabilité plus large. Cette contrainte doit être prise en compte lors de l'évaluation de son utilisation dans différents scénarios.
Dans l'ensemble, le transpileur IA démontre des améliorations prometteuses en matière d'optimisation de la profondeur et du nombre de portes pour ces circuits spécifiques tout en maintenant des temps de transpilation comparables.
Étape 3 : Exécuter en utilisant les primitives Qiskit
Comme ce tutoriel se concentre sur la transpilation, aucune expérience ne sera exécutée sur le dispositif quantique. L'objectif est de tirer parti des optimisations de l'étape 2 pour obtenir un circuit transpilé avec une profondeur ou un nombre de portes réduit.
Étape 4 : Post-traiter et retourner le résultat dans le format classique souhaité
Puisqu'il n'y a pas d'exécution pour ce notebook, il n'y a pas de résultats à post-traiter.
Enquête sur le tutoriel
Veuillez répondre à cette courte enquête pour donner votre avis sur ce tutoriel. Vos retours nous aideront à améliorer notre contenu et l'expérience utilisateur.