2014-07-18 37 views
10

我正在使用RStan從大量高斯過程(GPs)中抽樣,即使用函數stan()。對於每一個我適合GP,另一個DLL被加載,如可以通過運行R命令可以看出超過R中DLL的最大數量

getLoadedDLLs() 

我遇到的問題是,因爲我需要適應這麼多獨特的GPS,我米超過可裝入的DLL的最大數量,在該點處,收到以下錯誤:

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

據我所知,這在基礎R代碼的Rdynload.c設置,如下:

#define MAX_NUM_DLLS 100 

所以,我的問題是,可以做些什麼來解決這個問題?使用更大的MAX_NUM_DLLS從源代碼構建R不是一種選擇,因爲我的代碼將由不熟悉該過程的協作者運行。我已經嘗試過使用dyn.unload()卸載DLL的幼稚方法,希望它們在需要時重新加載。卸載工作正常,但是當我嘗試再次使用合適的,R還算意料之中用類似的錯誤崩潰:

我也試過在希望的DLL文件將被自動卸載分離RStan,但即使在卸載程序包後它們仍然存在(如預期的那樣,在分離的幫助中給出以下內容:「分離通常不會卸載任何動態加載的編譯代碼(DLL)」)。

從這個問題,Can Rcpp package DLLs be unloaded without restarting R?,似乎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) 
} 

此代碼要求下面的模型定義在文件中的GP-SIM的工作目錄。斯坦(此模型是包含斯坦一個例子):

// 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); 
} 

注:此代碼需要相當長的一段時間才能運行,因爲它是建立〜100個斯坦車型。

+1

我很驚訝爲每個進程加載另一個DLL。我想知道是否最容易防止這種情況發生。你能提供一個最小但功能完整的代碼來捕捉你的問題嗎? – nograpes

+2

這是一個(R)斯坦設計問題和限制。 Rcpp只是幫助創建可動態加載的庫;它沒有意見是否建議裝載100個這樣的數據。最終你會達到我懷疑的操作系統限制(超出了你確定的硬編碼R限制)。 –

回答

7

我不能說有關DLL的問題,但你不應該每次都需要編譯模型。您可以編譯一次模型並重新使用它,這不會導致此問題,並且會加速您的代碼。

功能stanstan_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) 
} 

這類似於平行鏈的問題,在Rstan wiki討論。您可以通過將for循環替換爲並行處理採樣的東西來加快代碼的執行速度。

+3

爲了完整起見,如果你確實有一個合理的理由來在R會話中加載100個DLL,我想你可以使用'dyn.unload'函數來卸載它們中的一些'dyn.unload(file.path(tempdir() ,paste0(get_stanmodel(stanfit)@ dso @ dso_filename,.Platform $ dynlib.ext)))',其中'stanfit'是'sampling'或'stan'函數產生的對象。或者你可以用'stan_model'生成的對象替換'get_stanmodel(stanfit)'。然而,你會非常有限的事情,你可以隨後用'stanfit'對象做什麼而不會崩潰R(沒有'monitor','print','log_prob'等等) –

0

這是,我用什麼來連續運行幾個stan模型(Win10,R 3.3.0)。

我不僅需要卸載dll文件,還要刪除它們和其他臨時文件。然後,正如Ben所建議的那樣,我的文件名與stan對象中的文件名不同。

dso_filenames <- dir(tempdir(), pattern=.Platform$dynlib.ext) 
    filenames <- dir(tempdir()) 
    for (i in seq(dso_filenames)) 
    dyn.unload(file.path(tempdir(), dso_filenames[i])) 
    for (i in seq(filenames)) 
    if (file.exists(file.path(tempdir(), filenames[i])) & nchar(filenames[i]) < 42) # some files w/ long filenames that didn't like to be removeed 
     file.remove(file.path(tempdir(), filenames[i])) 
相關問題