MPI_Allgather 收到垃圾邮件

MPI_Allgather receiving junk

我有以下代码:

              real          :: s_s, d_s, s_r(size), d_r(size)
              integer       :: k, k_r(size)

              ! - size = number of processors
              ! - Do something to initialise s_s, d_s, k
              write(*,*) "SENDING >>>>"
              write(*,*) s_s, d_s
              call MPI_Allgather( s_s, 1, MPI_REAL,
 &                 s_r, 1, MPI_REAL, MPI_COMM_PGM, mpi_err)

              call MPI_Allgather( d_s, 1, MPI_REAL,
 &                 d_r, 1, MPI_REAL, MPI_COMM_PGM, mpi_err)

              call MPI_Allgather ( k, 1, MPI_INTEGER,
 &                 k_r, 1, MPI_INTEGER, MPI_COMM_PGM, mpi_err)


              write(*,*) "RECEIVED <<<<"
              write(*,*) s_r, d_r, kr

这会生成以下输出:

SENDING >>>>
  -1803.80339864908       0.616157856320407     
 RECEIVED <<<<
  6.953077622513053E-310  3.565412685916647E-314  1.221334434576037E-314
  1.498827614035474E-314  6.952991536467244E-310  6.953288052096687E-310
  6.953108563966064E-310  2.350861403096908E-314           4           1
           2           3

kr 正在正确收集,但是,s_r 和 d_r 似乎收到垃圾。这可能是因为 MPI 数据类型吗?我尝试使用 MPI_REAL MPI_REAL8MPI_DOUBLE 但这没有用。此外,mpi_err = MPI_SUCCESS

我该怎么做才能解决这个问题?

编辑 1 我开发了以下原型程序:

program allgather
  implicit none

  include "mpif.h"

  real a(4)
  integer rank,size,ierr
  real as(4)
  real ar(16)
  integer i, j, k,z 

  a=1
  call MPI_INIT(ierr)
  call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
  call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
  if(size.ne.4)then 
     write(*,*)'Error!:# of processors must be equal to 4'
     write(*,*)'Programm aborting....'
     call MPI_ABORT(ierr)
  endif

  do k=1,4
     if ( rank == (mod(k, size))) then
        a(k)  = k
     else
        a(k)  = 0.0 
     endif
  enddo

  write(*,*) "Rank :", rank
  write(*,*) a

  call MPI_Allgather(a, 4, MPI_REAL, ar,
 &     4,
 &     MPI_REAL, MPI_COMM_WORLD, ierr)

  write(*,*) "Recieved array"
  write(*,*) ar

  do i = 1, 16
     if ( ar(i) /= 0.0 ) then
        z = mod(i, size)
        if ( z == 0 ) then
           a( size ) = ar(i)
        else
           a ( z ) = ar(i)
        endif
     endif
  enddo

  write(*,*) "---------"
  write(*,*) a
  write(*,*) "---------"

  call MPI_FINALIZE(ierr)
  end

这会产生预期的结果,即 ar 不会收集垃圾。但是,我无法分辨实现之间的区别。

原来项目要使用的数据类型是MPI_FLT。奇怪的是 MPI_FLT 有效而不是 MPI_REALx,其中 x=4,8 也不 MPI_FLOAT。我在项目中 grep-ed MPI_FLT 以查看它被定义为什么但没有出现在项目的任何地方。

我使用的 OpenMPI 版本是:

$ mpirun --version
mpirun (Open MPI) 3.0.0

我使用的编译器是:

$ mpifort --version
ifort (IFORT) 19.0.1.144 20181018

在以后的编辑中我会详细说明原因。