2014-11-06 76 views
-1

我用MPI_TYPE_create_struct來定義一個MPI結構數據類型。具有1個int和4個double的結構。但是,我的結構中的最後一個元素(double)永遠不會正確傳遞。C,open_MPI,用戶定義的結構類型傳遞不正確

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 
#include <mpi.h> 

struct c{ 
    int index; 
    double charge,x,y,z; 
};  
main(int argc,char **argv) 
{ 
    int rank,p; 
    int i,j; 
    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&p); 

    MPI_Datatype old_type[2]={MPI_INT,MPI_DOUBLE}; 
    MPI_Datatype chargestruct;//create mpi data struct 
    int blocklens[2]={1,4}; 
    MPI_Aint disa[2]; 
    MPI_Aint span,lb; 
    MPI_Type_get_extent(MPI_INT,&lb,&span); 
    disa[0]=0; 
    disa[1]=span; 
    MPI_Type_create_struct(2,blocklens,disa,old_type,&chargestruct);//the struct has MPI_TYPE chargestruct 
    MPI_Type_commit(&chargestruct); 

    struct c buff,charge; 
    MPI_Status status; 
    charge.z=1.0; 
    int targetp,sourcep; 
    targetp=(rank-1)<0?p-1:(rank-1); 
    sourcep=(rank+1)==p?0:(rank+1); 

    if(rank==0){ 
    MPI_Send(&charge,1,chargestruct,targetp,rank,MPI_COMM_WORLD); 
    } 
    else{ 
    MPI_Recv(&buff,1,chargestruct,sourcep,sourcep,MPI_COMM_WORLD,&status); 
    } 
    printf("%d %lf %lf\n",rank,charge.z,buff.z); 
    MPI_Finalize(); 
} 

最後一個「z」,在接收緩衝區中,我總是得到0.0000。 任何人都知道爲什麼?

+0

嘗試不同的可能性後,如果我改變的結構定義的反序{雙充,X,Y,Z; int index}。並相應地更改MPI_TYPE_create_struct。我可以成功發送和接收。我認爲這是關於在結構中填充的東西,但我無法確切知道它是什麼。有人可以善意解釋。 – DDD 2014-11-06 15:25:21

回答

0

問題是填充,int是4個字節,但在問題中定義的結構中。 int後面添加了4個字節的填充字節。 disa [1]應該是8而不是4(通過MPi_TYPE_get_extent調用返回)。在這種情況下,由於每個元素的開始位置不正確,因此無法通過send和recv正確處理。 最簡單的修復方法可能是使用MPI_get_address,它可以安全地給出元素的開始。

MPI_Get_address(struct c*.charge,&disa[1]) 
MPI_Get_address(struct c*.index,&disa[0]) 
disa[1]-=disa[0] 

這應該給了正確的位移,以及更安全的方式來創建MPI數據類型