2017-09-13 15 views
0

때 오류 "기능을 찾을 수 없습니다"-의이 AddOne를 호출하자 - doParallel 패키지를 통해, foreach%dopar%을 나는 알고 있어요 .packages.export 인수는 foreach입니다.의 foreach % dopar % 항복 parallelised 할 수있는 기능이 나는 성공적으로 기능을 parallelised 한리스트 요소

제 문제는 "독립 실행 형"기능 대신에 목록의 요소가되도록이 AddOne을 사용하고 싶습니다.이 경우에는 작동하지 않을 수 있습니다. 특히 AddOne이 서브 루틴 AddOneSubroutine을 호출하면 AddOneSubroutine은 "내 보낸"경우에도 "작업자"환경에서 발견되지 않습니다.

나는 윈도우 10 R.version 수익률을 사용하고 있습니다 :

platform  x86_64-w64-mingw32   
arch   x86_64      
os    mingw32      
system   x86_64, mingw32    
status          
major   3       
minor   4.1       
year   2017       
month   06       
day   30       
svn rev  72865      
language  R       
version.string R version 3.4.1 (2017-06-30) 
nickname  Single Candle 

내가 가진 doParallel 버전은 1.0.10입니다. 다음은 가능한 한 간결하게 문제를 설명하는 코드입니다.

library(doParallel) 
if(!exists("Registered")){ 
    registerDoParallel(cores = detectCores(logical = TRUE)) 
    Registered = TRUE 
} 

AddOne<-function(x){AddOneSubroutine(x)} 
AddOneSubroutine <-function(x){x+1} 

MyList<-list() 
MyList$f<-AddOne 

# Not using parallel environments, works correctly when calling AddOne 3 times 
Result1 = foreach(i = 1:3) %do% AddOne(i) 
Result1 

# Not using parallel environments, works correctly when calling MyList$f 3 times 
Result2 = foreach(i = 1:3) %do% MyList$f(i) 
Result2 

# Using parallel environments, works correctly when calling AddOne 3 times, 
# despite not explicitly using the .export argument to export AddOneSubroutine 
Result3 = foreach(i = 1:3) %dopar% AddOne(i) 
Result3 

# Using parallel environments, fails when calling MyList$f with error 
# "could not find function "AddOneSubroutine"", even though that function is "exported" 
Result4 = foreach(i = 1:3,.export = "AddOneSubroutine") %dopar% MyList$f(i) 
Result4 

무엇을 이해하지 못합니까? 이제

library("doParallel") 
cl <- parallel::makeCluster(detectCores(logical = TRUE)) 
registerDoParallel(cl) 

, 나는 많은 세부 사항에 doParallel 백엔드 코드에 파고하지 않은, 그래서 100을 아니에요 :

사방 전체 재현성

답변

1

, 우리가 배경 R 세션에서 근로자를 사용 있는지 확인하자 이 문제의 원인은 무엇입니까? 그러나 우리는 당신이 foreach(..., .verbose = TRUE)를 사용하는 경우 당신이 볼 수있는 AddOneSubroutine가 참으로 내 보낸 것을 알고, 또는 간단하게 수행하지만

AddOneSubroutine <- function(x) { x + 1 } 
y <- foreach(i = 1L, .export = "AddOneSubroutine") %dopar% { 
    get("AddOneSubroutine") 
} 
str(y) 
## List of 1 
## $ :function (x) 
## ..- attr(*, "srcref")=Class 'srcref' atomic [1:8] 1 20 1 40 20 40 1 1 
## .. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x2e475a0> 

사용하여 확인할 수가 발견되지 않는 기능 MyList$f()를 호출 할 때 :

AddOne <- function(x) exists("AddOneSubroutine") 
MyList <- list() 
MyList$f <- AddOne 
y <- foreach(i = 1L, .export = "AddOneSubroutine") %dopar% { 
    MyList$f(i) 
} 
str(y) 
## List of 1 
## $ : logi FALSE 

따라서 AddOneSubroutine은 (는) MyList$f에서 검색된 프레임에 없습니다. doParallel이 MyList$f에 대한 환경을 올바로 입력하지 못했기 때문일 수 있습니다. 해결 방법은 다음과 같은 해킹입니다.

AddOne <- function(x) { AddOneSubroutine(x) } 
y <- foreach(i = 1L) %dopar% { 
    environment(MyList$f) <- environment(AddOneSubroutine) 
    MyList$f(i) 
} 
str(y) 
## List of 1 
## $ : num 2 

불행히도, 매우 그리트하지도 매우 편리하지도 않습니다.

library("doFuture") 
registerDoFuture() 
plan(multisession) 

AddOneSubroutine <- function(x) { x + 1 } 
AddOne <- function(x) { AddOneSubroutine(x) } 
MyList <- list() 
MyList$f <- AddOne 

y <- foreach(i = 1L) %dopar% { 
    AddOneSubroutine ## dummy guiding auto-export 
    MyList$f(i) 
} 
str(y) 
## List of 1 
## $ : num 2 

PS : 대안으로

doFuture 백엔드 (나는 저자 해요) 약간 더 나은 작동하는 것 같다. doFuture를 사용할 때 이상적으로 AddOneSubroutine을 내 보내야했기 때문에 특정 유스 케이스에 관심이 있었지만 그렇지 않았다. 기본 globals 패키지 (나는 저자 임)에서이 문제를 발견했지만 게시하기 전에 그것에 대해 더 생각할 필요가 있습니다.

내 세부 정보 :

> sessionInfo() 
R version 3.4.1 (2017-06-30) 
Platform: x86_64-pc-linux-gnu (64-bit) 
Running under: Ubuntu 16.04.3 LTS 

Matrix products: default 
BLAS: /usr/lib/atlas-base/atlas/libblas.so.3.0 
LAPACK: /usr/lib/atlas-base/atlas/liblapack.so.3.0 

locale: 
[1] LC_CTYPE=en_US.UTF-8  LC_NUMERIC=C    
[3] LC_TIME=en_US.UTF-8  LC_COLLATE=en_US.UTF-8  
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 
[7] LC_PAPER=en_US.UTF-8  LC_NAME=C     
[9] LC_ADDRESS=C    LC_TELEPHONE=C    
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C  

attached base packages: 
[1] parallel stats  graphics grDevices utils  datasets methods 
[8] base  

other attached packages: 
[1] doFuture_0.5.1 iterators_1.0.8 foreach_1.4.3 future_1.6.1 

loaded via a namespace (and not attached): 
[1] compiler_3.4.1 tools_3.4.1  listenv_0.6.0 codetools_0.2-15 
[5] digest_0.6.12 globals_0.10.2