2016-10-22 2 views
1

:)Mpi recv:信号分割エラーを使用しようとするとエラーが発生する

mpiプログラムに関して迷惑な質問がありました。アイデアは:各プロセス(スレーブ)は、マンデルブロフラクタルを計算するためにマスタにデータを送信します。

まず、各スレーブはポイントとワーカーを送信しました。それから、彼らはラインを送って、それは働いた!

今、私はそれらに行のブロックを送信しようとします(5行、つまり部分行列を仮定しましょう)。

私の考えは、これらの5行を1行にすることです。マスターは最初の「新しい」行を受け取るが、他のO_oは受け入れない。私は邪魔されている。私は他人のために受信

(> 1): 信号セグメンテーションフォールト 信号コード:住所

で失敗 をマッピングされていないアドレスには、私を助けてください!それは長い時間ですので、i'haveは:(

Psを探して:私は必要MPI_Recv()機能フランス語だ(私の英語が悪いですなぜそれはだ)

//the whole table to be used in a master //int table[NX*NY]; //int count =0; if (rank == 0) { int res; int line[MAXY+MAXY+1]; int block[5*(MAXY+MAXY+1)]; int count = 0; /* Begin User Program - the master */ //MPI_Recv(&line, MAXY+MAXY+1, MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status); MPI_Recv(&block, 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status); printf("sizeof of datablock received is = %d \n",sizeof(block)/sizeof(block[0])); recvd = status.MPI_SOURCE; printf("i have received blockdata from %d \n",recvd); /* remplissage du case */ for(i = -MAXX; i <= MAXX; i++) { for(j = -MAXY; j <= MAXY; j++) { cases[i + MAXX][j + MAXY] = block[count%(MAXY+MAXY+1)]; //printf("j'ai fait un bloc[count], pas credible\n"); count++; } } dump_ppm("mandel.ppm", cases); printf("Fini.\n"); } else { /* On est l'un des fils */ /* for the block;let's suppose each son send 5 rows*/ double x, y; int i, j, res, rc, rank,count; //int line[MAXY + MAXY + 1]; int block[5*(MAXY+MAXY+1)]; count = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); for(i = -MAXX; i <= MAXX; i++) { for(j = -MAXY; j <= MAXY; j++) { x = 2 * i/(double)MAXX; y = 1.5 * j/(double)MAXY; res = mandel(x, y); //line[j+MAXY] = res; block[count] =res; if (count % (5*(MAXY+MAXY+1)) == 0){ //we send each five rows MPI_Send(&block,5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD); printf("me slave %d, have sent datablock to master\n",rank); printf("sizeof of datablock sent is = %d\n",sizeof(block)/sizeof(block[0])); } count++; } //MPI_Send(&line, MAXY+MAXY+1 , MPI_INT, 0, DATATAG, MPI_COMM_WORLD); } } MPI_Finalize(); return 0; }

答えて

0

アドレスはMPI_Send()と同じです。int block[5*(MAXY+MAXY+1)]は配列なので、blockは配列block[0]の最初の項目を指しています:これは、必要なアドレスです。一方、&block 01を指す:intへのポインタへのポインタに似ています。しかし、&blockの値は配列の最初の項目のアドレスではありません!したがって

、あなたが試みることができる:あなたはどのような単一の整数int aを送信する場合

int block[5*(MAXY+MAXY+1)] 
... 
MPI_Send(&block[0],5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD); 
... 
MPI_Recv(&block[0], 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status); 

:?

int block[5*(MAXY+MAXY+1)] 
... 
MPI_Send(block,5*(MAXY+MAXY+1), MPI_INT, 0, DATATAG, MPI_COMM_WORLD); 
... 
MPI_Recv(block, 5*(MAXY+MAXY+1), MPI_INT,MPI_ANY_SOURCE, DATATAG, MPI_COMM_WORLD, &status); 

に相当しますかMPI_Send()に専念多くの例で実行されるようa&a)のアドレスは、MPI_Send()に提供することができます。

int a=42; 
MPI_Send(&a,1, MPI_INT, 0, DATATAG, MPI_COMM_WORLD); 

最後には、MPI_Send()MPI_Recv()として何度と呼ばれていることを確認してください。実際に投稿したコードでは、MPI_Recv()がルートプロセスによって1回だけ呼び出され、ルート以外の各プロセスはルートにメッセージを送信します。したがって、プログラムは2つのプロセスで動作し、さらに多くのプロセスが使用されたり、単一のプロセスが使用されたりすると失敗する可能性があります。

関連する問題