【问题标题】:MPI subroutines in FortranFortran 中的 MPI 子例程
【发布时间】: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


【解决方案1】:

您的主程序可能会获得(或者更确切地说是试图获得)mpif.h 中所有内容的两个副本。通过在模块中include-ing 它,您可以有效地使其所有内容模块成为事物(变量、例程、参数、what-nots)。然后,在 main 中,你们俩都 use 模块,从而使用关联模块事物,并尝试 include mpif.h 并再次重新声明所有这些事物。

也按照@Jonathan Dursi 的建议去做。

【讨论】:

  • 非常感谢!现在一切正常!只需要让我的系统管理员让我使用“使用 mpi”...所以包含 mpif.h 永远不会那样工作?
猜你喜欢
  • 2018-11-05
  • 2015-04-14
  • 1970-01-01
  • 2019-08-29
  • 1970-01-01
  • 2023-03-14
  • 2020-12-15
  • 2022-01-08
  • 2012-12-22
相关资源
最近更新 更多