Building a Workflow
Audience: advanced users who need full control over the optimization.
The simple API covers most cases. When you need more — custom event handling, several optimizers, or nested runs — you assemble the low-level workflow components yourself. This page follows examples/advanced/workflow.py.
See Optimization Workflows for the full reference on the components used here.
The evaluator
At the low level the evaluation callback receives the whole batch of variable
vectors at once (a 2-D array) and returns an
EvaluationBatchResult:
def rosenbrock(variables, context, a, b):
objectives = np.zeros((variables.shape[0], 1))
for v_idx, r in enumerate(context.realizations):
...
return EvaluationBatchResult(objectives=objectives)
Wrap it in a BatchEvaluator:
from ropt.components.evaluators import BatchEvaluator
evaluator = BatchEvaluator(callback=partial(rosenbrock, a=a, b=b))
See Writing Evaluation Callbacks for the batch callback signature and the other evaluators.
The compute step and its handlers
An OptimizationStep runs the
optimization. You attach event handlers to it: a
ResultsHandler to keep the best
result, and a CallbackHandler
to report progress:
from ropt.components.compute_steps import OptimizationStep
from ropt.components.event_handlers import CallbackHandler, ResultsHandler
from ropt.enums import EnOptEventType
step = OptimizationStep(evaluator=evaluator)
result_handler = ResultsHandler()
step.add_event_handler(result_handler)
step.add_event_handler(
CallbackHandler(callback=report, event_types={EnOptEventType.FINISHED_EVALUATION})
)
Run it and read the result
The step takes the variables and an
EnOptContext built from the config. The best result
is on the handler:
from ropt.context import EnOptContext
step.run(variables=INITIAL_VALUES, context=EnOptContext.model_validate(CONFIG))
best = result_handler.result
Next
- The full component reference: Optimization Workflows.
- Writing the evaluation callback: Writing Evaluation Callbacks.
- Running evaluations in parallel: Parallel Evaluation.