C、 打开\u MPI,用户定义的结构类型传递不正确

C、 打开\u MPI,用户定义的结构类型传递不正确,c,struct,C,Struct,我已经使用MPI_TYPE_create_struct定义了一个MPI struct数据类型。具有1 int和4 double的结构。但是,我的结构中的最后一个elementdouble从未正确传递 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <mpi.h> struct c{ int index; do

我已经使用MPI_TYPE_create_struct定义了一个MPI struct数据类型。具有1 int和4 double的结构。但是,我的结构中的最后一个elementdouble从未正确传递

#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。
有人知道为什么吗?

问题是填充,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]  

如果我将结构定义更改为倒序{double charge,x,y,z;int index},那么在尝试了不同的可能性之后,这应该提供了正确的置换,以及更安全的方法来创建MPI数据类型。并相应更改MPI\u类型\u创建\u结构。我可以成功地发送和接收。我认为这是关于在struct中填充的,但我不能确切地说出它是什么。有人能解释一下吗。