我的节目如下:
模块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模块有什么特别之处会导致这种行为吗?
答案 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初始化为符合标准隐式规则的任何其认为合适的变量。
这对我来说只是一个教训,不仅要通过关键字,还要通过编译器标志强制执行'隐式无'。每个结束声明后都会潜伏着邪恶。
我很抱歉你遇到了制作测试示例的麻烦,如果可以的话,我会给你买啤酒: - )