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保留的内存位置开始复制浮点数。temp您需要为temp(取消注释对 malloc 的调用)分配内存并将 MPI_Recv 调用更改为:

MPI_Recv(temp, ...

这很可能my_rank是获得垃圾价值的地方。MPI_Recv 正在尝试写入n * sizeof(float)存储的数据字节,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

除了段错误之外,您的代码也可能会阻塞,因为对于更大n的 MPI 实现可能会使用同步语义和死锁,因为两个等级都等待MPI_Send完成以发布接收,但这永远不会发生,因为对于同步发送返回,匹配的接收必须被张贴。

您应该在MPI_Send其中MPI_Recv一种if情况下(例如 for my_rank == 0)或(更好的解决方案是)使用MPI_Sendrecv专门设计为永不死锁的使用的顺序。

要回答您为什么要这样打印排名的问题-堆栈损坏。通过传递缓冲区指针的地址,您实际上会在堆栈中收到消息,从而覆盖其他局部变量。

于 2012-05-04T16:09:50.490 回答