可怜的简单MPI_Send / Recv问题我不明白

时间:2011-03-28 18:55:52

标签: c mpi

我有两种不同算法的功能。在第一个函数中,我实现了非阻塞通信(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杀死

如果我只使用两个函数中的一个来运行程序,那么它们可以正常工作。但两者一起导致上面的错误消息。我确实理解错误信息,但我不知道我能做些什么来阻止它。有人可以向我解释我在哪里寻找错误吗?由于我没有在第一个函数中遇到死锁,我假设第一个函数没有未接收的发送,导致第二个函数出错。

1 个答案:

答案 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的数据类型。所以没有截断错误。所以,没有解决方案......

相关问题