来自 MPI_Gather 的不一致行为

Inconsistent behavior from MPI_Gather

我正在 运行 在本地使用两个进程运行 MPI C++ 程序:mpirun -np 2 <programname>。我发现 MPI_Gather 命令的行为不一致。为了测试,我写了一个非常短的代码片段。我将代码复制到 main 的开头并且工作正常。但是当把它复制到代码中的其他点时,它有时会给出正确的结果,有时则不会。代码片段复制如下。我怀疑问题出在代码片段本身(因为它有时可以正常工作)。通常,当我看到像这样不一致的代码行为时,我怀疑是内存损坏。但是,在这种情况下,我有 运行 Valgrind,它没有报告任何错误(尽管也许我没有为 MPI 正确地 运行ning Valgrind - 我没有在 MPI 程序上使用 Valgrind 的经验)。 是什么导致了这种不一致的行为,我该怎么做才能检测到这个问题?

这是 代码片段。

double val[2] = {0, 1};    
val[0] += 10.0*double(gmpirank);    
val[1] += 10.0*double(gmpirank);    
double recv[4];    
printdebug("send", val[0],val[1]);    
int err = MPI_Gather(val,2,MPI_DOUBLE,recv,2,MPI_DOUBLE,0,MPI_COMM_WORLD);    
if (gmpirank == 0) {
    printdebug("recv");    
    printdebug(recv[0],recv[1]);    
    printdebug(recv[2],recv[3]);
}    
printdebug("finished test", err);

打印调试函数打印到一个文件,每个进程都是独立的,并用逗号分隔输入参数。

进程 1 打印:

send, 10, 11
finished test, 0

有时,进程 0 打印:

send, 0, 1

recv

0, 1

10, 11

finished test, 0

但是当我将代码放在代码的其他部分时,进程 0 有时会打印如下内容:

send, 0, 1

recv

0, 1

2.9643938750474793e-322, 0

finished test, 0

我找到了解决办法。正如所怀疑的那样,问题是内存损坏。

我在 运行 Valgrind 和 MPI 时犯了一个新手错误。我运行:

valgrind <options> mpirun -np 2 <programname>

而不是

mpirun -np 2 valgrind <options> <programname>

因此,我是 运行 valgrind "mpirun" 本身,而不是预期的程序。当我 运行 Valgrind 正确时,它在代码的不相关部分识别出内存损坏。

感谢另一个 Stack Overflow Q/A 帮助我解决了这个问题: