Spécifier les options
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
Tu peux utiliser des options pour personnaliser les primitives Estimator et Sampler. Cette section explique comment spécifier les options des primitives Qiskit Runtime. Bien que l'interface de la méthode run() des primitives soit commune à toutes les implémentations, leurs options ne le sont pas. Consulte les références API correspondantes pour en savoir plus sur les options de qiskit.primitives et qiskit_aer.primitives.
Remarques sur la spécification des options dans les primitives :
SamplerV2etEstimatorV2ont des classes d'options séparées. Tu peux consulter les options disponibles et mettre à jour leurs valeurs pendant ou après l'initialisation de la primitive.- Utilise la méthode
update()pour appliquer des modifications à l'attributoptions. - Si tu ne spécifies pas de valeur pour une option, elle reçoit la valeur spéciale
Unsetet les valeurs par défaut du serveur sont utilisées. - L'attribut
optionsest du type Pythondataclass. Tu peux utiliser la méthode intégréeasdictpour le convertir en dictionnaire.
Définir les options des primitives
Tu peux définir les options lors de l'initialisation de la primitive, après son initialisation, ou dans la méthode run(). Consulte la section sur les règles de priorité pour comprendre ce qui se passe lorsqu'une même option est spécifiée à plusieurs endroits.
Initialisation de la primitive
Tu peux passer une instance de la classe d'options ou un dictionnaire lors de l'initialisation d'une primitive ; celle-ci en fait alors une copie. Ainsi, modifier le dictionnaire ou l'instance d'options d'origine n'affecte pas les options détenues par les primitives.
Classe d'options
Lors de la création d'une instance des classes EstimatorV2 ou SamplerV2, tu peux passer une instance de la classe d'options. Ces options seront ensuite appliquées lors de l'appel à run() pour effectuer le calcul. Spécifie les options selon ce format : options.option.sous-option.sous-sous-option = valeur. Par exemple : options.dynamical_decoupling.enable = True
Exemple :
SamplerV2 et EstimatorV2 ont des classes d'options séparées (EstimatorOptions et SamplerOptions).
# Added by doQumentation — required packages for this notebook
!pip install -q qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.options import EstimatorOptions
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
options = EstimatorOptions(
resilience_level=2,
resilience={"zne_mitigation": True, "zne": {"noise_factors": [1, 3, 5]}},
)
# or...
options = EstimatorOptions()
options.resilience_level = 2
options.resilience.zne_mitigation = True
options.resilience.zne.noise_factors = [1, 3, 5]
estimator = Estimator(mode=backend, options=options)
Dictionnaire
Tu peux spécifier les options sous forme de dictionnaire lors de l'initialisation de la primitive.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Setting options during primitive initialization
estimator = Estimator(
backend,
options={
"resilience_level": 2,
"resilience": {
"zne_mitigation": True,
"zne": {"noise_factors": [1, 3, 5]},
},
},
)
Mettre à jour les options après l'initialisation
Tu peux spécifier les options au format primitive.options.option.sous-option.sous-sous-option = valeur pour profiter de l'autocomplétion, ou utiliser la méthode update() pour effectuer des mises à jour groupées.
Les classes d'options de SamplerV2 et EstimatorV2 (EstimatorOptions et SamplerOptions) n'ont pas besoin d'être instanciées si tu définis les options après l'initialisation de la primitive.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = Estimator(mode=backend)
# Setting options after primitive initialization
# This uses auto-complete.
estimator.options.default_shots = 4000
# This does bulk update.
estimator.options.update(
default_shots=4000, resilience={"zne_mitigation": True}
)
Méthode Run()
Les seules valeurs que tu peux passer à run() sont celles définies dans l'interface, c'est-à-dire shots pour le Sampler et precision pour l'Estimator. Ces valeurs écrasent toute valeur définie pour default_shots ou default_precision pour l'exécution en cours.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)
sampler = Sampler(mode=backend)
# Default shots to use if not specified in run()
sampler.options.default_shots = 500
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
# Sample two circuits with different numbers of shots.
# 100 shots is used for transpiled1 and 200 for transpiled.
sampler.run([(transpiled1, None, 100), (transpiled2, None, 200)])
<RuntimeJobV2('d5k96cn853es738djikg', 'sampler')>
Cas particuliers
Niveau de résilience (Estimator uniquement)
Le niveau de résilience n'est pas réellement une option qui impacte directement la requête de la primitive, mais il spécifie un ensemble de base d'options préconfigurées sur lequel s'appuyer. En général, le niveau 0 désactive toute atténuation d'erreurs, le niveau 1 active les options d'atténuation des erreurs de mesure, et le niveau 2 active les options d'atténuation des erreurs de porte et de mesure.
Toutes les options que tu spécifies manuellement en plus du niveau de résilience s'appliquent par-dessus l'ensemble d'options de base défini par ce niveau. En principe, tu pourrais donc définir le niveau de résilience à 1 puis désactiver l'atténuation des mesures, bien que cela ne soit pas recommandé.
Dans l'exemple suivant, définir le niveau de résilience à 0 désactive initialement zne_mitigation, mais estimator.options.resilience.zne_mitigation = True remplace la configuration correspondante issue de estimator.options.resilience_level = 0.
from qiskit_ibm_runtime import EstimatorV2, QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = EstimatorV2(backend)
estimator.options.default_shots = 100
estimator.options.resilience_level = 0
estimator.options.resilience.zne_mitigation = True
Shots (Sampler uniquement)
La méthode SamplerV2.run accepte deux arguments : une liste de PUBs, dont chacun peut spécifier une valeur de shots propre au PUB, et un argument mot-clé shots. Ces valeurs de shots font partie de l'interface d'exécution du Sampler et sont indépendantes des options du Sampler Runtime. Elles ont la priorité sur toute valeur spécifiée dans les options, afin de respecter l'abstraction du Sampler.
Cependant, si shots n'est spécifié ni dans un PUB ni dans l'argument mot-clé de run (ou s'ils sont tous None), la valeur de shots provenant des options est utilisée, notamment default_shots.
En résumé, voici l'ordre de priorité pour spécifier les shots dans le Sampler, pour un PUB donné :
- Si le PUB spécifie des shots, cette valeur est utilisée.
- Si l'argument mot-clé
shotsest spécifié dansrun, cette valeur est utilisée. - Si
num_randomizationsetshots_per_randomizationsont spécifiés comme options detwirling, les shots correspondent au produit de ces deux valeurs. - Si
sampler.options.default_shotsest spécifié, cette valeur est utilisée.
Ainsi, si des shots sont spécifiés à tous les emplacements possibles, c'est celui ayant la priorité la plus haute (les shots spécifiés dans le PUB) qui est utilisé.
Précision (Estimator uniquement)
La précision est analogue aux shots, décrits dans la section précédente, sauf que les options de l'Estimator contiennent à la fois default_shots et default_precision. De plus, comme le twirling de portes est activé par défaut, le produit de num_randomizations et shots_per_randomization a la priorité sur ces deux options.
Plus précisément, pour un PUB Estimator donné :
- Si le PUB spécifie une précision, cette valeur est utilisée.
- Si l'argument mot-clé
precisionest spécifié dansrun, cette valeur est utilisée. - Si
num_randomizationsetshots_per_randomizationsont spécifiés comme options detwirling(activées par défaut), leur produit est utilisé pour contrôler la quantité de données. - Si
estimator.options.default_shotsest spécifié, cette valeur est utilisée pour contrôler la quantité de données. - Si
estimator.options.default_precisionest spécifié, cette valeur est utilisée.
Par exemple, si la précision est spécifiée aux quatre emplacements, c'est celui ayant la priorité la plus haute (la précision spécifiée dans le PUB) qui est utilisé.
La précision varie inversement avec l'utilisation. Autrement dit, plus la précision est faible, plus le temps QPU nécessaire à l'exécution est long.
Options couramment utilisées
Il existe de nombreuses options disponibles, mais voici les plus couramment utilisées :
Shots
Pour certains algorithmes, définir un nombre précis de shots est une étape centrale de leur routine. Les shots (ou la précision) peuvent être spécifiés à plusieurs endroits. Voici leur ordre de priorité :
Pour tout PUB du Sampler :
- Les shots entiers contenus dans le PUB
- La valeur
run(...,shots=val) - La valeur
options.default_shots
Pour tout PUB de l'Estimator :
- La précision en virgule flottante contenue dans le PUB
- La valeur
run(...,precision=val) - La valeur
options.default_shots - La valeur
options.default_precision
Exemple :
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit.circuit.library import random_iqp
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
circuit1 = random_iqp(3)
circuit1.measure_all()
circuit2 = random_iqp(3)
circuit2.measure_all()
pass_manager = generate_preset_pass_manager(
optimization_level=3, backend=backend
)
transpiled1 = pass_manager.run(circuit1)
transpiled2 = pass_manager.run(circuit2)
# Setting shots during primitive initialization
sampler = Sampler(mode=backend, options={"default_shots": 4096})
# Setting options after primitive initialization
# This uses auto-complete.
sampler.options.default_shots = 2000
# This does bulk update. The value for default_shots is overridden if you specify shots with run() or in the PUB.
sampler.options.update(
default_shots=1024, dynamical_decoupling={"sequence_type": "XpXm"}
)
# Sample two circuits at 128 shots each.
sampler.run([transpiled1, transpiled2], shots=128)
<RuntimeJobV2('d5k96icjt3vs73ds5t0g', 'sampler')>
Temps d'exécution maximal
Le temps d'exécution maximal (max_execution_time) limite la durée d'exécution d'un job. Si un job dépasse cette limite, il est annulé de force. Cette valeur s'applique aux jobs individuels, qu'ils soient exécutés en mode job, session ou batch.
La valeur est exprimée en secondes, sur la base du temps quantique (et non du temps horloge), c'est-à-dire le temps pendant lequel le QPU est dédié au traitement de ton job. Elle est ignorée en mode de test local car ce mode n'utilise pas de temps quantique.
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import EstimatorV2 as Estimator
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
estimator = Estimator(mode=backend)
estimator.options.max_execution_time = 2500
Désactiver toute atténuation et suppression d'erreurs
Tu peux désactiver toute atténuation et suppression d'erreurs si tu mènes, par exemple, des recherches sur tes propres techniques d'atténuation. Pour ce faire, avec EstimatorV2, définis resilience_level = 0. Pour SamplerV2, aucune modification n'est nécessaire car aucune option d'atténuation ou de suppression d'erreurs n'est activée par défaut.
Exemple :
Désactiver toute atténuation et suppression d'erreurs dans l'Estimator.
from qiskit_ibm_runtime import EstimatorV2 as Estimator, QiskitRuntimeService
# Define the service. This allows you to access IBM QPU.
service = QiskitRuntimeService()
# Get a backend
backend = service.least_busy(operational=True, simulator=False)
# Define Estimator
estimator = Estimator(backend)
options = estimator.options
# Turn off all error mitigation and suppression
options.resilience_level = 0
Prochaines étapes
- Trouve plus de détails sur les méthodes d'
EstimatorV2dans la référence API d'Estimator. - Trouve plus de détails sur les méthodes de
SamplerV2dans la référence API de Sampler. - Trouve des détails sur la configuration de la suppression d'erreurs et de l'atténuation d'erreurs.
- Choisis le mode d'exécution dans lequel lancer ton job.