2017-09-05 13 views
1

foreach文とdoMPIバックエンド内に複数のネストされた関数を含むRパッケージを作成しようとしています。 "XXX"オブジェクトエラーを見つけることができません。奇妙なことは、doParallelをバックエンドとして使用するとこのエラーは発生しないということです。大きな問題。foreachを含むRパッケージはdoParallelで動作しますがdoMPIでは動作しません。オブジェクトが見つかりません

このRStudioを使用してR-パッケージにコンパイルされたコードであり、roxygen、デベロッパーツールなど

#' Test function level 1 
#' @param var11 first variable for function 1 
#' @param var12 second variable for function 1 
#' @param var13 third variable for function 1 
#' @export fun1 

fun1 <- function (fun2.params, fun3.params, var11, var12, var13, ...) { 

    results <- data.frame (foreach::`%dopar%`(
       foreach::`%:%`(foreach::foreach(j = 1:var11, .combine = cbind), 
       foreach::foreach (i = 1:var12, .combine=rbind)), 
       { 
        out3 <- replicate(var13, 
            do.call(fun2, 
              c(list(fun3.params=fun3.params), 
               fun2.params))) 
        output2 <- data.frame(mean(out3)) 
     } 
    ) 
) 
    ## save outputs for subsequent analyses if required 
saveRDS(results, file = paste("./outputs/", var13 ,"_", var12, "_", var11, "_", 
           format(Sys.time(), "%d_%m_%Y"), ".rds", sep="")) 
} 

#' Test function level 2 
#' @param var21 first variable for function 2 
#' @param var22 second variable for function 2 
#' @export fun2 

fun2 <- function (fun3.params, var21, var22, ...) { 
    out2 <- `if` (rpois(1, var21) > 0, var22 * do.call(fun3, fun3.params), 0) 
} 

#' Test function level 3 
#' @param var31 first variable for function 3 
#' @param var32 second variable for function 3 
#' @param var33 third variable for function 3 
#' @export fun3 

fun3 <- function (var31, var32, var33, ...) { 
    out3 <- var31 * rnorm(1, mean=var32, sd= var33) 
} 

私は、ライブラリをロードして.Rからトップレベルの関数を呼び出しますemacs ESS(またはRStudioエディタ)とこれらのコマンドを使用してファイルを作成します。

library(toymod) 
library(doParallel) 
cl <-makeCluster(10) 
registerDoParallel(cl) 

fun1.params <- list(var11=10, var12=150, var13=365) 
fun2.params <- list(var21=0.05,var22=9.876) 
fun3.params <- list(var31=1.396,var32=14.387,var33=3.219) 

do.call(fun1, c(list(fun2.params = fun2.params, 
        fun3.params = fun3.params), 
       fun1.params)) 

私は、これはR 3.4.1を使用して、Ubuntuの16.04 Linux上で実行されている私はdoMPIを使用して、それを実行するときしかし、私は次のエラーを取得する、それが正常に動作パラレルバックエンドとしてdoMPIを

Error in { : task 12 failed - "object 'fun2' not found" 

をdoParallelを使用してそれを実行します0.2.2、およびdoParallel。私はgithubに全体のパッケージを入れましたhttps://github.com/jamaas/toymod.git

doMPIのコードを変更する必要があるかどうか誰かに教えてください。それはRパッケージを作ることに関連しているようです。

+0

これは推測ですが、これは 'doParallel'が親のR環境を* X *ワーカーにクローンするためですが、' doMPI'はおそらくこれをしません。関数を親環境から各作業者にエクスポートする必要があります( 'cl')、' foreach'の '{}'の中に組み込む必要があります。 – CPak

+0

doMPIはsnow-derivedインターフェイス(これはあなたがやっていることです)とdoParallelと同じように動作する必要があるので、これは奇妙なことに同意します。私は強化/バグの修正がdoParallelになされたと思っています。これは私がMPIを作ったことはありません。私はこれを調べ始めていますが、時間がかかることがあります。 –

答えて

1

私は、foreach .packages='toymod'オプションを使用する必要があると考えています。これは、foreachループの本体が実際に 'toymod'パッケージの一部ではないため、他のRパッケージから関数にアクセスする場合と同様に 'toymod'をロードする必要があるためです。

doParallelを使用する場合、なぜこれが必要でないのかわかりません。私はdoParallelがforeachループがあるパッケージを自動的にロードする必要があると思います。私はこれをさらに調べ、doMPIを変更して同じことを行うでしょう。

+0

それは動作します!どうも。ちょっと変わったようですが、正しい専門用語はわかりませんが、「循環型」(Ouroboros)や「近親性」の春が心に響きます。それ自身の中に関数をロードする必要があるのは私にとって論理的ではありませんが、これはプログラミングのいくつかのパラダイムでは普通のことでしょうか? –

+0

@ JimMaasリモートプロセスでR式を評価する環境を設定するのは難しいです。 foreachループの本体が、定義されているパッケージからエクスポートされていない関数にアクセスできるようにしたいのですが、このような状況では可能ではないと思います。私はパッケージが自動的に読み込まれるようにするのは理にかなっていると思いますが、それでもforeach本体をパッケージの第二種市民として扱います。 –

関連する問題