我有两种不同算法的功能。在第一个函数中,我实现了非阻塞通信(MPI_Irecv,MPI_Isend),程序运行时没有任何错误。即使我将非阻塞更改为阻塞通信,一切都很好。没有死锁。 但是如果我用这样的基本阻塞通信实现第二个功能(将算法简化为问题):
if( my_rank == 0)
{
a = 3 ;
MPI_Send(&a,1,MPI_DOUBLE,1,0,MPI_COMM_WORLD) ;
}
else if( my_rank == 1 )
{
MPI_Recv(&a,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD, &status ) ;
}
因此,进程1应该从进程0接收值a。但是我收到了这个错误:
MPI_Recv中的致命错误:消息 截断,错误堆栈: MPI_RECV(187).......................: MPI_Recv(buf = 0xbfbef2a8,count = 1, MPI_DOUBLE,src = 0,tag = 0, MPI_COMM_WORLD,status = 0xbfbef294) 失败 MPIDI_CH3U_Request_unpack_uebuf(600): 消息被截断;收到32个字节 但是缓冲区大小在作业39中是8级2 布拉布拉引起了集体 所有级别的中止退出状态 等级2:被信号9杀死
如果我只使用两个函数中的一个来运行程序,那么它们可以正常工作。但两者一起导致上面的错误消息。我确实理解错误信息,但我不知道我能做些什么来阻止它。有人可以向我解释我在哪里寻找错误吗?由于我没有在第一个函数中遇到死锁,我假设第一个函数没有未接收的发送,导致第二个函数出错。
答案 0 :(得分:0)
所以,这是第一个函数:
MPI_Type_vector(m,1,m,MPI_DOUBLE, &column_mpi_t ) ;
MPI_Type_commit(&column_mpi_t) ;
T = (double**)malloc(m*sizeof(double*)) ;
T_data = (double*)malloc(m*m*sizeof(double)) ;
for(i=0;i<m;i++)
{
T[i] = &(T_data[i*m]) ;
}
if(my_rank==0)
{
s = &(T[0][0]) ;
for(i=1;i<p;i++)
{
MPI_Send(s,1,column_mpi_t,i,0,MPI_COMM_WORLD) ;
}
}
for(k=0;k<m-1;k++)
{
if(k%p != my_rank)
{
rbuffer = &(T[0][k]) ;
MPI_Recv(rbuffer,1,column_mpi_t,k%p,0,MPI_COMM_WORLD,&status) ;
}
for(j=k+1;j<n;j++)
{
if(j%p==my_rank)
{
if(j==k+1 && j!=n-1)
{
sbuffer = &(T[0][k+1]) ;
for(i=0;i<p;i++)
{
if(i!= (k+1)%p )
MPI_Send(sbuffer,1,column_mpi_t,i,0,MPI_COMM_WORLD) ;
}
}
}
}
}
我得出结论,派生的数据类型是我的问题的根源。有人看到了原因吗?
好的,我错了。如果我将MPI_Irecv / send中的MPI数据类型更改为MPI_DOUBLE,那么这将适合第二个函数的recv / send的数据类型。所以没有截断错误。所以,没有解决方案......