【发布时间】:2019-05-30 12:08:32
【问题描述】:
我有以下代码:
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_REAL8 和 MPI_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 不会收集垃圾。但是,我无法区分实现之间的区别。
【问题讨论】:
-
我现在看不出你的第一个块有什么问题。您能否在重现您的问题时最小限度地更改 that 版本(通过为要传递的值设置一些初始值)以使其可运行?如果你不能,很可能是你从你的真实代码中删除了一些导致错误的东西。
-
一个不同的是通信器,我看到通信器
MPI_COMM_PGM已在另一个模块中定义。我使用该模块并在代码中指定通信器。重现错误的最小示例将非常冗长,因为这段代码深深嵌入类型绑定方法中。由于它发送的是正确的值,我认为只有接收存在问题。 -
在这种情况下,您要求我们调试我们看不到的代码。
-
@AndrasDeak,明白了!将很快上传一个最小的代码
-
@AndrasDeak 实际上,问题似乎出在控制缓冲区大小的代码的另一部分。目前,我已经解决了这个问题(见答案)。