超过R中的最大DLL数

Dou*_*son 11 r rcpp stan

我正在使用RStan从大量高斯过程(GP)中进行采样,即使用函数stan().对于我适合的每个GP,都会加载另一个DLL,这可以通过运行R命令看到

getLoadedDLLs()
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,因为我需要适应这么多独特的GP,我超过了可以加载的最大DLL数量,此时我收到以下错误:

Error in dyn.load(libLFile) : 
unable to load shared object '/var/folders/8x/n7pqd49j4ybfhrm999z3cwp81814xh/T//RtmpmXCRCy/file80d1219ef10d.so':
maximal number of DLLs reached...
Run Code Online (Sandbox Code Playgroud)

据我所知,这是在基本R代码的Rdynload.c中设置的,如下所示:

#define MAX_NUM_DLLS 100
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,可以采取哪些措施来解决这个问题?使用较大的MAX_NUM_DLLS从源代码构建R不是一个选项,因为我的代码将由不熟悉该过程的协作者运行.我尝试过使用dyn.unload()卸载DLL的天真方法,希望在需要时再重新加载它们.卸载工作正常,但当我尝试再次使用适合时,R毫不奇怪地崩溃,出现如下错误:

*** caught segfault ***
address 0x121366da8, cause 'memory not mapped'
Run Code Online (Sandbox Code Playgroud)

我也尝试分离RStan,希望自动卸载DLL,但是即使在卸载软件包之后它们仍然存在(正如预期的那样,在分离帮助中给出以下内容:"分离通常不会卸载任何动态加载的编译代码(DLLs)").

从这个问题,可以在不重新启动R的情况下卸载Rcpp包DLL吗?,它似乎library.dynam.unload()可能在解决方案中有一些作用,但我没有任何成功使用它来卸载DLL,我怀疑在卸载DLL后我会遇到与以前相同的段错误.

编辑:添加一个最小的,功能齐全的示例:

R代码:

require(rstan)

x <- c(1,2)
N <- length(x)

fits <- list()
for(i in 1:100)
{
    fits[i] <- stan(file="gp-sim.stan", data=list(x=x,N=N), iter=1, chains=1)
}
Run Code Online (Sandbox Code Playgroud)

此代码要求以下模型定义位于文件gp-sim.stan中的工作目录中(此模型是Stan中包含的示例之一):

// Sample from Gaussian process
// Fixed covar function: eta_sq=1, rho_sq=1, sigma_sq=0.1

data {
  int<lower=1> N;
  real x[N];
}
transformed data {
   vector[N] mu;
   cov_matrix[N] Sigma;
   for (i in 1:N) 
     mu[i] <- 0;
   for (i in 1:N) 
     for (j in 1:N)
       Sigma[i,j] <- exp(-pow(x[i] - x[j],2)) + if_else(i==j, 0.1, 0.0);
 }
 parameters {
   vector[N] y;
 }
 model {
   y ~ multi_normal(mu,Sigma);
 }
Run Code Online (Sandbox Code Playgroud)

注意:此代码需要相当长的时间才能运行,因为它创建了~100个Stan模型.

小智 8

我不能代表有关dll的问题,但你不应该每次都要编译模型.您可以编译模型一次并重复使用它,这不会导致此问题,它将加快您的代码.

该函数stan是一个包装器,stan_model用于编译模型和sampling从模型中提取样本的方法.您应运行stan_model一次以编译模型并将其保存到对象,然后使用该sampling对象上的方法绘制样本.

require(rstan)

x <- c(1,2)
N <- length(x)

fits <- list()
mod <- stan_model("gp-sim.stan")
for(i in 1:100)
{
    fits[i] <- sampling(mod, data=list(x=x,N=N), iter=1, chains=1)
}
Run Code Online (Sandbox Code Playgroud)

这类似于运行并行链的问题,在Rstan wiki中讨论过.您的代码可以通过用并行处理采样的东西替换for循环来加速.

  • 为了完整性,如果你确实有一个有效的理由在R会话中加载100个DLL,我想你可以使用`dyn.unload`函数来卸载其中一些`dyn.unload(file.path(tempdir(), paste0(get_stanmodel(stanfit)@dso @dso_filename,.Platform $ dynlib.ext)))`,其中`stanfit`是`sampling`或`stan`functions生成的对象.或者你可以用'stan_model`生成的对象替换`get_stanmodel(stanfit)`.但是,对于你可以随后用`stanfit`对象做什么而不会崩溃R(没有`monitor`,`print`,`log_prob`等),你会非常有限. (4认同)