2017-09-13 8 views
0

ときにエラー「機能を見つけることができません」 - さんはAddOneそれを呼びましょう - doParallelパッケージを経由して、foreach%dopar%を、私はよく知っています.packages.exportの引数はforeachです。のforeach%dopar%得並列化する機能は、私が正常に機能を並列化しましリスト要素

私の問題は、「スタンドアロン」機能ではなく、リストの要素であることを願っています。この場合、私は機能しません。具体的には、AddOneがサブルーチンAddOneSubroutineを呼び出す場合、AddOneSubroutineは、「エクスポート」されているにもかかわらず、「ワーカー」環境では見つかりません。

私は、Windows 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 

私は何を理解していませんか?どこでも完全な再現性のために

答えて

1

、私たちはバックグラウンドRセッションの労働者を使用することを確認してみましょう:

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

、私はあまり詳細にdoParallelバックエンドのコードに掘っていないので、私は100ありませんよこの問題の原因は確かです。しかし、我々はあなたが​​を使用する場合は見ることができる、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バックエンドは(私は著者のよ)少し良く動作しているようです。理想的にはAddOneSubroutineがdoFutureの使用時に自動的にエクスポートされていたはずだが、そうではなかったので、あなたは私が興味を持った特定のユースケースです。私は基礎となる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 
関連する問題