我有一个非常奇怪的MPI错误的巨大代码。 MPI并行化是微不足道的,只需在代码中的某个位置计算平均值即可将其隔离为:
// Declaration
std::vector<double> local;
std::vector<double> global;
unsigned int size;
/* ... huge computations here ... */
size = 10000; // approximately
local.resize(size);
global.resize(size);
local.shrink_to_fit();
global.shrink_to_fit();
/* ... some operations to fill in the local vector ... */
MPI_Allreduce(local.data(), global.data(), int(size),
MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
/* ... some final operations here ... */
但是如果我绘制global
的值,那么在向量中随机分布的10
错误值(超过10000
)(但始终在~1000th
之间~2000th
值):
对于所有MPI任务都不相同(约80%的任务具有相同的错误值,但重新约20%具有不同的任务)
对于2次不同的运行(不可重现)不一样
我在valgrind
处理器上使用1
对该程序进行了测试(仅删除了MPI_Init
,MPI_Allreduce
和MPI_Finalize
)并且没有内存泄漏或问题任何形式(至少这是valgrind
告诉我的)。
并行版本的正常任务数为1024
,程序位于使用C++11
编译的g++4.8.1
中。
Valgrind
是我最后的希望,我完全不知道发生了什么。欢迎任何想法或建议!
注意:问题可能不在代码本身(MPI配置,硬件等等),因此欢迎任何关于测试内容的想法。
答案 0 :(得分:0)
仅供参考,经过2天的研究后,问题就解决了。如果存在缓冲区大小不匹配但是会产生奇怪的行为,MPI_Allreduce
不会崩溃。我发现通过MPI_Reduce
+ MPI_Bcast
替换它们(由于缓冲区大小不匹配导致MPI_Reduce
崩溃)。仅使用问题中提供的信息无法找到错误:密钥就行了:
size = 10000; // approximately
和单词approximately
因为在我的实际代码中,这个大小依赖于很多微分方程的计算和数值积分。但是这段代码使用的是混合并行化MPI+std::thread
。并且集成的某些部分依赖于std::thread
,并且集成的最后几位依赖于非预测的操作顺序。最终的size
很大程度上依赖于此。因此,当每个MPI任务以不同的顺序执行其线程时,size
对于两个或三个MPI任务略有不同......导致MPI_Allreduce
中的未定义行为(但没有崩溃)。 / p>