45#include "../base/base_uses.f90"
49 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbt_types'
100 INTEGER :: nproc = -1
104 REAL(
dp) :: nsplit_avg = 0.0_dp
105 INTEGER :: ibatch = -1
107 LOGICAL :: static = .false.
119 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nblks_local
120 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nfull_local
121 LOGICAL :: valid = .false.
122 LOGICAL :: owns_matrix = .false.
123 CHARACTER(LEN=default_string_length) :: name =
""
125 INTEGER,
POINTER :: refcount => null()
134 INTEGER,
POINTER :: refcount => null()
146 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dims
147 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dims_grid
150 PROCEDURE :: dist => tas_dist_t
151 PROCEDURE :: rowcols => tas_rowcols_t
160 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dims
163 PROCEDURE :: data => tas_blk_size_t
167 MODULE PROCEDURE dbt_create_new
168 MODULE PROCEDURE dbt_create_template
169 MODULE PROCEDURE dbt_create_matrix
172 INTERFACE dbt_tas_dist_t
173 MODULE PROCEDURE new_dbt_tas_dist_t
176 INTERFACE dbt_tas_blk_size_t
177 MODULE PROCEDURE new_dbt_tas_blk_size_t
191 FUNCTION new_dbt_tas_dist_t(nd_dist, map_blks, map_grid, which_dim)
192 TYPE(array_list),
INTENT(IN) :: nd_dist
193 TYPE(nd_to_2d_mapping),
INTENT(IN) :: map_blks, map_grid
194 INTEGER,
INTENT(IN) :: which_dim
196 TYPE(dbt_tas_dist_t) :: new_dbt_tas_dist_t
197 INTEGER,
DIMENSION(2) :: grid_dims
198 INTEGER(KIND=int_8),
DIMENSION(2) :: matrix_dims
199 INTEGER,
DIMENSION(:),
ALLOCATABLE :: index_map
201 IF (which_dim == 1)
THEN
205 dims_2d_i8=matrix_dims, &
207 dims1_2d=new_dbt_tas_dist_t%dims)
211 dims1_2d=new_dbt_tas_dist_t%dims_grid)
212 ELSEIF (which_dim == 2)
THEN
216 dims_2d_i8=matrix_dims, &
218 dims2_2d=new_dbt_tas_dist_t%dims)
222 dims2_2d=new_dbt_tas_dist_t%dims_grid)
224 cpabort(
"Unknown value for which_dim")
227 new_dbt_tas_dist_t%nd_dist =
array_sublist(nd_dist, index_map)
228 new_dbt_tas_dist_t%nprowcol = grid_dims(which_dim)
229 new_dbt_tas_dist_t%nmrowcol = matrix_dims(which_dim)
235 FUNCTION tas_dist_t(t, rowcol)
236 CLASS(dbt_tas_dist_t),
INTENT(IN) :: t
237 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
238 INTEGER,
DIMENSION(4) :: ind_blk
239 INTEGER,
DIMENSION(4) :: dist_blk
240 INTEGER :: tas_dist_t
250 FUNCTION tas_rowcols_t(t, dist)
251 CLASS(dbt_tas_dist_t),
INTENT(IN) :: t
252 INTEGER,
INTENT(IN) :: dist
253 INTEGER(KIND=int_8),
DIMENSION(:),
ALLOCATABLE :: tas_rowcols_t
254 INTEGER,
DIMENSION(4) :: dist_blk
255 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_1, dist_2, dist_3, dist_4, blks_1, blks_2, blks_3, blks_4, blks_tmp, nd_ind
256 INTEGER :: i_1, i_2, i_3, i_4, i, iblk, iblk_count, nblks
257 INTEGER(KIND=int_8) :: nrowcols
258 TYPE(array_list) :: blks
262 IF (
SIZE(t%dims) == 1)
THEN
265 IF (
SIZE(t%dims) == 2)
THEN
268 IF (
SIZE(t%dims) == 3)
THEN
269 CALL get_arrays(t%nd_dist, dist_1, dist_2, dist_3)
271 IF (
SIZE(t%dims) == 4)
THEN
272 CALL get_arrays(t%nd_dist, dist_1, dist_2, dist_3, dist_4)
275 IF (
SIZE(t%dims) .GE. 1)
THEN
277 ALLOCATE (blks_tmp(nblks))
280 IF (dist_1(iblk) == dist_blk(1))
THEN
281 iblk_count = iblk_count + 1
282 blks_tmp(iblk_count) = iblk
285 ALLOCATE (blks_1(iblk_count))
286 blks_1(:) = blks_tmp(:iblk_count)
287 DEALLOCATE (blks_tmp)
289 IF (
SIZE(t%dims) .GE. 2)
THEN
291 ALLOCATE (blks_tmp(nblks))
294 IF (dist_2(iblk) == dist_blk(2))
THEN
295 iblk_count = iblk_count + 1
296 blks_tmp(iblk_count) = iblk
299 ALLOCATE (blks_2(iblk_count))
300 blks_2(:) = blks_tmp(:iblk_count)
301 DEALLOCATE (blks_tmp)
303 IF (
SIZE(t%dims) .GE. 3)
THEN
305 ALLOCATE (blks_tmp(nblks))
308 IF (dist_3(iblk) == dist_blk(3))
THEN
309 iblk_count = iblk_count + 1
310 blks_tmp(iblk_count) = iblk
313 ALLOCATE (blks_3(iblk_count))
314 blks_3(:) = blks_tmp(:iblk_count)
315 DEALLOCATE (blks_tmp)
317 IF (
SIZE(t%dims) .GE. 4)
THEN
319 ALLOCATE (blks_tmp(nblks))
322 IF (dist_4(iblk) == dist_blk(4))
THEN
323 iblk_count = iblk_count + 1
324 blks_tmp(iblk_count) = iblk
327 ALLOCATE (blks_4(iblk_count))
328 blks_4(:) = blks_tmp(:iblk_count)
329 DEALLOCATE (blks_tmp)
332 IF (
SIZE(t%dims) == 1)
THEN
335 IF (
SIZE(t%dims) == 2)
THEN
338 IF (
SIZE(t%dims) == 3)
THEN
341 IF (
SIZE(t%dims) == 4)
THEN
346 ALLOCATE (tas_rowcols_t(nrowcols))
348 IF (
SIZE(t%dims) == 1)
THEN
351 DO i_1 = 1,
SIZE(blks_1)
358 IF (
SIZE(t%dims) == 2)
THEN
361 DO i_1 = 1,
SIZE(blks_1)
362 DO i_2 = 1,
SIZE(blks_2)
370 IF (
SIZE(t%dims) == 3)
THEN
373 DO i_1 = 1,
SIZE(blks_1)
374 DO i_2 = 1,
SIZE(blks_2)
375 DO i_3 = 1,
SIZE(blks_3)
384 IF (
SIZE(t%dims) == 4)
THEN
387 DO i_1 = 1,
SIZE(blks_1)
388 DO i_2 = 1,
SIZE(blks_2)
389 DO i_3 = 1,
SIZE(blks_3)
390 DO i_4 = 1,
SIZE(blks_4)
411 FUNCTION new_dbt_tas_blk_size_t(blk_size, map_blks, which_dim)
412 TYPE(array_list),
INTENT(IN) :: blk_size
413 TYPE(nd_to_2d_mapping),
INTENT(IN) :: map_blks
414 INTEGER,
INTENT(IN) :: which_dim
415 INTEGER(KIND=int_8),
DIMENSION(2) :: matrix_dims
416 INTEGER,
DIMENSION(:),
ALLOCATABLE :: index_map
417 TYPE(dbt_tas_blk_size_t) :: new_dbt_tas_blk_size_t
419 IF (which_dim == 1)
THEN
423 dims_2d_i8=matrix_dims, &
425 dims1_2d=new_dbt_tas_blk_size_t%dims)
426 ELSEIF (which_dim == 2)
THEN
430 dims_2d_i8=matrix_dims, &
432 dims2_2d=new_dbt_tas_blk_size_t%dims)
434 cpabort(
"Unknown value for which_dim")
437 new_dbt_tas_blk_size_t%blk_size =
array_sublist(blk_size, index_map)
438 new_dbt_tas_blk_size_t%nmrowcol = matrix_dims(which_dim)
440 new_dbt_tas_blk_size_t%nfullrowcol = product(int(
sum_of_arrays(new_dbt_tas_blk_size_t%blk_size), &
447 FUNCTION tas_blk_size_t(t, rowcol)
448 CLASS(dbt_tas_blk_size_t),
INTENT(IN) :: t
449 INTEGER(KIND=int_8),
INTENT(IN) :: rowcol
450 INTEGER :: tas_blk_size_t
451 INTEGER,
DIMENSION(SIZE(t%dims)) :: ind_blk
452 INTEGER,
DIMENSION(SIZE(t%dims)) :: blk_size
456 tas_blk_size_t = product(blk_size)
469 PURE FUNCTION accept_pdims_loadbalancing(pdims_avail, pdim, tdim, lb_ratio)
470 INTEGER,
INTENT(IN) :: pdims_avail
471 INTEGER,
INTENT(IN) :: pdim
472 INTEGER,
INTENT(IN) :: tdim
473 REAL(dp),
INTENT(IN) :: lb_ratio
474 LOGICAL :: accept_pdims_loadbalancing
476 accept_pdims_loadbalancing = .false.
477 IF (mod(pdims_avail, pdim) == 0)
THEN
478 IF (real(tdim, dp)*lb_ratio < real(pdim, dp))
THEN
479 IF (mod(tdim, pdim) == 0) accept_pdims_loadbalancing = .true.
481 accept_pdims_loadbalancing = .true.
498 INTEGER,
INTENT(IN) :: nodes
499 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: dims
500 INTEGER,
DIMENSION(:),
INTENT(IN) :: tensor_dims
501 REAL(
dp),
INTENT(IN),
OPTIONAL :: lb_ratio
503 INTEGER,
DIMENSION(:),
ALLOCATABLE :: tensor_dims_sorted, sort_indices, dims_store
504 REAL(
dp),
DIMENSION(:),
ALLOCATABLE :: sort_key
505 INTEGER :: pdims_rem, idim, pdim
506 REAL(
dp) :: lb_ratio_prv
508 IF (
PRESENT(lb_ratio))
THEN
509 lb_ratio_prv = lb_ratio
511 lb_ratio_prv = 0.1_dp
514 ALLOCATE (dims_store, source=dims)
517 IF (any(dims == 0))
THEN
522 ALLOCATE (sort_key(
SIZE(tensor_dims)))
523 sort_key(:) = real(tensor_dims,
dp)/dims
525 ALLOCATE (tensor_dims_sorted, source=tensor_dims)
526 ALLOCATE (sort_indices(
SIZE(sort_key)))
527 CALL sort(sort_key,
SIZE(sort_key), sort_indices)
528 tensor_dims_sorted(:) = tensor_dims_sorted(sort_indices)
529 dims(:) = dims(sort_indices)
534 DO idim = 1,
SIZE(tensor_dims_sorted)
535 IF (.NOT. accept_pdims_loadbalancing(pdims_rem, dims(idim), tensor_dims_sorted(idim), lb_ratio_prv))
THEN
536 pdim = tensor_dims_sorted(idim)
537 DO WHILE (.NOT. accept_pdims_loadbalancing(pdims_rem, pdim, tensor_dims_sorted(idim), lb_ratio_prv))
541 pdims_rem = pdims_rem/dims(idim)
543 IF (idim .NE.
SIZE(tensor_dims_sorted))
THEN
546 ELSEIF (lb_ratio_prv < 0.5_dp)
THEN
559 pdims_rem = pdims_rem/dims(idim)
563 dims(sort_indices) = dims
595 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: dims
597 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d, map2_2d
598 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: tensor_dims
599 INTEGER,
INTENT(IN),
OPTIONAL :: nsplit, dimsplit
600 INTEGER,
DIMENSION(2) :: pdims_2d
601 INTEGER :: nproc, ndims, handle
604 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_pgrid_create_expert'
606 CALL timeset(routinen, handle)
610 nproc = mp_comm%num_pe
611 IF (any(dims == 0))
THEN
612 IF (.NOT.
PRESENT(tensor_dims))
THEN
620 CALL pgrid%mp_comm_2d%create(mp_comm, 2, pdims_2d)
622 IF (
PRESENT(nsplit))
THEN
623 cpassert(
PRESENT(dimsplit))
625 ALLOCATE (pgrid%tas_split_info, source=info)
631 CALL timestop(handle)
651 FUNCTION dbt_nd_mp_comm(comm_2d, map1_2d, map2_2d, dims_nd, dims1_nd, dims2_nd, pdims_2d, tdims, &
654 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d, map2_2d
655 INTEGER,
DIMENSION(SIZE(map1_2d) + SIZE(map2_2d)), &
656 INTENT(IN),
OPTIONAL :: dims_nd
657 INTEGER,
DIMENSION(SIZE(map1_2d)),
INTENT(IN),
OPTIONAL :: dims1_nd
658 INTEGER,
DIMENSION(SIZE(map2_2d)),
INTENT(IN),
OPTIONAL :: dims2_nd
659 INTEGER,
DIMENSION(2),
INTENT(IN),
OPTIONAL :: pdims_2d
660 INTEGER,
DIMENSION(SIZE(map1_2d) + SIZE(map2_2d)), &
661 INTENT(IN),
OPTIONAL :: tdims
662 INTEGER,
INTENT(IN),
OPTIONAL :: nsplit, dimsplit
663 INTEGER :: ndim1, ndim2
664 INTEGER,
DIMENSION(2) :: dims_2d
666 INTEGER,
DIMENSION(SIZE(map1_2d)) :: dims1_nd_prv
667 INTEGER,
DIMENSION(SIZE(map2_2d)) :: dims2_nd_prv
668 INTEGER,
DIMENSION(SIZE(map1_2d) + SIZE(map2_2d)) :: dims_nd_prv
670 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_nd_mp_comm'
673 CALL timeset(routinen, handle)
675 ndim1 =
SIZE(map1_2d); ndim2 =
SIZE(map2_2d)
677 IF (
PRESENT(pdims_2d))
THEN
678 dims_2d(:) = pdims_2d
682 SELECT TYPE (comm_2d)
684 dims_2d = comm_2d%num_pe_cart
686 CALL cp_abort(__location__,
"If the argument pdims_2d is not given, the "// &
687 "communicator comm_2d must be of class mp_cart_type.")
691 IF (.NOT.
PRESENT(dims_nd))
THEN
692 dims1_nd_prv = 0; dims2_nd_prv = 0
693 IF (
PRESENT(dims1_nd))
THEN
694 dims1_nd_prv(:) = dims1_nd
697 IF (
PRESENT(tdims))
THEN
704 IF (
PRESENT(dims2_nd))
THEN
705 dims2_nd_prv(:) = dims2_nd
707 IF (
PRESENT(tdims))
THEN
713 dims_nd_prv(map1_2d) = dims1_nd_prv
714 dims_nd_prv(map2_2d) = dims2_nd_prv
716 cpassert(product(dims_nd(map1_2d)) == dims_2d(1))
717 cpassert(product(dims_nd(map2_2d)) == dims_2d(2))
718 dims_nd_prv = dims_nd
722 tensor_dims=tdims, map1_2d=map1_2d, map2_2d=map2_2d, nsplit=nsplit, dimsplit=dimsplit)
724 CALL timestop(handle)
744 SUBROUTINE dbt_pgrid_remap(pgrid_in, map1_2d, map2_2d, pgrid_out)
746 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d, map2_2d
748 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dims
749 INTEGER,
DIMENSION(ndims_mapping_row(pgrid_in%nd_index_grid)) :: map1_2d_old
750 INTEGER,
DIMENSION(ndims_mapping_column(pgrid_in%nd_index_grid)) :: map2_2d_old
752 ALLOCATE (dims(
SIZE(map1_2d) +
SIZE(map2_2d)))
753 CALL dbt_get_mapping_info(pgrid_in%nd_index_grid, dims_nd=dims, map1_2d=map1_2d_old, map2_2d=map2_2d_old)
755 IF (array_eq_i(map1_2d_old, map1_2d) .AND. array_eq_i(map2_2d_old, map2_2d))
THEN
756 IF (
ALLOCATED(pgrid_in%tas_split_info))
THEN
757 ALLOCATE (pgrid_out%tas_split_info, source=pgrid_in%tas_split_info)
769 INTEGER,
DIMENSION(ndims_mapping(pgrid%nd_index_grid)),
INTENT(OUT) :: dims
770 INTEGER,
DIMENSION(ndims_mapping(pgrid%nd_index_grid)),
INTENT(OUT) :: task_coor
771 INTEGER,
DIMENSION(2) :: task_coor_2d
773 task_coor_2d = pgrid%mp_comm_2d%mepos_cart
789 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d
790 INTEGER,
DIMENSION(:),
INTENT(IN) :: map2_2d
791 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: nd_dist_1, nd_dist_2, nd_dist_3, nd_dist_4
792 LOGICAL,
INTENT(IN),
OPTIONAL :: own_comm
795 INTEGER,
DIMENSION(2) :: pdims_2d_check, &
797 INTEGER,
DIMENSION(SIZE(map1_2d) + SIZE(map2_2d)) :: dims, nblks_nd, task_coor
801 TYPE(dbt_tas_dist_t) :: row_dist_obj, col_dist_obj
803 LOGICAL :: need_pgrid_remap
804 INTEGER,
DIMENSION(ndims_mapping_row(pgrid%nd_index_grid)) :: map1_2d_check
805 INTEGER,
DIMENSION(ndims_mapping_column(pgrid%nd_index_grid)) :: map2_2d_check
806 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_distribution_new_expert'
808 CALL timeset(routinen, handle)
809 ndims =
SIZE(map1_2d) +
SIZE(map2_2d)
810 cpassert(ndims .GE. 2 .AND. ndims .LE. 4)
812 CALL create_array_list(nd_dist, ndims, nd_dist_1, nd_dist_2, nd_dist_3, nd_dist_4)
816 need_pgrid_remap = .true.
817 IF (
PRESENT(own_comm))
THEN
820 IF (.NOT. array_eq_i(map1_2d_check, map1_2d) .OR. .NOT. array_eq_i(map2_2d_check, map2_2d))
THEN
821 cpabort(
"map1_2d / map2_2d are not consistent with pgrid")
824 need_pgrid_remap = .false.
828 IF (need_pgrid_remap)
CALL dbt_pgrid_remap(pgrid, map1_2d, map2_2d, pgrid_prv)
839 row_dist_obj = dbt_tas_dist_t(nd_dist, map_blks, map_grid, 1)
840 col_dist_obj = dbt_tas_dist_t(nd_dist, map_blks, map_grid, 2)
844 comm_2d = pgrid_prv%mp_comm_2d
846 pdims_2d_check = comm_2d%num_pe_cart
847 IF (any(pdims_2d_check .NE. pdims_2d))
THEN
848 cpabort(
"inconsistent process grid dimensions")
851 IF (
ALLOCATED(pgrid_prv%tas_split_info))
THEN
855 ALLOCATE (pgrid_prv%tas_split_info, source=dist%dist%info)
859 dist%nd_dist = nd_dist
860 dist%pgrid = pgrid_prv
862 ALLOCATE (dist%refcount)
864 CALL timestop(handle)
877 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: nd_dist_1, nd_dist_2, nd_dist_3, nd_dist_4
878 INTEGER,
DIMENSION(ndims_mapping_row(pgrid%nd_index_grid)) :: map1_2d
879 INTEGER,
DIMENSION(ndims_mapping_column(pgrid%nd_index_grid)) :: map2_2d
895 LOGICAL,
INTENT(IN),
OPTIONAL :: keep_comm
896 LOGICAL :: keep_comm_prv
897 IF (
PRESENT(keep_comm))
THEN
898 keep_comm_prv = keep_comm
900 keep_comm_prv = .false.
902 IF (.NOT. keep_comm_prv)
CALL pgrid%mp_comm_2d%free()
904 IF (
ALLOCATED(pgrid%tas_split_info) .AND. .NOT. keep_comm_prv)
THEN
906 DEALLOCATE (pgrid%tas_split_info)
917 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_distribution_destroy'
920 CALL timeset(routinen, handle)
925 IF (.NOT.
ASSOCIATED(dist%refcount))
THEN
927 ELSEIF (dist%refcount < 1)
THEN
932 cpabort(
"can not destroy non-existing tensor distribution")
935 dist%refcount = dist%refcount - 1
937 IF (dist%refcount == 0)
THEN
939 DEALLOCATE (dist%refcount)
944 CALL timestop(handle)
952 SUBROUTINE dbt_distribution_hold(dist)
954 INTEGER,
POINTER :: ref
956 IF (dist%refcount < 1)
THEN
957 cpabort(
"can not hold non-existing tensor distribution")
981 SUBROUTINE dbt_distribution_remap(dist_in, map1_2d, map2_2d, dist_out)
983 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d, map2_2d
985 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_1, dist_2, dist_3, dist_4
987 ndims =
SIZE(map1_2d) +
SIZE(map2_2d)
993 CALL get_arrays(dist_in%nd_dist, dist_1, dist_2)
997 CALL get_arrays(dist_in%nd_dist, dist_1, dist_2, dist_3)
1000 IF (ndims == 4)
THEN
1001 CALL get_arrays(dist_in%nd_dist, dist_1, dist_2, dist_3, dist_4)
1016 SUBROUTINE dbt_create_new(tensor, name, dist, map1_2d, map2_2d, &
1017 blk_size_1, blk_size_2, blk_size_3, blk_size_4)
1018 TYPE(
dbt_type),
INTENT(OUT) :: tensor
1019 CHARACTER(len=*),
INTENT(IN) :: name
1021 INTEGER,
DIMENSION(:),
INTENT(IN) :: map1_2d
1022 INTEGER,
DIMENSION(:),
INTENT(IN) :: map2_2d
1023 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: blk_size_1, blk_size_2, blk_size_3, blk_size_4
1025 INTEGER(KIND=int_8),
DIMENSION(2) :: dims_2d
1026 INTEGER,
DIMENSION(SIZE(map1_2d) + SIZE(map2_2d)) :: dims, pdims, task_coor
1027 TYPE(dbt_tas_blk_size_t) :: col_blk_size_obj, row_blk_size_obj
1032 CHARACTER(LEN=*),
PARAMETER :: routineN =
'dbt_create_new'
1033 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blks_local_1, blks_local_2, blks_local_3, blks_local_4
1034 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_1, dist_2, dist_3, dist_4
1035 INTEGER :: iblk_count, iblk
1036 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nblks_local, nfull_local
1038 CALL timeset(routinen, handle)
1039 ndims =
SIZE(map1_2d) +
SIZE(map2_2d)
1040 CALL create_array_list(blk_size, ndims, blk_size_1, blk_size_2, blk_size_3, blk_size_4)
1046 row_blk_size_obj = dbt_tas_blk_size_t(blk_size, map, 1)
1047 col_blk_size_obj = dbt_tas_blk_size_t(blk_size, map, 2)
1049 CALL dbt_distribution_remap(dist, map1_2d, map2_2d, dist_new)
1051 ALLOCATE (tensor%matrix_rep)
1053 name=trim(name)//
" matrix", &
1054 dist=dist_new%dist, &
1055 row_blk_size=row_blk_size_obj, &
1056 col_blk_size=col_blk_size_obj)
1058 tensor%owns_matrix = .true.
1060 tensor%nd_index_blk = map
1068 tensor%nd_index = map
1069 tensor%blk_sizes = blk_size
1073 IF (ndims == 1)
THEN
1076 IF (ndims == 2)
THEN
1077 CALL get_arrays(dist_new%nd_dist, dist_1, dist_2)
1079 IF (ndims == 3)
THEN
1080 CALL get_arrays(dist_new%nd_dist, dist_1, dist_2, dist_3)
1082 IF (ndims == 4)
THEN
1083 CALL get_arrays(dist_new%nd_dist, dist_1, dist_2, dist_3, dist_4)
1086 ALLOCATE (nblks_local(ndims))
1087 ALLOCATE (nfull_local(ndims))
1089 IF (ndims .GE. 1)
THEN
1090 nblks_local(1) = count(dist_1 == task_coor(1))
1091 ALLOCATE (blks_local_1(nblks_local(1)))
1093 DO iblk = 1,
SIZE(dist_1)
1094 IF (dist_1(iblk) == task_coor(1))
THEN
1095 iblk_count = iblk_count + 1
1096 blks_local_1(iblk_count) = iblk
1097 nfull_local(1) = nfull_local(1) + blk_size_1(iblk)
1101 IF (ndims .GE. 2)
THEN
1102 nblks_local(2) = count(dist_2 == task_coor(2))
1103 ALLOCATE (blks_local_2(nblks_local(2)))
1105 DO iblk = 1,
SIZE(dist_2)
1106 IF (dist_2(iblk) == task_coor(2))
THEN
1107 iblk_count = iblk_count + 1
1108 blks_local_2(iblk_count) = iblk
1109 nfull_local(2) = nfull_local(2) + blk_size_2(iblk)
1113 IF (ndims .GE. 3)
THEN
1114 nblks_local(3) = count(dist_3 == task_coor(3))
1115 ALLOCATE (blks_local_3(nblks_local(3)))
1117 DO iblk = 1,
SIZE(dist_3)
1118 IF (dist_3(iblk) == task_coor(3))
THEN
1119 iblk_count = iblk_count + 1
1120 blks_local_3(iblk_count) = iblk
1121 nfull_local(3) = nfull_local(3) + blk_size_3(iblk)
1125 IF (ndims .GE. 4)
THEN
1126 nblks_local(4) = count(dist_4 == task_coor(4))
1127 ALLOCATE (blks_local_4(nblks_local(4)))
1129 DO iblk = 1,
SIZE(dist_4)
1130 IF (dist_4(iblk) == task_coor(4))
THEN
1131 iblk_count = iblk_count + 1
1132 blks_local_4(iblk_count) = iblk
1133 nfull_local(4) = nfull_local(4) + blk_size_4(iblk)
1138 IF (ndims == 1)
THEN
1141 IF (ndims == 2)
THEN
1144 IF (ndims == 3)
THEN
1147 IF (ndims == 4)
THEN
1148 CALL create_array_list(blks_local, 4, blks_local_1, blks_local_2, blks_local_3, blks_local_4)
1151 ALLOCATE (tensor%nblks_local(ndims))
1152 ALLOCATE (tensor%nfull_local(ndims))
1153 tensor%nblks_local(:) = nblks_local
1154 tensor%nfull_local(:) = nfull_local
1156 tensor%blks_local = blks_local
1158 tensor%nd_dist = dist_new%nd_dist
1159 tensor%pgrid = dist_new%pgrid
1161 CALL dbt_distribution_hold(dist_new)
1162 tensor%refcount => dist_new%refcount
1167 tensor%valid = .true.
1168 CALL timestop(handle)
1178 INTEGER,
POINTER :: ref
1180 IF (
tensor%refcount < 1)
THEN
1181 cpabort(
"can not hold non-existing tensor")
1228 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1232 dims =
tensor%nd_index%dims_nd
1239 SUBROUTINE dbt_create_template(tensor_in, tensor, name, dist, map1_2d, map2_2d)
1240 TYPE(
dbt_type),
INTENT(INOUT) :: tensor_in
1241 TYPE(
dbt_type),
INTENT(OUT) :: tensor
1242 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
1244 INTENT(INOUT),
OPTIONAL :: dist
1245 INTEGER,
DIMENSION(:),
INTENT(IN), &
1246 OPTIONAL :: map1_2d, map2_2d
1248 CHARACTER(LEN=*),
PARAMETER :: routineN =
'dbt_create_template'
1249 INTEGER,
DIMENSION(:),
ALLOCATABLE :: bsize_1, bsize_2, bsize_3, bsize_4
1250 INTEGER,
DIMENSION(:),
ALLOCATABLE :: map1_2d_prv, map2_2d_prv
1251 CHARACTER(len=default_string_length) :: name_prv
1254 CALL timeset(routinen, handle)
1256 IF (
PRESENT(dist) .OR.
PRESENT(map1_2d) .OR.
PRESENT(map2_2d))
THEN
1258 IF (
PRESENT(dist))
THEN
1263 IF (
PRESENT(map1_2d) .AND.
PRESENT(map2_2d))
THEN
1264 ALLOCATE (map1_2d_prv, source=map1_2d)
1265 ALLOCATE (map2_2d_prv, source=map2_2d)
1271 IF (
PRESENT(name))
THEN
1274 name_prv = tensor_in%name
1278 CALL get_arrays(tensor_in%blk_sizes, bsize_1)
1279 CALL dbt_create(tensor, name_prv, dist_prv, map1_2d_prv, map2_2d_prv, &
1283 CALL get_arrays(tensor_in%blk_sizes, bsize_1, bsize_2)
1284 CALL dbt_create(tensor, name_prv, dist_prv, map1_2d_prv, map2_2d_prv, &
1288 CALL get_arrays(tensor_in%blk_sizes, bsize_1, bsize_2, bsize_3)
1289 CALL dbt_create(tensor, name_prv, dist_prv, map1_2d_prv, map2_2d_prv, &
1290 bsize_1, bsize_2, bsize_3)
1293 CALL get_arrays(tensor_in%blk_sizes, bsize_1, bsize_2, bsize_3, bsize_4)
1294 CALL dbt_create(tensor, name_prv, dist_prv, map1_2d_prv, map2_2d_prv, &
1295 bsize_1, bsize_2, bsize_3, bsize_4)
1299 ALLOCATE (tensor%matrix_rep)
1300 IF (.NOT.
PRESENT(name))
THEN
1302 name=trim(tensor_in%name)//
" matrix")
1304 CALL dbt_tas_create(tensor_in%matrix_rep, tensor%matrix_rep, name=trim(name)//
" matrix")
1306 tensor%owns_matrix = .true.
1309 tensor%nd_index_blk = tensor_in%nd_index_blk
1310 tensor%nd_index = tensor_in%nd_index
1311 tensor%blk_sizes = tensor_in%blk_sizes
1312 tensor%blk_offsets = tensor_in%blk_offsets
1313 tensor%nd_dist = tensor_in%nd_dist
1314 tensor%blks_local = tensor_in%blks_local
1316 tensor%nblks_local(:) = tensor_in%nblks_local
1318 tensor%nfull_local(:) = tensor_in%nfull_local
1319 tensor%pgrid = tensor_in%pgrid
1321 tensor%refcount => tensor_in%refcount
1324 tensor%valid = .true.
1325 IF (
PRESENT(name))
THEN
1328 tensor%name = tensor_in%name
1331 CALL timestop(handle)
1338 SUBROUTINE dbt_create_matrix(matrix_in, tensor, order, name)
1340 TYPE(
dbt_type),
INTENT(OUT) :: tensor
1341 INTEGER,
DIMENSION(2),
INTENT(IN),
OPTIONAL :: order
1342 CHARACTER(len=*),
INTENT(IN),
OPTIONAL :: name
1344 CHARACTER(len=default_string_length) :: name_in
1345 INTEGER,
DIMENSION(2) :: order_in
1349 INTEGER,
DIMENSION(:),
POINTER :: row_blk_size, col_blk_size
1350 INTEGER,
DIMENSION(:),
POINTER :: col_dist, row_dist
1351 INTEGER :: handle, comm_2d_handle
1352 CHARACTER(LEN=*),
PARAMETER :: routineN =
'dbt_create_matrix'
1354 INTEGER,
DIMENSION(2) :: pdims_2d
1356 CALL timeset(routinen, handle)
1358 NULLIFY (row_blk_size, col_blk_size, col_dist, row_dist)
1359 IF (
PRESENT(name))
THEN
1365 IF (
PRESENT(order))
THEN
1373 nprows=pdims_2d(1), npcols=pdims_2d(2))
1374 CALL comm_2d%set_handle(comm_2d_handle)
1375 comm_nd =
dbt_nd_mp_comm(comm_2d, [order_in(1)], [order_in(2)], pdims_2d=pdims_2d)
1380 [order_in(1)], [order_in(2)], &
1381 row_dist, col_dist, own_comm=.true.)
1383 CALL dbcsr_get_info(matrix_in, row_blk_size=row_blk_size, col_blk_size=col_blk_size)
1385 CALL dbt_create_new(tensor, name_in, dist, &
1386 [order_in(1)], [order_in(2)], &
1391 CALL timestop(handle)
1401 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_destroy'
1404 CALL timeset(routinen, handle)
1405 IF (
tensor%owns_matrix)
THEN
1407 DEALLOCATE (
tensor%matrix_rep)
1409 NULLIFY (
tensor%matrix_rep)
1411 tensor%owns_matrix = .false.
1424 IF (.NOT.
ASSOCIATED(
tensor%refcount))
THEN
1426 ELSEIF (
tensor%refcount < 1)
THEN
1431 cpabort(
"can not destroy non-existing tensor")
1436 IF (
tensor%refcount == 0)
THEN
1440 DEALLOCATE (
tensor%refcount)
1447 CALL timestop(handle)
1456 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1460 dims =
tensor%nd_index_blk%dims_nd
1469 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1471 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1472 INTENT(OUT) :: blk_size
1485 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1487 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1488 INTENT(OUT) :: blk_offset
1500 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1501 INTENT(IN) :: ind_nd
1502 INTEGER,
INTENT(OUT) :: processor
1504 INTEGER(KIND=int_8),
DIMENSION(2) :: ind_2d
1515 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: dims
1517 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: tensor_dims
1518 INTEGER,
DIMENSION(:),
ALLOCATABLE :: map1_2d, map2_2d
1523 ALLOCATE (map1_2d(ndims/2))
1524 ALLOCATE (map2_2d(ndims - ndims/2))
1525 map1_2d(:) = (/(i, i=1,
SIZE(map1_2d))/)
1526 map2_2d(:) = (/(i, i=
SIZE(map1_2d) + 1,
SIZE(map1_2d) +
SIZE(map2_2d))/)
1549 INTEGER,
DIMENSION(:),
INTENT(INOUT) :: pdims
1551 INTEGER :: nsplit, dimsplit
1552 INTEGER,
DIMENSION(ndims_mapping_row(pgrid%nd_index_grid)) :: map1_2d
1553 INTEGER,
DIMENSION(ndims_mapping_column(pgrid%nd_index_grid)) :: map2_2d
1555 INTEGER,
DIMENSION(2) :: pdims_2d
1557 cpassert(all(pdims > 0))
1562 IF (mod(pdims_2d(dimsplit), nsplit) == 0)
THEN
1564 nsplit=nsplit, dimsplit=dimsplit)
1578 REAL(
dp),
INTENT(IN) :: eps
1590 INTEGER,
INTENT(IN) :: idim
1607 INTEGER,
INTENT(IN) :: idim
1639 blks_local_1, blks_local_2, blks_local_3, blks_local_4, &
1640 proc_dist_1, proc_dist_2, proc_dist_3, proc_dist_4, &
1641 blk_size_1, blk_size_2, blk_size_3, blk_size_4, &
1642 blk_offset_1, blk_offset_2, blk_offset_3, blk_offset_4, &
1646 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: nblks_total
1647 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: nfull_total
1648 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: nblks_local
1649 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: nfull_local
1650 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: my_ploc
1651 INTEGER,
INTENT(OUT),
OPTIONAL,
DIMENSION(ndims_tensor(tensor)) :: pdims
1652 INTEGER,
DIMENSION(dbt_nblks_local(tensor, 1)),
INTENT(OUT),
OPTIONAL :: blks_local_1
1653 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 1)),
INTENT(OUT),
OPTIONAL :: proc_dist_1
1654 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 1)),
INTENT(OUT),
OPTIONAL :: blk_size_1
1655 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 1)),
INTENT(OUT),
OPTIONAL :: blk_offset_1
1656 INTEGER,
DIMENSION(dbt_nblks_local(tensor, 2)),
INTENT(OUT),
OPTIONAL :: blks_local_2
1657 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 2)),
INTENT(OUT),
OPTIONAL :: proc_dist_2
1658 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 2)),
INTENT(OUT),
OPTIONAL :: blk_size_2
1659 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 2)),
INTENT(OUT),
OPTIONAL :: blk_offset_2
1660 INTEGER,
DIMENSION(dbt_nblks_local(tensor, 3)),
INTENT(OUT),
OPTIONAL :: blks_local_3
1661 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 3)),
INTENT(OUT),
OPTIONAL :: proc_dist_3
1662 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 3)),
INTENT(OUT),
OPTIONAL :: blk_size_3
1663 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 3)),
INTENT(OUT),
OPTIONAL :: blk_offset_3
1664 INTEGER,
DIMENSION(dbt_nblks_local(tensor, 4)),
INTENT(OUT),
OPTIONAL :: blks_local_4
1665 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 4)),
INTENT(OUT),
OPTIONAL :: proc_dist_4
1666 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 4)),
INTENT(OUT),
OPTIONAL :: blk_size_4
1667 INTEGER,
DIMENSION(dbt_nblks_total(tensor, 4)),
INTENT(OUT),
OPTIONAL :: blk_offset_4
1669 CHARACTER(len=*),
INTENT(OUT),
OPTIONAL :: name
1670 INTEGER,
DIMENSION(ndims_tensor(tensor)) :: pdims_tmp, my_ploc_tmp
1674 IF (
PRESENT(nblks_local)) nblks_local(:) =
tensor%nblks_local
1675 IF (
PRESENT(nfull_local)) nfull_local(:) =
tensor%nfull_local
1678 IF (
PRESENT(my_ploc)) my_ploc = my_ploc_tmp
1679 IF (
PRESENT(pdims)) pdims = pdims_tmp
1739 IF (
PRESENT(name)) name =
tensor%name
1749 INTEGER :: num_blocks
1759 INTEGER(KIND=int_8) :: num_blocks
1789 REAL(
dp),
INTENT(IN) :: alpha
1817 INTEGER,
DIMENSION(ndims_tensor(tensor)), &
1819 INTEGER,
INTENT(IN) :: idim
1820 INTEGER,
DIMENSION(ndims_tensor(tensor)) :: blk_size
1840 INTEGER :: blk_count, nproc
1841 INTEGER,
DIMENSION(ndims_tensor(tensor)) :: bdims
1842 INTEGER(int_8) :: blk_count_total
1843 INTEGER,
PARAMETER :: max_load_imbalance = 2
1847 blk_count_total = product(int(bdims,
int_8))
1850 nproc =
tensor%pgrid%nproc
1852 blk_count = int(blk_count_total/nproc*max_load_imbalance)
1865 INTEGER,
INTENT(IN) :: nblk
1866 INTEGER,
INTENT(IN) :: nproc
1867 INTEGER,
DIMENSION(nblk),
INTENT(IN) :: blk_size
1868 INTEGER,
DIMENSION(nblk),
INTENT(OUT) :: dist
1877 TYPE(
dbt_type),
INTENT(IN) :: tensor_in
1878 TYPE(
dbt_type),
INTENT(INOUT) :: tensor_out
1882 IF (tensor_in%matrix_rep%do_batched > 0)
THEN
1883 ALLOCATE (tas_storage_tmp, source=tensor_in%matrix_rep%mm_storage)
1885 IF (
ALLOCATED(tensor_out%matrix_rep%mm_storage))
DEALLOCATE (tensor_out%matrix_rep%mm_storage)
1886 CALL move_alloc(tas_storage_tmp, tensor_out%matrix_rep%mm_storage)
1889 opt_grid=tensor_in%matrix_rep%has_opt_pgrid)
1890 IF (
ALLOCATED(tensor_in%contraction_storage))
THEN
1891 ALLOCATE (tensor_storage_tmp, source=tensor_in%contraction_storage)
1893 IF (
ALLOCATED(tensor_out%contraction_storage))
DEALLOCATE (tensor_out%contraction_storage)
1894 IF (
ALLOCATED(tensor_storage_tmp))
CALL move_alloc(tensor_storage_tmp, tensor_out%contraction_storage)
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
subroutine, public dbm_scale(matrix, alpha)
Multiplies all entries in the given matrix by the given factor alpha.
Wrapper for allocating, copying and reshaping arrays.
Representation of arbitrary number of 1d integer arrays with arbitrary sizes. This is needed for gene...
integer function, dimension(:), allocatable, public sum_of_arrays(list)
sum of all elements for each array stored in list
subroutine, public get_arrays(list, data_1, data_2, data_3, data_4, i_selected)
Get all arrays contained in list.
subroutine, public create_array_list(list, ndata, data_1, data_2, data_3, data_4)
collects any number of arrays of different sizes into a single array (listcol_data),...
subroutine, public destroy_array_list(list)
destroy array list.
integer function, dimension(:), allocatable, public sizes_of_arrays(list)
sizes of arrays stored in list
subroutine, public array_offsets(list_in, list_out)
partial sums of array elements.
pure integer function, dimension(number_of_arrays(list)), public get_array_elements(list, indices)
Get an element for each array.
type(array_list) function, public array_sublist(list, i_selected)
extract a subset of arrays
tensor index and mapping to DBM index
subroutine, public create_nd_to_2d_mapping(map, dims, map1_2d, map2_2d, base, col_major)
Create all data needed to quickly map between nd index and 2d index.
pure integer function, dimension(map%ndim_nd), public get_nd_indices_pgrid(map, ind_in)
transform 2d index to nd index, using info from index mapping.
pure integer function, public ndims_mapping_row(map)
how many tensor dimensions are mapped to matrix row
pure integer(kind=int_8) function, dimension(2), public get_2d_indices_tensor(map, ind_in)
transform nd index to 2d index, using info from index mapping.
pure integer function, public ndims_mapping(map)
pure integer(kind=int_8) function, public combine_tensor_index(ind_in, dims)
transform nd index to flat index
pure subroutine, public dbt_get_mapping_info(map, ndim_nd, ndim1_2d, ndim2_2d, dims_2d_i8, dims_2d, dims_nd, dims1_2d, dims2_2d, map1_2d, map2_2d, map_nd, base, col_major)
get mapping info
pure integer function, public combine_pgrid_index(ind_in, dims)
transform nd index to flat index
pure integer function, public ndims_mapping_column(map)
how many tensor dimensions are mapped to matrix column
subroutine, public destroy_nd_to_2d_mapping(map)
pure integer function, dimension(size(dims)), public split_tensor_index(ind_in, dims)
transform flat index to nd index
pure integer function, dimension(size(dims)), public split_pgrid_index(ind_in, dims)
transform flat index to nd index
Tall-and-skinny matrices: base routines similar to DBM API, mostly wrappers around existing DBM routi...
integer(kind=int_8) function, public dbt_tas_get_nze_total(matrix)
Get total number of non-zero elements.
subroutine, public dbt_tas_distribution_destroy(dist)
...
subroutine, public dbt_tas_get_stored_coordinates(matrix, row, column, processor)
As dbt_get_stored_coordinates.
pure integer function, public dbt_tas_get_nze(matrix)
As dbt_get_nze: get number of local non-zero elements.
subroutine, public dbt_tas_get_info(matrix, nblkrows_total, nblkcols_total, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, distribution, name)
...
subroutine, public dbt_tas_finalize(matrix)
...
subroutine, public dbt_tas_distribution_new(dist, mp_comm, row_dist, col_dist, split_info, nosplit)
create new distribution. Exactly like dbm_distribution_new but with custom types for row_dist and col...
subroutine, public dbt_tas_filter(matrix, eps)
As dbm_filter.
subroutine, public dbt_tas_clear(matrix)
Clear matrix (erase all data)
subroutine, public dbt_tas_destroy(matrix)
...
integer(kind=int_8) function, public dbt_tas_get_num_blocks_total(matrix)
get total number of blocks
pure integer function, public dbt_tas_get_num_blocks(matrix)
As dbt_get_num_blocks: get number of local blocks.
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
Matrix multiplication for tall-and-skinny matrices. This uses the k-split (non-recursive) CARMA algor...
subroutine, public dbt_tas_set_batched_state(matrix, state, opt_grid)
set state flags during batched multiplication
methods to split tall-and-skinny matrices along longest dimension. Basically, we are splitting proces...
subroutine, public dbt_tas_release_info(split_info)
...
subroutine, public dbt_tas_get_split_info(info, mp_comm, nsplit, igroup, mp_comm_group, split_rowcol, pgrid_offset)
Get info on split.
subroutine, public dbt_tas_create_split(split_info, mp_comm, split_rowcol, nsplit, own_comm, opt_nsplit)
Split Cartesian process grid using a default split heuristic.
subroutine, public dbt_tas_create_split_rows_or_cols(split_info, mp_comm, ngroup, igroup, split_rowcol, own_comm)
split mpi grid by rows or columns
subroutine, public dbt_tas_info_hold(split_info)
...
subroutine, public dbt_tas_set_strict_split(info)
freeze current split factor such that it is never changed during multiplication
DBT tall-and-skinny base types. Mostly wrappers around existing DBM routines.
DBT tensor framework for block-sparse tensor contraction: Types and create/destroy routines.
subroutine, public dbt_pgrid_destroy(pgrid, keep_comm)
destroy process grid
subroutine, public dbt_distribution_new(dist, pgrid, nd_dist_1, nd_dist_2, nd_dist_3, nd_dist_4)
Create a tensor distribution.
subroutine, public blk_dims_tensor(tensor, dims)
tensor block dimensions
subroutine, public dims_tensor(tensor, dims)
tensor dimensions
subroutine, public dbt_copy_contraction_storage(tensor_in, tensor_out)
type(dbt_pgrid_type) function, public dbt_nd_mp_comm(comm_2d, map1_2d, map2_2d, dims_nd, dims1_nd, dims2_nd, pdims_2d, tdims, nsplit, dimsplit)
Create a default nd process topology that is consistent with a given 2d topology. Purpose: a nd tenso...
subroutine, public dbt_blk_sizes(tensor, ind, blk_size)
Size of tensor block.
subroutine, public dbt_destroy(tensor)
Destroy a tensor.
pure integer function, public dbt_max_nblks_local(tensor)
returns an estimate of maximum number of local blocks in tensor (irrespective of the actual number of...
recursive subroutine, public dbt_mp_dims_create(nodes, dims, tensor_dims, lb_ratio)
Create process grid dimensions corresponding to one dimension of the matrix representation of a tenso...
subroutine, public dbt_get_info(tensor, nblks_total, nfull_total, nblks_local, nfull_local, pdims, my_ploc, blks_local_1, blks_local_2, blks_local_3, blks_local_4, proc_dist_1, proc_dist_2, proc_dist_3, proc_dist_4, blk_size_1, blk_size_2, blk_size_3, blk_size_4, blk_offset_1, blk_offset_2, blk_offset_3, blk_offset_4, distribution, name)
As block_get_info but for tensors.
subroutine, public dbt_distribution_new_expert(dist, pgrid, map1_2d, map2_2d, nd_dist_1, nd_dist_2, nd_dist_3, nd_dist_4, own_comm)
Create a tensor distribution.
type(dbt_distribution_type) function, public dbt_distribution(tensor)
get distribution from tensor
pure integer function, public ndims_tensor(tensor)
tensor rank
subroutine, public dbt_pgrid_set_strict_split(pgrid)
freeze current split factor such that it is never changed during contraction
pure integer function, public dbt_nblks_total(tensor, idim)
total numbers of blocks along dimension idim
pure integer function, public dbt_blk_size(tensor, ind, idim)
block size of block with index ind along dimension idim
pure integer function, public dbt_get_num_blocks(tensor)
As block_get_num_blocks: get number of local blocks.
subroutine, public dbt_default_distvec(nblk, nproc, blk_size, dist)
get a load-balanced and randomized distribution along one tensor dimension
subroutine, public dbt_hold(tensor)
reference counting for tensors (only needed for communicator handle that must be freed when no longer...
subroutine, public dbt_pgrid_create_expert(mp_comm, dims, pgrid, map1_2d, map2_2d, tensor_dims, nsplit, dimsplit)
Create an n-dimensional process grid. We can not use a n-dimensional MPI cartesian grid for tensors s...
subroutine, public dbt_clear(tensor)
Clear tensor (s.t. it does not contain any blocks)
subroutine, public dbt_finalize(tensor)
Finalize tensor, as block_finalize. This should be taken care of internally in DBT tensors,...
integer(kind=int_8) function, public dbt_get_nze_total(tensor)
pure integer function, public dbt_nblks_local(tensor, idim)
local number of blocks along dimension idim
subroutine, public mp_environ_pgrid(pgrid, dims, task_coor)
as mp_environ but for special pgrid type
subroutine, public dbt_get_stored_coordinates(tensor, ind_nd, processor)
Generalization of block_get_stored_coordinates for tensors.
pure integer function, public dbt_get_nze(tensor)
subroutine, public dbt_pgrid_create(mp_comm, dims, pgrid, tensor_dims)
integer(kind=int_8) function, public dbt_get_num_blocks_total(tensor)
Get total number of blocks.
pure integer(int_8) function, public ndims_matrix_row(tensor)
how many tensor dimensions are mapped to matrix row
subroutine, public dbt_pgrid_change_dims(pgrid, pdims)
change dimensions of an existing process grid.
pure integer(int_8) function, public ndims_matrix_column(tensor)
how many tensor dimensions are mapped to matrix column
subroutine, public dbt_nd_mp_free(mp_comm)
Release the MPI communicator.
subroutine, public dbt_blk_offsets(tensor, ind, blk_offset)
offset of tensor block
subroutine, public dbt_filter(tensor, eps)
As block_filter.
subroutine, public dbt_distribution_destroy(dist)
Destroy tensor distribution.
subroutine, public dbt_scale(tensor, alpha)
as block_scale
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_string_length
Interface to the message passing library MPI.
subroutine, public mp_dims_create(nodes, dims)
wrapper to MPI_Dims_create
All kind of helpful little routines.