2014-07-18 2 views
10

RStan을 사용하여 많은 수의 Gaussian Processes (GP)에서 샘플링합니다 (stan() 함수 사용). 는 R 명령을 실행하여 볼 수 있듯이 내가 맞는 모든 GP를 들어, 다른 DLL이로드되는 내가 실행 해요 문제는 내가 너무 많은 독특한 개업에 맞게해야하기 때문에, 내가 '이다최대 DLL 수를 초과했습니다.

getLoadedDLLs() 

나는 다음과 같은 오류가 발생하는 시점에서로드 할 수있는 DLL을의 최대 수를 초과 m :

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를 분리하려고했습니다

*** caught segfault *** 
address 0x121366da8, cause 'memory not mapped' 

하지만, (detach의 도움으로 다음과 같이 "분리는 일반적으로 동적으로로드 된 컴파일 된 코드 (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) 
} 

이 코드는 다음과 같은 모델 정의 파일의 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) Stan 디자인 문제 및 제한 사항입니다. Rcpp는 동적으로로드 할 수있는 라이브러리를 만드는 데 도움이됩니다. 그것들을로드하는 것이 바람직한지에 대한 견해가 없다. 결국 당신은 의심되는 R 제한을 초과 한 OS 제한을 공격 할 것입니다. –

답변

7

dll에 관한 문제는 말할 수 없지만 매번 모델을 컴파일 할 필요는 없습니다. 모델을 한 번 컴파일하고 다시 사용하면이 문제가 발생하지 않으며 코드 속도가 빨라집니다.

함수 stan은 모델을 컴파일하는 stan_model의 래퍼이며 모델에서 샘플을 그리는 메서드입니다. 모델을 컴파일하고 개체에 저장하려면 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' 함수에 의해 생성 된 객체입니다. 또는'get_stanmodel (stanfit)'을'stan_model'에 의해 생성 된 객체로 대체 할 수 있습니다. 그러나 R (no monitor, print, log_prob 등)을 부수 지 않고'stanfit' 객체로 할 수있는 것에 대해서는 매우 제한적입니다. –

0

다음은 행 (Win10, R 3.3.0)에서 여러 스탠 모델을 실행하는 데 사용하는 예제입니다.

dll 파일을 언로드 할뿐만 아니라 임시 파일을 삭제해야했습니다. Ben이 제안한 것처럼, 파일 이름은 스탠 오브젝트에서 발견 된 것과 다릅니다.

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])) 
관련 문제