2011-07-14 5 views
18

によって呼び出される関数の中でのforeach%のdoparの%での問題:呼び出された関数は、そのように見えるR - エラーが発生するforeach%dopar%OPTIMから構築を含む関数を呼び出すOPTIM

> workers <- startWorkers(6) # 6 cores 
> 
> registerDoSMP(workers) 
> 
> t0 <- Sys.time() 
> 
> optim(w,maxProb2,control=list(fnscale=-1)) 
> 
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)" 
> 
> Sys.time()-t0 
> 
> Time difference of 2.032 secs 
> 
> stopWorkers(workers) 

> maxProb2 <- function(wp) { 
> 
> r <- foreach (i=s0:s1, .combine=c) %dopar% { pf(i,x[i,5],wp,isPrebuilt=TRUE) } 
> 
> cat("w=",wp,"max=",sum(r),"\n") 
> 
> sum(r) 
> 
> } 

pfは他の関数であり、xは事前計算された要素の静的なテーブルです。

がまた一度だけ最適化されるように関数を呼び出すことは、同じエラーが発生:

> workers <- startWorkers(6) # 6 cores 
> 
> Warning message: 
> In startWorkers(6) : there is an existing doSMP session using doSMP1 
> 
> registerDoSMP(workers) 
> 
> maxProb2(w) 
> Error in { : task 1 failed - "unused argument(s) (isPrebuilt = TRUE)" 
> 
> stopWorkers(workers) 

奇妙何を単一の時間(OPTIMは、同じ機能を何度もcalles)を直接呼び出されたときに、同じコードが正常に動作します

%dop%の代わりに%do%を使用すると、呼び出される関数(maxProb2)は正常に動作します。

foreach%dopar%の構造を含む関数を正しく呼び出すにはどうすればよいですか?

UPDATE 2011-07-17:

私はprobfにPF機能の名前を変更したが、問題が残っています。

probf関数がスクリプトで定義されています。一部の外部パッケージでは定義されていません。

2つのノート:OS:Windows 7の、IDE:革命解析エンタープライズ4.3

> workers <- startWorkers(workerCount = 3) 
> 
> registerDoSMP(workers) 
> 
> maxProb2(w) 
> 
Error in { : task 1 failed - "could not find function "probf"" 
+0

質問には常に正確なエラーメッセージを含めてください。 –

答えて

2

[[編集]]

あなたpf機能し、あなたの "静的なテーブル" xは、すべての労働者に配布されなければなりませんノード。並列ライブラリのドキュメントを読んでその動作を確認する必要があります。

optimを実行すると、pf関数はそれが別のもの(おそらくstats::pfisPrebuilt引数を持たない)であることがわかります。

pfの名前を変更することはできますか(たとえば、mypf)。

mypf <- pf # renaming the function 

maxProb2 <- function(wp) { 
    r <- foreach (i=s0:s1, .combine=c) %dopar% { mypf(i,x[i,5],wp,isPrebuilt=TRUE) } 
    cat("w=",wp,"max=",sum(r),"\n") 
    sum(r) 
} 

それとも、あなたのpf関数は、名前空間(たとえば、mypackage)、あなたはこのようにそれを参照することができて、パッケージの一部である場合:mypackage::pf

maxProb2 <- function(wp) { 
    r <- foreach (i=s0:s1, .combine=c) %dopar% { mypackage::pf(i,x[i,5],wp,isPrebuilt=TRUE) } 
    cat("w=",wp,"max=",sum(r),"\n") 
    sum(r) 
} 
+0

どのように私は、呼び出される関数とテーブルがワーカーノードに配布されていることを確認しますか? – mjaniec

+1

'pf'は組み込みの' stats'パッケージに存在し、F配布の配布関数です。 – James

+0

私はそれが疑わしいと思われるので、答えを更新しました。間違った 'pf'関数が呼び出されました。 – Tommy

18

は、私は同じ問題に遭遇しました問題は、環境がサブスレッドに含まれていないことです。あなたのエラー

Error in { : task 1 failed - "could not find function "simple_fn""

は、この非常に単純な例で再現することができます。

simple_fn <- function(x) 
    x+1 

test_par <- function(){ 
    library("parallel") 
    no_cores <- detectCores() 
    library("foreach") 
    cl<-makeCluster(no_cores) 
    library("doSNOW") 
    registerDoSNOW(cl) 
    out <- foreach(i=1:10) %dopar% { 
     simple_fn(i) 
    } 

    stopCluster(cl) 
    return(out) 
} 

test_par() 

は今、すべてのあなたはforeach(i=1:10, .export=c("simple_fn"))foreach(i=1:10)を変更することがあるためにする必要があります。完全な地球環境を輸出したい場合は.export=ls(envir=globalenv())と書いてください。あなたはそれを良くするか悪化させるでしょうか? foreach%のdoparの%での問題のため

+1

私はいつも '.export = ls()'がデフォルトではないのか疑問に思っています。このトピックの記事の数から判断すると、ほとんどの状況で良いアイデアのように思えます...どんな考えですか? – Ruben

+1

@Ruben - 大規模なデータセットを扱うときは、並列化が最も関連性が高いので、実際には意味があります –

+1

しかし、各ノードでデータのまとまりを個別にロードするのでしょうか?私はグローバルセッションでdf全体をロードしません。また、いくつかのものが自動的に読み込まれます(例:反復処理中のベクトル)。さらに、lsを使用すると、私はちょうど今期待したように動作しませんでした。私が起こると予想していることを確実に得る唯一の解決策は、ループの内部を定義することです。非効率で、時には醜い。 – Ruben

0

クイックフィックスはこれらのパッケージを再インストールすることです:

install.packages("doSNOW") 

install.packages("doParallel") 

install.packages("doMPI") 

のStackOverflowでさまざまなスレッドで述べたように、これらは、これらの古いバージョンに存在していたR.バグで並列処理を担当していますパッケージが削除されました。それは私の場合に働いた。私はあなたのプロジェクト/パッケージでこれらのパッケージを使用していなくても、おそらく役立つでしょう。

関連する問題