1

我不确定我是否正确理解了“count”参数之间的区别:

    int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, 
           MPI_Op op, int root, MPI_Comm comm);

和'blocklens'参数:

int MPI_Type_struct(int count,
               int blocklens[],
               MPI_Aint indices[],
               MPI_Datatype old_types[],
               MPI_Datatype *newtype);

假设我想减少我自己的类型:

typedef struct buffers_s
{
   double *buf1, *buf2;
} Buffers;

其中 buf1 和 buf2 都分配给 N 个元素。

然后,当调用 MPI_Type_struct() 以基于 'Buffers' 创建新的 mpi 类型 'Custom_MPI_Type' 时,我会将 'count' 设置为 2,将 blocklens[0] 设置为 N,并将 blocklens[1] 设置为 N。

然后,当创建 MPI 类型时,假设我还创建了归约运算符“MyOp”,我将调用 MPI_Reduce(),并将“datatype”设置为“Custom_MPI_Type”。那么'count'参数的值应该是多少?

根据我将其设置为 N 的经验,但我并不真正理解其含义,因为我已经指定我刚刚创建的 MPI 类型由 2 个长度为 N 的块组成。

换句话说,当将 MPI_Reduce() 与 MPI_FLOAT 等基本类型的数组一起使用时,'count' 参数指定 MPI_FLOAT 类型的元素的数量,从作为 MPI_Reduce() 的第一个参数给出的地址开始......所以逻辑上我会已经期望,当使用自定义数据类型时,将计数设置为自定义_MPI_Type 类型的 1 个元素,前提是 MPI 已经知道此类型由给定基本 MPI_Datatype(例如 MPI_DOUBLE)的 N 个元素的 2 个块组成。

有人可以解释这一切吗?

4

1 回答 1

0

MPI 中的派生数据类型通常不适用于您的Buffers. Jonathan Dursi 在您的另一个问题中解释了原因。结构数据类型适用于 C/C++ 结构,例如:

#define N 1000

typedef struct buffers_s
{
   double buf1[N], buf2[N];
} Buffers;

buf1在这种情况下,buf2实例开头的偏移量Buffers总是相同的,这buf1buf2两者都指向动态分配的内存的情况不同。

这就是说,blocklengths参数MPI_Type_create_struct(MPI_Type_struct在 MPI-2 中已弃用,甚至在 MPI-3.0 中已删除,因此您不应使用它) 用于描述数据类型本身的形状。blocklengts[i]告诉 MPI 有多少类型的元素old_types[i]包含在i新数据类型的第 - 个元素中。对于上述结构,blocklengths[0] = blocklengths[1] = N.

count参数MPI_Reduce告诉 MPI 有多少元素datatype要减少。如果datatype是您的结构数据类型,则表示该结构有多少个实例。继续上面的示例代码,如果您有一个包含 10 个实例的数组Buffers,例如:

Buffers bufs[10];

然后你会10count论点中提供。这与结构类型构造函数中的块计数完全正交。单个进程通信的元素总数将count乘以所有元素的总和blocklengts[]。您已正确得出结论,如果仅减少派生数据类型的一个元素,count则应将其设置为 1。

于 2012-11-19T09:15:48.173 回答