我正在尝试使用就地MPI_Allreduce
结合MinGW-w64 gfortran(MSYS64提供的版本9.2)和Microsoft MPI(版本10),
call MPI_Allreduce(MPI_IN_PLACE, srcdst, n, MPI_REAL8, MPI_SUM, MPI_COMM_WORLD, ierr)
标准MPI_Allreduce
(具有不同的源和目标)效果很好,当我使用 C 而不是 Fortran 时,就地变体也是如此。
完整的测试程序test_allreduce.f90 is
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
没有任何影响。