2016-12-09 18 views
1

我正在两个进程本地运行MPI C++程序:mpirun -np 2 <programname>。我看到MPI_Gather命令的行为不一致。为了测试,我写了一个非常短的代码片段。我将代码复制到main的开头,它工作正常。但是,将其复制到代码中的其他位置时,它有时会提供正确的结果,有时不会。代码片段在下面复制。我怀疑问题是代码片段本身(因为它有时可以正常工作)。通常,当我看到这样的不一致的代码行为时,我怀疑存在内存损坏。然而,在这种情况下我运行了Valgrind,并没有报告任何错误(虽然也许我没有正确运行Valgrind for MPI--我没有在MPI程序中使用Valgrind)。 什么可能导致这种类型的不一致的行为,我能做些什么来检测问题?来自MPI_Gather的行为不一致

这里是的代码片段。

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 
+1

未定义行为可以采取多种形式,这将是很难说没有其他的代码。 – Zulan

+0

'其他代码'是一个非常大的程序,因此读取它的所有内容并查找无效的读/写错误是不可行的。我的问题主要是关于使用MPI时发现这些错误的一般策略。我使用Valgrind找到了解决方案(列于下面)。如果这些类型的MPI问题(以及解决方案)存在其他潜在的原因,则有兴趣了解它们。 –

回答

1

我找到了解决方案。怀疑,问题是内存腐败。

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

valgrind <options> mpirun -np 2 <programname> 

,而不是

mpirun -np 2 valgrind <options> <programname> 

因此,我跑的 “的mpirun” 本身Valgrind的,而不是预期的计划。当我正确运行Valgrind时,它在代码的不相关部分中识别出内存损坏。

荣誉给帮助我想出解决办法的另一个堆栈溢出Q/A:Using valgrind to spot error in mpi code

+0

干得好。您可以通过勾选左侧的复选标记来接受自己的答案。 –