传递3D数组usnig MPI_ALLGATHERV

时间:2013-11-07 21:24:16

标签: arrays 3d mpi fortran77

我正在尝试使用MPI_ALLGATHERV将3D数组传递给所有其他进程。 v1是一个公共块数组。

parameter (nprocz=48,nzro=1)
do 1 i=i101,i102
  do 2 j = je0, je1-1
  do 2  k = ke0, ke1
    v1(k,j,i) = v1(k,j,i)*0.015*float(i-iv0)
2    continue
1   continue      
nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
if (mpirank .le. nprocz-2) then
   i101=ie0+(mpirank*nmpi01)
   i102=ie0+(mpirank+1)*nmpi01-1
else
   i101=ie0+(mpirank*nmpi01)
   i102=iv0-1
endif
scount=(i102-i101+1)*(je1-je0)*(ke1-ke0+1)
rcount(mpirank+1)=scount
displs(mpirank+1)=mpirank*scount+1 call
MPI_ALLGATHERV(v1(1,1,i101),scount,MPI_REAL,v1(1,1,1)  ,rcount,displs,MPI_REAL,MPI_COMM_WORLD,ierr004)

但是我得到的错误和我的进程一样多:

Fatal error in PMPI_Allgatherv: Internal MPI error!, error stack:
...
MPIR_Localcopy(378).......: memcpy arguments alias each other, dst=0x7ccddb44  
src=0x7ccddb40 len=3642752

然后我试过,MPI_IN_PLACE像这样:

 MPI_ALLGATHERV(MPI_IN_PlACE,scount,MPI_REAL,v1(1,1,1),   
 rcount,displs,MPI_REAL,MPI_COMM_WORLD,ierr004) 

但是内存一直在逐渐使用,直到probram崩溃。

1 个答案:

答案 0 :(得分:0)

MPI_ALLGATHERV要求每个等级指定通信器中每个等级的大小和位移。您所做的只是填写单一等级的值:

rcount(mpirank+1)=scount
displs(mpirank+1)=mpirank*scount+1

相反,您应该遍历排名并计算每个排名中rcountdispls的所有元素:

integer :: myscount, myi101

displs(1) = 0
do rank = 0, nprocz-1
   nmpi01=floor((iv0-ie0-nzro)/(nprocz-1))
   if (rank .le. nprocz-2) then
      i101=ie0+(rank*nmpi01)
      i102=ie0+(rank+1)*nmpi01-1
   else
      i101=ie0+(rank*nmpi01)
      i102=iv0-1
   endif
   scount=(i102-i101+1)*(je1-je0)*(ke1-ke0+1)
   rcount(rank+1)=scount
   if (rank .gt. 0) then
      displs(rank+1) = displs(rank) + rcount(rank)
   endif
   if (rank .eq. mpirank) then
      myscount = scount
      myi101 = i101
   end if
end do

scount = myscount
i101 = myi101

call mpi_allgatherv(...)

另请注意,计算displs的方式可能是错误的。如果收到的数据之间没有间隙,则应保持以下关系:displs(i) = sum(rcount(1:i-1))编辑:我已经使用正确计算displs数组元素的代码更改了上面的代码。