Optimization Plans
ropt.plan
Code for executing optimization plans.
The Plan
class orchestrates optimization workflows by
managing steps and event handlers.
A plan consists of PlanStep
objects, which
define individual actions, and
EventHandler
objects, which process and
store data generated during execution. Both steps and event handlers are
implemented using a plugin mechanism, making it easy to
extend the range of supported actions and data processing. The ropt
library
provides default implementations through the default plan
handler and default plan
step plugins. These provide
basic steps and event handlers to support a wide range of optimization
workflows.
Setting up and executing a Plan
object for simple optimization cases can be
complex. The BasicOptimizer
class simplifies this
process by providing a convenient way to build and execute straightforward plans
involving a single optimization.
ropt.plan.Plan
Plan class for executing optimization workflows.
The Plan
object is the core component for executing optimization workflows.
It orchestrates the execution of individual steps, manages evaluators for
function computations, and processes data and results through event handlers.
Building a Plan:
A Plan
is constructed by adding three main types of components, typically
instantiated via the PluginManager
:
- Steps (
PlanStep
): These define individual actions or operations within the optimization workflow. Steps are added using theadd_step
method. - Event Handlers (
EventHandler
): These components process data, track results, or react to events emitted during plan execution. Event handlers are added using theadd_event_handler
method. - Evaluators (
Evaluator
): These are responsible for performing function evaluations (e.g., objective functions, constraints). Evaluators are added using theadd_evaluator
method and can be passed to steps that need them.
Tags:
Steps, event handlers, and evaluators can be assigned one or more tags.
These tags can be used to identify the components instead of their unique
IDs. Unlike ID's, tags do not need to be unique. This is useful when the
components are created dynamically or if multiple components are to be
identified as a group. For example, when specifying the source of events
that a handler should process, its sources
argument may contain both
component objects, which identifies by their ID, or tags, which could refer
to multiple components that have that tag.
Executing a Plan:
Once a plan is assembled, the run
method can be invoked for each step individually. This approach allows for
the integration of complex logic and custom functions, leveraging the full
capabilities of Python.
PluginManager:
A PluginManager
object can be provided that
is used by the plan object to find and instantiate step, event handler, and
evaluator objects. This manager can also be used by these components to
implement further plugin-based functionality.
Events:
Steps can communicate events by retrieving a list of handlers using the
event_handlers
property. Event handlers
can respond to these events, enabling actions such as processing
optimization results. Event handlers are added to the plan using the
add_event_handler
method. To connect
the event handlers to steps, they generally accept a set of steps via the
sources
argument. The steps must be part of the same plan, or a child plan
(if existent).
Evaluators:
Evaluators (Evaluator
) are key
components responsible for performing function evaluations, such as
computing objective functions or constraint values. They are added to the
plan using the add_evaluator
method. They
connect to the steps in the plan, or in child plans, via the clients
argument.
Nested Plans:
Multiple plans can be defined. A step within one plan can trigger the execution of another plan, enabling nested workflows.
Aborting a Plan:
A plan's execution can be terminated, either programmatically from within a
step or event handler, or externally by directly calling the
abort
method. The
aborted
property can be used to check if a plan
has been aborted.
Handler Data:
Individual event handlers may store values that they accumulate or calculate
from the events that they handle. Code outside of the event handlers, such
as the optimization workflow code that runs the steps, can set and retrieve
these values using the []
operator.
aborted
property
Check if the plan was aborted.
Determines whether the plan's execution has been aborted.
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
|
plugin_manager
property
Return the plugin manager.
Retrieves the PluginManager
object
associated with this plan.
Returns:
Type | Description |
---|---|
PluginManager
|
The plugin manager stored by the plan. |
event_handlers
property
Get the event handlers available to this plan.
Returns:
Type | Description |
---|---|
list[EventHandler]
|
A list of handlers. |
evaluators
property
__init__
__init__(
plugin_manager: PluginManager,
*,
event_handlers: list[EventHandler] | None = None,
evaluators: list[Evaluator] | None = None,
) -> None
Initialize a plan object.
Constructs a new plan, associating it with an evaluator, and optionally with a plugin manager and/or a event handlers and evaluators.
The plugin_manager
is used by the plan, and possibly by steps and
event handlers to add plugin functionality.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
plugin_manager
|
PluginManager
|
A plugin manager. |
required |
event_handlers
|
list[EventHandler] | None
|
Event handlers to add to the plan. |
None
|
evaluators
|
list[Evaluator] | None
|
Evaluators to add to the plan. |
None
|
add_event_handler
add_event_handler(
name: str,
tags: set[str] | None = None,
sources: set[PlanComponent | str] | None = None,
**kwargs: Any,
) -> EventHandler
Add an event handler to the plan.
Constructs and registers an event handler with the plan. The handler's
type is determined by the provided name
, which the plugin system uses
to locate the corresponding handler class. Any additional keyword
arguments are passed to the handler's constructor.
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.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name
|
str
|
The name of the event handler to add. |
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 the handler's constructor. |
{}
|
Returns:
Type | Description |
---|---|
EventHandler
|
The newly added event handler. |
add_step
Add a step to the plan.
Registers a step with the plan. The step's type is determined by the
provided name
, which the plugin system uses to locate the
corresponding step class. Any additional keyword arguments are passed to
the step's constructor.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name
|
str
|
The name of the step to add. |
required |
tags
|
set[str] | None
|
Optional tags |
None
|
kwargs
|
Any
|
Additional arguments for the step's constructor. |
{}
|
Returns:
Type | Description |
---|---|
PlanStep
|
The newly added step. |
add_evaluator
add_evaluator(
name: str,
tags: set[str] | None = None,
clients: set[PlanComponent | str] | None = None,
**kwargs: Any,
) -> Evaluator
Add an evaluator object to the plan.
Creates an evaluator of a type that is determined by the provided name
,
which the plugin system uses to locate the corresponding evaluator class.
Any additional keyword arguments are passed to the evaluators's constructor.
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 name of the evaluator to add. |
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 the evaluators's constructor. |
{}
|
Returns:
Type | Description |
---|---|
Evaluator
|
The new evaluator object. |
pre_run
Run checks before executing a step.
This method must be called by the run
method of step before executing
its function. If the plan has been aborted, a
PlanAborted
exception is raised before
the step is executed.
Raises:
Type | Description |
---|---|
PlanAborted
|
If the plan has been aborted. |
abort
Abort the plan.
Prevents further steps in the plan from being executed. This method does not interrupt a currently running step but ensures that no subsequent steps will be initiated. It can be used to halt the plan's execution due to a step failure or external intervention.
The aborted
property can be used to check if
the plan has been aborted.
ropt.plan.Event
dataclass
Stores data related to an optimization event.
During the execution of an optimization plan, events are triggered to signal
specific occurrences. Callbacks can be registered to react to these events
and will receive an Event
object containing relevant information.
The specific data within the Event
object varies depending on the event
type. See the EventType
documentation for details.
Attributes:
Name | Type | Description |
---|---|---|
event_type |
EventType
|
The type of event that occurred. |
data |
dict[str, Any]
|
A dictionary containing additional event-specific data. |