C,open_MPI,用户定义的结构类型未正确传递

标签 c struct

我使用 MPI_TYPE_create_struct 来定义 MPI 结构数据类型。具有 1 个 int 和 4 个 double 的结构。但是,我的结构中的最后一个元素( 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。 有人知道为什么吗?

最佳答案

问题是填充,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 数据类型的更安全的方法

关于C,open_MPI,用户定义的结构类型未正确传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26771695/

相关文章:

c++ - 具有调试功能的 C/C++ IDE 的建议

c - WinDBG 扩展 - 断点列表

c - 结构指针有问题

mongodb - 使用 time.Time 字段插入文档时设置默认日期

c - 使用 C 在显示屏上通过停止/暂停/播放按钮绘制正弦波

c - 为什么我无法输入所需的输入数量?

c - C 中 main 中第三个参数 char *arge[] 的含义

ios - Swift 通过引用传递结构?

c++ - C++结构可以有成员函数吗?

无法弄清楚我是如何遇到段错误的