来自MPI_聚集的不一致行为 我在本地运行MPI C++程序,有两个过程: MPRUN-NP 2 < /COD>。我看到MPI_Gather命令的行为不一致。为了测试,我编写了一个非常短的代码片段。我把代码复制到main的开头,效果很好。但是,当将其复制到代码中的其他点时,它有时会给出正确的结果,有时则不会。代码片段复制到下面。我怀疑问题在于代码片段本身(因为它有时工作正常)。通常,当我看到这样不一致的代码行为时,我怀疑内存损坏。但是,我在本例中运行了Valgrind,它没有报告任何错误(尽管可能我没有为MPI正确运行Valgrind-我没有在MPI程序上使用Valgrind的经验)是什么导致了这种不一致的行为?我可以做些什么来检测问题?

来自MPI_聚集的不一致行为 我在本地运行MPI C++程序,有两个过程: MPRUN-NP 2 < /COD>。我看到MPI_Gather命令的行为不一致。为了测试,我编写了一个非常短的代码片段。我把代码复制到main的开头,效果很好。但是,当将其复制到代码中的其他点时,它有时会给出正确的结果,有时则不会。代码片段复制到下面。我怀疑问题在于代码片段本身(因为它有时工作正常)。通常,当我看到这样不一致的代码行为时,我怀疑内存损坏。但是,我在本例中运行了Valgrind,它没有报告任何错误(尽管可能我没有为MPI正确运行Valgrind-我没有在MPI程序上使用Valgrind的经验)是什么导致了这种不一致的行为?我可以做些什么来检测问题?,mpi,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

这是代码片段。

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);
print debug函数打印到一个文件,该文件对于每个进程都是独立的,并用逗号分隔输入参数

过程1打印:

send, 10, 11
finished test, 0
send, 0, 1

recv

0, 1

10, 11

finished test, 0
send, 0, 1

recv

0, 1

2.9643938750474793e-322, 0

finished test, 0
有时,处理0打印:

send, 10, 11
finished test, 0
send, 0, 1

recv

0, 1

10, 11

finished test, 0
send, 0, 1

recv

0, 1

2.9643938750474793e-322, 0

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

send, 10, 11
finished test, 0
send, 0, 1

recv

0, 1

10, 11

finished test, 0
send, 0, 1

recv

0, 1

2.9643938750474793e-322, 0

finished test, 0

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

我在使用MPI运行Valgrind时犯了一个初学者错误。我跑:

valgrind <options> mpirun -np 2 <programname>
valgrind mpirun-np 2
而不是

mpirun -np 2 valgrind <options> <programname>
mpirun-np2-valgrind
因此,我在“mpirun”本身上运行valgrind,而不是在预期的程序上。当我正确运行Valgrind时,它发现了代码中一个不相关部分的内存损坏


感谢另一个堆栈溢出Q/A帮助我解决了这个问题:

未定义的行为可以有多种形式,如果没有其他代码,这将很难判断。其他代码是一个非常大的程序,因此不可能通读所有代码并查找无效的读/写错误。我的问题主要是关于在使用MPI时查找此类错误的一般策略。我使用Valgrind找到了解决方案(如下所列)。如果这些类型的MPI问题(和解决方案)还有其他潜在的原因,我们有兴趣了解它们。