从底层 MPI_Op 句柄访问 MPI_User_function

Access MPI_User_function from underlying MPI_Op handle

我想用 MPI 风格编写自己的扫描函数,这意味着我必须从 MPI_Op 参数访问关联操作。我真的找不到 MPI_Op 结构的定义,因此不知道用于访问该函数的偏移量是多少。我想这样做是因为我还想处理用户定义的函数,这些函数被创建并绑定到 MPI_Op_Create 函数的句柄,并且尽可能接近 MPI_Scan 的 MPI 实现。 到目前为止,我尝试了以下代码片段,假设函数的地址在没有偏移的情况下保存在例如MPI_SUM句柄:

int asize = 10;
int inArray[asize];
int outArray[asize];

for(int i = 0; i < asize; i++) {
   inArray[i] = i;
   inOutArray[i] = i;
}

MPI_User_function *f = (MPI_User_function*) MPI_SUM;
MPI_Datatype type = MPI_INT;

f(inArray, inOutArray, &asize, &type);

此代码对我不起作用,我主要遇到“信号代码:无效权限”的分段错误。如果我不能访问预定义的操作,如 MPI_SUM、MPI_MAX、...(我可以自己编写功能),这不会是悲剧,但我至少想要访问用户定义的函数。我不确定我想做的事情是否可行,有人有任何见解吗?

MPI_Op 是一个 MPI 句柄 - 它是一个不透明的值,可以是指向结构的指针,或者是 table 中的整数索引,或者是一个魔法值。但关键是,这并不重要,因为您不应该知道它到底是什么(因此“不透明”)。

不是通过检查内部 MPI 结构来突破 API 障碍,您应该使用 MPI_Reduce_local,这是从操作中提取归约函数并调用的 portable 版本它与两个数组。

您的代码应为:

int asize = 10;
int inArray[asize];
int outArray[asize];

for(int i = 0; i < asize; i++) {
   inArray[i] = i;
   inOutArray[i] = i;
}

MPI_Reduce_local(inArray, inOutArray, asize, MPI_INT, MPI_SUM);

该函数适用于预定义的缩减操作(例如 MPI_SUM)和用户定义的操作。

在实现全局归约时,需要特别注意操作的可交换性,尤其是在处理用户自定义操作时。让MPI_Op_commutative成为你最好的朋友,不要在操作不可交换时执行乱序(子)归约。

这两个函数在 MPI standard 的第 5.9.7 节(第 189 页)中进行了描述。