Skip to content

Commit

Permalink
feat: add new callback stage to result method (#263)
Browse files Browse the repository at this point in the history
* feat: add new callback stage to result method

* ...

* ...

* ...

* ...
  • Loading branch information
be-marc authored Nov 6, 2024
1 parent ac26edd commit daa03bb
Show file tree
Hide file tree
Showing 21 changed files with 734 additions and 180 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# bbotk (development version)

* feat: Add new stage `on_result_begin` to `CallbackAsyncTuning` and `CallbackBatchTuning`.
* refactor: Rename stage `on_result` to `on_result_end` in `CallbackAsyncTuning` and `CallbackBatchTuning`.
* docs: Extend the `CallbackAsyncTuning` and `CallbackBatchTuning` documentation.

# bbotk 1.2.0

* feat: `ContextBatch` and `ContextAsync` have a `result_extra` field now to access additional results passed to the instance.
Expand Down
105 changes: 70 additions & 35 deletions R/CallbackAsync.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,15 @@ CallbackAsync = R6Class("CallbackAsync",
#' Called in the worker loop.
on_worker_end = NULL,

#' @field on_result (`function()`)\cr
#' Stage called after result are written.
#' @field on_result_begin (`function()`)\cr
#' Stage called before the results are written.
#' Called in `OptimInstance$assign_result()`.
on_result = NULL,
on_result_begin = NULL,

#' @field on_result_end (`function()`)\cr
#' Stage called after the results are written.
#' Called in `OptimInstance$assign_result()`.
on_result_end = NULL,

#' @field on_optimization_end (`function()`)\cr
#' Stage called at the end of the optimization in the main process.
Expand Down Expand Up @@ -68,7 +73,8 @@ CallbackAsync = R6Class("CallbackAsync",
#' End Optimization on Worker
#' - on_worker_end
#' End Worker
#' - on_result
#' - on_result_begin
#' - on_result_end
#' - on_optimization_end
#' End Optimization
#' ```
Expand All @@ -81,40 +87,56 @@ CallbackAsync = R6Class("CallbackAsync",
#' The [ContextAsync] allows to modify the instance, archive, optimizer and final result.
#'
#' @param id (`character(1)`)\cr
#' Identifier for the new instance.
#' Identifier for the new instance.
#' @param label (`character(1)`)\cr
#' Label for the new instance.
#' Label for the new instance.
#' @param man (`character(1)`)\cr
#' String in the format `[pkg]::[topic]` pointing to a manual page for this object.
#' The referenced help package can be opened via method `$help()`.
#' String in the format `[pkg]::[topic]` pointing to a manual page for this object.
#' The referenced help package can be opened via method `$help()`.
#'
#' @param on_optimization_begin (`function()`)\cr
#' Stage called at the beginning of the optimization in the main process.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the beginning of the optimization in the main process.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_worker_begin (`function()`)\cr
#' Stage called at the beginning of the optimization on the worker.
#' Called in the worker loop.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the beginning of the optimization on the worker.
#' Called in the worker loop.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_optimizer_before_eval (`function()`)\cr
#' Stage called after the optimizer proposes points.
#' Called in `OptimInstance$eval_point()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called after the optimizer proposes points.
#' Called in `OptimInstance$.eval_point()`.
#' The functions must have two arguments named `callback` and `context`.
#' The argument of `instance$.eval_point(xs)` and `xs_trafoed` and `extra` are available in the `context`.
#' Or `xs` and `xs_trafoed` of `instance$.eval_queue()` are available in the `context`.
#' @param on_optimizer_after_eval (`function()`)\cr
#' Stage called after points are evaluated.
#' Called in `OptimInstance$eval_point()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called after points are evaluated.
#' Called in `OptimInstance$.eval_point()`.
#' The functions must have two arguments named `callback` and `context`.
#' The outcome `y` is available in the `context`.
#' @param on_worker_end (`function()`)\cr
#' Stage called at the end of the optimization on the worker.
#' Called in the worker loop.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the end of the optimization on the worker.
#' Called in the worker loop.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_result_begin (`function()`)\cr
#' Stage called before result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' The arguments of `$.assign_result(xdt, y, extra)` are available in the `context`.
#' @param on_result_end (`function()`)\cr
#' Stage called after result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' The final result `instance$result` is available in the `context`.
#' @param on_result (`function()`)\cr
#' Stage called after result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' Deprecated.
#' Use `on_result_end` instead.
#' Stage called after result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_optimization_end (`function()`)\cr
#' Stage called at the end of the optimization in the main process.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the end of the optimization in the main process.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#'
#' @export
callback_async = function(
Expand All @@ -126,6 +148,8 @@ callback_async = function(
on_optimizer_before_eval = NULL,
on_optimizer_after_eval = NULL,
on_worker_end = NULL,
on_result_begin = NULL,
on_result_end = NULL,
on_result = NULL,
on_optimization_end = NULL
) {
Expand All @@ -135,15 +159,26 @@ callback_async = function(
on_optimizer_before_eval,
on_optimizer_after_eval,
on_worker_end,
on_result_begin,
on_result_end,
on_result,
on_optimization_end),
c("on_optimization_begin",
"on_worker_begin",
"on_optimizer_before_eval",
"on_optimizer_after_eval",
"on_worker_end",
"on_result",
"on_optimization_end")), is.null)
"on_worker_begin",
"on_optimizer_before_eval",
"on_optimizer_after_eval",
"on_worker_end",
"on_result_begin",
"on_result_end",
"on_result",
"on_optimization_end")), is.null)

if ("on_result" %in% names(stages)) {
.Deprecated(old = "on_result", new = "on_result_end")
stages$on_result_end = stages$on_result
stages$on_result = NULL
}

walk(stages, function(stage) assert_function(stage, args = c("callback", "context")))
callback = CallbackAsync$new(id, label, man)
iwalk(stages, function(stage, name) callback[[name]] = stage)
Expand Down
80 changes: 57 additions & 23 deletions R/CallbackBatch.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,15 @@ CallbackBatch = R6Class("CallbackBatch",
#' Called in `OptimInstance$eval_batch()`.
on_optimizer_after_eval = NULL,

#' @field on_result (`function()`)\cr
#' Stage called after result are written.
#' @field on_result_begin (`function()`)\cr
#' Stage called before the results are written.
#' Called in `OptimInstance$assign_result()`.
on_result = NULL,
on_result_begin = NULL,

#' @field on_result_end (`function()`)\cr
#' Stage called after the results are written.
#' Called in `OptimInstance$assign_result()`.
on_result_end = NULL,

#' @field on_optimization_end (`function()`)\cr
#' Stage called at the end of the optimization.
Expand All @@ -61,7 +66,8 @@ CallbackBatch = R6Class("CallbackBatch",
#' - on_optimizer_before_eval
#' - on_optimizer_after_eval
#' End Optimizer Batch
#' - on_result
#' - on_result_begin
#' - on_result_end
#' - on_optimization_end
#' End Optimization
#' ```
Expand All @@ -75,32 +81,47 @@ CallbackBatch = R6Class("CallbackBatch",
#'
#'
#' @param id (`character(1)`)\cr
#' Identifier for the new instance.
#' Identifier for the new instance.
#' @param label (`character(1)`)\cr
#' Label for the new instance.
#' Label for the new instance.
#' @param man (`character(1)`)\cr
#' String in the format `[pkg]::[topic]` pointing to a manual page for this object.
#' The referenced help package can be opened via method `$help()`.
#' String in the format `[pkg]::[topic]` pointing to a manual page for this object.
#' The referenced help package can be opened via method `$help()`.
#'
#' @param on_optimization_begin (`function()`)\cr
#' Stage called at the beginning of the optimization.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the beginning of the optimization.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_optimizer_before_eval (`function()`)\cr
#' Stage called after the optimizer proposes points.
#' Called in `OptimInstance$eval_batch()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called after the optimizer proposes points.
#' Called in `OptimInstance$eval_batch()`.
#' The functions must have two arguments named `callback` and `context`.
#' The argument of `$eval_batch(xdt)` is available in `context`.
#' @param on_optimizer_after_eval (`function()`)\cr
#' Stage called after points are evaluated.
#' Called in `OptimInstance$eval_batch()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called after points are evaluated.
#' Called in `OptimInstance$eval_batch()`.
#' The functions must have two arguments named `callback` and `context`.
#' The new points and outcomes in `instance$archive` are available in `context`.
#' @param on_result_begin (`function()`)\cr
#' Stage called before result are written to the instance.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' The arguments of `$assign_result(xdt, y, extra)` are available in `context`.
#' @param on_result_end (`function()`)\cr
#' Stage called after result are written to the instance.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' The final result `instance$result` is available in `context`.
#' @param on_result (`function()`)\cr
#' Stage called after result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' Deprecated.
#' Use `on_result_end` instead.
#' Stage called after result are written.
#' Called in `OptimInstance$assign_result()`.
#' The functions must have two arguments named `callback` and `context`.
#' @param on_optimization_end (`function()`)\cr
#' Stage called at the end of the optimization.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#' Stage called at the end of the optimization.
#' Called in `Optimizer$optimize()`.
#' The functions must have two arguments named `callback` and `context`.
#'
#' @export
#' @inherit CallbackBatch examples
Expand All @@ -111,21 +132,34 @@ callback_batch = function(
on_optimization_begin = NULL,
on_optimizer_before_eval = NULL,
on_optimizer_after_eval = NULL,
on_result_begin = NULL,
on_result_end = NULL,
on_result = NULL,
on_optimization_end = NULL
) {
stages = discard(set_names(list(
on_optimization_begin,
on_optimizer_before_eval,
on_optimizer_after_eval,
on_result_begin,
on_result_end,
on_result,
on_optimization_end),
c(
"on_optimization_begin",
"on_optimizer_before_eval",
"on_optimizer_after_eval",
"on_result_begin",
"on_result_end",
"on_result",
"on_optimization_end")), is.null)

if ("on_result" %in% names(stages)) {
.Deprecated(old = "on_result", new = "on_result_end")
stages$on_result_end = stages$on_result
stages$on_result = NULL
}

walk(stages, function(stage) assert_function(stage, args = c("callback", "context")))
callback = CallbackBatch$new(id, label, man)
iwalk(stages, function(stage, name) callback[[name]] = stage)
Expand Down
Loading

0 comments on commit daa03bb

Please sign in to comment.