2011-03-28 211 views
0

我有两种不同算法的函数。在第一个函数中,我实现了非阻塞通信(MPI_Irecv,MPI_Isend),程序运行时没有任何错误。即使当我将非阻塞改为阻塞通信时,一切都很好。没有死锁。 但是,如果我实现具有这样的基本阻挡通信(该算法降低的问题)第二功能:荒谬简单的MPI_Send/Recv问题,我不明白为什么

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,但即时得到此错误:

Fatal error in MPI_Recv: Message truncated, error stack: MPI_Recv(187).......................: MPI_Recv(buf=0xbfbef2a8, count=1, MPI_DOUBLE, src=0, tag=0, MPI_COMM_WORLD, status=0xbfbef294) failed MPIDI_CH3U_Request_unpack_uebuf(600): Message truncated; 32 bytes received but buffer size is 8 rank 2 in job 39 Blabla caused collective abort of all ranks exit status of rank 2: killed by signal 9

如果我只用两个函数中的一个运行程序,它们按假定的方式工作。但是两者都会导致上面的错误信息。我明白错误信息,但我不知道我能对付它。有人可以解释我在哪里寻找错误?由于即时通讯没有得到第一个函数的死锁,我假设不能从第一个函数发出一个未接收到的发送,导致第二个函数出错。

+0

问题不是Recv vs Irecv,它肯定没有任何死锁。问题在于来自任务0的Rank 2的Recv()(它正在接收单个MPI_DOUBLE)与来自32个字节的等级0(4个双打可能?)的SEND相匹配。因此消息截断了错误。所以我们需要看到更多的代码来看看发生了什么。 – 2011-03-28 20:14:03

+0

我知道。第二个函数仅包含send/recv操作。它绝对位于第一个函数中,因为(取决于用户输入),这正好是通信阵列的大小。但那怎么可能?所有的send/recv操作都必须完成,否则会导致死锁。或者我完全错了?整个代码大约有六百行。必须简化它...可能需要一段时间。 – Rade 2011-03-28 20:41:57

回答

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中的MPI数据类型更改为/发送给MPI_DOUBLE,那将适合第二个函数recv/send的数据类型..因此不会出现截断错误。所以,没有解决方案....

+1

这里有什么'm'和'p'?目前,发送和接收可能不匹配。 – Hbcdev 2012-08-02 21:05:26