2016-10-28 12 views
1

パラレルパッケージを使用して生成されたクラスターにグローバルに定義されたクラスを渡す方法がわかりません。私はそれが機能するために働いてきた:R並列プログラミングでグローバルにS4クラスを定義

funs = "testClass" 
fun = function(x) testClass(test = x^2) 
testClass = function(test) return(test) 

cl <- parallel::makeCluster(2, outfile='') 
parallel::clusterExport(cl = cl, varlist = funs, envir = globalenv()) 
res <- parallel::parLapply(cl = cl, X = seq_len(10L), fun = fun) 
parallel::stopCluster(cl) 
res 

は同じアプローチは、クラスのために動作しません:

funs = "testClass" 
fun = function(x) testClass(test = x^2) 
testClass = setClass("testClass", slots = c(test = "numeric")) 

cl <- parallel::makeCluster(2, outfile='') 
parallel::clusterExport(cl = cl, varlist = funs, envir = globalenv()) 
res <- parallel::parLapply(cl = cl, X = seq_len(10L), fun = fun) 
parallel::stopCluster(cl) 

私はパッケージ内のクラスと発電機能を置くことが可能である知っているが、そこにありますこの問題を解決する簡単な方法はありますか?

+0

あなたのコードは動作しません。 'funs'と' fun'とは何ですか? –

+0

funsとfunは両方のコードチャンクで同じです。わかりやすくするために更新されました。 –

答えて

1

S4クラスを定義すると、実際にはグローバル環境内の一部の非表示のメタデータオブジェクトが変更されます。スレーブノードにジェネレータ機能をコピーするだけでは不十分です。各ノードでクラス定義ステートメントを実行する必要があります。 (さて、あなたはそれらのメタデータがオーバーオブジェクトコピーできますが、それだけでトラブルを求めています。)

cl <- parallel::makeCluster(2, outfile='') 
parallel::clusterEvalQ(cl, expr={ 
    testClass <- setClass("testClass", slots = c(test = "numeric")) 
}) 
res <- parallel::parLapply(cl = cl, X = seq_len(10L), fun = fun) 

res 

# [[1]] 
# An object of class "testClass" 
# Slot "test": 
# [1] 1 
# 
# [[2]] 
# An object of class "testClass" 
# Slot "test": 
# [1] 4 
# . . . 
+0

この情報をお寄せいただきありがとうございます。私が上で与えた小さな例を解決します。私が苦労していたより複雑な問題を解決するのにも役立っています。代わりにparallel :: clusterCallを使用することになりました。なぜなら、変数を渡すことができるからです。 –

関連する問題