R defer model compiling to first fit, to remove compiling from onLoad per CRAN

This commit is contained in:
Ben Letham 2020-02-19 21:30:08 -08:00
parent 101dd50e31
commit 46e5611983
7 changed files with 49 additions and 101 deletions

View file

@ -236,52 +236,38 @@ validate_column_name <- function(
}
}
#' Load compiled Stan model
#'
#' @param model String 'linear' or 'logistic' to specify a linear or logistic
#' trend.
#'
#' @return Stan model.
#'
#' @keywords internal
get_prophet_stan_model <- function() {
## If the cached model doesn't work, just compile a new one.
tryCatch({
binary <- system.file(
'libs',
Sys.getenv('R_ARCH'),
'prophet_stan_model.RData',
package = 'prophet',
mustWork = TRUE
)
load(binary)
obj.name <- 'model.stanm'
stanm <- eval(parse(text = obj.name))
## Should cause an error if the model doesn't work.
stanm@mk_cppmodule(stanm)
stanm
}, error = function(cond) {
compile_stan_model()
})
}
#' Compile Stan model
#'
#' @param model String 'linear' or 'logistic' to specify a linear or logistic
#' trend.
#'
#' @return Stan model.
#'
#' @keywords internal
compile_stan_model <- function() {
packageStartupMessage('Compiling model (this will take a few minutes...)')
packageStartupMessage(
'If this is the first time fitting a model since package install, this is normal. ',
'You should not see this message more than once after install.'
)
dest <- file.path(path.package("prophet"), 'libs')
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
packageStartupMessage(paste('Writing model to:', dest))
packageStartupMessage(paste('Compiling using binary:', R.home('bin')))
fn <- 'stan/prophet.stan'
stan.src <- system.file(fn, package = 'prophet', mustWork = TRUE)
stanc <- rstan::stanc(stan.src)
model.binary <- file.path(dest, 'prophet_stan_model.RData')
return(rstan::stan_model(stanc_ret = stanc, model_name = 'prophet_model'))
stanc <- rstan::stanc(stan.src)
model.stanm <- rstan::stan_model(
stanc_ret = stanc,
model_name = 'prophet_model'
)
save('model.stanm', file = model.binary)
packageStartupMessage('------ Model successfully compiled!')
packageStartupMessage('You can ignore any compiler warnings above.')
assign(".prophet.stan.model", model.stanm, envir = prophet_model_env)
return(model.stanm)
}
#' Convert date vector
@ -1238,10 +1224,10 @@ fit.prophet <- function(m, df, ...) {
kinit <- logistic_growth_init(history)
}
if (exists(".prophet.stan.model")) {
model <- .prophet.stan.model
if (exists(".prophet.stan.model", where = prophet_model_env)) {
model <- get('.prophet.stan.model', envir = prophet_model_env)
} else {
model <- get_prophet_stan_model()
model <- compile_stan_model()
}
stan_init <- function() {

View file

@ -4,10 +4,28 @@
# LICENSE file in the root directory of this source tree.
.onLoad <- function(libname, pkgname) {
.prophet.stan.model <- get_prophet_stan_model()
assign(
".prophet.stan.model",
.prophet.stan.model,
envir=parent.env(environment())
# Create environment for storing stan model
assign("prophet_model_env", new.env(), parent.env(environment()))
tryCatch({
binary <- system.file(
'libs',
'prophet_stan_model.RData',
package = 'prophet',
mustWork = TRUE
)
load(binary)
obj.name <- 'model.stanm'
stanm <- eval(parse(text = obj.name))
## Should cause an error if the model doesn't work.
stanm@mk_cppmodule(stanm)
assign(
".prophet.stan.model",
stanm,
envir=prophet_model_env
)
},
error = function(cond) {}
)
}

View file

@ -6,10 +6,6 @@
\usage{
compile_stan_model()
}
\arguments{
\item{model}{String 'linear' or 'logistic' to specify a linear or logistic
trend.}
}
\value{
Stan model.
}

View file

@ -1,19 +0,0 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/prophet.R
\name{get_prophet_stan_model}
\alias{get_prophet_stan_model}
\title{Load compiled Stan model}
\usage{
get_prophet_stan_model()
}
\arguments{
\item{model}{String 'linear' or 'logistic' to specify a linear or logistic
trend.}
}
\value{
Stan model.
}
\description{
Load compiled Stan model
}
\keyword{internal}

View file

@ -1,2 +0,0 @@
CXX_STD = CXX11

View file

@ -1 +0,0 @@
CXX_STD = CXX11

View file

@ -1,30 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
packageStartupMessage('Compiling model (this will take a minute...)')
dest <- file.path(R_PACKAGE_DIR, paste0('libs', R_ARCH))
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
packageStartupMessage(paste('Writing model to:', dest))
packageStartupMessage(paste('Compiling using binary:', R.home('bin')))
model.src <- file.path(R_PACKAGE_SOURCE, 'inst', 'stan', 'prophet.stan')
model.binary <- file.path(dest, 'prophet_stan_model.RData')
# See: https://github.com/r-lib/pkgbuild/issues/54#issuecomment-448702834
# TODO: move stan compilation into Makevars
suppressMessages({
model.stanc <- rstan::stanc(model.src)
model.stanm <- rstan::stan_model(
stanc_ret = model.stanc,
model_name = 'prophet_model'
)
})
save('model.stanm', file = model.binary)
packageStartupMessage('------ Model successfully compiled!')
packageStartupMessage('You can ignore any compiler warnings above.')