aru*_*zhi 1 parallel-processing fortran mpi fortran90
我有一个fortran MPI代码,其中在2D数组的每个元素上调用计算密集型函数.我正在尝试将任务分配给队伍.例如,如果有30列和10个等级,那么每个等级得到3列.以下代码执行此拆分并使用allgather收集结果.但是最终数组没有来自所有排名的值.
program allgather
include 'mpif.h'
!create a 2 x 30 myarray
integer :: x=2,y=30
integer :: numprocs,myid
integer :: i,j,k,myelements,mycolumns,jb,je
integer*4,dimension(:),allocatable :: displacement,recvcnt
real :: checksum
real,dimension(:,:),allocatable :: myarr,combinedarr
call MPI_INIT(IERR)
call MPI_COMM_SIZE(MPI_COMM_WORLD,NUMPROCS,IERR)
call MPI_COMM_RANK(MPI_COMM_WORLD,MYID,IERR)
mycolumns = y/numprocs
myelements = x * mycolumns
allocate(displacement(numprocs),recvcnt(numprocs))
jb = 1 + ( myid * mycolumns )
je = ( myid + 1 ) * mycolumns
allocate(myarr(x,mycolumns))
allocate(combinedarr(x,y))
myarr(:,:) =0
do j=jb,je
do i=1,x
myarr(i,j) = 1
enddo
enddo
!myarr(:,:)=1
if(mod(y,numprocs) > 0) then
if(myid==numprocs-1) then
jb=(myid + 1) * mycolumns + 1
do j=jb,y
do i=1,x
myarr(i,j) = 1
enddo
enddo
endif
endif
combinedarr(:,:) =0
recvcnt(:)=myelements
do k=1,numprocs
displacement(k) = (k-1) *myelements
enddo
call MPI_ALLGATHERV(myarr,myelements,MPI_REAL,combinedarr,recvcnt,displacement,MPI_REAL,MPI_COMM_WORLD,IERR)
if(mod(y,numprocs) > 0) then
recvcnt(:) = 0
recvcnt(numprocs) = (x*y) - myelements * (numprocs)
displacement(numprocs) = displacement(numprocs) + myelements
call MPI_ALLGATHERV(myarr,recvcnt(numprocs),MPI_REAL,combinedarr,recvcnt,displacement,MPI_REAL,MPI_COMM_WORLD,IERR)
endif
if (myid==0) then
checksum=0
write(6,*) "mycolumns:",mycolumns,"myelements:",myelements
do j=1,y
do i=1,x
checksum = checksum + combinedarr(i,j)
enddo
enddo
write(6,*) checksum
endif
end
Run Code Online (Sandbox Code Playgroud)
首先,您正在使用MPI_ALLGATHERV()它,MPI_ALLGATHER()并且无法从每个进程发送不同数量的元素.但这不是你程序中的错误.错误在于它填充的方式myarr.您将其分配为,myarr(x,mycolumns)但是当从列jb到列填充它时je,您将在所有进程中超过数组的末尾但排名0从那时起jb并且je大于mycolumns那里.因此myarr,仅包含0所有其他等级中的等级和零.所以,是的,最终数组没有你期望的值,但这是因为你填错了它们,而不是因为MPI子程序的使用方式.
在可分配数组的末尾写入会破坏用于管理堆分配的隐藏结构,并且通常会使程序崩溃.在你的情况下,你很幸运 - 我用Open MPI运行你的代码,每次都崩溃了核心转储.
而且您也错过了MPI_FINALIZE()代码末尾的调用.
提示:如果可用,请使用Fortran 90接口 - 替换include 'mpif.h'为use mpi
| 归档时间: |
|
| 查看次数: |
788 次 |
| 最近记录: |