0
void iso_diffusion_denoising(image *u, image *u_bar, float kappa, int iters) { 

  int my_rank,num_procs;
  float *temp;
  int i,j,k=0;
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
  int m=u->m;
  int n=u->n;
  //temp= malloc(n*sizeof(float));//1*n array ?

  float *ptr;

  for(k=0;k<iters;k++) {

for(i=1; i<m-1; i++) { 

  for(j=1; j<n-1; j++) {

    /*  temp[m-1]=u->image_data[m-1][0];
    temp[m-1]=u->image_data[m-1][n-1];
    temp[i]=u->image_data[m-1][j];*/


    u_bar->image_data[i][j]= u->image_data[i][j] + kappa*(u->image_data[i-1][j] + u->image_data[i][j-1] - 4*u->image_data[i][j] + u->image_data[i][j+1] + u->image_data[i+1][j]);
    u->image_data[i][j]=u_bar->image_data[i][j];
  } 
}

//temp[m-1][n-1]
if(my_rank==0) {
  ptr = u->image_data[m-1];
  MPI_Send(&ptr[0],n,MPI_FLOAT,1,1,MPI_COMM_WORLD);
  MPI_Recv(&temp,n,MPI_FLOAT,1,2,MPI_COMM_WORLD,&status);
  printf("my rank is :  %d ", my_rank);
  fflush(stdout);
} else if(my_rank==1) { //if(my_rank!=num_procs) {
  ptr = u->image_data[0];
  MPI_Send(&ptr[0],n,MPI_FLOAT,0,2,MPI_COMM_WORLD);
  MPI_Recv(&temp,n,MPI_FLOAT,1,1,MPI_COMM_WORLD,&status);
  printf("my rank is :  %d ", my_rank);
  fflush(stdout);
}

  }

}

mpirun -np 2 Oblig 0.1 20 noisy denoised

my rank is : 1114636288 [safir:22140] *** Process received signal ***
--------------------------------------------------------------------------
mpirun noticed that process rank 0 with PID 22140 on node safir.ifi.uio.no exited on signal 11 (Segmentation fault).

非常に大きな値で出力されるのはなぜmy_rankですか? また、セグメンテーション違反が発生します。

4

2 に答える 2

3

問題は、MPI_Recv への最初の引数にあるようです。tempここでは、それ自体がポインターであるポインターを送信しています。MPI_Recv は、ポインタn用に予約されたメモリ位置から始まる floatをコピーしようとしています。temp(malloc への呼び出しのコメントを外して)にメモリを割り当てtemp、MPI_Recv 呼び出しを次のように変更する必要があります。

MPI_Recv(temp, ...

my_rankこれは、ガベージ値を取得している場所である可能性が最も高いです。n * sizeof(float)MPI_Recv は、 が保存されている場所にバイト単位のデータを書き込もうとしてtempおり、他の変数用に予約されているメモリに上書きしていますmy_rank

そして、使い終わったら、割り当てたメモリを解放することを忘れないでくださいtemp!

他にもいくつかありますが、私は MPI プログラミングをほとんど行っていませんが、my_rank == 1ブロック内の MPI_Recv 呼び出しには 0 のソースが必要だと思います。また、MPI_Send と MPI_Recv が呼び出しをブロックしていると思いました。つまり、転送まで返されません。完了するか、失敗します。両方のランクが最初に MPI_Send を呼び出しているため、プログラムをブロックしてデッドロックすることが予想されます。失敗している可能性があります。MPI_Send の戻り値を確認して、成功したかどうかを確認してください。

于 2012-04-29T14:27:07.067 に答える
0

大規模なMPI実装では、受信を送信するためにn両方のランクが終了するのを待つため、同期セマンティクスとデッドロックを使用する可能性があるため、コードのセグフォールトに加えて、コードがブロックされる可能性があります。MPI_Send投稿されます。

いずれかの場合(たとえば)の順序MPI_Sendを入れ替えるか、(はるかに優れた解決策は)デッドロックしないように特別に設計された使用を行う必要があります。MPI_Recvifmy_rank == 0MPI_Sendrecv

ランクがそのように出力される理由についての質問に答えるには、スタックの破損です。バッファポインタのアドレスを渡すことにより、実際にスタック内のメッセージを受信し、他のローカル変数を上書きします。

于 2012-05-04T16:09:50.490 に答える