问题描述
下面是使用数据类型的MPI原型程序。 该代码是此示例的简化版本:https://mpi.deino.net/mpi_functions/MPI_Type_vector.html。 与许多其他示例一样,MPI数据类型仅创建一次并提交一次,并多次使用。
我对其进行了修改,以便在函数(f
)内传递的MPI消息旁边创建并提交该类型。
考虑到f
在每次调用中都创建并提交了类型,本示例将询问重复调用函数f
是否正确。
我希望以某种方式提交用于“一次性使用”的类型是错误的。
但是,该程序运行正常,并且在重复调用多次时不占用更多内存。
通常可以创建一个类型,多次提交(并销毁)它吗?
我期望程序最终会失败,因为类型被反复提交,这将消耗越来越多的内存。
(也就是说,提交的数据类型将消耗资源。)
特别是因为MPI中没有“取消提交”功能。
还有另一种选择,就是MPI_Type_free
足够聪明,也可以“取消提交”数据类型。
在许多地方,我读到MPI一旦提交便会“编译”数据类型,因此有可能在数据类型句柄中“就地”完成了该操作。
尽管有一段时间,我还是因为这是因为MPI系统检测到同一类型正在被提交并且该提交没有执行任何操作(即,在检查后忽略了该提交)。 但是,当我使用所有不同的参数创建类型时,仍然没有额外的内存消耗。
注意:我了解创建数据类型和提交不是免费的,并且存在运行时开销,但是在stride
是运行时变量的情况下,这可以简化程序的设计因为您不需要全局变量或全局注册函数。
此外,如果类型的参数在运行时发生更改,则无法进行预注册。
问题是,当重复调用这些数据类型时,这些提交是否确实占用了内存;如果要根据使用情况而不是全局创建这些类型,则这种设计是否正确。
MPI手册中没有这方面的内容,只有示例发生一次注册并且多次使用该类型的例子。
#include "mpi.h"
#include<assert.h>
#include <stdio.h>
// can this be called unlimited number of times?
void f(int stride,int* buffer,int rank){
MPI_Datatype type,type2;
MPI_Type_contiguous(3,MPI_INT,&type2);
MPI_Type_commit(&type2);
MPI_Type_vector(3,stride,3,type2,&type);
MPI_Type_commit(&type);
if(rank == 0){
for(int i=0; i<24; i++) buffer[i] = i;
MPI_Send(buffer,1,type,123,MPI_COMM_WORLD);
}
MPI_Status status;
if (rank == 1){
for(int i=0; i<24; i++) buffer[i] = -1;
MPI_Recv(buffer,MPI_COMM_WORLD,&status);
}
MPI_Type_free(&type); // this is important and doesn't affect one committed
MPI_Type_free(&type2);
}
int main(int argc,char *argv[]){
int rank,size;
int buffer[24];
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
assert(size == 2);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
// one time call is ok,is many calls correct too?
// for(int n = 0; n != 100000000; ++n) f(3,buffer,rank);
f(3,rank);
MPI_Finalize();
return 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)