0

我已经成功地用 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,它不会。

如果被问到,我可以发布代码,但它很长而且很复杂(科学上,而不是信息上),我认为需要时间来解释。

我的想法是我搞砸了内存分配,但我不明白在哪里。对不起我的英语和糟糕的格式。

4

2 回答 2

1

好吧,我不知道是否有人感兴趣,但问题是 PETScPetscMalloc函数对数据进行零初始化,不像标准 C malloc。愚蠢的错误...... – user3029623

于 2014-10-31T13:20:33.917 回答
0

在不参考代码本身的情况下,我可以提供的唯一建议是尝试构建更简单的测试用例来证明您的问题。

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

错误输出是否总是出现在特定的循环索引上,尤其是第一个或最后一个?也许您缺少一些重影或晕轮值,或者您没有正确考虑某些边界条件。

于 2013-11-25T02:52:19.367 回答