R/odin_build.R

Defines functions odin_build

Documented in odin_build

##' Build an odin model generator from its intermediate
##' representation, as generated by [odin::odin_parse].  This
##' function is for advanced use.
##'
##' In applications that want to inspect the intermediate
##' representation rather before compiling, rather than directly using
##' [odin::odin], use either [odin::odin_parse] or
##' [odin::odin_validate] and then pass the result to
##' `odin::odin_build`.
##'
##' The return value of this function includes information about how
##' long the compilation took, if it was successful, etc, in the same
##' style as [odin::odin_validate]:
##'
##' \describe{
##' \item{success}{Logical, indicating if compilation was successful}
##'
##' \item{elapsed}{Time taken to compile the model, as a
##' `proc_time` object, as returned by [proc.time].}
##'
##' \item{output}{Any output produced when compiling the model (only
##' present if compiling to C, and if the cache was not hit.}
##'
##' \item{model}{The model itself, as an `odin_generator` object,
##' as returned by [odin::odin].}
##'
##' \item{ir}{The intermediate representation.}
##'
##' \item{error}{Any error thrown during compilation}
##' }
##'
##' @title Build an odin model generator from its IR
##'
##' @param x An odin ir (json) object or output from
##'   [odin::odin_validate].
##'
##' @param options Options to pass to the build stage (see
##'   [odin::odin_options]
##'
##' @export
##'
##' @seealso [odin::odin_parse], which creates intermediate
##'   representations used by this function.
##'
##' @examples
##' # Parse a model of exponential decay
##' ir <- odin::odin_parse({
##'   deriv(y) <- -0.5 * y
##'   initial(y) <- 1
##' })
##'
##' # Compile the model:
##' options <- odin::odin_options(target = "r")
##' res <- odin::odin_build(ir, options)
##'
##' # All results:
##' res
##'
##' # The model:
##' mod <- res$model$new()
##' mod$run(0:10)
odin_build <- function(x, options = NULL) {
  options <- odin_options(options = options)

  if (is.list(x) && inherits(x$result, "json")) {
    x <- x$result
  } else if (!inherits(x, "json")) {
    stop("Expected an odin intermediate representation")
  }

  elapsed <- system.time(
    output <- utils::capture.output(
      suppressMessages(
        model <- tryCatch(
          odin_generate(x, options),
          error = identity))),
    gcFirst = FALSE)

  is_error <- inherits(model, "error")

  if (is_error) {
    error <- model$message
    model <- NULL
  } else {
    error <- NULL
  }

  list(
    success = !is_error,
    elapsed = elapsed,
    output = output,
    model = model,
    ir = x,
    error = error)
}
richfitz/odin documentation built on Feb. 23, 2024, 1:11 p.m.