【问题标题】:C,open_MPI, user-defined-struct type not passing correctlyC,open_MPI,用户定义的结构类型未正确传递
【发布时间】:2014-11-07 00:00:16
【问题描述】:

我使用 MPI_TYPE_create_struct 来定义 MPI 结构数据类型。具有 1 个 int 和 4 个 double 的结构。但是,我的结构中的最后一个元素(双精度)从未正确传递。

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

【问题讨论】:

  • 尝试不同的可能性后,如果我将结构定义更改为反向顺序 {double charge,x,y,z;整数索引}。并相应地更改 MPI_TYPE_create_struct。我可以成功发送和接收。我认为这与结构中的填充有关,但我无法确切地说出它是什么。谁能解释一下。

标签: c struct


【解决方案1】:

问题是填充,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 数据类型

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多