MPI_COMM_WORLD 句柄在子例程中丢失值

发布于 2024-09-28 14:24:26 字数 916 浏览 5 评论 0原文

我的程序如下:
模块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 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 模块有什么特殊之处会导致这种行为吗?

my program is as follows:
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  

...
end module x

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

This program fails with the following error: MPI_Cart_create(199): Invalid communicator, unless
the line marked with (**) is uncommented.

Now, maybe my knowledge of Fortran 90 is incomplete, but i thought if you have a use clause in the module definition (see my module x), whichever global variable exists in the included module (in case of x : MPI_COMM_WORLD from include module mpi) will have the same value in any of the contained subroutines ( do_something_with_mpicommworld ) even when those subroutines do not explicitly include the module (e.g. when (**) is commented out). Or, to put it simply, if you include a module within another module, the subroutines contained in the second module will have access to the globals in the included module without a special use statement.

When I ran my programme, I saw a different behaviour. The sub contained in x was creating errors unless it had the 'use mpi' statement.

So what is the problem, do I have a wrong idea about Fortran 90, or is there something special about MPI module which induces such behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落画卷 2024-10-05 14:24:26

令人烦恼的是,很难找到关于这些情况下应该发生什么和不应该发生什么的确切细节,我的期望与你的相同——“使用 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 没有定义——所以显然一些相关信息正在被传播到子例程。您能否发布一个更简单的完整示例,但仍然无法正常工作?

Its annoyingly hard to find exact details about what should and shouldn't happen in these cases, and my expectation was the same as yours -- the `use mpi' should work as above. So I tried the following:

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

and it works fine under both gfortran and ifort with OpenMPI. Adding a cart_create doesn't change anything.

What strikes me as weird with your case is that it isn't complaining that MPI_COMM_WORLD isn't defined -- so obviously some of the relevant information is being propagated to the subroutine. Can you post a simpler full example which still fails to work?

Spring初心 2024-10-05 14:24:26

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

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

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

Thank you Johnatan for your answer. The problem was really, really simple. I added the subroutine in question after the "end module"
:-D, 'implicit none' did not apply to now external sub and compiler happily initialised a brand new variable MPI_COMM_WORLD to whatever it thought suitable following the standard implicit rules.

This is just a lesson to me to enforce 'implicit none' not only by keywords, but also via the compiler flag. Evil lurks after every end statement.

I'm sorry you went trough the trouble of making the test example, I'd buy you a beer if I could :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文