2011-03-28 223 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