Simple API
ropt.simple
The high-level convenience API for running optimizations.
This module builds on the low-level ropt primitives. Import its names
directly, for example from ropt.simple import optimize, session. See
Running Optimizations for a walkthrough.
Enumerations used in the configuration and results (for example
ExitCode and VariableType)
are not re-exported here; import them from ropt.enums.
Nothing about a run depends on where it is called from. Where its evaluations
happen is decided by the pool it is given with pool=, and which handlers see
its results by the handlers= it is given. A session
hands out both; a run given no pool evaluates in-process. This holds wherever
the run is started from, including a thread you spawn yourself.
Running optimizations
ropt.simple.optimize
optimize(
config: dict[str, Any],
x0: ArrayLike,
function: EvaluationFunction,
*,
pool: WorkerPool | None = None,
handlers: Sequence[EventHandler | SharedHandlers]
| None = None,
report: ReportCallback | None = None,
constraint_tolerance: float = 1e-10,
metadata: dict[str, Any] | None = None,
) -> OptimizationResult
Run a single optimization.
See Running Optimizations for a walkthrough.
A pool or group that is closed — because it was closed directly, or
because its session ended — is refused here with a
WorkflowError, as is one carried into
a worker process, where it cannot work at all.
Without a pool the evaluations run in-process, on the calling thread. A
run started from inside an evaluation needs a different pool: the pool it
is already running on refuses the work.
handlers mixes two kinds. An
EventHandler is local: it
is claimed for the duration of this run, and may be reused by a later run to
accumulate results, but not shared with a concurrent one, and never
afterwards with a SharedHandlers group. A
group is shared: this run feeds it alongside every other run that lists it.
Returning True from report stops the optimization early with
USER_ABORT. Reporting stops there, so results after it in the same batch
are not passed on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
dict[str, Any]
|
The optimization configuration. |
required |
x0
|
ArrayLike
|
The initial variable vector. |
required |
function
|
EvaluationFunction
|
The per-realization evaluation function. |
required |
pool
|
WorkerPool | None
|
The pool to evaluate on, from a session factory. |
None
|
handlers
|
Sequence[EventHandler | SharedHandlers] | None
|
Optional local handlers and shared groups. |
None
|
report
|
ReportCallback | None
|
Optional callback invoked per function evaluation. |
None
|
constraint_tolerance
|
float
|
The tolerance within which a constraint is satisfied. |
1e-10
|
metadata
|
dict[str, Any] | None
|
Optional dictionary attached to every emitted result. |
None
|
Returns:
| Type | Description |
|---|---|
OptimizationResult
|
An |
ropt.simple.optimize_many
optimize_many(
config: dict[str, Any] | Sequence[dict[str, Any]],
x0: ArrayLike,
function: EvaluationFunction
| Sequence[EvaluationFunction],
*,
pool: WorkerPool | None = None,
handlers: Sequence[SharedHandlers] | None = None,
report: ReportCallback
| Sequence[ReportCallback]
| None = None,
limit: int | None = None,
constraint_tolerance: float = 1e-10,
metadata: dict[str, Any]
| Sequence[dict[str, Any]]
| None = None,
) -> tuple[OptimizationResult, ...]
Run several optimizations concurrently, sharing one pool.
Each of config, x0, and function may be a single value (used for
every run) or a sequence (one per run). Sequences set the number of runs and
must agree in length; single values are broadcast. A single x0 is a 1-D
vector; a per-run sequence of x0s is a 2-D matrix with one vector per row.
A sequence that is empty gives no runs, and returns no results.
The runs execute concurrently on driver threads and all evaluate on the
same pool, so its workers are shared between them; limit bounds how
many run simultaneously. Without a pool the runs still overlap, but each
evaluation runs in-process on its own driver thread, so function is then
called by several threads at once and must tolerate that. See
Parallel Execution and Many Runs
for a walkthrough, and Failure in one run
for what happens when one raises.
Unlike optimize, this takes no local handlers: a local handler belongs
to one run at a time and these runs overlap, so handlers= accepts only
SharedHandlers groups, which every run feeds
together. report=, being local by nature, is the opposite: it is given per
run, or broadcast to all of them.
A pool or group that is closed — because it was closed directly, or
because its session ended — is refused here with a
WorkflowError, as is one carried into
a worker process, where it cannot work at all.
A run started from inside an evaluation needs a different pool: the pool
it is already running on refuses the work. Returning True from a report
callback stops that run early with USER_ABORT. metadata also reaches
each run's function as context.metadata, which makes it a way to tag a
run, for example with {"run_id": i}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
dict[str, Any] | Sequence[dict[str, Any]]
|
The configuration, or one per run. |
required |
x0
|
ArrayLike
|
The initial variable vector, or one per row. |
required |
function
|
EvaluationFunction | Sequence[EvaluationFunction]
|
The evaluation function, or one per run. |
required |
pool
|
WorkerPool | None
|
The pool every run evaluates on. |
None
|
handlers
|
Sequence[SharedHandlers] | None
|
Optional shared groups, fed by every run. |
None
|
report
|
ReportCallback | Sequence[ReportCallback] | None
|
Optional callback per evaluation, shared or one per run. |
None
|
limit
|
int | None
|
The maximum number of runs to execute at once. |
None
|
constraint_tolerance
|
float
|
The tolerance within which a constraint is satisfied. |
1e-10
|
metadata
|
dict[str, Any] | Sequence[dict[str, Any]] | None
|
Optional dictionary attached to every emitted result. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[OptimizationResult, ...]
|
One |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If |
Evaluating without optimizing
ropt.simple.evaluate
evaluate(
config: dict[str, Any],
variables: ArrayLike,
function: EvaluationFunction,
*,
pool: WorkerPool | None = None,
handlers: Sequence[EventHandler | SharedHandlers]
| None = None,
report: ReportCallback | None = None,
metadata: dict[str, Any] | None = None,
) -> FunctionResults
Evaluate a single variable vector without optimizing.
Use evaluate_many to evaluate several
vectors at once. See Running Optimizations for a
walkthrough.
A pool or group that is closed — because it was closed directly, or
because its session ended — is refused here with a
WorkflowError, as is one carried into
a worker process, where it cannot work at all.
Without a pool the evaluations run in-process, on the calling thread. A
run started from inside an evaluation needs a different pool: the pool it
is already running on refuses the work. handlers mixes local
EventHandler objects with
shared SharedHandlers groups, as
optimize takes them.
An evaluation is a single batch that has already run by the time report
sees it, and there is no optimizer loop to interrupt, so unlike on
optimize returning True cannot stop anything: it
only ends the reporting, and every result is still returned. metadata also
reaches function as context.metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
dict[str, Any]
|
The optimization configuration. |
required |
variables
|
ArrayLike
|
The variable vector to evaluate. |
required |
function
|
EvaluationFunction
|
The per-realization evaluation function. |
required |
pool
|
WorkerPool | None
|
The pool to evaluate on, from a session factory. |
None
|
handlers
|
Sequence[EventHandler | SharedHandlers] | None
|
Optional local handlers and shared groups. |
None
|
report
|
ReportCallback | None
|
Optional callback invoked with each evaluation's results. |
None
|
metadata
|
dict[str, Any] | None
|
Optional dictionary attached to the emitted results. |
None
|
Returns:
| Type | Description |
|---|---|
FunctionResults
|
The |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
ropt.simple.evaluate_many
evaluate_many(
config: dict[str, Any],
variables: ArrayLike,
function: EvaluationFunction,
*,
pool: WorkerPool | None = None,
handlers: Sequence[EventHandler | SharedHandlers]
| None = None,
report: ReportCallback | None = None,
metadata: dict[str, Any] | None = None,
) -> tuple[FunctionResults, ...]
Evaluate a batch of variable vectors without optimizing.
Each row of variables is one variable vector; the results are returned in
the same order. See Running Optimizations for a
walkthrough.
A pool or group that is closed — because it was closed directly, or
because its session ended — is refused here with a
WorkflowError, as is one carried into
a worker process, where it cannot work at all.
Without a pool the evaluations run in-process, on the calling thread. A
run started from inside an evaluation needs a different pool: the pool it
is already running on refuses the work. handlers mixes local
EventHandler objects with
shared SharedHandlers groups, as
optimize takes them.
An evaluation is a single batch that has already run by the time report
sees it, and there is no optimizer loop to interrupt, so unlike on
optimize returning True cannot stop anything: it
only ends the reporting, and every result is still returned. metadata also
reaches function as context.metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
dict[str, Any]
|
The optimization configuration. |
required |
variables
|
ArrayLike
|
The variable vectors to evaluate, one per row. |
required |
function
|
EvaluationFunction
|
The per-realization evaluation function. |
required |
pool
|
WorkerPool | None
|
The pool to evaluate on, from a session factory. |
None
|
handlers
|
Sequence[EventHandler | SharedHandlers] | None
|
Optional local handlers and shared groups. |
None
|
report
|
ReportCallback | None
|
Optional callback invoked with each evaluation's results. |
None
|
metadata
|
dict[str, Any] | None
|
Optional dictionary attached to every emitted result. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[FunctionResults, ...]
|
One |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Evaluation functions
ropt.simple.EvaluationFunctionContext
dataclass
Context for a single function evaluation.
Attributes:
| Name | Type | Description |
|---|---|---|
realization |
int
|
The realization index. |
perturbation |
int
|
The perturbation index ( |
batch_id |
int
|
Integer identifying the current evaluation batch. |
eval_idx |
int
|
Row index within the batch. |
metadata |
dict[str, Any] | None
|
The metadata the run was started with, if any. |
ropt.simple.EvaluationFunctionResult
dataclass
Result of a single function evaluation.
Attributes:
| Name | Type | Description |
|---|---|---|
objectives |
NDArray[float64] | float
|
The objective values as an array. |
constraints |
NDArray[float64] | float | None
|
Optional constraint values as an array. |
metadata |
dict[str, Any] | None
|
Optional dictionary with extra information. |
Sessions and pools
ropt.simple.session
Open a background session that pools and shared handlers run on.
The session owns one event loop, on a daemon thread, for as long as the block is open. Build pools on it with its factories, and pass them to the runs that should use them. Closing the session releases every pool it created, so most code needs no further cleanup. See Running Optimizations for a walkthrough.
Returns:
| Type | Description |
|---|---|
Session
|
A context manager binding the |
ropt.simple.Session
An open session, and the factories that build on it.
A session owns one background event loop, on its own daemon thread. Pools need that loop to run on, which is why they are built here rather than constructed on their own. Everything a session creates is returned to the caller and passed on explicitly; nothing is discovered from the surroundings.
Bind the session with as and call its factories inside the block. See
Running Optimizations.
A session may be opened inside another: each gets its own loop, and pools from different sessions never interact. A session is single use — once closed it cannot be reopened.
__enter__
Open the session's event loop.
Returns:
| Type | Description |
|---|---|
Self
|
The session itself. |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the session was already opened. |
thread_pool
Create a pool that runs evaluations in worker threads.
See Running Optimizations for a walkthrough.
bundle_size matters more on a
process_pool, where a task is
transferred between processes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workers
|
int
|
The number of worker threads. |
1
|
bundle_size
|
int
|
Evaluations per task, |
1
|
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool backed by a thread pool. |
process_pool
Create a pool that runs evaluations in worker processes.
The evaluation function must be picklable. See Running Optimizations for a walkthrough.
Closing the pool terminates its worker processes and nothing else. A
program an evaluation started itself keeps running, without an error
being raised; use local_pool where
an evaluation launches external programs.
Every task is transferred to a worker separately, and the evaluations
within one run after another, so bundle_size is a trade between
spreading a batch and the cost of moving it. The default of 1 gives
every evaluation its own task, spreading a batch as widely as the
workers allow; a larger value groups that many per task; and 0 sends
the whole batch as a single task, which suits a pool whose parallelism
comes from the runs above it rather than from within a batch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workers
|
int
|
The number of worker processes. |
1
|
bundle_size
|
int
|
Evaluations per task, |
1
|
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool backed by a process pool. |
local_pool
local_pool(
*,
workers: int = 1,
workdir: Path | str | None = None,
retries: int = 0,
bundle_size: int = 1,
) -> WorkerPool
Create a pool that runs each evaluation as a separate local process.
Between a process pool and a cluster: every evaluation gets an
interpreter of its own, which can be stopped outright and whose output
is captured to a file, but there is no queueing system and nothing to
install. This is the local stand-in for
hpc_pool: the same job shape, so an
evaluation function that works here works there.
Each job is a fresh command rather than a re-import of your script, so
the evaluation function must live in a module the job can import, or
the ropt[cloudpickle] extra must be installed.
POSIX only. See Running Optimizations for a walkthrough.
The default workdir is a temporary directory that is removed when the
pool closes, unless an evaluation failed, in which case it is kept, with
that evaluation's output in it, and its path logged. The retries
default of 0 is enough here: a local job writes its result before it
exits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workers
|
int
|
The maximum number of concurrent local jobs. |
1
|
workdir
|
Path | str | None
|
The directory holding each evaluation's files. |
None
|
retries
|
int
|
Extra polls to wait for a result. |
0
|
bundle_size
|
int
|
Evaluations per task, |
1
|
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool backed by local processes. |
hpc_pool
hpc_pool(
*,
workers: int = 1,
cores: int = 1,
cluster: str | None = None,
queue: str | None = None,
workdir: Path | str | None = None,
config_path: Path | str | None = None,
template: str | None = None,
scheduler: str | None = None,
memory_max: int | str | None = None,
run_time_max: int | None = None,
submit_options: dict[str, Any] | None = None,
retries: int = 30,
bundle_size: int = 1,
) -> WorkerPool
Create a pool that runs evaluations on an HPC cluster.
Interfaces with a cluster queue (for example Slurm) through pysqa;
requires the ropt[hpc] extra. Each evaluation is a job started as its
own command, so the evaluation function must live in a module the
compute nodes can import, or the ropt[cloudpickle] extra must be
installed. Develop
against local_pool first: it has the
same shape and the same rule, without a cluster. The cluster is selected
from cluster/queue: give a queue to search for its cluster, a
cluster to use its default queue, or both to be explicit.
A template is the alternative to all of that: it submits without a
configuration, so it cannot be combined with config_path, cluster or
queue. See Running on an HPC
cluster for the
configuration layout and Slurm examples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
workers
|
int
|
The maximum number of concurrent cluster jobs. |
1
|
cores
|
int
|
The number of CPUs per job. |
1
|
cluster
|
str | None
|
The cluster name. |
None
|
queue
|
str | None
|
The queue name. |
None
|
workdir
|
Path | str | None
|
The shared-filesystem working directory. |
None
|
config_path
|
Path | str | None
|
The |
None
|
template
|
str | None
|
A submission-script template. |
None
|
scheduler
|
str | None
|
The queueing system a |
None
|
memory_max
|
int | str | None
|
The memory per job. |
None
|
run_time_max
|
int | None
|
The run time per job. |
None
|
submit_options
|
dict[str, Any] | None
|
Extra variables for the submission script. |
None
|
retries
|
int
|
Number of retries for polling the cluster for results. |
30
|
bundle_size
|
int
|
Evaluations per task, |
1
|
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool backed by an HPC cluster. |
serial_pool
Create a pool that evaluates in-process, on the calling thread.
Identical to the free serial_pool function,
except that this pool is closed when the session closes, so runs cannot
keep using it afterwards. The free function returns a pool that is tied
to no session.
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool without an executor. |
shared_handlers
shared_handlers(
*handler: EventHandler,
threaded: EventHandler | Sequence[EventHandler] = (),
report: ReportCallback | None = None,
) -> SharedHandlers
Group result handlers that several runs share.
Pass the group to every run that should feed it, in handlers=. Each
handler then sees the results of all those runs, serialized across them,
which is what makes accumulating over concurrent runs safe. A run may
feed several groups, and mix them with handlers of its own.
A handler joins one group at a time, and a handler that was ever passed to a run as a local handler cannot join a group at all; decide per handler whether it is local or shared. See Running Optimizations for a walkthrough.
Handlers run on the session's event-loop thread unless listed in
threaded. Running one on a worker thread only helps if it spends real
time in blocking, GIL-releasing I/O (files, databases, network); for
in-memory work it gives no benefit under CPython's GIL. See
Result Handlers.
Returning True from report stops the emitting run early with
USER_ABORT if it is an optimization; an evaluation has no optimizer
loop to interrupt, so there the return value is ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handler
|
EventHandler
|
The result handlers to share. |
()
|
threaded
|
EventHandler | Sequence[EventHandler]
|
Handlers to run on a worker thread instead of the loop. |
()
|
report
|
ReportCallback | None
|
Optional callback invoked per evaluation across the group. |
None
|
Returns:
| Type | Description |
|---|---|
SharedHandlers
|
A |
ropt.simple.WorkerPool
The workers that run evaluations, and the batch IDs they share.
Created by a session factory such as
thread_pool. Every run using the same
pool draws its batch IDs from the same counter, so concurrent runs never
produce the same batch ID.
A pool lives until its session closes, which releases it. Release it earlier
with close, or by using it as a context
manager. See Running Optimizations for a
walkthrough.
A pool built by serial_pool has no executor and
no workers to release; it exists to give runs one batch-ID sequence, whether
or not they run in parallel.
__init__
__init__(
executor: Executor | None = None,
session: _Session | None = None,
bundle_size: int = 1,
) -> None
Initialize the pool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
executor
|
Executor | None
|
The started executor, or |
None
|
session
|
_Session | None
|
The session that owns the pool, if it has one. |
None
|
bundle_size
|
int
|
Evaluations per worker task, |
1
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
closed
property
Whether the pool has been released.
Returns:
| Type | Description |
|---|---|
bool
|
|
executor
property
The executor that runs this pool's evaluations.
Returns:
| Type | Description |
|---|---|
Executor | None
|
The executor, or |
batch_ids
property
The counter every run on this pool draws its batch IDs from.
Returns:
| Type | Description |
|---|---|
BatchIdCounter
|
The batch ID counter. |
bundle_size
property
How many evaluations are sent to a worker as one task.
Returns:
| Type | Description |
|---|---|
int
|
The number of evaluations per task, |
close
Release the pool's workers without waiting for the session to close.
See Releasing a pool early for when this matters and the resulting lifecycle.
__enter__
ropt.simple.serial_pool
Create a pool that evaluates in-process, on the calling thread.
A serial pool has no workers: it carries only the batch-ID counter that the runs sharing it draw from. Use it to give concurrent runs one batch-ID sequence without running their evaluations in parallel, or as an explicit way to say that a run should evaluate in-process.
It needs no session, and needs no releasing.
Returns:
| Type | Description |
|---|---|
WorkerPool
|
A pool without an executor. |
Offloading work to a pool
ropt.simple.offload
offload(
work: Callable[[], _T] | Sequence[Callable[[], _T]],
*,
pool: WorkerPool | None = None,
) -> _T | tuple[_T, ...]
Offload one or more callables to a pool.
Pass a single zero-argument callable to run one call and return its result,
or a sequence of callables to run them concurrently (they may be entirely
different functions) and return a tuple of results in the order of work.
Bind arguments with functools.partial.
Without a pool, or with a serial_pool, the
callables run inline on the calling thread, one after another. Code that may
or may not have a pool to hand therefore needs no fallback: pass whatever it
has, including None. The callables must be picklable for a process or HPC
pool.
See Running Optimizations for a walkthrough.
A handler in a shared group runs on the session's own event loop and cannot
wait on it; offloading from there raises a
WorkflowError. So does a pool that is
closed, or one carried into a worker process. A call that the machinery
could not run, for instance because its worker process was killed, raises an
ExecutionError. Work offloaded from
inside an evaluation needs a different pool: the pool it is already
running on refuses it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
work
|
Callable[[], _T] | Sequence[Callable[[], _T]]
|
A single zero-argument callable, or a sequence of them. |
required |
pool
|
WorkerPool | None
|
The pool to dispatch to, or |
None
|
Returns:
| Type | Description |
|---|---|
_T | tuple[_T, ...]
|
The single result, or a tuple of results in the order of |
Handlers
ropt.simple.EventHandler
Bases: ABC
Abstract base class for event handlers.
A concrete handler reacts to the events emitted by a
ComputeStep it is attached to,
by implementing
handle_event.
Handlers may store state using dictionary-like access ([]).
Note
A handler's handle_event is not re-entrant, and not safe to call from
two threads at once: both raise WorkflowError. Register a handler
shared across concurrently running steps with an
EventDispatcher
instead, which serializes the calls. See
Optimization Workflows and
Event dispatcher for usage
and pitfalls.
claim
Claim this handler for exclusive use by one run at a time.
Claiming marks the handler as dedicated to a single consumer, such as
one optimization run, until it is released with
release. While a
claim is held, a second claim raises, so a handler can never be shared by
two runs at once; releasing it at the end of a run lets the same handler
be reused by a later, sequential run, for example to accumulate results.
Handlers meant to aggregate across concurrent runs are not claimed;
they are shared explicitly through an
EventDispatcher.
This claim is independent of the attachment to a dispatcher or a compute
step, and of the transient concurrency guard on handle_event.
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If the handler is currently claimed. |
release
Release a claim taken with claim so the handler can be reused.
Clears the exclusive-use flag, letting a later run claim the handler again, for example to accumulate results across sequential runs. The attachment to a dispatcher or a compute step is left untouched. Releasing an unclaimed handler is a no-op.
event_types
abstractmethod
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
handle_event
React to an emitted event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
Raises:
| Type | Description |
|---|---|
WorkflowError
|
If this handler is already running on another thread. |
__getitem__
Retrieve a stored value by key (handler[key]).
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 |
__setitem__
Store or update a value in the internal state (handler[key] = value).
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 |
ropt.simple.ResultsHandler
Bases: EventHandler
Track a single optimization result based on selection criteria.
Listens for FINISHED_EVALUATION events and retains either the best
(lowest weighted objective) or most recent valid result. Optionally
filters by constraint tolerance. The selected result is accessible via the
result property or
handler["results"].
See Result Handlers for full details on selection criteria and scaling.
__init__
__init__(
*,
what: Literal["best", "last"] = "best",
constraint_tolerance: float | None = None,
filter: Callable[[Results], bool] | None = None,
) -> None
Initialize the ResultsHandler.
Constraint violations are compared in the domain the optimizer works in, so a scale applies to them as well.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
what
|
Literal['best', 'last']
|
Criterion for selecting results ('best' or 'last'). |
'best'
|
constraint_tolerance
|
float | None
|
Optional threshold for constraint violations. |
None
|
filter
|
Callable[[Results], bool] | None
|
Optional callable to filter results based on custom logic. |
None
|
result
property
The selected (best or last) result, or None if none is available.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
ropt.simple.HistoryHandler
Bases: EventHandler
Collect all optimization results into a tuple.
Listens for FINISHED_EVALUATION events and appends every
Results object to a growing tuple accessible
via the results
property or handler["results"].
See Result Handlers for full details on scaling and accumulation behavior.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
ropt.simple.DataFrameHandler
Bases: EventHandler
Build pandas or polars DataFrames from optimization results.
Collects FunctionResults and
GradientResults into named tables.
Tables are defined via add_table with a column specification, or
registered in bulk with set_default_tables.
The frame library is chosen with the engine argument. The "polars"
engine, the default, produces long-format tables in which batch and axis
labels are ordinary leading columns; the "pandas" engine produces tables
indexed by those instead.
Access tables via dictionary syntax: handler["functions"].
Warning
Tables are generated on the fly from internal data when accessing them in this way. When multiple accesses are needed, it is more efficient to first store them in a variable.
See Result Handlers for the column specification, default tables, and callback details.
__init__
Initialize a default table event handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
engine
|
DataFrameEngine
|
Frame library used to build the tables. |
'polars'
|
sep
|
str
|
Separator used in column names. |
','
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
UnsupportedError
|
If the selected frame library is not installed. |
engine
property
The frame library used to build the tables.
Returns:
| Type | Description |
|---|---|
DataFrameEngine
|
Either |
set_default_tables
Register a standard set of result tables.
Adds the default functions, evaluations, and constraints tables
for function results, and the default gradients and perturbations
tables for gradient results.
set_callback
Set a function to call whenever the tables are updated.
The callback receives the output directory configured for the run
(OptimizerConfig.output_dir, None if
it is not set), and reads the tables from this handler. If it performs
blocking operations (for example writing tables to disk), register this
handler with run_in_thread=True on the
EventDispatcher. See
Optimization Workflows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[Path | None], None]
|
A function that is called when the tables are updated. |
required |
add_table
add_table(
name: str,
table_type: Literal["functions", "gradients"],
columns: dict[str, str],
) -> None
Register a new table to be populated from incoming results.
Column keys are result-field attribute names, in dotted attribute syntax.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Key under which the table is stored and looked up. |
required |
table_type
|
Literal['functions', 'gradients']
|
Fill from |
required |
columns
|
dict[str, str]
|
Mapping from field paths to display titles. |
required |
get_tables
Return the tables stored in the event handler.
Returns:
| Type | Description |
|---|---|
dict[str, DataFrame | DataFrame]
|
A dictionary mapping table names to their corresponding tables. |
Warning
Tables are generated on the fly from internal data. When multiple access is needed, it is more efficient to first store them in a variable.
event_types
property
The event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__getitem__
Retrieve a of a table from the event handler.
Warning
The table is generated on the fly from internal data hen multiple access are needed, it is more efficient to first store them in a variable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the table to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The table associated with the specified key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If the requested table does not exist. |
add_column
Aggregating results across runs
ropt.simple.SharedHandlers
A group of result handlers that several runs share.
Created by shared_handlers and
passed to the runs that should feed it. Each handler in the group sees the
results of every one of those runs, sequential or concurrent, and the
group's dispatcher serializes them, so a handler that accumulates across
runs needs no locking of its own.
A group lives until its session closes, which releases it and its handlers.
Release it earlier with close, or by
using it as a context manager. See
Running Optimizations for a walkthrough.
__init__
Initialize the group and start its dispatcher.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entries
|
Sequence[tuple[EventHandler, bool]]
|
The handlers, each with whether to run it in a thread. |
required |
session
|
_Session
|
The session whose event loop the dispatcher runs on. |
required |
closed
property
Whether the group has been released.
Returns:
| Type | Description |
|---|---|
bool
|
|
attach_to
Forward the events of a run's compute step to this group's handlers.
A fresh forwarding handler is added per step (one handler cannot serve several steps), carrying only the event types the group's handlers want.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step
|
ComputeStep[Any]
|
The compute step whose events feed the shared handlers. |
required |
close
Release the group's handlers without waiting for the session to close.
See Sharing a handler across concurrent runs for when this matters and the resulting lifecycle.
__enter__
Result objects
ropt.simple.OptimizationResult
dataclass
The outcome of a single optimization run.
A run ends at one evaluation, the best one it found, and that evaluation is
carried unchanged on results. See
Running Optimizations for a walkthrough.
Attributes:
| Name | Type | Description |
|---|---|---|
exit_code |
ExitCode
|
The exit code describing how the optimization terminated. |
results |
FunctionResults | None
|
The best evaluation, or |
Callback types
ropt.simple.EvaluationFunction
Bases: Protocol
The call signature for a high-level evaluation function.
__call__
Evaluate the objectives and constraints for a single variable vector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
variables
|
NDArray[float64]
|
The 1-D variable vector for this evaluation. |
required |
context
|
EvaluationFunctionContext
|
The context identifying the evaluation. |
required |
Returns:
| Type | Description |
|---|---|
FunctionValue
|
|
FunctionValue
|
a scalar, or objectives followed by constraints. |