2011-08-17 4 views
2

私は「並列化」段階に進むために必要なRコードを持っています。私は間違った言葉を使用する場合、私はこれで新しいので、私を許してください。私は一度に個人ごとに悩まされ、最後に個人間で平均をとらなければならないプロセスを持っています。このプロセスは各個人(ブラウン橋)について全く同じですが、私は300人以上の人にこれを行わなければなりません。だから、ここで誰かが私のコードを変更して産んだのを知ることを望んでいただろうか?または並列化された? 48個のCPUがアクセスできるようにすることが何であれ、私の小さなノートパソコンでこれを計算するのにかかる58日を減らすのに役立ちます。私の頭の中では、1つのプロセッサを1つのプロセッサに送信するだけです。それはスクリプトを実行し、別のものを送信して....それが理にかなっている場合。Rコードをマルチコア処理に書き換えるには?

以下は私のコードです。私はそれにコメントしようとしましたが、コードを変更する必要があると思われる箇所を示しました。

for (n in 1:(length(IDNames))){ #THIS PROCESSES THROUGH EACH INDIVIDUAL 

#THIS FIRST PART IS JUST EXTRACTING THE DATA FROM MY TWO INPUT FILES. 
#I HAVE ONE FILE WITH ALL THE LOCATIONS AND THEN ANOTHER FILE WITH A DATE RANGE. 
#EACH INDIVIDUAL HAS DIFFERENT DATE RANGES, THUS IT HAS TO PULL OUT EACH INDIVIDUALS 
#DATA SET SEPARATELY AND THEN RUN THE FUNCTION ON IT. 

    IndivData = MovData[MovData$ID==IDNames[n],] 
    IndivData = IndivData[1:(nrow(IndivData)-1),] 
    if (UseTimeWindow==T){ 
     IndivDates = dates[dates$ID==IDNames[n],] 
     IndivData = IndivData[IndivData$DateTime>IndivDates$Start[1]&IndivData$DateTime<IndivDates$End[1],] 
    } 
    IndivData$TimeDif[nrow(IndivData)]=NA 

    ######################## 
#THIS IS THE PROCESS WHERE I THINK I NEED THAT HAS TO HAVE EACH INDIVIDUAL RUN THROUGH IT 

    BBMM <- brownian.bridge(x=IndivData$x, y=IndivData$y, 
    time.lag = IndivData$TimeDif[1:(nrow(IndivData)-1)], location.error=20, 
    area.grid = Grid, time.step = 0.1) 

    ############################# 
    # BELOW IS JUST CODE TO BIND THE RESULTS INTO A GRID DATA FRAME I ALREADY CREATED. 
    #I DO NOT UNDERSTAND HOW THE MULTICORE PROCESSED CODE WOULD JOIN THE DATA BACK 
    #WHICH IS WHY IVE INCLUDED THIS PART OF THE CODE. 

    if(n==1){ #creating a data fram with the x, y, and probabilities for the first individual 
     BBMMProbGrid = as.data.frame(1:length(BBMM[[2]])) 
     BBMMProbGrid = cbind(BBMMProbGrid,BBMM[[2]],BBMM[[3]],BBMM[[4]]) 
     colnames(BBMMProbGrid)=c("GrdId","X","Y",paste(IDNames[n],"_Prob", sep="")) 
    } else {    #For every other individual just add the new information to the dataframe 
     BBMMProbGrid = cbind(BBMMProbGrid,BBMM[[4]]) 
     colnames(BBMMProbGrid)[n*2+2]=paste(IDNames[n],"_Prob", sep ="") 
    }# end if 


    } #end loop through individuals 
+4

誰かが-1で投票したことは分かりませんが、あなたのコードが複雑すぎるため、疑わしいと思います。人々がそれを見分けるのに時間がかかります。あなたは私たちに10〜20行しかない簡略化されたバージョンを与えることができますか?まだ完全なR構文を持っていますが、あなたがしたいことのアイデアを与えますか?また、マルチコア、密接に結合されたマシンなど、計算機の設定についてもう少し詳しく教えてください。どのようなアプローチが考えられましたか(高性能タスクビュー(http://cran.r-project.org/web/views/HighPerformanceComputing.html)を参照) –

+0

ブライアンをSeconding。あなたの仕事のすべてを私たちにさせてはいけません。並列化が必要な手順を私たちに教えてください。私たちはそれを手助けすることができます。 – Maiasaura

+0

おっと、私はベンを入力するつもりだった。ごめんなさい! – Maiasaura

答えて

4

これがなぜ投票されたのかわかりません。私はforeachパッケージがあなたの後になっていると思います。最初の数少ないpdfには、非常に明確な有用な情報があります。基本的に、それぞれの人のために何をしたいかを関数として書く。その後、foreachを使ってある人のデータをノードに送り、関数を実行します(別の人を別のノードに送るなど)。そして、rbindのようなものを使ってすべての結果をコンパイルします。私はこれを数回使って素晴らしい結果を得ました。

編集:これまでのところ、関数にラップして1つのライナーforeachを使用するスキルを手に入れることができれば、私はあなたのコードを書き直すようには見ませんでした。

編集2:これは長すぎて返信するコメントがありませんでした。

私は、あなたがそれを関数に入れることができるコードを持っているので、考えました:)まだこれについて作業しているなら、forループを書くことを考えるのが役立ちますその主題に必要な計算を行います。それで、forループがあなたの関数に必要なものです。私は、あなたのコードでは、 'area.grid'までのすべてのものだと思います。その後、データは反復ごとに1回のみサブセットになるので、ほとんどの[n]を取り除くことができます。おそらく、

pernode <- function(MovData) { 
    IndivData = MovData[MovData$ID==IDNames[i],] 
    IndivData = IndivData[1:(nrow(IndivData)-1),] 
    if (UseTimeWindow==T){ 
         IndivDates = dates[dates$ID==IDNames,] 
         IndivData = IndivData[IndivData$DateTime>IndivDates$Start[1] 
         &IndivData$DateTime<IndivDates$End[1],] 
         } 
    IndivData$TimeDif[nrow(IndivData)]=NA 

    BBMM <- brownian.bridge(x=IndivData$x, y=IndivData$y, 
    time.lag = IndivData$TimeDif[1:(nrow(IndivData)-1)], location.error=20, 
    area.grid = Grid, time.step = 0.1) 

return(BBMM) 
} 

その後のようなもの:

library(doMC) 
library(foreach) 
registerDoMC(cores=48) # or perhaps a few less than all you have 

system.time(
    output <- foreach(i = 1:length(IDNames)), .combine = "rbind", .multicombine=T, 
.inorder = FALSE) %dopar% {pernode(i)} 
) 

私はあなたが取得する方法を知ってみましょう、それはいくつかのテストデータがないことであるかどうかを言うのは難しいです。

+0

@nezcoops - あなたは私の兄弟に信仰をたくさん持っていますiveは右のskillzzzを持っていると思う!ありがとう。それは、他の人のスクリプトや例を使って、現在どのようなものが生まれているのかを判断するのに苦労しています。しかし、私は辛抱強く頑張ります。私はlapplyコマンドを使用したことがないし、これはforeachについて聞いた最初のiveです。 – Kerry

+0

は、コメント欄に空きがなくなったために答えを拡張しました。 – nzcoops

4

これは一般的な例です。私はすべてのコードを読み込むことができませんでした。これを複数のプロセッサに分散する最も簡単な方法の1つは、multicoreライブラリとmclapply(並列化バージョンlapply)を使用してリストをプッシュすることです(リスト内の個々のアイテムは、300人以上の個人のデータフレームになります)。大文字小文字を区別します)。

例:私はあなたに説明を理解したよう

library(multicore) 
result=mclapply(data_list, your_function,mc.preschedule=FALSE, mc.set.seed=FALSE) 
+0

あなたの提案をありがとう、私はさまざまなプロセッサに解析されると思うセクションにコードをカットしました。コードには主な機能が1つしかありません(brownian.bridgeコマンド)。これは、データセット内の各個人について計算する必要があるものです。私がIF文で始めるところは、結果を受け取り、それらをグリッドにバインドするところです。私はこれがクラスタに送信する必要はないと想定していますが、プロセスがどのように戻って、すべての異なるプロセッサから参加するかを理解していません。 – Kerry

+1

forループは、Rで非効率的です。plyrを使用して、各個人のデータをリストにスローします。例:個体= dlply(元データ、。(IDNames))。次に、bbbm関数と結果のフォーマットの両方を含むラッパー関数(その関数に一度に1つのリスト項目を渡す)を作成します。したがって、マルチコアが実行されると、両方が実行され、個々の項目がグリッドにバインドされた結果であるリストが返されます。それから、あなたは何でもすることができます(例えば、リストを折り畳む、プロットするなど)。 – Maiasaura

2

あなたは、分散コンピュータクラスタへのアクセス権を持っています。したがって、マルチコアパッケージは動作しません。 Rmpi、snow、foreachを使用する必要があります。あなたの既存のループ構造に基づいて、私はforeachとdoSnowパッケージを使用するようアドバイスをします。しかし、あなたのコードは、あなたがたくさんのデータを持っているように見えます。おそらく、ノードに送信されるデータ(必要なもののみ)を減らすためにチェックする必要があります。

関連する問題