0

Rmpi の並列処理ツールを使用して、大学の Unix クラスターで分析を実行しています。以下に示す R スクリプトを自分のローカル (Windows) マシンで snow パッケージまたは標準の適用関数だけを使用して実行すると、非常に遅くなりますが、正常に動作するようです。Rmpi を使用して Unix クラスターで実行すると、「シリアル化が大きすぎて生のベクターに保存できません」というエラーが表示されます。この投稿適切に思えますが、私が行ったり来たりしているベクトル (50K) は、このエラーのトリガーに近づくべきではありません。さらに、データを小さな断片に分割することで、物事を部分的に機能させることができます。問題は Rmpi​​ に関連するある種のメモリ リークに違いないと思いますが、そのようなことをデバッグするために必要なツールがありません。うまくいけば、少なくともここで何が起こっているかをデバッグするためのツールの方向に私を向けることができます.

私が扱っているデータには最大 250 万件のレコードがあり、各レコードには最大 40 列あります。50K x 40 のデータ フレームを parApply に送信すると、50K の数値ベクトルが返されます。

#In an effort to avoid the serialization error I break into smaller pieces to avoid    
#problems with large vectors getting transferred between master and slave nodes
numBreaks<-floor(length(data[,1])/50000)
base<-min(length(data[,1]),50000)  #test data sets are < 50K and shouldn't 
                                   #crash the function    piece.in<-data[c(1:base),]         #this is the first batch of records I submit

status<-mpi.parApply(piece.in,1,test) #returns a vector of length 50K
#status<-apply(piece.in,1,test)   #commented out, function runs fine locally using                 
                                  #standard apply function
#cl <- makeSOCKcluster(c("localhost","localhost","localhost","localhost","localhost"))
#status<-parApply(cl,piece.in,1,test) #commented out, function runs fine locally
                                      #using snow's SOCK cluster and identical
                                      #parApply function
if(numBreaks>1){
for (i in 2:numBreaks){
  piece.in<-data[c((base+1):(base+50000)),]
  piece.out<-mpi.parApply(piece.in,1,test)  #returns a vector of length 50K

 #piece.out<-apply(piece.in,1,test)
 #piece.out<-parApply(cl,piece.in,1,test)
  status<-append(status,piece.out)          #add to existing vector
  base<-base+50000                          #increment base
  print(paste("clusters assigned to records",base,"through",(base+50000)))
 }
}

#This piece cleans up the residual records 
if((length(c(base:length(data[,1])))>1) & (base < length(data[,1]))){
  piece.in<-data[c((base+1):length(data[,1])),]
  #piece.out<-apply(piece.in,1,test)
  piece.out<-mpi.parApply(piece.in,1,test)
  #piece.out<-parApply(cl,piece.in,1,test)
  status<-append(status,piece.out)
  print(paste("Final: status has length",length(status)))
 }

この関数は、テスト データセット (~100K レコード) で意図したとおりに機能します。Snow または標準の適用機能を使用してローカルで動作します (ただし、1 日かかります)。小さい断片に分割する前に、「シリアル化が大きすぎます...」というエラーで失敗しました。断片を 100K レコードの長さにすると、同じエラーで失敗しました。50K のバッチで送信されるレコードで 130 万から 135 万のレコードをカバーする繰り返しまで (ファイルに書き込まれた print ステートメントで文書化されているように) 正常に実行され、シリアル化エラーで失敗します。

並列処理を行う方法が他にもあることは知っていますが (ここで foreach コマンドを使用したかったのですが)、並列ノードが作成されるコンピューティング環境について何も知らないという制約があるため、そのままにしておきたいと思います。できればRmpiで。これをデバッグする方法に関するヒントはありますか?

とても感謝しております。

クリス

4

0 に答える 0