Skip to content

Plan Plugins

ropt.plugins.plan

Framework and Implementations for Optimization Plan Plugins.

This module provides the core components and default implementations for extending ropt's optimization plan capabilities (Plan) through plugins. It allows users to define custom sequences of operations (steps) and ways to process the results and events generated during plan execution (handlers).

Core Concepts:

  • Plan Steps: Represent individual actions within an optimization plan, such as running an optimizer or performing evaluations.
  • Plan Handlers: Process events emitted by the plan or its steps, enabling tasks like result tracking, data storage, or logging.
  • Evaluators: Perform the actual function evaluations (e.g., objective functions, constraints) required by the optimization process.

The implementation of these core concepts relies on classes derived from the following abstract base classes:

  1. Plugin Base Classes:

    • PlanStepPlugin: The base for plugins that create plan steps. These plugins are discovered by the PluginManager and used to instantiate actual PlanStep objects.
    • EventHandlerPlugin: The base for plugins that create event handlers. Similar to step plugins, these are used by the PluginManager to instantiate EventHandler objects.
    • EvaluatorPlugin: The base for plugins that create evaluators. These are used by the PluginManager to instantiate Evaluator objects, which are responsible for function computations.
  2. Component Base Classes:

    • PlanStep: The abstract base class that all concrete plan step implementations must inherit from. It defines the run method where the step's logic resides.
    • EventHandler: The abstract base class for all event handlers. It defines the handle_event method for processing events emitted during plan execution and allows storing state using dictionary-like access.
    • Evaluator: The abstract base class for all evaluators. It defines the eval method responsible for performing function computations.

By inheriting from these classes, developers can create custom steps and handlers that integrate seamlessly into the ropt optimization plan execution framework (Plan).

Built-in Plan Plugins:

ropt includes default plugins providing common plan components:

These built-in components allow for the construction of standard optimization workflows out-of-the-box, while the plugin architecture enables customization and extension.

ropt.plugins.plan.base.PlanComponent

Base class for components that are part of an optimization plan.

This class provides common functionality for components like steps, event handlers, and evaluators that are managed within a Plan.

Each PlanComponent is assigned a unique identifier (id) upon initialization, an optional tag (tag), and maintains a reference to its parent plan.

id property

id: UUID

Return the unique identifier of the event handler.

Returns:

Type Description
UUID

A UUID object representing the unique identifier of the event handler.

plan property

plan: Plan

Return the parent plan associated with this event handler.

Returns:

Type Description
Plan

The Plan object that owns this event handler.

tags property

tags: set[str]

Return the optional tags.

Returns:

Type Description
set[str]

The tags.

__init__

__init__(plan: Plan, tags: set[str] | None) -> None

Initialize the PlanComponent.

This constructor is called by subclasses to set up common attributes. It stores a reference to the parent plan, an optional tag, and assigns a unique id.

Parameters:

Name Type Description Default
plan Plan

The parent Plan instance.

required
tags set[str] | None

Optional tags

required

ropt.plugins.plan.base.PlanStepPlugin

Bases: Plugin

Abstract base class for plugins that create PlanStep instances.

This class defines the interface for plugins that act as factories for PlanStep objects.

The PluginManager uses the create class method of these plugins to instantiate PlanStep objects when they are added to an optimization Plan via Plan.add_step.

create abstractmethod classmethod

create(
    name: str,
    plan: Plan,
    tags: set[str] | None = None,
    **kwargs: Any,
) -> PlanStep

Create a PlanStep instance.

This abstract class method serves as a factory for creating concrete PlanStep objects. Plugin implementations must override this method to return an instance of their specific PlanStep subclass.

The PluginManager calls this method when a plan requests a step provided by this plugin via Plan.add_step.

The name argument specifies the requested step, potentially in the format "plugin-name/method-name" or just "method-name". Implementations can use this name to vary the created step if the plugin supports multiple step types.

The optional tags argument assigns the given string tags to the plan step. Similar to its id, the tags can be used for identification. However, unlike an id, a tag does not need to be unique, allowing multiple components to be grouped under the same tag.

Any additional keyword arguments (kwargs) passed during the Plan.add_step call are forwarded here, allowing for custom configuration of the step instance.

Parameters:

Name Type Description Default
name str

The requested step name (potentially plugin-specific).

required
plan Plan

The parent Plan instance.

required
tags set[str] | None

Optional tags

None
kwargs Any

Additional arguments for custom configuration.

{}

Returns:

Type Description
PlanStep

An initialized instance of a PlanStep subclass.

ropt.plugins.plan.base.EventHandlerPlugin

Bases: Plugin

Abstract Base Class for Plan Handler Plugins.

This class defines the interface for plugins responsible for creating EventHandler instances within an optimization plan (Plan).

During plan setup, the PluginManager identifies the appropriate event handler plugin based on a requested name and uses its create class method to instantiate the actual EventHandler object that will process events during plan execution.

create abstractmethod classmethod

create(
    name: str,
    plan: Plan,
    tags: set[str] | None = None,
    sources: set[PlanComponent | str] | None = None,
    **kwargs: Any,
) -> EventHandler

Create a EventHandler instance.

This abstract class method serves as a factory for creating concrete EventHandler objects. Plugin implementations must override this method to return an instance of their specific EventHandler subclass.

The PluginManager calls this method when a plan requests an event handler provided by this plugin via Plan.add_event_handler.

The name argument specifies the requested event handler, potentially in the format "plugin-name/method-name" or just "method-name". Implementations can use this name to vary the created event handler if the plugin supports multiple event handler types.

The optional tags argument assigns the given string tags to the event handler. Similar to its id, the tags can be used for identification. However, unlike an id, a tag does not need to be unique, allowing multiple components to be grouped under the same tag.

The sources parameter acts as a filter, determining which plan steps this event handler should listen to. It should be a set containing the PlanStep instances whose event you want to receive. When an event is received, this event handler checks if the step that emitted the event (event.source) is present in the sources set. If sources is None, events from all sources will be processed.

Any additional keyword arguments (kwargs) passed during the Plan.add_event_handler call are forwarded here, allowing for custom configuration of the event handler instance.

Parameters:

Name Type Description Default
name str

The requested event handler name (potentially plugin-specific).

required
plan Plan

The parent Plan instance.

required
tags set[str] | None

Optional tags

None
sources set[PlanComponent | str] | None

The steps whose events should be processed.

None
kwargs Any

Additional arguments for custom configuration.

{}

Returns:

Type Description
EventHandler

An initialized instance of a EventHandler subclass.

ropt.plugins.plan.base.EvaluatorPlugin

Bases: Plugin

Abstract base class for evaluator plugins.

This class defines the interface for plugins responsible for creating plan-aware Evaluator instances within an optimization plan (Plan).

During plan setup, the PluginManager identifies the appropriate evaluator plugin based on a requested name and uses its create class method to instantiate the actual Evaluator object that will perform evaluations during plan execution.

create abstractmethod classmethod

create(
    name: str,
    plan: Plan,
    tags: set[str] | None = None,
    clients: set[PlanComponent | str] | None = None,
    **kwargs: Any,
) -> Evaluator

Create an Evaluator instance.

This abstract class method serves as a factory for creating concrete Evaluator objects. Plugin implementations must override this method to return an instance of their specific Evaluator subclass.

The PluginManager calls this method when an evaluator provided by this plugin is requested.

The name argument specifies the requested evaluator, potentially in the format "plugin-name/method-name" or just "method-name". Implementations can use this name to vary the created evaluator if the plugin supports multiple evaluator types.

The optional tags argument assigns the given string tags to the evaluator. Similar to its id, the tags can be used for identification. However, unlike an id, a tag does not need to be unique, allowing multiple components to be grouped under the same tag.

The clients parameter acts as a filter, determining which plan steps this evaluator should serve. It should be a set containing the PlanStep instances that should be handled. When an evaluation is requested, this evaluator checks if the step is present in the client set.

Parameters:

Name Type Description Default
name str

The requested evaluator name (potentially plugin-specific).

required
plan Plan

The parent Plan instance.

required
tags set[str] | None

Optional tags

None
clients set[PlanComponent | str] | None

The clients that should be served by this evaluator.

None
kwargs Any

Additional arguments for custom configuration.

{}

Returns:

Type Description
Evaluator

An initialized instance of an Evaluator subclass.

ropt.plugins.plan.base.PlanStep

Bases: ABC, PlanComponent

Abstract base class for optimization plan steps.

This class defines the fundamental interface for all executable steps within an optimization Plan. Concrete step implementations, which perform specific actions like running an optimizer or evaluating functions, must inherit from this base class.

PlanStep objects are typically created by corresponding PlanStepPlugin factories, which are managed by the PluginManager. Once instantiated and added to a Plan, their run_step_from_plan method is called by the plan during execution. This is generally done indirectly by calling the run method on the step object.

Subclasses must implement the abstract run_step_from_plan method to define the step's specific behavior.

__init__

__init__(plan: Plan, tags: set[str] | None = None) -> None

Initialize the PlanStep.

Associates the step with its parent Plan and assigns a unique ID. The parent plan is accessible via the plan property.

Parameters:

Name Type Description Default
plan Plan

The Plan instance that owns this step.

required
tags set[str] | None

Optional tags

None

run

run(*args: Any, **kwargs: Any) -> Any

Execute this plan step.

This method initiates the execution of the current plan step. It delegates the actual execution to the parent Plan object's run_step method, passing itself (the step instance) along with any provided arguments.

The parent Plan then calls the concrete run_step_from_plan method implemented by the subclass of this PlanStep. This allows the plan to do some bookkeeping, for instance to check if the plan was aborted.

Parameters:

Name Type Description Default
*args Any

Positional arguments to be passed to the step's specific run_step method.

()
**kwargs Any

Keyword arguments to be passed to the step's specific run_step method.

{}

Returns:

Type Description
Any

The result returned by the step's specific run_step_from_plan method.

run_step_from_plan abstractmethod

run_step_from_plan(*args: Any, **kwargs: Any) -> Any

Execute the logic defined by this plan step.

This abstract method must be implemented by concrete PlanStep subclasses to define the specific action the step performs within the optimization Plan.

The Plan object calls this method during its execution sequence, passing any arguments provided when the step was invoked via Plan.run_step. The return value and type can vary depending on the specific step implementation.

Parameters:

Name Type Description Default
args Any

Positional arguments passed from Plan.run_step.

()
kwargs Any

Keyword arguments passed from Plan.run_step.

{}

Returns:

Type Description
Any

The result of the step's execution, if any.

ropt.plugins.plan.base.EventHandler

Bases: ABC, PlanComponent

Abstract Base Class for Optimization Plan Result Handlers.

This class defines the fundamental interface for all event handlers within an optimization Plan. Concrete handler implementations, which process events emitted during plan execution (e.g., tracking results, storing data, logging), must inherit from this base class.

EventHandler objects are typically created by corresponding EventHandlerPlugin factories, managed by the PluginManager. Once instantiated and added to a Plan, their handle_event method is called by the plan whenever an Event is emitted.

Handlers can also store state using dictionary-like access ([]), allowing them to accumulate information or make data available to subsequent steps or event handlers within the plan.

Subclasses must implement the abstract handle_event method to define their specific event processing logic.

sources property

sources: set[UUID | str]

Return the source IDs or tags that are listened to.

Returns:

Type Description
set[UUID | str]

The source IDs or tags this event handler is interested in.

event_types abstractmethod property

event_types: set[EventType]

Return the event types that are handled.

Returns:

Type Description
set[EventType]

A set of event types that are handled.

__init__

__init__(
    plan: Plan,
    tags: set[str] | None = None,
    sources: set[PlanComponent | str] | None = None,
) -> None

Initialize the EventHandler.

Associates the event handler with its parent Plan, assigns a unique ID, and initializes an internal dictionary for storing state. The parent plan is accessible via the plan property.

The sources parameter acts as a filter, determining which plan steps this event handler should listen to. It should be a set containing the components or tags that should be handled. When an event is received, this event handler checks if the component, or one of its tag, is present in the sources set.

Parameters:

Name Type Description Default
plan Plan

The Plan instance that owns this event handler.

required
tags set[str] | None

Optional tags

None
sources set[PlanComponent | str] | None

Optional set of steps whose events should be processed.

None

handle_event abstractmethod

handle_event(event: Event) -> None

Process an event emitted by the optimization plan.

This abstract method must be implemented by concrete EventHandler subclasses. It defines the event handler's core logic for reacting to Event objects emitted during the execution of the parent Plan.

Implementations should inspect the event object (its event_type and data) and perform actions accordingly, such as storing results, logging information, or updating internal state.

Parameters:

Name Type Description Default
event Event

The event object containing details about what occurred in the plan.

required

__getitem__

__getitem__(key: str) -> Any

Retrieve a value from the event handler's internal state.

This method enables dictionary-like access (handler[key]) to the values stored within the event handler's internal state dictionary. This allows handlers to store and retrieve data accumulated during plan execution.

Parameters:

Name Type Description Default
key str

The string key identifying the value to retrieve.

required

Returns:

Type Description
Any

The value associated with the specified key.

Raises:

Type Description
AttributeError

If the provided key does not exist in the event handler's stored values.

__setitem__

__setitem__(key: str, value: Any) -> None

Store or update a value in the event handler's internal state.

This method enables dictionary-like assignment (handler[key] = value) to store arbitrary data within the event handler's internal state dictionary. This allows event handlers to accumulate information or make data available to other components of plan.

The key must be a valid Python identifier.

Parameters:

Name Type Description Default
key str

The string key identifying the value to store (must be an identifier).

required
value Any

The value to associate with the key.

required

Raises:

Type Description
AttributeError

If the provided key is not a valid identifier.

ropt.plugins.plan.base.Evaluator

Bases: ABC, PlanComponent

abstract base class for evaluator components within an optimization plan.

Subclasses must implement the abstract eval method, which is responsible for performing the actual evaluation of variables using an EvaluatorContext and returning an EvaluatorResult.

clients property

clients: set[UUID | str]

Return the client IDs or tags that are served.

Returns:

Type Description
set[UUID | str]

The IDs of the clients, or the tags, this evaluator will handle.

__init__

__init__(
    plan: Plan,
    tags: set[str] | None = None,
    clients: set[PlanComponent | str] | None = None,
) -> None

Initialize the Evaluator.

Associates the evaluator with its parent Plan, and assigns a unique ID. The parent plan is accessible via the plan property.

The clients parameter acts as a filter, determining which plan steps this evaluator should serve. It should be a set containing the the components or tags that should be handled. When an evaluation is requested, this evaluator checks if the component, or one of its tags, is present in the client set.

Parameters:

Name Type Description Default
plan Plan

The Plan instance that owns this evaluator.

required
tags set[str] | None

Optional tags

None
clients set[PlanComponent | str] | None

The steps that use this evaluator.

None

eval abstractmethod

eval(
    variables: NDArray[float64], context: EvaluatorContext
) -> EvaluatorResult

Evaluate objective and constraint functions for given variables.

This method defines function evaluator callback, which calculates objective and constraint functions for a set of variable vectors, potentially for a subset of realizations and perturbations.

Parameters:

Name Type Description Default
variables NDArray[float64]

The matrix of variables to evaluate. Each row represents a variable vector.

required
context EvaluatorContext

The evaluation context, providing additional information about the evaluation.

required

Returns:

Type Description
EvaluatorResult

An evaluation results object containing the calculated values.

Reusing Objectives and Constraints

When defining multiple objectives, there may be a need to reuse the same objective or constraint value multiple times. For instance, a total objective could consist of the mean of the objectives for each realization, plus the standard deviation of the same values. This can be implemented by defining two objectives: the first calculated as the mean of the realizations, and the second using a function estimator to compute the standard deviations. The optimizer is unaware that both objectives use the same set of realizations. To prevent redundant calculations, the evaluator should compute the results of the realizations once and return them for both objectives.

add_clients

add_clients(
    clients: PlanComponent
    | str
    | Sequence[PlanComponent | str]
    | set[PlanComponent | str],
) -> None

Add one or more clients to the evaluator.

Parameters:

Name Type Description Default
clients PlanComponent | str | Sequence[PlanComponent | str] | set[PlanComponent | str]

The clients to add.

required

remove_clients

remove_clients(
    clients: PlanComponent
    | str
    | Sequence[PlanComponent | str]
    | set[PlanComponent | str],
) -> None

Remove one or more clients from the evaluator.

Parameters:

Name Type Description Default
clients PlanComponent | str | Sequence[PlanComponent | str] | set[PlanComponent | str]

The clients to remove.

required