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
打印出一个非常大的值?我也遇到了分段错误。
答案 0 :(得分:3)
问题似乎是您对MPI_Recv的第一个参数。在这里,您发送一个指向temp
的指针,它本身就是一个指针。 MPI_Recv正在尝试从为n
指针保留的内存位置开始复制temp
个浮点数。您需要为temp
分配内存(取消对malloc的调用)并将MPI_Recv调用更改为:
MPI_Recv(temp, ...
这很可能是my_rank
获得垃圾价值的地方。 MPI_Recv正在尝试写入存储n * sizeof(float)
的{{1}}字节数据,并覆盖到为其他变量保留的内存中,即temp
。
并且忘记释放为my_rank
完成后为temp
分配的内存!
还有其他一些事情,我做了很少的MPI编程,但我认为my_rank == 1
块中的MPI_Recv调用应该有0的源。我还认为MPI_Send和MPI_Recv阻塞了调用 - 在换句话说,他们不会返回,直到转移完成或失败。由于你的两个队伍都首先调用MPI_Send,我希望它们能够阻止你的程序并使其死锁。也许他们失败了 - 你应该检查MPI_Send的返回值是否成功。
答案 1 :(得分:0)
除了segfaulting,你的代码也可能会阻塞,因为对于较大的n
你的MPI实现可能会使用同步语义和死锁,因为两个排队等待MPI_Send
完成以便发布接收但是永远不会发生因为要返回同步发送,必须发布匹配的接收。
您应该在其中一个MPI_Send
个案例中交换MPI_Recv
和if
的顺序(例如my_rank == 0
)或者(更好的解决方案)是使用专门设计为永不死锁的MPI_Sendrecv
。
回答你为什么排名被打印的问题 - 堆栈损坏。通过传递缓冲区指针的地址,您实际上会在堆栈中接收消息,从而覆盖其他局部变量。