Gestione password
qiskit.passmanager
Panoramica
Il gestore dei passaggi di Qiskit si ispira al compilatore LLVM. L'infrastruttura del compilatore suddivide le responsabilità in tre componenti principali: attività, controllori di flusso e gestori di passaggi.
Una pipeline di compilazione esegue una sequenza di oggetti Task , ciascuno dei quali accetta come input una rappresentazione intermedia (IR), esegue un'operazione e restituisce come output un'IR, eventualmente diversa. Laddove definisce Task l'interfaccia, un'attività atomica è un pass, che è una sottoclasse di GenericPass e ne implementa il metodo run() astratto. Questa è la classe che dovrebbe essere utilizzata come classe base quando si implementa una fase di compilazione personalizzata.
I controllori di flusso forniscono modelli di esecuzione per un insieme di attività. Il controllore di flusso più semplice è un FlowControllerLinear, che si limita a eseguire una serie di operazioni in sequenza lineare. I controllori di flusso più avanzati includono cicli o l'esecuzione condizionale. Queste vengono utilizzate, ad esempio, nelle pipeline di transpiler predefinite di Qiskit per livelli di ottimizzazione più elevati, in cui le ottimizzazioni vengono eseguite fino al raggiungimento di un criterio di convergenza.
I responsabili dei pass hanno il compito di gestire le attività, compresa la pianificazione delle analisi richieste e la possibilità per l'utente di modificare la sequenza delle attività. Qiskit fornisce in questo modulo due gestori di passaggi generici per l'IR e un gestore di passaggi specializzato DAGCircuit per l'IR in qiskit.transpiler. Quelli generici IR sono:
-
BasePassManager: un gestore di pass con IR fisso. Questo gestore di pass consente di modificare l'insieme delle attività da eseguire e supporta l'esecuzione parallela di più input tramiteparallel_map(). Questa classe supporta ulteriori conversioni della rappresentazione di un programma in ingresso nell'IR interno, nonché la conversione in un formato di programma in uscita.La classe
BasePassManagerè la classe base per i gestori di passaggi predefiniti di Qiskit per la transpilazioneDAGCircuit, come quelli restituiti dagenerate_preset_pass_manager(). In questo caso vengono utilizzate conversioni implicite da e verso il formatoQuantumCircuitdi input e output del programma. -
MultiStagePassManager: un gestore di passaggi a fasi in cui ogni fase può mantenere o ridurre l'IR. Uno stadio è definito da un oTaskda un suo iterabile, che può anche essere raggruppato all’interno di unBasePassManager. Gli stadi devono essere configurati in modo tale che l'IR in uscita dello stadio corrente corrisponda all'IR in ingresso dello stadio successivo; (al momento) non sono disponibili conversioni automatiche.
I gestori di passaggi forniscono inoltre un'infrastruttura che consente di trasmettere un PropertySet con informazioni di contesto attraverso ogni attività e una funzione di callback per l'introspezione. Il è PropertySet un dizionario a struttura libera, che può essere popolato e letto da un passaggio durante l'esecuzione, oppure letto da un controllore di flusso per gestire l'esecuzione dei passaggi. L'insieme delle proprietà è portabile e viene trasferito da un passaggio all'altro durante l'esecuzione. Oltre all'insieme di proprietà, alle attività viene assegnata anche una struttura dati WorkflowStatus . Questo oggetto viene inizializzato all'avvio del gestore dei passaggi e trasferito alle attività sottostanti. Lo stato viene aggiornato al termine di ogni passaggio ed è contenente informazioni sullo stato della pipeline (numero di passaggi eseguiti, stato di errore e così via), a differenza del PropertySet, che contiene informazioni sull'IR oggetto di ottimizzazione.
La callback viene chiamata dalle istanze GenericPass che si aspettano la seguente firma:
def callback(
*,
task: Task[IR_IN, IR_OUT],
passmanager_ir: IR_OUT,
property_set: PropertySet,
running_time: float,
count: int
) -> None:
...Si noti che questa firma differisce leggermente per i pass e i gestori di pass definiti nel modulo qiskit.transpiler .
Esempi
Esaminiamo un problema di ottimizzazione di tipo "toy", ovvero preparare una serie di numeri ed eliminare una cifra se il numero è cinque. Questo compito potrebbe essere facilmente risolto convertendo i numeri in stringhe. In questo caso utilizziamo il framework Pass Manager, tralasciando per un attimo l'aspetto dell'efficienza per imparare a creare un compilatore Qiskit personalizzato.
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)Questo gestore di passaggi immette ed emette un numero intero, mentre esegue le operazioni di ottimizzazione su una stringa di dati. Quindi, i tipi di ingresso, IR e uscita sono rispettivamente intero, stringa e intero. Il metodo _passmanager_frontend() definisce la conversione dei dati di ingresso in IR, mentre _passmanager_backend() definisce la conversione di IR in dati di uscita. Al backend del gestore di passaggi viene dato anche un parametro in_program che contiene l'originale input_program al front-end, per fare riferimento a qualsiasi metadato originale del programma in ingresso per la conversione finale.
Quindi, implementiamo un passaggio che rimuove una cifra quando il numero è cinque.
class RemoveFive(GenericPass):
def run(self, passmanager_ir: str):
return passmanager_ir.replace("5", "")
task = RemoveFive()Infine, creiamo un oggetto Pass Manager e pianifichiamo l'attività tramite esso. Se si esegue il gestore delle password con una sequenza casuale di numeri, vengono restituiti nuovi numeri che non contengono il cinque.
pm = ToyPassManager()
pm.append(task)
pm.run([123456789, 45654, 36785554])Output:
[12346789, 464, 36784]Consideriamo ora il caso dell'esecuzione condizionale. Evitiamo l'esecuzione del task "rimuovi cinque" quando il numero in ingresso è di sei cifre o meno. Tale controllo può essere implementato da un controllore di flusso. Si parte da un passaggio di analisi che fornisce al controllore di flusso informazioni sul numero di cifre.
class CountDigits(GenericPass):
def run(self, passmanager_ir: str):
self.property_set["ndigits"] = len(passmanager_ir)
analysis_task = CountDigits()Quindi, racchiudiamo l'operazione "remove five" all'interno del ConditionalController che esegue le operazioni memorizzate solo quando la condizione è soddisfatta.
def digit_condition(property_set):
# Return True when condition is met.
return property_set["ndigits"] > 6
conditional_task = ConditionalController(
tasks=[RemoveFive()],
condition=digit_condition,
)Come prima, programmiamo questi passaggi con il gestore di passaggi ed eseguiamo.
pm = ToyPassManager()
pm.append(analysis_task)
pm.append(conditional_task)
pm.run([123456789, 45654, 36785554])Output:
[12346789, 45654, 36784]Il task "rimuovi cinque" viene attivato solo per il primo e il terzo valore di input, che hanno più di sei cifre.
Grazie al framework di gestione dei passaggi, uno sviluppatore può personalizzare in modo flessibile l'attività di ottimizzazione combinando più passaggi e controllori di flusso. Per ulteriori dettagli, consultare la documentazione dell'API della classe riportata di seguito.
Interfaccia
Esiti positivi
GenericPass() | Classe base di un task di gestione di un singolo passaggio. |
Task() | Un'interfaccia del processo di gestione dei pass. |
Gestori di pass
BasePassManager( [attività, max_iterazioni] ) | Classe di base del gestore di passaggi. |
MultiStagePassManager(**fasi) | Un gestore di passaggi a tappe che supporta più IR. |
Regolatori di flusso
BaseController( [opzioni] ) | Classe base del controllore. |
FlowControllerLinear( [attività, opzioni] ) | Un controllore di flusso standard che esegue i task uno dopo l'altro. |
ConditionalController( [attività, condizioni,...] ) | Un controllore di flusso esegue la pipeline una volta se la condizione è vera, oppure non fa nulla se la condizione è falsa. |
DoWhileController( [attività, do_while, opzioni] ) | Eseguire i task dati in un ciclo fino a quando la condizione do_while sul set di proprietà diventa False. |
Stato della compilazione
PropertySet | Un oggetto di tipo dizionario predefinito. |
WorkflowStatus( [count, completed_passes,...] ) | Raccolta dello stato di compilazione del flusso di lavoro, ad esempio l'esecuzione del gestore dei passaggi. |
PassManagerState(stato_del_flusso_di_lavoro, impostazione_proprietà) | Un oggetto contenitore portatile che fa comunicare i task del gestore di passaggi attraverso il generatore. |
Eccezioni
PassManagerError
exception qiskit.passmanager.PassManagerError(*message)
Basi: QiskitError
Errore del gestore del passaggio.
Impostare il messaggio di errore.