MPI_COMM_WORLD句柄在子例程中丢失值

时间:2010-10-19 14:37:41

标签: mpi fortran90

我的节目如下:
模块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):无效的通信器,除非 标有( * *)的行是未注释的。

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

当我运行程序时,我看到了不同的行为。 x中包含的子句创建错误,除非它有'use mpi'语句。

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

2 个答案:

答案 0 :(得分: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

并且在使用OpenMPI的gfortran和ifort下都能正常工作。添加cart_create不会改变任何内容。

令我觉得奇怪的是,你并没有抱怨MPI_COMM_WORLD没有被定义 - 所以显然某些的相关信息正在传播到子程序。你能发布一个更简单的完整例子但仍无法正常工作吗?

答案 1 :(得分:0)

感谢Johnatan的回答。问题非常非常简单。我在“结束模块”之后添加了有问题的子程序 :-D,'implicit none'不适用于现在的外部子程序,编译器愉快地将一个全新的变量MPI_COMM_WORLD初始化为符合标准隐式规则的任何其认为合适的变量。

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

我很抱歉你遇到了制作测试示例的麻烦,如果可以的话,我会给你买啤酒: - )