0

更新:我有一个问题,我不知道它是什么。我有一个带有 MPI_INIT 和 MPI_FINALIZE 的测试程序。我有一个包含 5 个子例程的模块:3 个子例程是依赖的,并且独立于其他 2 个子例程。我想把测试程序中的MPI代码放到这个模块中。我将 MPI_INIT 放在声明变量的模块中和子例程之前。我收到了一系列带有相同错误消息的错误:

This statement must not appear in the specification part of a module

“MPI_INIT 和 MPI_FINALIZE 只应调用一次”如何影响 Fortran 程序、模块和子例程?如果有多个独立程序,每个程序多次调用该模块的子例程,我应该将 MPI 函数和变量放在哪里?

~~~~~~~~~ 我有一个包含一系列子例程的模块,其中包含我希望并行化的do循环。子程序是其他程序使用的公共程序。我应该在子程序之外定义 MPI:

module ...
call MPI_INIT
subroutine 1
... (MPI code)
subroutine 2
subroutine 3
MPI_GATHERV
call MPI_FINALIZE
module

还是在每个子程序中?

module ...
subroutine 1
call MPI_INIT
... (MPI code)
MPI_GATHERV
call MPI_FINALIZE
subroutine 2
call MPI_INIT
... (MPI code)
MPI_GATHERV
call MPI_FINALIZE
subroutine 3
call MPI_INIT
... (MPI code)
MPI_GATHERV
call MPI_FINALIZE
module

我看到了解决方案 1 遵循粗粒度原则的优势。如果程序调用子程序 1,它还会在子程序之外执行 MPI 代码吗?

4

1 回答 1

6

您应该在程序中只初始化和完成一次 MPI。调用 MPI_Finalize 后,您将无法执行进一步的 MPI 操作。标准说:

一旦 MPI_FINALIZE 返回,除了 MPI_GET_VERSION、MPI_GET_LIBRARY_VERSION、MPI_INITIALIZED、MPI_FINALIZED 和任何具有前缀 MPI_T_ 的函数(在第 14.3.4 节中列出的具有此前缀的函数的约束范围内)之外,不能调用任何 MPI 例程(甚至 MPI_INIT)。

(MPI3, p361, l25) MPI3 PDF

回复更新:不允许将可执行语句放入代码的声明部分。关键是,在您的执行中应该只调用一次 MPI_Init 和 MPI_Finalize 就意味着这一点。您的应用程序可能会读取如下内容:

program mini
  use mpi
  implicit none
  integer :: iError
  call mpi_init(iError)
  call do_some_stuff()
  call mpi_finalize(iError)
end program mini

如果你在程序的开头有各种初始化的东西,你当然可以将它组合到模块子程序中并在那里调用 mpi_init 。如果您对模块使用测试程序,请在此处使用 mpi_init 和 mpi_finalize。在某些子例程中调用 mpi_init 和 mpi_finalize 的示例可以在例如我们用来设置非常通用的东西的 treelm 库的 env_module 中找到。

如果有多个独立程序,每个程序多次调用该模块的子例程,我应该将 MPI 函数和变量放在哪里?

你能改写一下吗?我不明白。MPI 函数和变量应该在 mpi 模块中,如果您有多个独立程序调用它们,它们都必须“使用” mpi 模块。独立程序也可以单独拥有 MPI_Init 和 MPI_Finalize。也许您可以发布一个简短的代码示例,说明您想要实现什么以及您的问题是什么。

于 2012-11-18T14:04:51.897 回答