Exécutez votre premier circuit sur le matériel
Le code figurant sur cette page a été développé selon les 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
Cet exemple comporte deux parties. Vous allez d'abord créer un programme quantique simple « Hello world » et l'exécuter sur une unité de traitement quantique (QPU). Étant donné que la recherche quantique réelle nécessite des programmes beaucoup plus robustes, dans la deuxième section ( Échelle à un grand nombre de qubits ), vous allez faire passer le programme simple à un niveau utilitaire.
Installer et authentifier
-
Si vous n'avez pas encore installé Qiskit, consultez les instructions dans le guide de démarrage rapide.
-
Installez le client Compute d' IBM Quantum pour exécuter des tâches sur du matériel quantique :
pip install qiskit-ibm-runtime -
Configurez un environnement pour exécuter les notebooks Jupyter localement :
pip install jupyter
-
-
Configurez votre authentification pour accéder au matériel quantique grâce au programme gratuit Open Plan.
(Si vous avez reçu une invitation par e-mail pour rejoindre un compte, suivez plutôt les étapes destinées aux utilisateurs invités.)
-
Rendez-vous sur IBM Quantum Platform pour vous connecter ou créer un compte.
ImportantSi vous vous connectez via un serveur proxy, vous devez utiliser v0.44.0
qiskit-ibm-runtimeou une version ultérieure. -
Générez votre clé API (également appelée jeton API) sur le tableau de bord, puis copiez-la dans un emplacement sécurisé.
-
Accédez à la page Instances et recherchez l'instance que vous souhaitez utiliser. Passez la souris sur son CRN et cliquez pour le copier.
-
Enregistrez vos identifiants localement à l'aide de ce code :
from qiskit_ibm_runtime import QiskitRuntimeService QiskitRuntimeService.save_account( # For `token`, use the 44-character API_KEY you created # and saved from the IBM Quantum Platform Home dashboard token="<your-api-key>", instance="<CRN>", # Optional )
-
-
Vous pouvez désormais utiliser ce code « Python » chaque fois que vous souhaitez vous authentifier auprès du service Compute de IBM Quantum :
from qiskit_ibm_runtime import QiskitRuntimeService # Run every time you need the service service = QiskitRuntimeService()
Si vous utilisez un ordinateur public ou tout autre environnement non sécurisé, suivez plutôt les instructions d'authentification manuelle afin de protéger vos identifiants d'authentification.
Créer et exécuter un programme quantique simple
Les quatre étapes pour écrire un programme quantique à l'aide des modèles Qiskit sont les suivantes :
-
Mapper le problème dans un format quantique natif.
-
Optimiser les circuits et les opérateurs.
-
Exécuter à l'aide d'une fonction primitive quantique.
-
Analysez les résultats.
Etape 1. Mapper le problème vers un format quantique natif
Dans un programme quantique, les circuits quantiques sont le format natif dans lequel sont représentées les instructions quantiques, et les opérateurs représentent les observables à mesurer. Lorsque vous créez un circuit, vous créez généralement un nouvel QuantumCircuit objet, puis vous y ajoutez des instructions dans l'ordre.
La cellule de code suivante crée un circuit qui produit un état de Bell, qui est un état dans lequel deux qubits sont entièrement intriqués l'un avec l'autre.
Le Qiskit SDK utilise la numérotation LSb 0 où le chiffre a la valeur ou . Pour plus de détails, voir la section Ordre des bits dans la Qiskit SDK rubrique.
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorOptions
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from matplotlib import pyplot as plt
# Uncomment the next line if you want to use a simulator:
# from qiskit_ibm_runtime.fake_provider import FakeBelemV2
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
# Add a Hadamard gate to qubit 0
qc.h(0)
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
# Return a drawing of the circuit using MatPlotLib ("mpl").
# These guides are written by using Jupyter notebooks, which
# display the output of the last line of each cell.
# If you're running this in a script, use `print(qc.draw())` to
# print a text drawing.
qc.draw("mpl")Output:
Consultez QuantumCircuit la documentation pour connaître toutes les opérations disponibles.
Lors de la création de circuits quantiques, vous devez également déterminer quel type de données vous souhaitez obtenir à l'issue de l'exécution. Qiskit propose deux façons de renvoyer des données : vous pouvez obtenir des résultats d'échantillonnage pour un ensemble de qubits que vous choisissez de mesurer, ou vous pouvez obtenir la valeur attendue d'une observable. Préparez votre projet de manière à pouvoir mesurer votre circuit selon l'une de ces deux méthodes à l'aide de primitives (expliquées en détail à l'étape 3 ).
Cet exemple mesure les valeurs attendues à l'aide du qiskit.quantum_info sous-module, qui est spécifié à l'aide d'opérateurs (objets mathématiques utilisés pour représenter une action ou un processus qui modifie un état quantique). La cellule de code suivante crée six opérateurs de Pauli à deux qubits : IZ, IX, ZI XI, ZZ, et XX.
# Set up six different observables.
observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]Ici, quelque chose comme ZZ l'opérateur est un raccourci pour le produit tensoriel, ce qui signifie mesurer Z sur le qubit 1 et Z sur le qubit 0 ensemble, et obtenir des informations sur la corrélation entre le qubit 1 et le qubit 0. Les valeurs attendues de ce type sont généralement écrites sous la forme .
Si l'état est intriqué, alors la mesure de devrait être différente de la mesure de . Pour l'état intriqué spécifique créé par notre circuit décrit ci-dessus, la mesure de devrait être 1 et la mesure de devrait être zéro.
Étape 2. Optimiser les circuits et les opérateurs
Lors de l'exécution de circuits sur un appareil, il est important d'optimiser l'ensemble des instructions contenues dans le circuit et de minimiser la profondeur globale (grosso modo le nombre d'instructions) du circuit. Cela vous garantit d'obtenir les meilleurs résultats possibles en réduisant les effets des erreurs et du bruit. De plus, les instructions du circuit doivent être conformes à l 'architecture du jeu d'instructions (ISA) du dispositif backend et doivent tenir compte des portes de base et de la connectivité des qubits du dispositif.
Le code suivant instancie un périphérique réel auquel envoyer une tâche et transforme le circuit et les observables afin qu'ils correspondent à l'ISA de ce backend. Cela nécessite que vous ayez déjà enregistré vos identifiants.
service = QiskitRuntimeService()
backend = service.least_busy(simulator=False, operational=True)
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
isa_circuit.draw("mpl", idle_wires=False)Output:
Étape 3. Exécuter à l'aide des primitives quantiques
Les ordinateurs quantiques peuvent produire des résultats aléatoires; c'est pourquoi on recueille généralement un échantillon des résultats en exécutant le circuit à plusieurs reprises. Vous pouvez estimer la valeur de l'observable à l'aide de la Estimator classe. Estimator est l'une des deux fonctions primitives; l'autre est Sampler, qui permet d'extraire des données d'un ordinateur quantique. Ces objets disposent d'une run() méthode qui effectue la sélection des circuits, des observables et des paramètres (le cas échéant), à l'aide d'un bloc unifié primitif ( PUB ).
# Construct the Estimator instance.
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])
# Use the job ID to retrieve your job data later
print(f">>> Job ID: {job.job_id()}")Output:
>>> Job ID: d9mqa588csec73fagtu0
Une fois la tâche soumise, vous pouvez attendre qu'elle soit terminée dans votre instance Python actuelle ou utiliser job_id pour récupérer les données ultérieurement. (Pour plus de détails, consultez la section sur la récupération des tâches.)
Une fois le travail terminé, examinez son résultat à l'aide de result() l'attribut du travail.
# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).
job_result = job.result()
# This is the result from our single pub, which had six observables,
# so contains information on all six.
pub_result = job.result()[0]Lorsque vous exécutez votre programme quantique sur un appareil réel, votre charge de travail doit attendre dans une file d'attente avant d'être exécutée. Pour gagner du temps, vous pouvez utiliser le code suivant pour exécuter cette petite charge de travail fake_provider en mode de test local qiskit-ibm-runtime . Notez que cela n'est possible que pour un petit circuit. Lorsque vous passerez à l'étape suivante, vous devrez utiliser un appareil réel.
# Use the following code instead if you want to run on a simulator:
from qiskit_ibm_runtime.fake_provider import FakeBelemV2
backend = FakeBelemV2()
estimator = Estimator(backend)
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
job = estimator.run([(isa_circuit, mapped_observables)])
result = job.result()
# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).
job_result = job.result()
# This is the result from our single pub, which had five observables,
# so contains information on all five.
pub_result = job.result()[0]Étape 4 : Analyser les résultats
L'étape d'analyse est généralement celle où vous pouvez post-traiter vos résultats en utilisant, par exemple, l'atténuation des erreurs de mesure ou l'extrapolation du bruit zéro (ZNE). Vous pouvez intégrer ces résultats dans un autre flux de travail pour une analyse plus approfondie ou préparer un graphique des valeurs et données clés. En général, cette étape est spécifique à votre problème. Pour cet exemple, tracez chacune des valeurs attendues qui ont été mesurées pour notre circuit.
Les valeurs attendues et les écarts-types des grandeurs observables que vous avez indiquées à Estimator sont accessibles via les attributs et PubResult.data.stds du PubResult.data.evs résultat de la tâche. Pour récupérer les résultats de Sampler, utilisez la PubResult.data.meas.get_counts() fonction, qui renvoie un dict tableau de mesures sous la forme de chaînes de bits en tant que clés et de nombres en tant que valeurs correspondantes. Pour plus d'informations, consultez le guide de démarrage rapide de Sampler.
# Plot the result
values = pub_result.data.evs
errors = pub_result.data.stds
# plotting graph
plt.plot(observables_labels, values, "-o")
plt.xlabel("Observables")
plt.ylabel("Values")
plt.show()Output:
Notez que pour les qubits 0 et 1, les valeurs attendues indépendantes de X et Z sont toutes deux égales à 0, tandis que les corrélations (XX et ZZ) sont égales à 1. C'est une caractéristique distinctive de l'intrication quantique.
Évolutivité vers un grand nombre de qubits
Dans le domaine de l'informatique quantique, les travaux à l'échelle industrielle sont essentiels pour faire progresser la recherche. Ce type de travail nécessite des calculs à une échelle beaucoup plus grande, avec des circuits pouvant utiliser plus de 100 qubits et plus de 1 000 portes. Cet exemple montre comment vous pouvez réaliser des travaux à l'échelle industrielle sur IBM® des QPU en créant et en analysant un état GHZ de 100 qubits. Il utilise le workflow Qiskit patterns et se termine par la mesure de la valeur attendue pour chaque qubit.
Etape 1. Cartographier le problème
Écrivez une fonction qui renvoie un QuantumCircuit qui prépare un état GHZ à qubits (essentiellement un état de Bell étendu), puis utilisez cette fonction pour préparer un état GHZ à 100 qubits et collecter les observables à mesurer.
def get_qc_for_n_qubit_GHZ_state(n: int) -> QuantumCircuit:
"""This function will create a qiskit.QuantumCircuit (qc)
for an n-qubit GHZ state.
Args:
n (int): Number of qubits in the n-qubit GHZ state
Returns:
QuantumCircuit: Quantum circuit that generate the n-qubit GHZ state,
assuming all qubits start in the 0 state
"""
if isinstance(n, int) and n >= 2:
qc = QuantumCircuit(n)
qc.h(0)
for i in range(n - 1):
qc.cx(i, i + 1)
else:
raise Exception("n is not a valid input")
return qc
# Create a new circuit with 100 qubits in the GHZ state
n = 100
qc = get_qc_for_n_qubit_GHZ_state(n)Ensuite, mappez les opérateurs qui vous intéressent. Cet exemple utilise les ZZ opérateurs entre qubits pour examiner leur comportement à mesure qu'ils s'éloignent les uns des autres. Des valeurs d'attente de plus en plus inexactes (corrompues) entre des qubits distants révéleraient le niveau de bruit présent.
# ZZII...II, ZIZI...II, ... , ZIII...IZ
operator_strings = [
"Z" + "I" * i + "Z" + "I" * (n - 2 - i) for i in range(n - 1)
]
operators = [SparsePauliOp(operator) for operator in operator_strings]Étape 2. Optimiser le problème pour l'exécution sur du matériel quantique
Le code suivant transforme le circuit et les observables afin qu'ils correspondent à l'ISA du backend. Cela nécessite que vous ayez déjà enregistré vos identifiants.
service = QiskitRuntimeService()
backend = service.least_busy(
simulator=False, operational=True, min_num_qubits=100
)
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(qc)
isa_operators_list = [op.apply_layout(isa_circuit.layout) for op in operators]Étape 3. Exécuter sur le matériel
Soumettez la tâche et activez la suppression des erreurs à l'aide d'une technique permettant de réduire les erreurs, appelée « découplage dynamique ». Le niveau de résilience détermine le degré de résilience à mettre en place face aux erreurs. Des niveaux plus élevés permettent d'obtenir des résultats plus précis, au prix d'un temps de traitement plus long. Pour plus d'explications sur les options définies dans le code ci-dessous, consultez la section « Techniques d'atténuation et de suppression des erreurs ».
options = EstimatorOptions()
options.resilience_level = 1
options.dynamical_decoupling.enable = True
options.dynamical_decoupling.sequence_type = "XY4"
# Create an Estimator object
estimator = Estimator(backend, options=options)# Submit the circuit to Estimator
job = estimator.run([(isa_circuit, isa_operators_list)])
job_id = job.job_id()
print(job_id)Output:
d9mqnjmh4e6s738vioqg
Étape 4 : Résultats du post-traitement
Une fois le travail terminé, tracez les résultats et remarquez que diminue à mesure que augmente , même si dans une simulation idéale, tous les devraient être égaux à 1.
# data
data = list(range(1, len(operators) + 1)) # Distance between the Z operators
result = job.result()[0]
values = result.data.evs # Expectation value at each Z operator.
values = [
v / values[0] for v in values
] # Normalize the expectation values to evaluate how they decay with distance.
# plotting graph
plt.plot(data, values, marker="o", label="100-qubit GHZ state")
plt.xlabel("Distance between qubits $i$")
plt.ylabel(r"$\langle Z_i Z_0 \rangle / \langle Z_1 Z_0 \rangle $")
plt.legend()
plt.show()Output:
Le graphique précédent montre que lorsque la distance entre les qubits augmente, le signal s'affaiblit en raison de la présence de bruit.
Etapes suivantes
- Essayez l'un de ces tutoriels :
- Estimation de l'énergie de l'état fondamental de la chaîne de Heisenberg avec VQE
- Résoudre des problèmes d'optimisation à l'aide du QAOA
- Entraîner des modèles de noyau quantique pour des tâches d'apprentissage automatique
- Vous trouverez des instructions d'installation détaillées dans le guide d'installation de Qiskit.
- Si vous préférez ne pas installer Qiskit localement, consultez les options permettant d'utiliser Qiskit dans un environnement de développement en ligne.
- Pour enregistrer plusieurs identifiants de compte ou pour spécifier d'autres options de compte, consultez les instructions détaillées dans le guide Enregistrer vos identifiants de connexion.