21#include "../../base/base_uses.f90"
26 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbt_tas_global'
48 INTEGER :: nprowcol = -1
49 INTEGER(KIND=int_8) :: nmrowcol = -1
52 PROCEDURE(dist_rowcols),
deferred :: rowcols
61 INTEGER :: split_size = -1
63 PROCEDURE :: dist => cyclic_dist
64 PROCEDURE :: rowcols => cyclic_rowcols
73 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_vec
75 PROCEDURE :: dist => arb_dist
76 PROCEDURE :: rowcols => arb_rowcols
85 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_vec
86 INTEGER :: nmrowcol_local = -1
87 INTEGER :: n_repl = -1
88 INTEGER :: dist_size = -1
90 PROCEDURE :: dist => repl_dist
91 PROCEDURE :: rowcols => repl_rowcols
101 INTEGER(KIND=int_8) :: nmrowcol = -1
102 INTEGER(KIND=int_8) :: nfullrowcol = -1
104 PROCEDURE(rowcol_data),
deferred :: data
113 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_vec
115 PROCEDURE :: data => blk_size_arb
124 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_vec
125 INTEGER :: nmrowcol_local = -1
127 PROCEDURE :: data => blk_size_repl
136 PROCEDURE :: data => blk_size_one
150 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
160 FUNCTION dist_rowcols(t, dist)
163 INTEGER,
INTENT(IN) :: dist
164 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: dist_rowcols
173 FUNCTION rowcol_data(t, rowcol)
176 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
177 INTEGER :: rowcol_data
183 MODULE PROCEDURE new_block_tas_dist_cyclic
187 MODULE PROCEDURE new_block_tas_dist_arb
191 MODULE PROCEDURE new_block_tas_dist_repl
195 MODULE PROCEDURE new_block_tas_blk_size_arb
199 MODULE PROCEDURE new_block_tas_blk_size_repl
203 MODULE PROCEDURE new_block_tas_blk_size_one
215 FUNCTION blk_size_arb(t, rowcol)
217 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
218 INTEGER :: blk_size_arb
219 blk_size_arb = t%blk_size_vec(rowcol)
229 FUNCTION blk_size_repl(t, rowcol)
231 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
232 INTEGER :: blk_size_repl
234 INTEGER :: rowcol_local
236 igroup = int((rowcol - 1_int_8)/t%nmrowcol_local)
237 rowcol_local = int(mod(rowcol - 1_int_8, int(t%nmrowcol_local, kind=
int_8))) + 1
238 blk_size_repl = t%blk_size_vec(rowcol_local)
249 FUNCTION blk_size_one(t, rowcol)
251 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
252 INTEGER :: blk_size_one
265 FUNCTION new_block_tas_blk_size_arb(blk_size_vec)
266 INTEGER,
DIMENSION(:),
INTENT(IN) :: blk_size_vec
269 ALLOCATE (new_block_tas_blk_size_arb%blk_size_vec(
SIZE(blk_size_vec)))
270 new_block_tas_blk_size_arb%blk_size_vec(:) = blk_size_vec(:)
271 new_block_tas_blk_size_arb%nmrowcol =
SIZE(blk_size_vec)
272 new_block_tas_blk_size_arb%nfullrowcol = sum(blk_size_vec)
282 FUNCTION new_block_tas_blk_size_repl(blk_size_vec, n_repl)
283 INTEGER,
DIMENSION(:),
INTENT(IN) :: blk_size_vec
284 INTEGER,
INTENT(IN) :: n_repl
287 new_block_tas_blk_size_repl%nmrowcol_local =
SIZE(blk_size_vec)
288 ALLOCATE (new_block_tas_blk_size_repl%blk_size_vec(new_block_tas_blk_size_repl%nmrowcol_local))
289 new_block_tas_blk_size_repl%blk_size_vec(:) = blk_size_vec(:)
290 new_block_tas_blk_size_repl%nmrowcol = new_block_tas_blk_size_repl%nmrowcol_local*n_repl
291 new_block_tas_blk_size_repl%nfullrowcol = sum(blk_size_vec)*n_repl
300 FUNCTION new_block_tas_blk_size_one(nrowcol)
301 INTEGER(KIND=int_8),
INTENT(IN) :: nrowcol
304 new_block_tas_blk_size_one%nmrowcol = nrowcol
305 new_block_tas_blk_size_one%nfullrowcol = nrowcol
315 FUNCTION arb_dist(t, rowcol)
317 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
320 arb_dist = t%dist_vec(rowcol)
330 FUNCTION repl_dist(t, rowcol)
332 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
334 INTEGER :: rowcol_local
337 igroup = int((rowcol - 1_int_8)/t%nmrowcol_local)
338 rowcol_local = int(mod(rowcol - 1_int_8, int(t%nmrowcol_local, kind=
int_8))) + 1
340 repl_dist = t%dist_vec(rowcol_local) + igroup*t%dist_size
351 FUNCTION repl_rowcols(t, dist)
353 INTEGER,
INTENT(IN) :: dist
355 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: repl_rowcols, rowcols_tmp
357 INTEGER :: rowcol, count
360 igroup = dist/t%dist_size
362 nrowcols = t%nmrowcol_local
364 ALLOCATE (rowcols_tmp(nrowcols))
366 DO rowcol = 1, nrowcols
367 cond = t%dist_vec(rowcol) + igroup*t%dist_size == dist
371 rowcols_tmp(count) = rowcol
375 ALLOCATE (repl_rowcols(count))
376 repl_rowcols(:) = rowcols_tmp(1:count) + igroup*t%nmrowcol_local
387 FUNCTION arb_rowcols(t, dist)
389 INTEGER,
INTENT(IN) :: dist
390 INTEGER(KIND=int_8) :: rowcol, nrowcols
391 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: arb_rowcols, rowcols_tmp
394 nrowcols = t%nmrowcol
396 ALLOCATE (rowcols_tmp(nrowcols))
398 DO rowcol = 1, nrowcols
399 IF (t%dist_vec(rowcol) == dist)
THEN
401 rowcols_tmp(count) = rowcol
405 ALLOCATE (arb_rowcols(count))
406 arb_rowcols(:) = rowcols_tmp(1:count)
417 FUNCTION new_block_tas_dist_cyclic(split_size, nprowcol, nmrowcol)
418 INTEGER,
INTENT(IN) :: split_size, nprowcol
419 INTEGER(KIND=int_8),
INTENT(IN) :: nmrowcol
422 new_block_tas_dist_cyclic%split_size = split_size
423 new_block_tas_dist_cyclic%nprowcol = nprowcol
424 new_block_tas_dist_cyclic%nmrowcol = nmrowcol
435 FUNCTION new_block_tas_dist_arb(dist_vec, nprowcol, nmrowcol)
436 INTEGER,
DIMENSION(:),
INTENT(IN) :: dist_vec
437 INTEGER,
INTENT(IN) :: nprowcol
438 INTEGER(KIND=int_8),
INTENT(IN) :: nmrowcol
441 ALLOCATE (new_block_tas_dist_arb%dist_vec(nmrowcol))
442 new_block_tas_dist_arb%dist_vec(:) = dist_vec(:)
443 new_block_tas_dist_arb%nprowcol = nprowcol
444 new_block_tas_dist_arb%nmrowcol = nmrowcol
460 INTEGER(KIND=int_8),
INTENT(IN) :: nmrowcol
464 INTEGER,
DIMENSION(nmrowcol) :: dist_vec, bsize_vec
465 INTEGER(KIND=int_8) :: ind
468 bsize_vec(ind) = dbt_sizes%data(ind)
485 INTEGER,
INTENT(IN) :: nblk, nproc
486 INTEGER,
DIMENSION(nblk),
INTENT(IN) :: blk_size
487 INTEGER,
DIMENSION(nblk),
INTENT(OUT) :: dist
489 CALL distribute_lpt_random(nblk, nproc, blk_size, dist)
504 SUBROUTINE distribute_lpt_random(nel, nbin, weights, dist)
506 INTEGER,
INTENT(IN) :: nel, nbin
507 INTEGER,
DIMENSION(nel),
INTENT(IN) :: weights
508 INTEGER,
DIMENSION(nel),
INTENT(OUT) :: dist
510 INTEGER,
PARAMETER :: n_idle = 1000
512 INTEGER :: i, i_select, ibin, iel, min_occup, &
514 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: bins_avail
515 INTEGER,
DIMENSION(4) :: iseed
516 INTEGER,
DIMENSION(nel) :: sort_index, weights_s
517 INTEGER,
DIMENSION(nbin) :: occup
518 LOGICAL,
DIMENSION(nbin) :: bin_mask
522 iseed(1) = nel; iseed(2) = nbin; iseed(3) = maxval(weights); iseed(4) = minval(weights)
524 iseed(4) = iseed(4)*2 + 1
526 iseed(:) =
modulo(iseed(:), 2**12)
529 CALL dlarnv(1, iseed, 1, rand)
534 CALL sort(weights_s, nel, sort_index)
538 min_occup = minval(occup, 1)
541 bin_mask = occup == min_occup
542 n_avail = count(bin_mask)
543 ALLOCATE (bins_avail(n_avail))
544 bins_avail(:) = pack((/(i, i=1, nbin)/), mask=bin_mask)
546 CALL dlarnv(1, iseed, 1, rand)
547 i_select = floor(rand*n_avail) + 1
548 ibin = bins_avail(i_select)
549 DEALLOCATE (bins_avail)
551 dist(sort_index(iel)) = ibin - 1
552 occup(ibin) = occup(ibin) + weights_s(iel)
567 FUNCTION new_block_tas_dist_repl(dist_vec, nprowcol, nmrowcol, n_repl, dist_size)
568 INTEGER,
DIMENSION(:),
INTENT(IN) :: dist_vec
569 INTEGER,
INTENT(IN) :: nprowcol, nmrowcol, n_repl, dist_size
572 new_block_tas_dist_repl%n_repl = n_repl
573 new_block_tas_dist_repl%dist_size = dist_size
574 ALLOCATE (new_block_tas_dist_repl%dist_vec(nmrowcol))
575 new_block_tas_dist_repl%dist_vec(:) = mod(dist_vec(:), dist_size)
576 new_block_tas_dist_repl%nprowcol = nprowcol
577 new_block_tas_dist_repl%nmrowcol_local = nmrowcol
578 new_block_tas_dist_repl%nmrowcol = nmrowcol*n_repl
588 FUNCTION cyclic_dist(t, rowcol)
590 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
591 INTEGER :: cyclic_dist
593 cyclic_dist = int(mod((rowcol - 1)/int(t%split_size, kind=
int_8), int(t%nprowcol, kind=
int_8)))
604 FUNCTION cyclic_rowcols(t, dist)
606 INTEGER,
INTENT(IN) :: dist
607 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: cyclic_rowcols
608 INTEGER :: count, nsplit, isplit, irowcol, max_size
609 INTEGER(KIND=int_8) :: rowcol
610 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: rowcols_tmp
612 nsplit = int((t%nmrowcol - 1)/int(t%split_size, kind=
int_8) + 1_int_8)
613 max_size = nsplit*t%split_size
614 ALLOCATE (rowcols_tmp(max_size))
617 loop:
DO isplit = 1, nsplit
618 DO irowcol = 1, t%split_size
619 rowcol = int((dist + (isplit - 1)*t%nprowcol), kind=
int_8)*int(t%split_size, kind=
int_8) + &
620 int(irowcol, kind=
int_8)
621 IF (rowcol > t%nmrowcol)
THEN
625 rowcols_tmp(count) = rowcol
630 ALLOCATE (cyclic_rowcols(count))
631 cyclic_rowcols(:) = rowcols_tmp(1:count)
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
map matrix rows/cols to distribution rows/cols
Global data (distribution and block sizes) for tall-and-skinny matrices For very sparse matrices with...
subroutine, public dbt_tas_default_distvec(nblk, nproc, blk_size, dist)
get a load-balanced and randomized distribution along one tensor dimension
type(dbt_tas_dist_arb) function, public dbt_tas_dist_arb_default(nprowcol, nmrowcol, dbt_sizes)
Distribution that is more or less cyclic (round robin) and load balanced with different weights for e...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
All kind of helpful little routines.
type for arbitrary block sizes
type for blocks of size one
type for replicated block sizes
type for arbitrary distributions
type for cyclic (round robin) distribution:
type for replicated distribution