web-dev-qa-db-ja.com

doParallelクラスターの「登録解除」

クラスターを登録せずに_foreach... %dopar%_を実行すると、foreachは警告を発し、コードを順次実行します。

_library("doParallel")
foreach(i=1:3) %dopar%
  sqrt(i)
_

利回り:

_Warning message:
executing %dopar% sequentially: no parallel backend registered 
_

ただし、クラスターを開始、登録、および停止した後にこの同じコードを実行すると、失敗します。

_cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
foreach(i=1:3) %dopar%
  sqrt(i)
_

利回り:

_Error in summary.connection(connection) : invalid connection
_

クラスター登録をクリーンアップするregisterDoParallel()の反対はありますか?それとも、Rセッションを再開するまで、古いクラスターのゴーストで立ち往生していますか?

/ edit:グーグルで bumphunter Biocondoctorパッケージのbumphunter:::foreachCleanup()関数を明らかにします:

_function () 
{
    if (exists(".revoDoParCluster", where = doParallel:::.options)) {
        if (!is.null(doParallel:::.options$.revoDoParCluster)) 
            stopCluster(doParallel:::.options$.revoDoParCluster)
        remove(".revoDoParCluster", envir = doParallel:::.options)
    }
}
<environment: namespace:bumphunter>
_

ただし、この関数は問題を解決しないようです。

_library(bumphunter)
cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
bumphunter:::foreachCleanup()
foreach(i=1:3) %dopar%
  sqrt(i)
_

Foreachは登録されたクラスターの情報をどこに保存しますか?

32
Zach

Foreachバックエンドを「登録解除」する唯一の公式な方法は、順次バックエンドを登録することです:

registerDoSEQ()

使用するバックエンドを宣言する必要があるため、これは理にかなっています。したがって、使用するバックエンドを「宣言解除」する方法を提供する意味はありませんでした。代わりに、デフォルトのシーケンシャルバックエンドを使用することを宣言します。

私はもともと「登録解除」関数を含めることを検討しましたが、それが有用であると納得できなかったため、関数を削除するよりも関数を追加する方がはるかに簡単なので、除外することにしました。

そうは言っても、foreachがすべての状態を保持しているforeach:::.foreachGlobalsからすべての変数を削除するだけでよいと思います。

unregister <- function() {
  env <- foreach:::.foreachGlobals
  rm(list=ls(name=env), pos=env)
}

この関数を呼び出した後、%dopar%が呼び出されると、並列バックエンドは登録解除され、警告が再度発行されます。

47
Steve Weston
    cl <- makeCluster(2)
    registerDoParallel(cl)
    on.exit(stopCluster(cl))

これはうまくいきました。

3
Smit