无法并行调用 PETSc/MPI-based 外部代码 OpenMDAO

Unable to call PETSc/MPI-based external code in parallel OpenMDAO

我正在写一个 OpenMDAO 问题,它在并行组中调用一组外部代码。这些外部代码之一是基于 PETSc 的 fortran FEM 代码。我意识到这可能存在问题,因为 OpenMDAO 也使用 PETSc。目前,我正在使用 python 的子进程调用组件中的外部代码。

如果我 运行 我的 OpenMDAO 串行问题(即 python2.7 omdao_problem.py),包括外部代码在内的所有内容都可以正常工作。但是,当我尝试并行 运行 它时(即 mpi运行 -np 4 python2.7 omdao_problem.py)然后它一直工作到子进程调用,此时我得到错误:

*** Process received signal ***
Signal: Segmentation fault: 11 (11)
Signal code: Address not mapped (1)
Failing at address: 0xe3c00
[ 0] 0   libsystem_platform.dylib            0x00007fff94cb652a _sigtramp + 26
[ 1] 0   libopen-pal.20.dylib                0x00000001031360c5 opal_timer_darwin_bias + 15469
 *** End of error message ***

我不能说太多,但在我看来,问题出在使用基于 MPI 的 python 代码调用另一个启用 MPI 的代码上似乎是合理的。我已经尝试在外部代码的位置使用非 mpi "hello world" 可执行文件,并且可以由并行 OpenMDAO 代码调用而不会出错。我不需要外部代码实际上 运行 并行,但我确实需要使用 PETSc 求解器等,因此固有地依赖 MPI。 (我想我可以考虑同时拥有启用 MPI 和不启用 MPI 的 PETSc 构建?如果可能的话我宁愿不这样做,因为我可以看到它很快就会变得一团糟。)

我发现 this discussion 似乎提出了类似的问题(并进一步指出,正如我正在做的那样,在 MPI 代码中使用子进程是一个禁忌)。在这种情况下,看起来使用 MPI_Comm_spawn 可能是一个选项,即使它不是为该用途而设计的。知道这是否适用于 OpenMDAO 的上下文吗?其他寻求使其发挥作用的途径?非常感谢任何想法或建议。

您不需要将外部代码作为子流程来调用。使用 F2py 将 fortran 代码包装在 python 中,并将一个 comm 对象传递给它。 This docs example 展示了如何使用使用通信的组件。

如果需要,您可以使用 MPI spawn。这种方法已经完成,但远非理想。如果您可以将代码包装在内存中并让 OpenMDAO 向您传递一个通信,您将会更有效率。