C和MPI:函数对相同数据的工作方式不同

C和MPI:函数对相同数据的工作方式不同,c,memory-management,mpi,petsc,C,Memory Management,Mpi,Petsc,我已经用PETSc库成功地编写了一个复杂的函数(它是一个基于MPI的科学库,用于并行求解大型线性系统)。该库提供自己的“malloc”版本和基本数据类型(即“PetscInt”作为标准的“int”)。对于这个函数,我一直使用PETSc的东西,而不是像“malloc”和“int”这样的标准东西。该功能经过广泛测试,始终工作良好。尽管使用了MPI,但该功能是完全串行的,所有处理器对相同的数据执行该功能(每个处理器都有其副本):根本不涉及通信 然后,我决定不使用PETSc,而是编写一个标准MPI版本。

我已经用PETSc库成功地编写了一个复杂的函数(它是一个基于MPI的科学库,用于并行求解大型线性系统)。该库提供自己的“malloc”版本和基本数据类型(即“PetscInt”作为标准的“int”)。对于这个函数,我一直使用PETSc的东西,而不是像“malloc”和“int”这样的标准东西。该功能经过广泛测试,始终工作良好。尽管使用了MPI,但该功能是完全串行的,所有处理器对相同的数据执行该功能(每个处理器都有其副本):根本不涉及通信

然后,我决定不使用PETSc,而是编写一个标准MPI版本。基本上,我重写了所有代码,用经典的C语言替换PETSc语言,不是用暴力而是注意替换(我的意思是,没有任何编辑器的“替换”工具!都是手工完成的)。在替换过程中,很少进行小的更改,例如声明两个不同的变量a和b,而不是声明a[2]。以下是替代品:

PetscMalloc->malloc

PetscScalar->double

PetscInt->int

PetscBool->创建了一个枚举结构来复制它,因为C没有布尔数据类型

基本上,算法在替换过程中没有改变。主函数是一个“for”循环(实际上是4个嵌套循环)。在每次迭代中,它调用另一个函数。我们称之为功能失调。好吧,函数失调在4周期外工作得很好(正如我单独测试的那样),但在4周期内,在某些情况下工作,在某些情况下不工作。此外,我还检查了每次迭代时传递给Disfunction的数据:对于完全相同的输入,Disfunction在一次迭代和另一次迭代之间执行不同的计算。 此外,计算数据似乎不是未定义的行为,因为Disfunction总是在不同的程序运行中返回相同的结果。 我注意到更改“mpiexec”的处理器数量会得到不同的计算结果

那是我的问题。其他考虑事项很少:程序广泛使用“malloc”;所有过程的计算数据相同,正确与否;Valgrind不检测错误(除了正常使用printf检测错误,这是另一个问题,也是一个OT);Disfunction递归调用另外两个函数(在PETSc版本中也进行了广泛测试);所涉及的算法在数学上是正确的;Disfunction依赖于一个整数参数p>0:对于p=1,2,3,4,5,它工作得很好,对于p>=6,它不工作

如果有人问我,我可以发布代码,但它既长又复杂(科学的,不是非正式的),我认为需要时间来解释

我的想法是我搞砸了内存分配,但我不知道在哪里。
很抱歉我的英语和糟糕的格式。

我能提供的唯一建议是,不参考代码本身,尝试构建逐步简化的测试用例来演示您的问题

当您将迭代过程缩小到数据集中的一个点或一个步骤(通过消除一些循环)时,错误仍然会发生吗?如果不是,这可能表明他们的界限是错误的


错误的输出是否总是发生在特定的循环索引上,尤其是第一个或最后一个?也许有一些幽灵或光环值丢失了,或者一些边界条件没有正确解释。

好吧,我不知道是否有人对stll感兴趣,但问题是PETSc functon
PetscMalloc
零初始化数据,不像标准C
malloc
。愚蠢的错误…——user3029623

您是否尝试在其上运行valgrind或任何类似工具?有可能你有一个bug没有用不同的分配算法出现……好吧,Valgrind似乎没有检测到任何越界。同样,算法也是一样的,我只是用标准C“malloc”替换了“PetscMalloc”。我使用的算法在数值上是稳定的(正如提出它的科学文章所说)。代码中的其他算法处理整数算术。而且,代码的特定部分没有并行性。我在其他部分使用MPI通信。这似乎不是不确定的:结果总是一样的。它们只会随着处理器数量的不同而变化。这会是一个分配不当的问题吗?比如将浮点数组分配为整数?我不知道是否有人对stll感兴趣,但问题是PETSc functon PetscMalloc zero初始化数据,而不是像标准的C malloc那样。愚蠢的错误…我想我会做类似的事情,尽管这非常无聊。边界应该有效,因为它们与PETSc版本相同,并且在该版本中工作良好。此外,边界是经过数学检查的。对不起,按enter键出错。此外,错误的迭代不是第一次或最后一次,而是一些在中间,没有明显的模式。如果这还不够,错误只会发生在大量数据的情况下,比如数百次迭代!我想对于像我这样的问题,只有详细的一步一步的分析才能解决。。。也许我应该学习如何使用调试器。。。