我已经成功地用 PETSc 库编写了一个复杂的函数(它是一个基于 MPI 的科学库,用于并行求解巨大的线性系统)。这个库提供了它自己的“malloc”版本和基本数据类型(即“PetscInt”作为标准“int”)。对于这个函数,我一直在使用 PETSc 的东西,而不是标准的东西,比如“malloc”和“int”。该功能已经过广泛测试,并且始终运行良好。尽管使用了 MPI,但该功能是完全串行的,并且所有处理器都在相同的数据上执行它(每个处理器都有它的副本):根本不涉及通信。
然后,我决定不使用 PETSc 并编写一个标准的 MPI 版本。基本上,我用经典的 C 语言重写了所有代码,用经典的 C 语言替换了 PETSc 的内容,不是用暴力而是注意替换(我的意思是,没有任何编辑器的“替换”工具!全部手动完成)。在替换期间,进行了一些小的更改,例如声明两个不同的变量 a 和 b,而不是声明 a[2]。这些是替换:
PetscMalloc -> malloc
PetscScalar -> 双
PetscInt -> int
PetscBool -> 创建了一个枚举结构来复制它,因为 C 没有布尔数据类型。
基本上,算法在替换过程中没有改变。主函数是一个“for”循环(实际上是 4 个嵌套循环)。在每次迭代中,它调用另一个函数。让我们称之为功能失调。好吧,Disfunction 在 4 周期之外完美工作(正如我单独测试的那样),但在 4 周期内,在某些情况下有效,在某些情况下无效。此外,我在每次迭代时检查了传递给 Disfunction 的数据:使用 ECXACTELY 相同的输入,Disfunction 在一次迭代和另一次迭代之间执行不同的计算。此外,计算数据似乎不是未定义的行为,因为 Disfunction 总是在程序的不同运行中返回相同的结果。我注意到更改“mpiexec”的处理器数量会产生不同的计算结果。
那是我的问题。其他几项考虑:程序广泛使用“malloc”;所有过程的计算数据都是相同的,无论正确与否;Valgrind 不检测错误(除了通过正常使用 printf 检测错误,这是另一个问题和一个 OT);Disfunction 递归调用另外两个函数(也在 PETSc 版本中进行了广泛测试);所涉及的算法在数学上是正确的;功能障碍取决于整数参数 p>0:对于 p=1,2,3,4,5,它可以完美地工作,对于 p>=6,它不会。
如果被问到,我可以发布代码,但它很长而且很复杂(科学上,而不是信息上),我认为需要时间来解释。
我的想法是我搞砸了内存分配,但我不明白在哪里。对不起我的英语和糟糕的格式。