Skip to main content
IBM Quantum Platform

Gestionnaire de mots de passe

qiskit.passmanager


Aperçu

Le gestionnaire de passes de Qiskit s'inspire du compilateur LLVM. L'infrastructure du compilateur répartit les responsabilités entre trois composants principaux : les tâches, les contrôleurs de flux et les gestionnaires de passes.

Un pipeline de compilation exécute une séquence d'objets Task , dont chacun prend en entrée une représentation intermédiaire (IR), effectue un traitement, puis renvoie en sortie une IR, éventuellement différente. Lorsqu'on définit Task l'interface, une tâche atomique est une « pass » qui hérite de cette interface et GenericPass implémente sa run() méthode abstraite. Il s'agit de la classe qui doit servir de classe de base lors de la mise en œuvre d'un passage de compilateur personnalisé.

Les contrôleurs de flux fournissent des modèles d'exécution pour un ensemble de tâches. Le contrôleur de flux le plus simple est un FlowControllerLinear, qui se contente d'exécuter une série de tâches dans un ordre linéaire. Les contrôleurs de flux plus avancés intègrent des boucles ou une exécution conditionnelle. Ils sont, par exemple, utilisés dans les pipelines de transcompilation prédéfinis de Qiskit pour des niveaux d'optimisation plus élevés, où les optimisations sont exécutées jusqu'à ce qu'un critère de convergence soit satisfait.

Les gestionnaires de passes sont chargés de gérer les tâches, notamment de planifier les analyses requises et de permettre à l'utilisateur de modifier l'ordre des tâches. Qiskit fournit deux gestionnaires de passes génériques pour l'IR dans ce module, ainsi qu'un gestionnaire de passes spécialisé DAGCircuit pour l'IR dans qiskit.transpiler. Les modèles génériques IR sont les suivants :

  • BasePassManager: un gestionnaire de passes avec un IR fixe. Ce gestionnaire de passes permet de modifier l'ensemble des tâches à exécuter et prend en charge l'exécution parallèle de plusieurs entrées grâce à parallel_map(). Cette classe prend en charge la conversion supplémentaire d'une représentation de programme en entrée vers l'IR interne, ainsi que la conversion vers un format de programme en sortie.

    La classe BasePassManager est la classe de base des gestionnaires de passes prédéfinis de Qiskit pour la transpilation DAGCircuit , tels que ceux renvoyés par generate_preset_pass_manager(). Dans ce cas, on utilise des conversions implicites vers et depuis le format de programme d'entrée et QuantumCircuit de sortie.

  • MultiStagePassManager: un gestionnaire de passes par étapes où chaque étape peut maintenir ou réduire l'IR. Une étape est définie par un ou Task un itérable de celui-ci, qui peut également être regroupé au sein d'un BasePassManager. Les étages doivent être configurés de manière à ce que la résistance d'entrée (IR) de l'étage actuel corresponde à la résistance d'entrée (IR) de l'étage suivant; il n'existe (pour l'instant) aucune conversion automatique.

Les gestionnaires de pass fournissent également une infrastructure permettant de transmettre un pass accompagné PropertySet d'informations de contexte à chaque tâche, ainsi qu'une fonction de rappel pour l'introspection. Le PropertySet est un dictionnaire de forme libre, qui peut être renseigné et lu par un passage lors de l'exécution, ou lu par un contrôleur de flux afin de contrôler l'exécution des passages. L'ensemble de propriétés est portable et est transmis d'une itération à l'autre lors de l'exécution. Outre l'ensemble de propriétés, les tâches reçoivent également une structure de données WorkflowStatus . Cet objet est initialisé lors de l'exécution du gestionnaire de passes, puis transmis aux tâches sous-jacentes. Le statut est mis à jour après l'exécution de chaque passe et contient des informations sur l'état du pipeline (nombre de passes exécutées, état des échecs, etc.), contrairement au PropertySet, qui contient des informations sur l'IR en cours d'optimisation.

La fonction de rappel est appelée par des instances GenericPass qui attendent la signature suivante :

def callback(
    *,
    task: Task[IR_IN, IR_OUT],
    passmanager_ir: IR_OUT,
    property_set: PropertySet,
    running_time: float,
    count: int
) -> None:
    ...

Notez que cette signature diffère légèrement pour les passes et les gestionnaires de passes définis dans le module qiskit.transpiler .


Exemples

Nous nous penchons sur un exercice d'optimisation simple : il s'agit de préparer une série de nombres et de supprimer un chiffre si le nombre en question est égal à cinq. Cette tâche pourrait être facilement réalisée en convertissant les nombres en chaînes de caractères. Nous utilisons ici le framework Pass Manager, en mettant de côté pour l'instant la question de l'efficacité afin d'apprendre à créer un compilateur Qiskit personnalisé.

from qiskit.passmanager import BasePassManager, GenericPass, ConditionalController

class ToyPassManager(BasePassManager):

    def _passmanager_frontend(self, input_program: int, **kwargs) -> str:
        return str(input_program)

    def _passmanager_backend(self, passmanager_ir: str, in_program: int, **kwargs) -> int:
        return int(passmanager_ir)

Ce gestionnaire de passes entre et sort un nombre entier, tout en effectuant les tâches d'optimisation sur une chaîne de données. Par conséquent, les types d'entrée, d'IR et de sortie sont respectivement un entier, une chaîne et un entier. La méthode _passmanager_frontend() définit la conversion des données d'entrée en IR, et _passmanager_backend() définit la conversion de l'IR en données de sortie. Le backend du gestionnaire de passe reçoit également un paramètre in_program qui contient l'original input_program pour le front-end, afin de référencer toutes les métadonnées originales du programme d'entrée pour la conversion finale.

Ensuite, nous mettons en œuvre une passe qui supprime un chiffre lorsque le nombre est égal à cinq.

class RemoveFive(GenericPass):

    def run(self, passmanager_ir: str):
        return passmanager_ir.replace("5", "")

task = RemoveFive()

Enfin, nous instancions un gestionnaire de passes et planifions la tâche à l'aide de celui-ci. Lorsque l'on exécute le gestionnaire de mots de passe avec une série aléatoire de chiffres, on obtient de nouveaux chiffres qui ne contiennent pas le chiffre 5.

pm = ToyPassManager()
pm.append(task)

pm.run([123456789, 45654, 36785554])

Sortie :

[12346789, 464, 36784]

Examinons maintenant le cas de l'exécution conditionnelle. Nous évitons l'exécution de la tâche "enlever cinq" lorsque le nombre d'entrée est inférieur ou égal à six chiffres. Ce contrôle peut être mis en œuvre par un régulateur de débit. Nous commençons par une passe d'analyse qui fournit au contrôleur de flux des informations sur le nombre de chiffres.

class CountDigits(GenericPass):

    def run(self, passmanager_ir: str):
        self.property_set["ndigits"] = len(passmanager_ir)

analysis_task = CountDigits()

Ensuite, nous encapsulons la tâche « remove five » dans la fonction ConditionalController qui n'exécute les tâches enregistrées que lorsque la condition est remplie.

def digit_condition(property_set):
    # Return True when condition is met.
    return property_set["ndigits"] > 6

conditional_task = ConditionalController(
    tasks=[RemoveFive()],
    condition=digit_condition,
)

Comme précédemment, nous programmons ces passes avec le gestionnaire de passes et nous les exécutons.

pm = ToyPassManager()
pm.append(analysis_task)
pm.append(conditional_task)

pm.run([123456789, 45654, 36785554])

Sortie :

[12346789, 45654, 36784]

La tâche "supprimer cinq" n'est déclenchée que pour les première et troisième valeurs d'entrée, qui comportent plus de six chiffres.

Grâce au cadre de gestion des passes, un développeur peut personnaliser de manière flexible la tâche d'optimisation en combinant plusieurs passes et contrôleurs de flux. Pour plus de détails, consultez la documentation de l'API de la classe ci-dessous.


Interface

Réussites

GenericPass()Classe de base d'une tâche de gestionnaire de passage unique.
Task()Une interface de la tâche de gestion des laissez-passer.

Gestionnaires de forfaits

BasePassManager( [tâches, max_itération] )Classe de base du gestionnaire de passage.
MultiStagePassManager(**étapes)Un gestionnaire de passes par étapes prenant en charge plusieurs IR.

Régulateurs de débit

BaseController( [options] )Classe de base du contrôleur.
FlowControllerLinear( [tâches, options] )Un contrôleur de flux standard qui exécute les tâches les unes après les autres.
ConditionalController( [tâches, condition,...] )Un contrôleur de flux exécute le pipeline une fois si la condition est vraie, ou ne fait rien si la condition est fausse.
DoWhileController( [tâches, do_while, options] )Exécutez les tâches données dans une boucle jusqu'à ce que la condition do_while sur l'ensemble de propriétés devienne False.

État de compilation

PropertySetUn objet de type dictionnaire par défaut.
WorkflowStatus( [nombre, passes_réussies,...] )Collecte de l'état de compilation du flux de travail, c'est-à-dire de l'exécution du gestionnaire de passage.
PassManagerState(état_du_workflow, propriété_définie)Un objet conteneur portable que les tâches du gestionnaire de passage communiquent par le biais d'un générateur.

Exceptions

PassManagerError

exception qiskit.passmanager.PassManagerError(*message)

GitHub

Bases : QiskitError

Erreur du gestionnaire de passe.

Définir le message d'erreur.

Cette page a-t-elle été utile ?
Signaler un bogue, une coquille ou proposer du contenu sur GitHub.