【发布时间】:2014-08-24 20:17:17
【问题描述】:
我已经浏览了我能找到的所有关于这个主题的帖子,但它们似乎并没有解决我的问题。我感谢任何输入/帮助/想法。所以这里是:
我有我的主程序(main.f90):
program inv_main
use mod_communication
implicit none
include 'mpif.h'
...
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,id,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,nproc,ierr)
...
call SENDRECEIVE(id, nproc, ierr, VVNP, VVN)
...
call MPI_FINALIZE(ierr)
end program inv_main
这是包含子例程的模块(我知道 allgather 可能是做同样事情的更好方法,但我还无法为我的 4D 数组弄清楚):
Module mod_communication
implicit none
include 'mpif.h'
integer, dimension(MPI_STATUS_SIZE) :: STATUS ! MPI
CONTAINS
Subroutine SENDRECEIVE(id, nproc, ierr, INPUT, OUTPUT )
integer, intent (in) :: nproc, id, ierr
real (dp), intent(in) :: INPUT(n,m)
real (dp), intent(out) :: OUTPUT(n,m,nty,nty)
integer :: sndr
IF (id .eq. 0) THEN
OUTPUT(1:n,1:m,1,1)=INPUT
call MPI_RECV(INPUT,n*m,MPI_DOUBLE_PRECISION,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,STATUS,ierr)
sndr=STATUS(MPI_SOURCE)
OUTPUT(1:n,1:m,int(sndr/nty)+1,sndr+1-nty*(int(sndr/nty))) = INPUT
END IF
IF (id .ne. 0) THEN
call MPI_SEND(INPUT,n*m,MPI_DOUBLE_PRECISION,0,id,MPI_COMM_WORLD,ierr)
ENDIF
call MPI_BARRIER(MPI_COMM_WORLD,ierr)
call MPI_BCAST(OUTPUT,n*m*nty*nty,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,ierr)
end Subroutine
end Module mod_communication
这是我在编译时得到的错误信息:
use mod_communication
2
Error: Symbol 'mpi_displacement_current' at (1) conflicts with symbol from module 'mod_communication', use-associated at (2)
mpif-mpi-io.h:71.36:
Included at mpif-config.h:65:
Included at mpif-common.h:70:
Included at mpif.h:59:
Included at main.f90:27:
integer MPI_MAX_DATAREP_STRING
1
main.f90:21.6:
use mod_communication
2
Error: Symbol 'mpi_max_datarep_string' at (1) conflicts with symbol from module 'mod_communication', use-associated at (2)
mpif-mpi-io.h:73.32:
Included at mpif-config.h:65:
Included at mpif-common.h:70:
Included at mpif.h:59:
Included at main.f90:27:
parameter (MPI_FILE_NULL=0)
这些只是前两个错误,它一直这样......我找不到我的错误。另外,我必须使用“include 'mpif.h'”而不是“使用 mpi”,因为我最终要在机器上运行它。如果我在我自己的计算机上使用 mpi 编译它,它会给我一个不同的错误,如下所示:
mod_MPI.f90:93.41:
call MPI_BARRIER(MPI_COMM_WORLD,ierr)
1
Error: There is no specific subroutine for the generic 'mpi_barrier' at (1)
mod_MPI.f90:52.41:
【问题讨论】:
-
如果你打算使用 Fortran+MPI,我会敦促你找到一种在你的最终机器上使用“使用 mpi”的方法(只需让你的系统管理员构建 fortran 绑定),因为,正如您在此处看到的,编译时检查和错误消息变得更好。特别是,在这里您不能使用intent(in) 虚拟变量来调用MPI_Barrier 的ierr,因为MPI_Barrier 更改了ierr,而这对于intent(in) arg 是不允许的。我还强烈建议您不要将 MPI_ 命名空间用于您自己的函数(例如,您自己的 MPI_SENDRECEIVE);标准禁止这样做,其他人会不必要地混淆。
-
非常感谢您的 cmets!我摆脱了我自己的所有 mpi_namespace 。使用 include mpif.h 我仍然收到相同的错误消息。
-
啊,现在我明白了,一切都与“使用 mpi”完美配合,并消除了障碍!非常感谢! (所以作为外卖:模块中没有障碍?)
-
问题不在这里不是障碍本身(尽管我确实在人们的 MPI 代码中看到了很多不必要的、昂贵的障碍),它试图修改一个意图(在) 参数由 any 表示,包括在子例程调用中。
-
如果我想在我的模块中设置障碍,另一种解决方法是让它成为一个意图(输入)变量?刚才我把障碍放在主代码中。我想我在这里需要它,因为我正在从不同的处理器收集所有这些东西,然后想将完成的矩阵发送给每个人。所以我根本不需要屏障? (抱歉所有问题,我对此很陌生)
标签: mpi fortran90 subroutine