通常,我编写串行代码,当我这样做时,我会使用一些 xUnit 风格的测试框架(MATLAB xUnit、PyUnit/nose 或 Google 的 C++ 测试框架)编写单元测试。
根据粗略的谷歌搜索,我没有看到很多关于从业者如何使用 MPI 进行单元测试的代码。有什么最佳实践吗?
与Strategies for unit testing 和 test-driven development相比,我正在寻找与我应该为测试框架使用什么软件相关的答案(如果有的话——答案很可能是“滚动你自己的代码”,其中自定义测试代码的案例示例会有所帮助)。
我要测试的大部分内容是用于集成半离散 PDE 的时间步进器的右侧函数评估和雅可比矩阵组装例程。我将使用 PETSc,所以如果有任何特定于 PETSc 的内容,除了更通用的测试框架之外,这将很有帮助。
澄清编辑:
一个例子是在${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
,我想测试类似RHSFunction
(右侧函数评估)和RHSJacobian
(雅可比矩阵评估)。我将针对组装的右侧和组装的雅可比矩阵的已知值进行测试;对于一些简单的问题实例,我可以通过分析获得这些值。这些函数是特定于应用程序的函数,不会执行任何其他应用程序级函数,但如果在函数内完成向量或矩阵组装(如上面链接的 PETSc 示例),它们可以调用 MPI。如果我编写的函数只计算处理器本地的向量或矩阵的一部分,我想尽可能地测试全局的组装版本,因为作为并行编程的新手,考虑全局向量和全局对我来说更直观矩阵。这些测试将在小问题和少量处理器上运行。
我可以想到一些策略来做到这一点:
- 根据我在该主题上所做的 Google 搜索,一个可能效果不佳的策略是构建一个已知输出,并行查找相对/绝对误差,然后进行简单的比较。输出可能会出现乱码——任何用 MPI 编写过“Hello, world”程序的人都知道原因——这限制了进行单元测试的效用。(这是提出这个问题的动力。)调用单元测试框架似乎也有一些潜在的技巧。
- 将输出写入文件(例如,在 PETSc 中,使用
VecView
and ),并使用类似orMatView
的东西与已知输出进行比较。从以前使用文件比较进行单元测试的经验中,我对这种方法的直觉是它会很挑剔,并且需要一些过滤。不过,这种方法似乎非常适合回归测试,因为我可以用 plain 替换上面的实用程序,而不必担心匹配文本格式。我收集到这个策略或多或少是 WolfgangBangerth 和 andybauer 所建议的。PETSc 似乎也对它所做的一些测试使用了类似的方法。ndiff
numdiff
diff
- 使用单元测试框架,将所有内容收集到 MPI 等级为 0 的处理器上,并要求它仅在处理器等级为 0 时执行单元测试。我可以用规范做类似的事情(这样可能更容易),尽管权衡是返回的任何错误都会告诉我我的计算有问题,但不会告诉我哪些元素有问题。那我就不用担心任何单元测试输出会乱码了;我只需要担心正确调用单元测试框架。当精确的解决方案可用时,PETSc 似乎在其示例程序中使用规范比较,但在进行这些比较时它不使用单元测试框架(也不一定)。