【问题标题】:MPI_COMM_WORLD handle loses value in a subroutineMPI_COMM_WORLD 句柄在子例程中失去价值
【发布时间】:2011-04-27 12:53:06
【问题描述】:

我的程序如下:
模块 x
使用 mpi !x 包括 mpi 模块
隐式无
...
包含

subroutine do_something_with_mpicommworld  

    !use mpi !uncommenting this makes a difference (****)  
    call MPI_...(MPI_COMM_WORLD,...,ierr)  

end subroutine  

...
结束模块 x

程序主
使用 mpi 使用 x
MPI_INIT(...)
调用 do_something_with_mpicommworld 结束程序主

此程序失败并出现以下错误:MPI_Cart_create(199): Invalid communicator,除非 标有 (**) 的行未注释。

现在,也许我对 Fortran 90 的了解不完整,但我想如果您在模块定​​义中有 use 子句(请参阅我的模块 x),则无论包含的模块中存在哪个全局变量(在 x 的情况下:包含模块 mpi 的 MPI_COMM_WORLD 将在任何包含的子例程( do_something_with_mpicommworld )中具有相同的值,即使这些子例程没有明确包含模块(例如,当 (**) 是注释掉)。或者,简单地说,如果您在另一个模块中包含一个模块,则第二个模块中包含的子例程将可以访问包含模块中的全局变量,而无需特殊的 use 语句。

当我运行我的程序时,我看到了不同的行为。 x 中包含的子程序会产生错误,除非它有“use mpi”语句。

那么问题是什么,我对 Fortran 90 有什么错误的想法,还是 MPI 模块有什么特别之处会导致这种行为?

【问题讨论】:

  • 你能发布代码,而不是你的代码摘要。魔鬼经常在细节中。

标签: mpi fortran90


【解决方案1】:

很难找到在这些情况下应该发生什么和不应该发生什么的确切细节,我的期望和你的一样——“使用 mpi”应该像上面那样工作。所以我尝试了以下方法:

module hellompi
use mpi
implicit none
contains

subroutine hello
    integer :: ierr, nprocs, rank
    call MPI_INIT(ierr)
    call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
    call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
    print *, 'Hello world, from ', rank, ' of ', nprocs
    print *, MPI_COMM_WORLD
    call MPI_FINALIZE(ierr)
    return
end subroutine hello

end module hellompi

它在 gfortran 和 ifort 和 OpenMPI 下都能正常工作。添加 cart_create 不会改变任何东西。

你的案例让我感到奇怪的是,它并没有抱怨 MPI_COMM_WORLD 没有定义——所以很明显一些相关信息正在传播到子例程。您能否发布一个更简单的完整示例,但仍然无法正常工作?

【讨论】:

    【解决方案2】:

    感谢乔纳坦的回答。问题非常非常简单。我在“结束模块”之后添加了有问题的子例程
    :-D,'implicit none' 不适用于现在的外部子,编译器很高兴按照标准隐式规则将一个全新的变量 MPI_COMM_WORLD 初始化为它认为合适的任何内容。

    这对我来说只是一个教训,不仅要通过关键字,还要通过编译器标志来强制执行“隐式无”。每个结束语句之后都潜伏着邪恶。

    很抱歉,您在制作测试示例时遇到了麻烦,如果可以的话,我会请您喝啤酒 :-)

    【讨论】:

      猜你喜欢
      • 2019-09-24
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      相关资源
      最近更新 更多