MPI_Allreduce在动态结构数组中的数组上

阿里贝兹

我在C中有一个结构的动态数组。说:

int n=100;
struct particle{
   double pos[3];   
   double force[3]; 
   double mass;
   int type;
};
struct particle *mypart;
mypart = (struct particle*) calloc(n,sizeof(struct particle));

在并行代码中,一些操作已完成,mypart[i].force[j]最后我需要在此数组(maypart[i].force上执行MPI_Allreduce 通过考虑MPI_Type_create_struct以及其他data_type函数,我无法获得任何有效的解决方案,只能将结构内部的数组传递给其他内核。有人知道吗?

更新:有关代码的一些细节:这是分子动力学代码,其中作用在每个粒子上的力归因于与其他粒子的相互作用。目的是拆分每个核心上的力计算。可以同时在不同的核上计算第i个粒子上的力。力循环后,应将此粒子上的力求和,以使每个粒子具有单一值的力(3个分量)。这是通过MPI_Allreduce + MPI_SUM函数完成的。我希望这可以阐明我要做什么。

赫里斯托·伊利耶夫(Hristo Iliev)

您想要实现的目标并非不可能,但也不是琐碎的。首先,您必须声明一个表示整个结构类型的数据类型,或者只声明一个力的数据类型。要构建后者,请以适当的位移从三个连续的双打开始:

MPI_Datatype type_force;
int blen = 3;
MPI_Aint displ = offsetof(struct particle, force);
MPI_Type types = MPI_DOUBLE;

MPI_Type_create_struct(1, &blen, &displ, &types, &type_force);

必须调整新数据类型的大小以匹配C结构的范围,因此我们可以直接访问多个数组元素:

MPI_Datatype type_force_resized;
MPI_Aint lb, extent;

MPI_Type_get_extent(type_force, &lb, &extent);
extent = sizeof(struct particle);
MPI_Type_create_resized(type_force, lb, extent, &type_force_resized);
MPI_Type_commit(&type_force_resized);

全局(清一色)减少,现在几乎可以归结为:

struct particle *particles = calloc(n, sizeof(struct particle));
MPI_Allreduce(mypart, particles, n, type_force_resized,
              MPI_SUM, MPI_COMM_WORLD);

由于MPI_(All)Reduce不允许将不同的MPI数据类型用于源缓冲区和接收缓冲区,因此必须使用数组struct particle而不是简单数组double[n][3]结果将放置在forces[]每个数组元素字段中。

现在,问题在于MPI_SUM无法对派生数据类型进行操作。解决方案是声明您自己的归约操作:

void force_sum(struct particle *in, struct particle *inout,
             int *len, MPI_Datatype *dptr)
{
   for (int i = 0; i < *len; i++)
   {
      inout[i].force[0] += in[i].force[0];
      inout[i].force[1] += in[i].force[1];
      inout[i].force[2] += in[i].force[2];
   }
}

MPI_Op force_sum_op;
MPI_Op_create(force_sum, 1, &force_sum_op);

通过以上所有准备工作,减少量变为:

MPI_Allreduce(mypart, particles, n, type_force_resized,
              force_sum_op, MPI_COMM_WORLD);

如果您首先将所有力集中在一个double forces[n][3]阵列中,则将是一个更简单的变体然后整个还原操作归结为:

double forces[n][3]; // Local forces
double total_forces[n][3]; // Total forces

... transfer mypart[i].force into forces[i] ...

MPI_Allreduce(forces, total_forces, 3*n, MPI_DOUBLE,
              MPI_SUM, MPI_COMM_WORLD);
// Done

但是此方法需要额外的内存,并且需要进行内存复制操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

动态结构数组中的数组上的MPI_Allreduce

来自分类Dev

MPI_Allreduce中的致命错误

来自分类Dev

mpi_allreduce派生数据类型向量上的总和

来自分类Dev

MPI_Allreduce:非常奇怪的错误结果

来自分类Dev

MPI_Allreduce:非常奇怪的错误结果

来自分类Dev

有效使用MPI_Allreduce

来自分类Dev

MPI_Allreduce无法正常工作-红黑SOR

来自分类Dev

在PHP中创建动态数组键结构

来自分类Dev

结构中数组的动态内存分配

来自分类Dev

如何动态更新结构中的数组?

来自分类Dev

C - 访问结构中的动态数组

来自分类Dev

结构体中动态数组的迭代器

来自分类Dev

类结构/动态数组

来自分类Dev

填充结构的动态数组

来自分类Dev

结构的动态数组

来自分类Dev

类结构/动态数组

来自分类Dev

存储结构的动态数组

来自分类Dev

两个MPI_Allreduce()函数不起作用,出现NULL Communicator错误

来自分类Dev

在函数中的结构数组上使用calloc

来自分类Dev

GPU上的内存分配用于动态结构数组

来自分类Dev

如何使用MPI传递带有动态数组的自定义结构?

来自分类Dev

动态嵌套结构数组

来自分类Dev

动态结构数组尽早终止

来自分类Dev

结构数组,动态分配

来自分类Dev

无法声明结构的动态数组

来自分类Dev

动态分配结构数组

来自分类Dev

MPI动态分配数组

来自分类Dev

在结构中动态分配数组-C

来自分类Dev

在C中的结构内的指针数组的动态内存分配