Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses.
Make every rank's isafety flags known to every rank.
The flags live in a [max_blocks, 0:npe-1] table, but only the leaves carry
a meaningful value and only the owner of a leaf writes one, so gathering
the whole table would move npe*max_blocks integers - sized by the
allocated bound rather than by the blocks that exist. Instead each rank
contributes just its own leaves, in Morton order, and the gather moves
nleafs integers in total.
sfc(1:2, Morton_no) is the globally replicated (igrid, ipe) of each leaf,
and Morton_start/Morton_stop cut it into the per-rank runs, so the counts
and displacements are known to everyone without a handshake and the
scatter back into (igrid, ipe) needs no inverse map.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Nodes of different colours represent the following:
Solid arrows point from a procedure to one which it calls. Dashed
arrows point from an interface to procedures which implement that interface.
This could include the module procedures in a generic interface or the
implementation in a submodule of an interface in a parent module.
Source Code
subroutine gather_isafetyuse mod_forestuse mod_global_parametersuse mod_comm_lib,only:mpistopinteger::Morton_no,ipe,nowninteger::cnt(0:npe-1),disp(0:npe-1)do ipe=0,npe-1cnt(ipe)=Morton_stop(ipe)-Morton_start(ipe)+1disp(ipe)=Morton_start(ipe)-1end donown=cnt(mype)if(.not.allocated(sndsafety))then allocate(sndsafety(max(nleafs,1)),rcvsafety(max(nleafs,1)))else if(size(rcvsafety)<nleafs)then deallocate(sndsafety,rcvsafety)allocate(sndsafety(max(nleafs,1)),rcvsafety(max(nleafs,1)))end if do Morton_no=Morton_start(mype),Morton_stop(mype)! the run this rank owns must be the run sfc says it owns, or the! displacements below would scatter another rank's flagsif(sfc(2,Morton_no)/=mype)call mpistop(&"gather_isafety: Morton range disagrees with the space-filling curve")sndsafety(Morton_no-Morton_start(mype)+1)=isafety(sfc(1,Morton_no),mype)end do call MPI_ALLGATHERV(sndsafety,nown,MPI_INTEGER,rcvsafety,cnt,disp,&MPI_INTEGER,icomm,ierrmpi)isafety=-1do Morton_no=1,nleafsisafety(sfc(1,Morton_no),sfc(2,Morton_no))=rcvsafety(Morton_no)end do end subroutine gather_isafety