web-dev-qa-db-ja.com

RにおけるmclapplyとparLapplyの違いを理解する

私は最近、プロジェクトでRの並列手法を使用し始めて、- parallel パッケージの mclapply を使用してLinuxシステムでプログラムを動作させています。しかし、私はWindowsのparLapplyを理解しているため、大きな障害に直面しました。

mclapplyを使用すると、コアと反復の数を設定し、それをワークスペースの既存の関数に渡すことができます。

_mclapply(1:8, function(z) adder(z, 100), mc.cores=4)
_

parLapplyを使用してWindowsで同じことを行うことができないようです。私が理解しているように、clusterExport()を使用してすべての変数を渡し、引数に適用する実際の関数を渡す必要があります。

これは正しいですか、またはWindowsに適用できるmclapply関数に似たものがありますか?

26
A_Skelton73

mclapplyの優れている点は、mclapplyが呼び出された時点でワーカープロセスがすべてマスターのクローンとして作成されるため、各クラスターワーカーで環境を再現する必要がないということです。残念ながら、これはWindowsでは不可能です。

parLapplyを使用する場合、通常、次の追加手順を実行する必要があります。

  • PSOCKクラスターを作成する
  • 必要に応じてクラスターを登録します
  • クラスターワーカーに必要なパッケージを読み込む
  • 必要なデータと機能をクラスターワーカーのグローバル環境にエクスポートする

また、完了したら、stopClusterを使用してPSOCKクラスターをシャットダウンすることをお勧めします。

ここにあなたの例のparLapplyへの翻訳があります:

library(parallel)
cl <- makePSOCKcluster(4)
setDefaultCluster(cl)
adder <- function(a, b) a + b
clusterExport(NULL, c('adder'))
parLapply(NULL, 1:8, function(z) adder(z, 100))

adder関数でパッケージが必要な場合は、parLapplyで呼び出す前に、各ワーカーでそのパッケージをロードする必要があります。 clusterEvalQを使用すると、非常に簡単にこれを行うことができます。

clusterEvalQ(NULL, library(MASS))

NULLclusterExportclusterEvalへのparLapplyの最初の引数は、setDefaultClusterを介して登録されたクラスターオブジェクトを使用する必要があることを示しています。プログラムがmclapplyを使用するようにプログラムを変換するときに、クラスターオブジェクトを必要とするすべての関数にクラスターオブジェクトを渡す必要がないように、プログラムがparLapplyを使用している場合に非常に役立ちます。

もちろん、adderが他の関数を呼び出すグローバル環境の他の関数を呼び出すこともあります。その場合、それらもエクスポートし、必要なパッケージをロードする必要があります。また、エクスポートした変数がプログラムの途中で変更された場合、クラスターワーカーでそれらを更新するために、変数を再度エクスポートする必要があります。繰り返しになりますが、mclapplyでは、ワーカーが呼び出されるたびに常にワーカーが作成/クローン/フォークされるため、不要です。

28
Steve Weston

mclapplyは使いやすく、基盤となるオペレーティングシステムのfork()機能を使用して並列化を実現します。ただし、Windowsにはfork()がないため、代わりに標準のlapplyが実行され、並列化は行われません。

parLapplyは別の獣です。プロセスのクラスターを作成します。これはネットワーク上の異なるマシンに存在することもでき、タスクと結果を相互に渡すためにTCP/IPを介して通信します。

コードの問題は、parLapplyの最初のパラメーターが「クラスター」オブジェクトであることを認識していないことです。 parLapplyを使用して単一のマシンで実行する最も簡単な例は、次のとおりです。

library(parallel)

# Spawn child processes using fork() on the local machine
cl <- makeForkCluster(getOption("cl.cores", 2))

# Use parLapply to calculate lengths of 1000 strings
text = rep("Hello, world!", 1000)
len = parLapply(cl, text, nchar)

# Kill child processes since they are no longer needed
stopCluster(cl)

上記のようにmakeForkClusterを使用して作成されたクラスターでparLapplyを使用することは、mclapplyを呼び出すことと機能的に同等です。したがって、Windowsでも機能しません。 :)ドキュメントでmakeClusterとmakePSOCKclusterを使用してクラスターを作成できる他の方法を見て、要件に最適な方法を確認してください。

3
asieira