-
-
Notifications
You must be signed in to change notification settings - Fork 219
Description
With 3.3.0 beta (2016-04-05 r70427) from Debian unstable I am having an issue with loading the Modules in the rstanarm package that does not occur on r-devel compiled from svn and was not occurring with 3.2.x. So, this might be a Debian bug, but it occurs whether I use r-cran-rcpp or install Rcpp 0.12.4 from CRAN (with various combinations of CXXFLAGS in ~/.R/Makevars).
In .onLoad(), I call loadRcppModules() to load the six modules listed in the RcppModules line of the DESCRIPTION file. This has worked for months and I'm pretty sure it was working with the Rcpp 0.12.4 for a few days before the 3.3.0 betas starting being uploaded to Debian unstable. Now, when it tries to the load the rstanarm package, it errors with "C stack usage is too close to the limit". If you have the 3.3.0 beta from Debian unstable, you should be able to reproduce this just by calling
install.packages("rstanarm")
If I first call ulimit -s 16384
in a shell to increase the stack limit, the error message becomes
** testing if installed package can be loaded
Error : .onLoad failed in loadNamespace() for 'rstanarm', details:
call: value[[3L]](cond)
error: failed to load module stan_fit4bernoulli_mod from package rstanarm
evaluation nested too deeply: infinite recursion / options(expressions=)?
Error: loading failed
Execution halted
ERROR: loading failed
To investigate, I commented out loadRcppModules() in .onLoad() and tried to load one of rstanarm's Modules manually. The error comes from the Module() function when it calls clname <- as.character(CLASS)
. The full session is below:
library(rstanarm) # with loadRcppModules() commented out in .onLoad()
library(Rcpp)
mod <- Module("stan_fit4bernoulli_mod", "rstanarm")
debug(Module)
populate(mod, .GlobalEnv)
debugging in: Module(module, mustStart = TRUE)
debug: {
if (inherits(module, "DLLInfo") && missing(mustStart))
mustStart <- TRUE
if (inherits(module, "Module")) {
xp <- .getModulePointer(module, FALSE)
if (!missing(PACKAGE))
warning("ignoring PACKAGE argument in favor of internal package from Module object")
env <- as.environment(module)
PACKAGE <- get("packageName", envir = env)
moduleName <- get("moduleName", envir = env)
}
else if (identical(typeof(module), "externalptr")) {
xp <- module
moduleName <- .Call(Module__name, xp)
module <- methods::new("Module", pointer = xp, packageName = PACKAGE,
moduleName = moduleName)
}
else if (is.character(module)) {
moduleName <- module
xp <- .badModulePointer
module <- methods::new("Module", pointer = xp, packageName = PACKAGE,
moduleName = moduleName)
}
if (identical(xp, .badModulePointer)) {
if (mustStart) {
name <- sprintf("_rcpp_module_boot_%s", moduleName)
symbol <- tryCatch(getNativeSymbolInfo(name, PACKAGE),
error = function(e) e)
if (inherits(symbol, "error"))
stop(gettextf("Failed to initialize module pointer: %s",
symbol), domain = NA)
xp <- .Call(symbol)
.setModulePointer(module, xp)
}
else return(module)
}
classes <- .Call(Module__classes_info, xp)
if (environmentIsLocked(where))
where <- .GlobalEnv
generators <- list()
storage <- new.env()
for (i in seq_along(classes)) {
CLASS <- classes[[i]]
clname <- as.character(CLASS)
fields <- cpp_fields(CLASS, where)
methods <- cpp_refMethods(CLASS, where)
generator <- methods::setRefClass(clname, fields = fields,
contains = "C++Object", methods = methods, where = where)
.self <- .refClassDef <- NULL
generator$methods(initialize = if (cpp_hasDefaultConstructor(CLASS))
function(...) cpp_object_initializer(.self, .refClassDef,
...)
else function(...) {
if (nargs())
cpp_object_initializer(.self, .refClassDef, ...)
else cpp_object_dummy(.self, .refClassDef)
})
rm(.self, .refClassDef)
classDef <- methods::getClass(clname)
fields <- classDef@fieldPrototypes
assign(".pointer", CLASS@pointer, envir = fields)
assign(".module", xp, envir = fields)
assign(".CppClassName", clname, envir = fields)
generators[[clname]] <- generator
if (any(grepl("^[[]", names(CLASS@methods)))) {
if ("[[" %in% names(CLASS@methods)) {
methods::setMethod("[[", clname, function(x,
i, j, ..., exact = TRUE) {
x$`[[`(i)
}, where = where)
}
if ("[[<-" %in% names(CLASS@methods)) {
methods::setReplaceMethod("[[", clname, function(x,
i, j, ..., exact = TRUE, value) {
x$`[[<-`(i, value)
x
}, where = where)
}
}
if (any(grepl("show", names(CLASS@methods)))) {
setMethod("show", clname, function(object) object$show(),
where = where)
}
}
if (length(classes)) {
module$refClassGenerators <- generators
}
for (i in seq_along(classes)) {
CLASS <- classes[[i]]
clname <- as.character(CLASS)
demangled_name <- sub("^Rcpp_", "", clname)
.classes_map[[CLASS@typeid]] <- storage[[demangled_name]] <- .get_Module_Class(module,
demangled_name, xp)
if (length(CLASS@enums)) {
for (enum in CLASS@enums) {
for (i in 1:length(enum)) {
storage[[paste(demangled_name, ".", names(enum)[i],
sep = "")]] <- enum[i]
}
}
}
}
functions <- .Call(Module__functions_names, xp)
for (fun in functions) {
storage[[fun]] <- .get_Module_function(module, fun, xp)
converter_rx <- "^[.]___converter___(.*)___(.*)$"
if (length(matches <- grep(converter_rx, functions))) {
for (i in matches) {
fun <- functions[i]
from <- sub(converter_rx, "\\1", fun)
to <- sub(converter_rx, "\\2", fun)
converter <- function(from) {
}
body(converter) <- substitute({
CONVERT(from)
}, list(CONVERT = storage[[fun]]))
setAs(from, to, converter, where = where)
}
}
}
assign("storage", storage, envir = as.environment(module))
module
}
Browse[2]>
debug: if (inherits(module, "DLLInfo") && missing(mustStart)) mustStart <- TRUE
Browse[2]>
debug: if (inherits(module, "Module")) {
xp <- .getModulePointer(module, FALSE)
if (!missing(PACKAGE))
warning("ignoring PACKAGE argument in favor of internal package from Module object")
env <- as.environment(module)
PACKAGE <- get("packageName", envir = env)
moduleName <- get("moduleName", envir = env)
} else if (identical(typeof(module), "externalptr")) {
xp <- module
moduleName <- .Call(Module__name, xp)
module <- methods::new("Module", pointer = xp, packageName = PACKAGE,
moduleName = moduleName)
} else if (is.character(module)) {
moduleName <- module
xp <- .badModulePointer
module <- methods::new("Module", pointer = xp, packageName = PACKAGE,
moduleName = moduleName)
}
Browse[2]>
debug: xp <- .getModulePointer(module, FALSE)
Browse[2]>
debug: if (!missing(PACKAGE)) warning("ignoring PACKAGE argument in favor of internal package from Module object")
Browse[2]>
debug: env <- as.environment(module)
Browse[2]>
debug: PACKAGE <- get("packageName", envir = env)
Browse[2]>
debug: moduleName <- get("moduleName", envir = env)
Browse[2]>
debug: if (identical(xp, .badModulePointer)) {
if (mustStart) {
name <- sprintf("_rcpp_module_boot_%s", moduleName)
symbol <- tryCatch(getNativeSymbolInfo(name, PACKAGE),
error = function(e) e)
if (inherits(symbol, "error"))
stop(gettextf("Failed to initialize module pointer: %s",
symbol), domain = NA)
xp <- .Call(symbol)
.setModulePointer(module, xp)
}
else return(module)
}
Browse[2]>
debug: if (mustStart) {
name <- sprintf("_rcpp_module_boot_%s", moduleName)
symbol <- tryCatch(getNativeSymbolInfo(name, PACKAGE), error = function(e) e)
if (inherits(symbol, "error"))
stop(gettextf("Failed to initialize module pointer: %s",
symbol), domain = NA)
xp <- .Call(symbol)
.setModulePointer(module, xp)
} else return(module)
Browse[2]>
debug: name <- sprintf("_rcpp_module_boot_%s", moduleName)
Browse[2]>
debug: symbol <- tryCatch(getNativeSymbolInfo(name, PACKAGE), error = function(e) e)
Browse[2]>
debug: if (inherits(symbol, "error")) stop(gettextf("Failed to initialize module pointer: %s",
symbol), domain = NA)
Browse[2]>
debug: xp <- .Call(symbol)
Browse[2]>
debug: .setModulePointer(module, xp)
Browse[2]>
debug: classes <- .Call(Module__classes_info, xp)
Browse[2]>
debug: if (environmentIsLocked(where)) where <- .GlobalEnv
Browse[2]>
debug: where <- .GlobalEnv
Browse[2]>
debug: generators <- list()
Browse[2]>
debug: storage <- new.env()
Browse[2]>
debug: for (i in seq_along(classes)) {
CLASS <- classes[[i]]
clname <- as.character(CLASS)
fields <- cpp_fields(CLASS, where)
methods <- cpp_refMethods(CLASS, where)
generator <- methods::setRefClass(clname, fields = fields,
contains = "C++Object", methods = methods, where = where)
.self <- .refClassDef <- NULL
generator$methods(initialize = if (cpp_hasDefaultConstructor(CLASS))
function(...) cpp_object_initializer(.self, .refClassDef,
...)
else function(...) {
if (nargs())
cpp_object_initializer(.self, .refClassDef, ...)
else cpp_object_dummy(.self, .refClassDef)
})
rm(.self, .refClassDef)
classDef <- methods::getClass(clname)
fields <- classDef@fieldPrototypes
assign(".pointer", CLASS@pointer, envir = fields)
assign(".module", xp, envir = fields)
assign(".CppClassName", clname, envir = fields)
generators[[clname]] <- generator
if (any(grepl("^[[]", names(CLASS@methods)))) {
if ("[[" %in% names(CLASS@methods)) {
methods::setMethod("[[", clname, function(x, i, j,
..., exact = TRUE) {
x$`[[`(i)
}, where = where)
}
if ("[[<-" %in% names(CLASS@methods)) {
methods::setReplaceMethod("[[", clname, function(x,
i, j, ..., exact = TRUE, value) {
x$`[[<-`(i, value)
x
}, where = where)
}
}
if (any(grepl("show", names(CLASS@methods)))) {
setMethod("show", clname, function(object) object$show(),
where = where)
}
}
Browse[2]>
debug: CLASS <- classes[[i]]
Browse[2]>
debug: clname <- as.character(CLASS) # before this executes, I print CLASS
Browse[2]> CLASS
C++ class 'model_bernoulli' <0x8a94400>
Constructors:
model_bernoulli(SEXP, SEXP)
Fields: No public fields exposed by this class
Methods:
SEXP call_sampler(SEXP)
SEXP constrain_pars(SEXP)
SEXP constrained_param_names(SEXP, SEXP)
SEXP grad_log_prob(SEXP, SEXP)
SEXP log_prob(SEXP, SEXP, SEXP)
SEXP num_pars_unconstrained()
SEXP param_dims() const
SEXP param_dims_oi() const
SEXP param_fnames_oi() const
SEXP param_names() const
SEXP param_names_oi() const
SEXP param_oi_tidx(SEXP)
SEXP unconstrain_pars(SEXP)
SEXP unconstrained_param_names(SEXP, SEXP)
SEXP update_param_oi(SEXP)
Browse[2]> # one more Enter executes as.character(CLASS)
Error: C stack usage 7970004 is too close to the limit
Thanks!