0

我的程序如下:
module x
use mpi !x includes mpi module
implicit none
...
contains

subroutine do_something_with_mpicommworld  

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

end subroutine  

...
结束模块 x

program main
use mpi use x
MPI_INIT(...)
call do_something_with_mpicommworld end program main

该程序失败并出现以下错误: MPI_Cart_create(199): 无效的通信器,除非标有 ( * *) 的行未注释。

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

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

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

4

2 回答 2

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 没有定义——所以很明显,一些相关信息正在传播到子程序。你能发布一个更简单的完整示例,但仍然无法正常工作吗?

于 2010-10-19T16:06:34.000 回答
-1

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

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

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

于 2010-10-19T18:14:48.273 回答