mod_load_balance Module


Uses

  • module~~mod_load_balance~~UsesGraph module~mod_load_balance mod_load_balance module~mod_mpi_wrapper mod_mpi_wrapper module~mod_load_balance->module~mod_mpi_wrapper mpi mpi module~mod_mpi_wrapper->mpi

Used by

  • module~~mod_load_balance~~UsedByGraph module~mod_load_balance mod_load_balance proc~amr_coarsen_refine amr_coarsen_refine proc~amr_coarsen_refine->module~mod_load_balance

Variables

Type Visibility Attributes Name Initial
integer, private :: igrid
integer, private :: irecv

MPI recv send variables for AMR. One request per neighbouring rank, so these are sized by npe.

integer, private :: isend

MPI recv send variables for AMR. One request per neighbouring rank, so these are sized by npe.

integer, private :: itag

MPI recv send variables for AMR. One request per neighbouring rank, so these are sized by npe.

integer, private, allocatable, dimension(:) :: lb_rcv_ibuf
integer, private, allocatable, dimension(:) :: lb_rcv_igrid
integer, private, allocatable, dimension(:) :: lb_rcv_key
integer, private, allocatable, dimension(:) :: lb_rcv_src
integer, private, allocatable, dimension(:) :: lb_recv_pe
integer, private, allocatable, dimension(:) :: lb_recv_pe_len
integer, private, allocatable, dimension(:) :: lb_recv_pe_off
integer, private, allocatable, dimension(:) :: lb_send_pe
integer, private, allocatable, dimension(:) :: lb_send_pe_len
integer, private, allocatable, dimension(:) :: lb_send_pe_off
integer, private, allocatable, dimension(:) :: lb_snd_dest
integer, private, allocatable, dimension(:) :: lb_snd_ibuf
integer, private, allocatable, dimension(:) :: lb_snd_igrid
integer, private, allocatable, dimension(:) :: lb_snd_key
integer, private :: max_buff = 0

high-water mark of the two buffers, in chunks

integer, private :: n_lb_rcv

Per migrating block, appended during the walk and turned into per-peer runs by exchange_migrated_blocks. lb_snd_igrid / lb_snd_ibuf and the rcv counterparts are read by the pack and unpack kernels and are therefore device-resident; the rest is the host-side working set.

integer, private :: n_lb_recv_pe

The peers themselves, ascending, with the extent of each one's run. Host only: these drive the MPI calls and nothing else.

integer, private :: n_lb_send_pe

The peers themselves, ascending, with the extent of each one's run. Host only: these drive the MPI calls and nothing else.

integer, private :: n_lb_snd

Per migrating block, appended during the walk and turned into per-peer runs by exchange_migrated_blocks. lb_snd_igrid / lb_snd_ibuf and the rcv counterparts are read by the pack and unpack kernels and are therefore device-resident; the rest is the host-side working set.

double precision, private, allocatable, dimension(:) :: rcv_buff_lb

MPI buffers to send blocks.

The migration is aggregated per destination rank: every block bound for one peer occupies a contiguous run of snd_buff_lb and travels in a single Isend. Both ranks order a run by the key

ikey = recv_igrid

the block index the block will occupy on its new owner. That is unique among the blocks arriving at a given receiver, because each comes from its own getnode(), and the sender knows it because load_balance walks the globally replicated Morton list in the same order on every rank and every rank calls getnode() for every migration - so igrid_inuse, and with it the destination index, stays replicated.

Sizing matters more here than the message count. These buffers used to be block_nx^3 * nw * max_blocks doubles each, allocated on the first call whether or not a single block ever moved: 1.05 GB apiece at block_nx=16, nw=8, max_blocks=4000, and device-resident. They are now sized by what actually migrates, and only ever grow, so the steady state neither wastes the memory nor reallocates every regrid.

Deliberately NOT declare create: these are resized, and an OpenACC declare-create allocatable does not reliably get a fresh device copy when the host array is reallocated - an update device afterwards then writes through a stale mapping. They are managed explicitly with enter data create / exit data delete instead, the same way mod_fix_conserve handles its own resizable exchange buffers.

integer, private :: recv_igrid
integer, private :: recv_ipe
integer, private, dimension(:), allocatable :: recvrequest
integer, private, dimension(:), allocatable :: recvrequest_stg

MPI recv send variables for staggered-variable AMR

integer, private, dimension(:,:), allocatable :: recvstatus
integer, private :: send_igrid
integer, private :: send_ipe
integer, private, dimension(:), allocatable :: sendrequest
integer, private, dimension(:), allocatable :: sendrequest_stg

MPI recv send variables for staggered-variable AMR

integer, private, dimension(:,:), allocatable :: sendstatus
double precision, private, allocatable, dimension(:) :: snd_buff_lb

MPI buffers to send blocks.

The migration is aggregated per destination rank: every block bound for one peer occupies a contiguous run of snd_buff_lb and travels in a single Isend. Both ranks order a run by the key

ikey = recv_igrid

the block index the block will occupy on its new owner. That is unique among the blocks arriving at a given receiver, because each comes from its own getnode(), and the sender knows it because load_balance walks the globally replicated Morton list in the same order on every rank and every rank calls getnode() for every migration - so igrid_inuse, and with it the destination index, stays replicated.

Sizing matters more here than the message count. These buffers used to be block_nx^3 * nw * max_blocks doubles each, allocated on the first call whether or not a single block ever moved: 1.05 GB apiece at block_nx=16, nw=8, max_blocks=4000, and device-resident. They are now sized by what actually migrates, and only ever grow, so the steady state neither wastes the memory nor reallocates every regrid.

Deliberately NOT declare create: these are resized, and an OpenACC declare-create allocatable does not reliably get a fresh device copy when the host array is reallocated - an update device afterwards then writes through a stale mapping. They are managed explicitly with enter data create / exit data delete instead, the same way mod_fix_conserve handles its own resizable exchange buffers.


Subroutines

public subroutine load_balance()

reallocate blocks into processors for load balance

Arguments

None

private subroutine exchange_migrated_blocks()

Exchange and apply the migrating blocks, one message per neighbouring rank, with the buffers sized by what actually moves.

Read more…

Arguments

None

private subroutine lb_recv()

Arguments

None

private subroutine lb_send()

Arguments

None