Gestor de contraseñas
qiskit.passmanager
Visión general
El gestor de pasadas de Qiskit se inspira en el compilador LLVM. La infraestructura del compilador divide las responsabilidades en tres componentes principales: tareas, controladores de flujo y gestores de pasadas.
Un canal de compilación ejecuta una secuencia de objetos Task , cada uno de los cuales toma como entrada una representación intermedia (IR), realiza una operación y devuelve como salida una IR, que puede ser diferente. Donde define Task la interfaz, una tarea atómica es una «pass», que es una subclase de GenericPass e implementa su run() método abstracto. Esta es la clase que debe utilizarse como clase base a la hora de implementar una pasada de compilador personalizada.
Los controladores de flujo proporcionan modelos de ejecución para un conjunto de tareas. El controlador de flujo más sencillo es un FlowControllerLinear, que simplemente ejecuta un conjunto de tareas en una secuencia lineal. Los controladores de flujo más avanzados incluyen bucles o ejecución condicional. Se utilizan, por ejemplo, en los flujos de trabajo de transpilación predefinidos de Qiskit para niveles de optimización más altos, en los que las optimizaciones se ejecutan hasta que se cumple un criterio de convergencia.
Los gestores de pases se encargan de gestionar las tareas, lo que incluye programar los análisis necesarios y permitir que el usuario modifique la secuencia de tareas. Qiskit ofrece dos gestores de pasos genéricos para IR en este módulo, así como un gestor de pasos especializado DAGCircuit en IR en qiskit.transpiler. Los genéricos de IR son:
-
BasePassManager: un gestor de pases con IR fijo. Este gestor de pases permite modificar el conjunto de tareas que se van a ejecutar y admite la ejecución en paralelo de varias entradas medianteparallel_map(). Esta clase admite la conversión adicional de la representación de un programa de entrada al IR interno, así como la conversión a un formato de programa de salida.La clase
BasePassManageres la clase base de los gestores de pasadas predefinidos de Qiskit para la transpilaciónDAGCircuit, como los que devuelvegenerate_preset_pass_manager(). En ese caso, se utilizan conversiones implícitas hacia y desde el formato deQuantumCircuitentrada y salida del programa. -
MultiStagePassManager: un gestor de pases por etapas en el que cada etapa puede mantener o reducir el IR. Una etapa viene definida por un oTaskun iterable del mismo, que también puede agruparse dentro de unBasePassManager. Las etapas deben configurarse de tal manera que la resistencia de salida (IR) de la etapa actual coincida con la resistencia de entrada (IR) de la siguiente etapa; (por el momento) no hay conversiones automáticas.
Los gestores de pases también proporcionan una infraestructura para transmitir un PropertySet con información de contexto a lo largo de cada tarea, así como una función de devolución de llamada para la introspección. El PropertySet es un diccionario de formato libre, que puede rellenarse y leerse por una pasada durante la ejecución, o bien leerse por un controlador de flujo para controlar la ejecución de las pasadas. El conjunto de propiedades es portátil y se transfiere de una pasada a otra durante la ejecución. Además del conjunto de propiedades, las tareas también reciben una estructura de datos WorkflowStatus . Este objeto se inicializa al ejecutar el gestor de pases y se transfiere a las tareas subyacentes. El estado se actualiza tras cada pasada y contiene información sobre el estado del proceso (número de pasadas ejecutadas, estado de fallo, etc.), a diferencia del PropertySet, que contiene información sobre el IR que se está optimizando.
La función de devolución de llamada es invocada por instancias GenericPass que esperan la siguiente firma:
def callback(
*,
task: Task[IR_IN, IR_OUT],
passmanager_ir: IR_OUT,
property_set: PropertySet,
running_time: float,
count: int
) -> None:
...Ten en cuenta que esta firma difiere ligeramente en el caso de los pases y los gestores de pases definidos en el módulo qiskit.transpiler .
Ejemplos
Analizamos una tarea de optimización sencilla, que consiste en preparar una serie de números y eliminar un dígito si el número es cinco. Esta tarea se puede realizar fácilmente convirtiendo los números de entrada en cadenas de caracteres. Aquí utilizamos el marco de gestión de pases; dejando de lado por un momento la eficiencia, vamos a aprender a crear un compilador personalizado de Qiskit.
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)Este gestor de pasadas introduce y extrae un número entero, mientras que realiza las tareas de optimización sobre los datos de una cadena. Por lo tanto, los tipos de entrada, IR y salida son entero, cadena y entero, respectivamente. El método _passmanager_frontend() define la conversión de los datos de entrada a IR, y _passmanager_backend() define la conversión de IR a datos de salida. El backend del gestor de pases también recibe un parámetro in_program que contiene el input_program original del front end, para referenciar cualquier metadato original del programa de entrada para la conversión final.
A continuación, implementamos un pase que elimina un dígito cuando el número es cinco.
class RemoveFive(GenericPass):
def run(self, passmanager_ir: str):
return passmanager_ir.replace("5", "")
task = RemoveFive()Por último, creamos una instancia del gestor de pases y programamos la tarea con él. Al ejecutar el gestor de contraseñas con una secuencia aleatoria de números, se obtienen nuevos números que no contienen el cinco.
pm = ToyPassManager()
pm.append(task)
pm.run([123456789, 45654, 36785554])Salida:
[12346789, 464, 36784]Consideremos ahora el caso de la ejecución condicional. Evitamos la ejecución de la tarea "eliminar cinco" cuando el número de entrada tiene seis dígitos o menos. Este control puede realizarse mediante un regulador de caudal. Partimos de un paso de análisis que proporciona al controlador de flujo información sobre el número de dígitos.
class CountDigits(GenericPass):
def run(self, passmanager_ir: str):
self.property_set["ndigits"] = len(passmanager_ir)
analysis_task = CountDigits()A continuación, envolvemos la tarea «remove five» con el ConditionalController que ejecuta las tareas almacenadas solo cuando se cumple la condición.
def digit_condition(property_set):
# Return True when condition is met.
return property_set["ndigits"] > 6
conditional_task = ConditionalController(
tasks=[RemoveFive()],
condition=digit_condition,
)Como antes, programamos estos pases con el gestor de pases y a correr.
pm = ToyPassManager()
pm.append(analysis_task)
pm.append(conditional_task)
pm.run([123456789, 45654, 36785554])Salida:
[12346789, 45654, 36784]La tarea "eliminar cinco" sólo se activa para los valores de entrada primero y tercero, que tienen más de seis dígitos.
Gracias al marco de trabajo del gestor de pasadas, un desarrollador puede personalizar con flexibilidad la tarea de optimización combinando varias pasadas y controladores de flujo. Consulte los detalles en la siguiente documentación de la API de la clase.
Interfaz
Pasa
Columna « 1 » | Columna « 2 » |
|---|---|
GenericPass() | Clase base de una tarea de gestión de una sola pasada. |
Task() | Una interfaz de la tarea del gestor de pases. |
Gestores de pases
Columna « 1 » | Columna « 2 » |
|---|---|
BasePassManager( [tareas, max_iteration] ) | Clase base del gestor de pases. |
MultiStagePassManager(**etapas) | Un gestor de pases por etapas compatible con múltiples IR. |
Controladores de flujo
Columna « 1 » | Columna « 2 » |
|---|---|
BaseController( [opciones] ) | Clase base del controlador. |
FlowControllerLinear( [tareas, opciones] ) | Un controlador de flujo estándar que ejecuta las tareas una tras otra. |
ConditionalController( [tareas, condición,...] ) | Un controlador de flujo ejecuta la canalización una vez si la condición es verdadera, o no hace nada si la condición es falsa. |
DoWhileController( [tareas, do_while, opciones] ) | Ejecute las tareas dadas en un bucle hasta que la condición do_while en el conjunto de propiedades se convierta en False. |
Estado de compilación
Columna « 1 » | Columna « 2 » |
|---|---|
PropertySet | Un objeto tipo diccionario por defecto. |
WorkflowStatus( [recuento, pases_completados,...] ) | Recopilación del estado de compilación del flujo de trabajo, es decir, ejecución del gestor de pases. |
PassManagerState(estado_del_flujo_de_trabajo, propiedad_establecida) | Un objeto contenedor portátil que pasa tareas de gestión se comunican a través de generador. |
Excepciones
PassManagerError
exception qiskit.passmanager.PassManagerError(*message)
Bases: QiskitError
Error del gestor de pases.
Configura el mensaje de error.