Module fd4_part_sfc_mod


Uses:
    module fd4_globaldef_mod
    module fd4_domain_mod
    module fd4_iter_mod
    module fd4_mpi_mod
    module hilbert_mod
    module mrgrnk_mod
    module stack_mod
    module rbtree_fd4_block_mod
Variables:
    integer (kind=i_k), public, parameter :: FD4_PART_SFC_SIMPLE = 1
    integer (kind=i_k), public, parameter :: FD4_PART_SFC_BINSRCH = 2
    integer (kind=i_k), public, parameter :: FD4_PART_SFC_PARALLEL = 3
Subroutines and functions:
    private function fd4_part_sfc_part1d_scan (nblocks, blkweights_ps, pstart, sumload, guess) result (pend)
    public subroutine fd4_part_sfc_part1d_binsrch (nblocks, nprocs, blkweights_ps, maxweight, steps, partition, maxload)
    public subroutine fd4_part_sfc_part1d_parallel (nblocks, nprocs, blkweights_ps, maxweight, steps, mpi, partition, maxload, err)
    public subroutine fd4_part_sfc_part1d_simple (nblocks, nprocs, blkweights_ps, partition, maxload)
    public subroutine fd4_part_sfc_weight (domain, all_blocks, all_blocks_len, local_blocks, local_blocks_len, method, err, opt_blocks_changed)
    private subroutine fd4_part_sfc_exch_weights (domain, err)
    public subroutine fd4_part_new (domain, all_blocks, all_blocks_len, local_blocks, local_blocks_len, add_only, opt_blocks_changed)

Hilbert SFC partitioning of an fd4_domain.

Preprocessor options:

Author: Matthias Lieber

See also: module hilbert_mod, module fd4_domain_mod


Description of Subroutines and Functions

fd4_part_sfc_part1d_scan

private function fd4_part_sfc_part1d_scan (nblocks, blkweights_ps, pstart, sumload, guess) result (pend)
    integer (kind=i_k), intent(in) :: nblocks
    real (kind=r8k), intent(in), dimension (0:nblocks) :: blkweights_ps
    integer (kind=i_k), intent(in) :: pstart
    real (kind=r8k), intent(in) :: sumload
    integer (kind=i_k), intent(inout) :: guess
    integer (kind=i_k) :: pend
end function fd4_part_sfc_part1d_scan
Parameters:
nblocks number of blocks
blkweights_ps prefix sum of ordered block weights, weights(0) must be 0
pstart start index for search
sumload upper bound for search in blkweights_ps values
guess guess for result value for clever algorithm
Search the largest value which not larger than sumload in the array of prefix summed block weights blkweights_ps starting at pstart and return the index in blkweights_ps.

If compiled with CLEVER_SEARCH, use a more sophisticated algorithm which starts searching at index guess. Returns a new value for guess for subsequent searches.

Internal function, called by fd4_part_sfc_part1d_binsrch and fd4_part_sfc_part1d_parallel.


fd4_part_sfc_part1d_binsrch

public subroutine fd4_part_sfc_part1d_binsrch (nblocks, nprocs, blkweights_ps, maxweight, steps, partition, maxload)
    integer (kind=i_k), intent(in) :: nblocks
    integer (kind=i_k), intent(in) :: nprocs
    real (kind=r8k), intent(in), dimension (0:nblocks) :: blkweights_ps
    real (kind=r8k), intent(in) :: maxweight
    integer (kind=i_k), intent(in) :: steps
    integer (kind=i_k), intent(out), dimension (0:nprocs) :: partition
    real (kind=r8k), intent(out) :: maxload
end subroutine fd4_part_sfc_part1d_binsrch
Parameters:
nblocks number of blocks
nprocs number of processes
blkweights_ps prefix sum of ordered block weights, weights(0) must be 0
maxweight max weight in weight array
steps number of binary search steps to find good bottleneck value
partition output partition vector, contains start indices of partitions
maxload estimation of load of max loaded process, real value is a bit smaller
Calculate a well-balanced partition for given block weigths. Note: weights have to be given as prefix sums!

Algorithm:

Internal routine.

fd4_part_sfc_part1d_parallel

public subroutine fd4_part_sfc_part1d_parallel (nblocks, nprocs, blkweights_ps, maxweight, steps, mpi, partition, maxload, err)
    integer (kind=i_k), intent(in) :: nblocks
    integer (kind=i_k), intent(in) :: nprocs
    real (kind=r8k), intent(in), dimension (0:nblocks) :: blkweights_ps
    real (kind=r8k), intent(in) :: maxweight
    integer (kind=i_k), intent(in) :: steps
    type (fd4_mpi), intent(in) :: mpi
    integer (kind=i_k), intent(out), dimension (0:nprocs) :: partition
    real (kind=r8k), intent(out) :: maxload
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_part_sfc_part1d_parallel
Parameters:
nblocks number of blocks
nprocs number of processes
blkweights_ps prefix sum of ordered block weights, weights(0) must be 0
maxweight max weight in weight array
steps number of binary search steps to find good bottleneck value
mpi domain's MPI context
partition output partition vector, contains start indices of partitions
maxload estimation of load of max loaded process, real value is a bit smaller
err error status: 0...ok
Calculate a well-balanced partition for given block weigths. Note: weights have to be given as prefix sums!

Algorithm:

Internal routine.

fd4_part_sfc_part1d_simple

public subroutine fd4_part_sfc_part1d_simple (nblocks, nprocs, blkweights_ps, partition, maxload)
    integer (kind=i_k), intent(in) :: nblocks
    integer (kind=i_k), intent(in) :: nprocs
    real (kind=r8k), intent(in), dimension (0:nblocks) :: blkweights_ps
    integer (kind=i_k), intent(out), dimension (0:nprocs) :: partition
    real (kind=r8k), intent(out) :: maxload
end subroutine fd4_part_sfc_part1d_simple
Parameters:
nblocks number of blocks
nprocs number of processes
blkweights_ps prefix sum of ordered block weights, weights(0) must be 0
partition output partition vector, contains start indices of partitions
maxload load of max loaded process
Calculate a partition for given block weigths. Note: weights have to be given as prefix sums!

Algorithm:

Internal routine.

fd4_part_sfc_weight

public subroutine fd4_part_sfc_weight (domain, all_blocks, all_blocks_len, local_blocks, local_blocks_len, method, err, opt_blocks_changed)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(in), dimension (3,all_blocks_len) :: all_blocks
    integer (kind=i_k), intent(in) :: all_blocks_len
    integer (kind=i_k), intent(inout), dimension (:,:) :: local_blocks
    integer (kind=i_k), intent(out) :: local_blocks_len
    integer (kind=i_k), intent(in) :: method
    integer (kind=i_k), intent(out) :: err
    logical, optional, intent(in) :: opt_blocks_changed
end subroutine fd4_part_sfc_weight
Parameters:
domain the domain
all_blocks array of positions of the blocks in the new partion
all_blocks_len length of all_blocks(3,:)
local_blocks array of new local partition (differs from rank to rank)
local_blocks_len length of local_blocks(3,:)
method 1D partitioning method to use
err error status: 0...ok
opt_blocks_changed tell me if the blocks have changed (created/removed)
Create a new partition using block position. Considers block weights from domain%balance%blkweights.

If opt_blocks_changed is present and is set to false: fd4_part_sfc_weight reuses the hilbert indexes and the ranking of blocks by the hilbert index from the last call!

*TODO:*


fd4_part_sfc_exch_weights

private subroutine fd4_part_sfc_exch_weights (domain, err)
    type (fd4_domain), intent(inout), target :: domain
    integer (kind=i_k), intent(out) :: err
end subroutine fd4_part_sfc_exch_weights
Parameters:
domain the domain
err error status: 0...ok
Exchange the weight of my blocks with all other processes.

Updates domain%balance%blkweights.

TODO:

Internal routine.

fd4_part_new

public subroutine fd4_part_new (domain, all_blocks, all_blocks_len, local_blocks, local_blocks_len, add_only, opt_blocks_changed)
    type (fd4_domain), intent(inout) :: domain
    integer (kind=i_k), intent(in), dimension (3,all_blocks_len) :: all_blocks
    integer (kind=i_k), intent(in) :: all_blocks_len
    integer (kind=i_k), intent(inout), dimension (:,:) :: local_blocks
    integer (kind=i_k), intent(out) :: local_blocks_len
    logical, optional, intent(in) :: add_only
    logical, optional, intent(in) :: opt_blocks_changed
end subroutine fd4_part_new
Parameters:
domain the domain
all_blocks array of positions of the blocks in the new partion
all_blocks_len length of all_blocks(3,:)
local_blocks array of new local partition (differs from rank to rank)
local_blocks_len length of local_blocks(3,:)
add_only only add new blocks, but don't touch existing blocks
opt_blocks_changed tell me if the blocks have changed (created/removed)
Create a new partition using block position. Weights are not considered.

The special option add_only effects: