2011-12-25 6 views
0

重力の干渉が問題です。システムにN個の粒子があり、M個のプロセスがある。 現在のプロセスの個々のブロックにパーティクル(すべて11個のパラメータがあります)の新しい位置を計算し、その後、すべての他のプロセスに新しいデータをブロードキャストします。MPI_BCastからデータを受信する方法

double * particles; 
... 
int startForProcess = numberOfParticlesPerThread * 11 * rank; 
int endForProcess = startForProcess + numberOfParticlesPerThread * 11; 
calculateNewPosition(particles, startForProcess, endForProcess, nParticles, rank); 
MPI_Barrier(MPI_COMM_WORLD); 
MPI_Bcast(particles+startForProcess, endForProcess - startForProcess, MPI_DOUBLE, rank, MPI_COMM_WORLD); 

残念ながら、各スレッドで私はこのスレッドで行われた変更を見ることができます。 はここに私のコードです。プロセス間に通信はありません。

私に間違っていると教えてください。

+0

私はこのストレートを手に入れましょう:各プロセス(MPIはスレッドではなくプロセスで動作します)をして、結果を他の人と共有したいですか? 「Bcast」は1対1の呼び出しであり、全部ではありません。 – suszterpatt

+0

g.inozemtsevによるMPI_Allgatherの答えはあなたの質問に対する正解ですが、実はこのコードをプロダクションコードとして使用することは望ましくありません。実際のn-bodyシミュレーションにこのアプローチを使用する予定がある場合は、離れたパーティクルが重力に寄与しないという事実を利用する他のアプローチがあります - barnes-hut、fast multipoleメソッド、particle-meshなどn^2アプローチを使用する直接的な計算機であっても、通常、「パイプライン化」型のコミュニケーション手法を使用します。 –

答えて

3

MPI_Bcastは、ルートからコミュニケータの残りのランクにデータをブロードキャストします。 MPI_Bcastコール内のすべてのプロセスは、同じプロセスからデータをすべて受信しているため、同じルートパラメータを使用する必要があります。

あなたが探している機能はMPI_Allgatherだと思います。更新されたデータがすべてのプロセス間で収集され、伝達されます。

コードは次のようなものになります:余談として

double * particles; 
double * my_particles; 
... 
int startForProcess = numberOfParticlesPerThread * 11 * rank; 
int endForProcess = startForProcess + numberOfParticlesPerThread * 11; 
calculateNewPosition(particles, startForProcess, endForProcess, nParticles, rank); 

memcpy(my_particles, particles + startForProcess * sizeof(double), 
     (endForProcess - startForProcess) * sizeof(double)); 
MPI_Allgather(my_particles, endForProcess - startForProcess, MPI_DOUBLE, 
       particles, endForProcess - startForProcess, MPI_DOUBLE, MPI_COMM_WORLD); 

をもちろん、あなたが他のいくつかの理由で同期が必要な場合を除き、あなたは、集団的呼び出しの前MPI_Barrierは必要ありません。

+1

+1;少し修正しますが、recvcountはプロセスごとですので、 'nParticles'ではなく、' endForProcess-startForProcess'(= 'numberOfParticlesPerThread')をsendcountとして使用します。 –

関連する問題