原来的麻烦是,在MSMPI中,变量MPI_IN_PLACE
包含在内部COMMON
块/MPIPRIV1/
中,而gfortran中的known bug是编译器无法正确导入COMMON
块变量的原因来自DLL。
[我正在尝试将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
可以正常工作。
原来的麻烦是,在MSMPI中,变量MPI_IN_PLACE
包含在内部COMMON
块/MPIPRIV1/
中,而gfortran中的known bug是编译器无法正确导入COMMON
块变量的原因来自DLL。