来自 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 帮助我解决了这个问题:
我正在 运行 在本地使用两个进程运行 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 帮助我解决了这个问题: