2014-11-06 78 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数据类型