21 #include "../../base/base_uses.f90"
26 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbt_tas_global'
29 dbt_tas_blk_size_arb, &
30 dbt_tas_blk_size_repl, &
31 dbt_tas_blk_size_one, &
34 dbt_tas_dist_cyclic, &
36 dbt_tas_distribution, &
37 dbt_tas_rowcol_data, &
47 TYPE,
ABSTRACT :: dbt_tas_distribution
48 INTEGER :: nprowcol = -1
49 INTEGER(KIND=int_8) :: nmrowcol = -1
51 PROCEDURE(rowcol_dist),
deferred :: dist
52 PROCEDURE(dist_rowcols),
deferred :: rowcols
60 TYPE,
EXTENDS(dbt_tas_distribution) :: dbt_tas_dist_cyclic
61 INTEGER :: split_size = -1
63 PROCEDURE :: dist => cyclic_dist
64 PROCEDURE :: rowcols => cyclic_rowcols
72 TYPE,
EXTENDS(dbt_tas_distribution) :: dbt_tas_dist_arb
73 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_vec
75 PROCEDURE :: dist => arb_dist
76 PROCEDURE :: rowcols => arb_rowcols
84 TYPE,
EXTENDS(dbt_tas_distribution) :: dbt_tas_dist_repl
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
100 TYPE,
ABSTRACT :: dbt_tas_rowcol_data
101 INTEGER(KIND=int_8) :: nmrowcol = -1
102 INTEGER(KIND=int_8) :: nfullrowcol = -1
104 PROCEDURE(rowcol_data),
deferred :: DATA
112 TYPE,
EXTENDS(dbt_tas_rowcol_data) :: dbt_tas_blk_size_arb
113 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_vec
115 PROCEDURE :: DATA => blk_size_arb
123 TYPE,
EXTENDS(dbt_tas_rowcol_data) :: dbt_tas_blk_size_repl
124 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_vec
125 INTEGER :: nmrowcol_local = -1
127 PROCEDURE :: DATA => blk_size_repl
134 TYPE,
EXTENDS(dbt_tas_rowcol_data) :: dbt_tas_blk_size_one
136 PROCEDURE :: DATA => blk_size_one
147 FUNCTION rowcol_dist(t, rowcol)
148 IMPORT :: dbt_tas_distribution,
int_8
149 CLASS(dbt_tas_distribution),
INTENT(IN) :: t
150 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
151 INTEGER :: rowcol_dist
160 FUNCTION dist_rowcols(t, dist)
161 IMPORT :: dbt_tas_distribution,
int_8
162 CLASS(dbt_tas_distribution),
INTENT(IN) :: t
163 INTEGER,
INTENT(IN) :: dist
164 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: dist_rowcols
173 FUNCTION rowcol_data(t, rowcol)
174 IMPORT :: dbt_tas_rowcol_data,
int_8
175 CLASS(dbt_tas_rowcol_data),
INTENT(IN) :: t
176 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
177 INTEGER :: rowcol_data
182 INTERFACE dbt_tas_dist_cyclic
183 MODULE PROCEDURE new_block_tas_dist_cyclic
186 INTERFACE dbt_tas_dist_arb
187 MODULE PROCEDURE new_block_tas_dist_arb
190 INTERFACE dbt_tas_dist_repl
191 MODULE PROCEDURE new_block_tas_dist_repl
194 INTERFACE dbt_tas_blk_size_arb
195 MODULE PROCEDURE new_block_tas_blk_size_arb
198 INTERFACE dbt_tas_blk_size_repl
199 MODULE PROCEDURE new_block_tas_blk_size_repl
202 INTERFACE dbt_tas_blk_size_one
203 MODULE PROCEDURE new_block_tas_blk_size_one
215 FUNCTION blk_size_arb(t, rowcol)
216 CLASS(dbt_tas_blk_size_arb),
INTENT(IN) :: t
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)
230 CLASS(dbt_tas_blk_size_repl),
INTENT(IN) :: t
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)
250 CLASS(dbt_tas_blk_size_one),
INTENT(IN) :: t
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
267 TYPE(dbt_tas_blk_size_arb) :: new_block_tas_blk_size_arb
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
285 TYPE(dbt_tas_blk_size_repl) :: new_block_tas_blk_size_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
302 TYPE(dbt_tas_blk_size_one) :: new_block_tas_blk_size_one
304 new_block_tas_blk_size_one%nmrowcol = nrowcol
305 new_block_tas_blk_size_one%nfullrowcol = nrowcol
315 FUNCTION arb_dist(t, rowcol)
316 CLASS(dbt_tas_dist_arb),
INTENT(IN) :: t
317 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
320 arb_dist = t%dist_vec(rowcol)
330 FUNCTION repl_dist(t, rowcol)
331 CLASS(dbt_tas_dist_repl),
INTENT(IN) :: t
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)
352 CLASS(dbt_tas_dist_repl),
INTENT(IN) :: t
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)
388 CLASS(dbt_tas_dist_arb),
INTENT(IN) :: t
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
420 TYPE(dbt_tas_dist_cyclic) :: new_block_tas_dist_cyclic
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
439 TYPE(dbt_tas_dist_arb) :: new_block_tas_dist_arb
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
462 CLASS(dbt_tas_rowcol_data),
INTENT(IN) :: dbt_sizes
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
570 TYPE(dbt_tas_dist_repl) :: new_block_tas_dist_repl
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)
589 CLASS(dbt_tas_dist_cyclic),
INTENT(IN) :: t
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)
605 CLASS(dbt_tas_dist_cyclic),
INTENT(IN) :: t
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....
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.