MSMPI就地MPI_Allreduce无法与MinGW-w64 gfortran一起使用

问题描述 投票:2回答:1

[我正在尝试将MinGW-w64 gfortran(MSYS64提供的9.2版)和Microsoft MPI(版本10)结合使用就位MPI_Allreduce

call MPI_Allreduce(MPI_IN_PLACE, srcdst, n, MPI_REAL8, MPI_SUM, MPI_COMM_WORLD, ierr)

标准MPI_Allreduce(具有不同的源和目标)效果很好,当我使用C代替Fortran时,就地变体也一样。

完整的测试程序test_allreduce.f90

program test_allreduce

    use iso_fortran_env, only: real64
    use mpi

    implicit none

    integer, parameter :: mpiint = kind(MPI_COMM_WORLD)

    integer(mpiint) :: n = 10
    integer(mpiint) :: ierr1 = -1, ierr2 = -1, ierr3 = -1, ierr4 = -1

    real(real64) :: src(10) = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
    real(real64) :: dst(10) = 0

    call MPI_Init(ierr1)
    call MPI_Allreduce(src, dst, n, MPI_REAL8, MPI_SUM, MPI_COMM_WORLD, ierr2)
    call MPI_Allreduce(MPI_IN_PLACE, src, n, MPI_REAL8, MPI_SUM, MPI_COMM_WORLD, ierr3)
    call MPI_Finalize(ierr4)

    write (*, '(I4)') MPI_IN_PLACE
    write (*, '(4I4)') ierr1, ierr2, ierr3, ierr4
    write (*, '(10F4.0)') src
    write (*, '(10F4.0)') dst

end program

这是我的编译方式:

set "PATH=C:\msys64\mingw64\bin;%PATH%"

x86_64-w64-mingw32-gfortran ^
    -fno-range-check ^
    "C:\Program Files (x86)\Microsoft SDKs\MPI\Include\mpi.f90" ^
    test_allreduce.f90 ^
    -I . ^
    -I "C:\Program Files (x86)\Microsoft SDKs\MPI\Include\x64" ^
    -o test_allreduce.exe ^
    C:\Windows\System32\msmpi.dll

这就是我执行它的方式(到目前为止,仅在单个过程中:)>

test_allreduce.exe

当前正在打印

   0
0   0   0   0
0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
1.  2.  3.  4.  5.  6.  7.  8.  9. 10.

显然,在第二次(就地)调用src时,MPI_Allreduce缓冲区被垃圾覆盖。

我在mpi.f90特定于Intel的DLLIMPORT指令的代码中看到,甚至试图添加类比]]

!GCC$ ATTRIBUTES DLLIMPORT :: MPI_IN_PLACE

没有任何效果。

我正在尝试将就地MPI_Allreduce与MinGW-w64 gfortran(MSYS64提供的9.2版)和Microsoft MPI(版本10)组合使用,请调用MPI_Allreduce(MPI_IN_PLACE,srcdst,n,...

] >

原来的麻烦是,在MSMPI中,变量MPI_IN_PLACE包含在内部COMMON/MPIPRIV1/中,而gfortran中的known bug是编译器无法正确导入COMMON块变量的原因来自DLL。

尽管如此,可以修复损坏的东西,最后所需要做的就是将patch应用于gfortran代码,并在MSYS2(phew ...

),和]中从头开始对其进行编译。 >添加指令
!GCC$ ATTRIBUTES DLLIMPORT ::  MPI_BOTTOM, MPI_IN_PLACE

在上述代码中implicit none之后。 (在指令中似乎都需要这两个变量,因为MPI_IN_PLACE在内部COMMON块中紧随MPI_BOTTOM之后排在第二位。)然后,就地MPI_Allreduce可以正常工作。

fortran mpi gfortran mingw-w64 ms-mpi
1个回答
0
投票

原来的麻烦是,在MSMPI中,变量MPI_IN_PLACE包含在内部COMMON/MPIPRIV1/中,而gfortran中的known bug是编译器无法正确导入COMMON块变量的原因来自DLL。

© www.soinside.com 2019 - 2024. All rights reserved.