MPI_Scatter
とMPI_Gather
を複数回使用してこれらの2つのMPI関数が完了するのを待って結果を出力する方法を学びたいと考えています。プログラムの最上位のプロセス0では、Scatter and Gatherを呼び出すwhileループを使いたいと思います。すべての計算が完了したら、この配列をこれらの関数に送り返して、より多くの計算を行いたいと思います。私は何をしようとしているのかをコードで説明しました。 /*.....*/
のコメントは私が達成しようとしている課題です。
次のコードは4つのプロセッサを使用して実行されます。
:$ mpicc test.c -o test
:$ mpirun -np 4 test
ループ内のMPI_ScatterとMPI_Gatherを再利用する方法
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[8];
int localdata[2];
int counter, i;
if (rank == 0)
{
for (i=0; i<size*2; i++)//initializing array to all zeros, one time
globaldata[i] = 0;
/*counter=0;
do
{
counter++; */
printf("Sending at Processor %d has data: ", rank);
for (i=0; i<size*2; i++)
printf("%d ", globaldata[i]);
printf("\n");
/*After MPI_Gather is done, I want to get the newly assined array here.
Now the globaldata array should hold values: 0 0 1 1 2 2 3 3
Therefore, in the next iteration of this while loop, these array values need
to be send for a new calculation with Scatter & Gather
}while(counter<2);*/
//Following need to be executed after all the scatter and gather has completed
printf("Finally at Processor %d has data: ", rank);
for (i=0; i<size*2; i++)//Here the result should be: 0 0 2 2 3 3 4 4
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Scatter(globaldata, 2, MPI_INT, &localdata, 2, MPI_INT, 0, MPI_COMM_WORLD);
localdata[0]= localdata[0]+rank;
localdata[1]= localdata[1]+rank;
MPI_Gather(&localdata, 2, MPI_INT, globaldata, 2, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {//Currently I can only see the newly assinged array values if I print out the result at the bottom
printf("At the bottom, Processor %d has data: ", rank);
for (i=0; i<size*2; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
MPI_Finalize();
return 0;
}
もっと私は上記のやろうとしています何の説明: 私はすべてのプロセッサに自分のglobaldata
配列を送信したいのです。更新されたglobaldata
配列を取得します。更新された配列を取得したら、この配列を他のすべてのプロセスに再送して、計算をやり直したいと思います。私はMPI_SendとMPI_Recvを使って同様の仕事をする次のコードを書いています。私はすべてのプロセッサに私の配列を送信するためにMPI_Sendを使用しています。次に、この配列はそれを変更し、ルート/プロセス0に戻します。変更された配列を取得すると、do while
ループが再度実行され、より多くの計算が実行されます。私がしようとしているのは、MPI_ScatterとMPI_Gatherを同様の方法で使用することです。私はその配列を変更するために更新globaldata
配列を取得し、MPI_ScatterとMPI_Gatherに戻ってそれを送信する場合は、再び
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int globaldata[8];
int counter, i;
if (rank == 0)
{
for (i=0; i<size*2; i++)
globaldata[i] = 0;
counter=0;
do
{ /*becase of this do while loop "globaldata" array will always be updated and resend for more caculations*/
counter++;
printf("Sending at Processor %d has data: ", rank);
for (i=0; i<size*2; i++)
printf("%d ", globaldata[i]);
printf("\n");
for(i = 0; i < 4; i++)
{
MPI_Send(&globaldata, 8, MPI_INT, i, 0, MPI_COMM_WORLD);
}
for(i = 1; i < 4; i++)
{
MPI_Recv(&globaldata, 8, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
}
}while(counter<2);
/*Following executes after all the above calculations has completed*/
printf("Finally at Processor %d has data: ", rank);
for (i=0; i<size*2; i++)
printf("%d ", globaldata[i]);
printf("\n");
}
counter=0;
do
{
counter++;
MPI_Recv(&globaldata, 8, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
globaldata[rank]=globaldata[rank]+rank;
globaldata[rank+1]=globaldata[rank+1]+rank;
MPI_Send(&globaldata, 8, MPI_INT, 0, 99, MPI_COMM_WORLD);
}while(counter<2);
MPI_Finalize();
return 0;
}
質問はしていません。 –
私もあなたの質問を理解していません。あなたが理解していないより具体的なものがありますか?あなたは何か特別な問題がありますか?うまくいかないものを試しましたか?あなたは、質問をより明確にするために、その質問をよく編集するべきです。 :-) – MakisH
コメントありがとうございました。私はここで何を達成しようとしているのか説明しようとしました。これが少なくとも少し助けてくれることを願っています。 – Newlearner