C、 打开\u MPI,用户定义的结构类型传递不正确
我已经使用MPI_TYPE_create_struct定义了一个MPI struct数据类型。具有1 int和4 double的结构。但是,我的结构中的最后一个elementdouble从未正确传递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
#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中填充的,但我不能确切地说出它是什么。有人能解释一下吗。