32 dbt_distribution_type, &
47 #include "../base/base_uses.f90"
50 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dbt_split'
69 TYPE(dbt_type),
INTENT(INOUT) :: tensor_in
70 TYPE(dbt_type),
INTENT(OUT) :: tensor_out
71 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: blk_size_1, blk_size_2, blk_size_3, blk_size_4
72 LOGICAL,
INTENT(IN),
OPTIONAL :: nodata
74 TYPE(dbt_distribution_type) :: dist_old, dist_split
75 TYPE(dbt_iterator_type) :: iter
76 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nd_dist_split_1, nd_dist_split_2, nd_dist_split_3, nd_dist_split_4
77 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nd_blk_size_split_1, nd_blk_size_split_2, nd_blk_size_split_3,&
79 INTEGER,
DIMENSION(:),
ALLOCATABLE :: index_split_offset_1, index_split_offset_2, index_split_offset_3,&
80 & index_split_offset_4
81 INTEGER,
DIMENSION(:),
ALLOCATABLE :: inblock_offset_1, inblock_offset_2, inblock_offset_3, inblock_offset_4
82 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_nsplit_1, blk_nsplit_2, blk_nsplit_3, blk_nsplit_4
83 INTEGER :: split_blk_1, split_blk_2, split_blk_3, split_blk_4
84 INTEGER :: idim, i, isplit_sum, nsplit, handle, splitsum, bcount
85 INTEGER,
DIMENSION(:, :),
ALLOCATABLE :: blks_to_allocate
86 INTEGER,
DIMENSION(:),
ALLOCATABLE :: dist_d, blk_size_d, blk_size_split_d, dist_split_d
87 INTEGER,
DIMENSION(ndims_matrix_row(tensor_in)) :: map1_2d
88 INTEGER,
DIMENSION(ndims_matrix_column(tensor_in)) :: map2_2d
89 INTEGER,
DIMENSION(ndims_tensor(tensor_in)) :: blk_index, blk_size, blk_offset, &
91 INTEGER,
DIMENSION(4) :: bi_split, inblock_offset
94 REAL(
dp),
DIMENSION(:,:),
ALLOCATABLE :: block_2d
95 REAL(
dp),
DIMENSION(:,:,:),
ALLOCATABLE :: block_3d
96 REAL(
dp),
DIMENSION(:,:,:,:),
ALLOCATABLE :: block_4d
97 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_split_blocks_generic'
99 CALL timeset(routinen, handle)
109 ALLOCATE (index_split_offset_1(
SIZE(dist_d)))
111 ALLOCATE (blk_nsplit_1(
SIZE(dist_d)))
113 ALLOCATE (inblock_offset_1(
SIZE(blk_size_1)))
114 ALLOCATE (blk_size_split_d, source=blk_size_1)
118 ALLOCATE (index_split_offset_2(
SIZE(dist_d)))
120 ALLOCATE (blk_nsplit_2(
SIZE(dist_d)))
122 ALLOCATE (inblock_offset_2(
SIZE(blk_size_2)))
123 ALLOCATE (blk_size_split_d, source=blk_size_2)
127 ALLOCATE (index_split_offset_3(
SIZE(dist_d)))
129 ALLOCATE (blk_nsplit_3(
SIZE(dist_d)))
131 ALLOCATE (inblock_offset_3(
SIZE(blk_size_3)))
132 ALLOCATE (blk_size_split_d, source=blk_size_3)
136 ALLOCATE (index_split_offset_4(
SIZE(dist_d)))
138 ALLOCATE (blk_nsplit_4(
SIZE(dist_d)))
140 ALLOCATE (inblock_offset_4(
SIZE(blk_size_4)))
141 ALLOCATE (blk_size_split_d, source=blk_size_4)
145 ALLOCATE (dist_split_d(
SIZE(blk_size_split_d)))
148 DO i = 1,
SIZE(blk_size_d)
151 DO WHILE (splitsum < blk_size_d(i))
153 isplit_sum = isplit_sum + 1
154 IF (idim == 1) inblock_offset_1(isplit_sum) = splitsum
155 IF (idim == 2) inblock_offset_2(isplit_sum) = splitsum
156 IF (idim == 3) inblock_offset_3(isplit_sum) = splitsum
157 IF (idim == 4) inblock_offset_4(isplit_sum) = splitsum
158 dist_split_d(isplit_sum) = dist_d(i)
159 splitsum = splitsum + blk_size_split_d(isplit_sum)
161 cpassert(splitsum == blk_size_d(i))
163 blk_nsplit_1(i) = nsplit
164 index_split_offset_1(i) = isplit_sum - nsplit
167 blk_nsplit_2(i) = nsplit
168 index_split_offset_2(i) = isplit_sum - nsplit
171 blk_nsplit_3(i) = nsplit
172 index_split_offset_3(i) = isplit_sum - nsplit
175 blk_nsplit_4(i) = nsplit
176 index_split_offset_4(i) = isplit_sum - nsplit
181 ALLOCATE (nd_dist_split_1, source=dist_split_d)
182 ALLOCATE (nd_blk_size_split_1, source=blk_size_split_d)
185 ALLOCATE (nd_dist_split_2, source=dist_split_d)
186 ALLOCATE (nd_blk_size_split_2, source=blk_size_split_d)
189 ALLOCATE (nd_dist_split_3, source=dist_split_d)
190 ALLOCATE (nd_blk_size_split_3, source=blk_size_split_d)
193 ALLOCATE (nd_dist_split_4, source=dist_split_d)
194 ALLOCATE (nd_blk_size_split_4, source=blk_size_split_d)
196 DEALLOCATE (dist_split_d)
197 DEALLOCATE (blk_size_split_d)
205 nd_dist_split_1, nd_dist_split_2)
206 CALL dbt_create(tensor_out, tensor_in%name, dist_split, map1_2d, map2_2d, &
207 nd_blk_size_split_1, nd_blk_size_split_2)
211 nd_dist_split_1, nd_dist_split_2, nd_dist_split_3)
212 CALL dbt_create(tensor_out, tensor_in%name, dist_split, map1_2d, map2_2d, &
213 nd_blk_size_split_1, nd_blk_size_split_2, nd_blk_size_split_3)
217 nd_dist_split_1, nd_dist_split_2, nd_dist_split_3, nd_dist_split_4)
218 CALL dbt_create(tensor_out, tensor_in%name, dist_split, map1_2d, map2_2d, &
219 nd_blk_size_split_1, nd_blk_size_split_2, nd_blk_size_split_3, nd_blk_size_split_4)
224 IF (
PRESENT(nodata))
THEN
226 CALL timestop(handle)
246 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
247 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
253 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
254 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
255 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
262 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
263 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
264 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
265 DO split_blk_4 = 1, blk_nsplit_4(blk_index(4))
275 ALLOCATE (blks_to_allocate(bcount,
ndims_tensor(tensor_in)))
284 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
285 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
286 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
287 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
289 blks_to_allocate(bcount, :) = bi_split(1:
ndims_tensor(tensor_in))
294 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
295 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
296 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
297 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
298 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
299 bi_split(3) = index_split_offset_3(blk_index(3)) + split_blk_3
301 blks_to_allocate(bcount, :) = bi_split(1:
ndims_tensor(tensor_in))
307 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
308 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
309 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
310 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
311 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
312 bi_split(3) = index_split_offset_3(blk_index(3)) + split_blk_3
313 DO split_blk_4 = 1, blk_nsplit_4(blk_index(4))
314 bi_split(4) = index_split_offset_4(blk_index(4)) + split_blk_4
316 blks_to_allocate(bcount, :) = bi_split(1:
ndims_tensor(tensor_in))
326 CALL dbt_reserve_blocks(tensor_out, blks_to_allocate)
333 CALL dbt_get_block(tensor_in, blk_index, block_2d, found)
337 CALL dbt_get_block(tensor_in, blk_index, block_3d, found)
341 CALL dbt_get_block(tensor_in, blk_index, block_4d, found)
345 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
347 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
348 blk_shape(1) = blk_size_1(bi_split(1))
349 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
351 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
352 blk_shape(2) = blk_size_2(bi_split(2))
354 inblock_offset(1) = inblock_offset_1(bi_split(1))
355 inblock_offset(2) = inblock_offset_2(bi_split(2))
356 CALL dbt_put_block(tensor_out, bi_split(1:2), &
359 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) +&
360 & 1:inblock_offset(2) + blk_shape(2)))
365 DEALLOCATE (block_2d)
368 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
370 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
371 blk_shape(1) = blk_size_1(bi_split(1))
372 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
374 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
375 blk_shape(2) = blk_size_2(bi_split(2))
376 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
378 bi_split(3) = index_split_offset_3(blk_index(3)) + split_blk_3
379 blk_shape(3) = blk_size_3(bi_split(3))
381 inblock_offset(1) = inblock_offset_1(bi_split(1))
382 inblock_offset(2) = inblock_offset_2(bi_split(2))
383 inblock_offset(3) = inblock_offset_3(bi_split(3))
384 CALL dbt_put_block(tensor_out, bi_split(1:3), &
387 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) +&
388 & 1:inblock_offset(2) + blk_shape(2), inblock_offset(3) + 1:inblock_offset(3) +&
395 DEALLOCATE (block_3d)
398 DO split_blk_1 = 1, blk_nsplit_1(blk_index(1))
400 bi_split(1) = index_split_offset_1(blk_index(1)) + split_blk_1
401 blk_shape(1) = blk_size_1(bi_split(1))
402 DO split_blk_2 = 1, blk_nsplit_2(blk_index(2))
404 bi_split(2) = index_split_offset_2(blk_index(2)) + split_blk_2
405 blk_shape(2) = blk_size_2(bi_split(2))
406 DO split_blk_3 = 1, blk_nsplit_3(blk_index(3))
408 bi_split(3) = index_split_offset_3(blk_index(3)) + split_blk_3
409 blk_shape(3) = blk_size_3(bi_split(3))
410 DO split_blk_4 = 1, blk_nsplit_4(blk_index(4))
412 bi_split(4) = index_split_offset_4(blk_index(4)) + split_blk_4
413 blk_shape(4) = blk_size_4(bi_split(4))
415 inblock_offset(1) = inblock_offset_1(bi_split(1))
416 inblock_offset(2) = inblock_offset_2(bi_split(2))
417 inblock_offset(3) = inblock_offset_3(bi_split(3))
418 inblock_offset(4) = inblock_offset_4(bi_split(4))
419 CALL dbt_put_block(tensor_out, bi_split(1:4), &
422 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) +&
423 & 1:inblock_offset(2) + blk_shape(2), inblock_offset(3) + 1:inblock_offset(3) +&
424 & blk_shape(3), inblock_offset(4) + 1:inblock_offset(4) + blk_shape(4)))
431 DEALLOCATE (block_4d)
442 CALL timestop(handle)
456 TYPE(dbt_type),
INTENT(INOUT) :: tensor_in
457 TYPE(dbt_type),
INTENT(OUT) :: tensor_out
458 INTEGER,
DIMENSION(ndims_tensor(tensor_in)), &
459 INTENT(IN) :: block_sizes
460 LOGICAL,
INTENT(IN),
OPTIONAL :: nodata
462 INTEGER,
DIMENSION(:),
ALLOCATABLE :: nd_blk_size_split_1, nd_blk_size_split_2,&
463 & nd_blk_size_split_3, nd_blk_size_split_4
464 INTEGER :: idim, i, isplit_sum, blk_remainder, nsplit, isplit
465 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_d, blk_size_split_d
471 DO i = 1,
SIZE(blk_size_d)
472 nsplit = (blk_size_d(i) + block_sizes(idim) - 1)/block_sizes(idim)
473 isplit_sum = isplit_sum + nsplit
476 ALLOCATE (blk_size_split_d(isplit_sum))
479 DO i = 1,
SIZE(blk_size_d)
480 nsplit = (blk_size_d(i) + block_sizes(idim) - 1)/block_sizes(idim)
481 blk_remainder = blk_size_d(i)
482 DO isplit = 1, nsplit
483 isplit_sum = isplit_sum + 1
484 blk_size_split_d(isplit_sum) = min(block_sizes(idim), blk_remainder)
485 blk_remainder = blk_remainder - block_sizes(idim)
491 ALLOCATE (nd_blk_size_split_1, source=blk_size_split_d)
494 ALLOCATE (nd_blk_size_split_2, source=blk_size_split_d)
497 ALLOCATE (nd_blk_size_split_3, source=blk_size_split_d)
500 ALLOCATE (nd_blk_size_split_4, source=blk_size_split_d)
502 DEALLOCATE (blk_size_split_d)
506 nd_blk_size_split_1, nd_blk_size_split_2, &
509 nd_blk_size_split_1, nd_blk_size_split_2,&
510 & nd_blk_size_split_3, &
513 nd_blk_size_split_1, nd_blk_size_split_2,&
514 & nd_blk_size_split_3, nd_blk_size_split_&
527 TYPE(dbt_type),
INTENT(INOUT) :: tensor_split_in
528 TYPE(dbt_type),
INTENT(INOUT) :: tensor_out
529 LOGICAL,
INTENT(IN),
OPTIONAL :: summation
530 INTEGER,
DIMENSION(:),
ALLOCATABLE :: first_split_d, last_split_d
531 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_split_d, blk_size_d
532 INTEGER,
DIMENSION(:),
ALLOCATABLE :: last_split_1, last_split_2, last_split_3, last_split_4, &
533 first_split_1, first_split_2, first_split_3,&
535 split_1, split_2, split_3, split_4
536 INTEGER,
DIMENSION(:),
ALLOCATABLE :: inblock_offset_1, inblock_offset_2, inblock_offset_3,&
537 & inblock_offset_4, blk_size_split_1, blk_size_split_2, blk_size_split_3, blk_size_split_4
538 INTEGER,
DIMENSION(:, :),
ALLOCATABLE :: blks_to_allocate
539 INTEGER :: idim, iblk, bcount
540 INTEGER :: iblk_1, iblk_2, iblk_3, iblk_4, isplit_sum, splitsum
541 TYPE(dbt_iterator_type) :: iter
542 INTEGER,
DIMENSION(ndims_tensor(tensor_out)) :: blk_index, blk_size, blk_offset, blk_shape, blk_index_n
545 INTEGER,
DIMENSION(4) :: inblock_offset
547 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_split_copyback'
548 REAL(
dp),
DIMENSION(:,:),
ALLOCATABLE :: block_2d
549 REAL(
dp),
DIMENSION(:,:),
ALLOCATABLE :: block_split_2d
550 REAL(
dp),
DIMENSION(:,:,:),
ALLOCATABLE :: block_3d
551 REAL(
dp),
DIMENSION(:,:,:),
ALLOCATABLE :: block_split_3d
552 REAL(
dp),
DIMENSION(:,:,:,:),
ALLOCATABLE :: block_4d
553 REAL(
dp),
DIMENSION(:,:,:,:),
ALLOCATABLE :: block_split_4d
555 CALL timeset(routinen, handle)
556 cpassert(tensor_out%valid)
557 IF (
PRESENT(summation))
THEN
558 IF (.NOT. summation)
CALL dbt_clear(tensor_out)
564 CALL get_ith_array(tensor_split_in%blk_sizes, idim, blk_size_split_d)
569 ALLOCATE (inblock_offset_1(
SIZE(blk_size_split_d)))
571 ALLOCATE (split_1(
SIZE(blk_size_split_d)))
575 ALLOCATE (inblock_offset_2(
SIZE(blk_size_split_d)))
577 ALLOCATE (split_2(
SIZE(blk_size_split_d)))
581 ALLOCATE (inblock_offset_3(
SIZE(blk_size_split_d)))
583 ALLOCATE (split_3(
SIZE(blk_size_split_d)))
587 ALLOCATE (inblock_offset_4(
SIZE(blk_size_split_d)))
589 ALLOCATE (split_4(
SIZE(blk_size_split_d)))
592 ALLOCATE (last_split_d(
SIZE(blk_size_d)))
593 ALLOCATE (first_split_d(
SIZE(blk_size_d)))
596 DO iblk = 1,
SIZE(blk_size_d)
598 IF (iblk .GT. 1) first_split_d(iblk) = last_split_d(iblk - 1) + 1
599 DO WHILE (splitsum < blk_size_d(iblk))
600 isplit_sum = isplit_sum + 1
602 inblock_offset_1(isplit_sum) = splitsum
603 split_1(isplit_sum) = iblk
606 inblock_offset_2(isplit_sum) = splitsum
607 split_2(isplit_sum) = iblk
610 inblock_offset_3(isplit_sum) = splitsum
611 split_3(isplit_sum) = iblk
614 inblock_offset_4(isplit_sum) = splitsum
615 split_4(isplit_sum) = iblk
617 splitsum = splitsum + blk_size_split_d(isplit_sum)
619 cpassert(splitsum == blk_size_d(iblk))
620 last_split_d(iblk) = isplit_sum
623 ALLOCATE (first_split_1, source=first_split_d)
624 ALLOCATE (last_split_1, source=last_split_d)
625 ALLOCATE (blk_size_split_1, source=blk_size_split_d)
628 ALLOCATE (first_split_2, source=first_split_d)
629 ALLOCATE (last_split_2, source=last_split_d)
630 ALLOCATE (blk_size_split_2, source=blk_size_split_d)
633 ALLOCATE (first_split_3, source=first_split_d)
634 ALLOCATE (last_split_3, source=last_split_d)
635 ALLOCATE (blk_size_split_3, source=blk_size_split_d)
638 ALLOCATE (first_split_4, source=first_split_d)
639 ALLOCATE (last_split_4, source=last_split_d)
640 ALLOCATE (blk_size_split_4, source=blk_size_split_d)
642 DEALLOCATE (first_split_d, last_split_d)
643 DEALLOCATE (blk_size_split_d, blk_size_d)
661 blk_index_n(1) = split_1(blk_index(1))
662 blk_index_n(2) = split_2(blk_index(2))
665 blk_index_n(1) = split_1(blk_index(1))
666 blk_index_n(2) = split_2(blk_index(2))
667 blk_index_n(3) = split_3(blk_index(3))
670 blk_index_n(1) = split_1(blk_index(1))
671 blk_index_n(2) = split_2(blk_index(2))
672 blk_index_n(3) = split_3(blk_index(3))
673 blk_index_n(4) = split_4(blk_index(4))
675 blks_to_allocate(bcount + 1, :) = blk_index_n
679 CALL dbt_reserve_blocks(tensor_out, blks_to_allocate)
686 CALL allocate_any(block_2d, blk_size)
688 DO iblk_1 = first_split_1(blk_index(1)), last_split_1(blk_index(1))
689 DO iblk_2 = first_split_2(blk_index(2)), last_split_2(blk_index(2))
690 inblock_offset(1) = inblock_offset_1(iblk_1)
691 inblock_offset(2) = inblock_offset_2(iblk_2)
693 CALL dbt_get_block(tensor_split_in, [iblk_1, iblk_2], &
694 block_split_2d, found)
696 blk_shape(1:2) = shape(block_split_2d)
698 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) + 1:inblock_offset(2) +&
705 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_2d, summation=summation)
706 DEALLOCATE (block_2d)
709 CALL allocate_any(block_3d, blk_size)
711 DO iblk_1 = first_split_1(blk_index(1)), last_split_1(blk_index(1))
712 DO iblk_2 = first_split_2(blk_index(2)), last_split_2(blk_index(2))
713 DO iblk_3 = first_split_3(blk_index(3)), last_split_3(blk_index(3))
714 inblock_offset(1) = inblock_offset_1(iblk_1)
715 inblock_offset(2) = inblock_offset_2(iblk_2)
716 inblock_offset(3) = inblock_offset_3(iblk_3)
718 CALL dbt_get_block(tensor_split_in, [iblk_1, iblk_2, iblk_3], &
719 block_split_3d, found)
721 blk_shape(1:3) = shape(block_split_3d)
723 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) + 1:inblock_offset(2) +&
724 & blk_shape(2), inblock_offset(3) + 1:inblock_offset(3) + blk_shape(3)) = &
731 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_3d, summation=summation)
732 DEALLOCATE (block_3d)
735 CALL allocate_any(block_4d, blk_size)
737 DO iblk_1 = first_split_1(blk_index(1)), last_split_1(blk_index(1))
738 DO iblk_2 = first_split_2(blk_index(2)), last_split_2(blk_index(2))
739 DO iblk_3 = first_split_3(blk_index(3)), last_split_3(blk_index(3))
740 DO iblk_4 = first_split_4(blk_index(4)), last_split_4(blk_index(4))
741 inblock_offset(1) = inblock_offset_1(iblk_1)
742 inblock_offset(2) = inblock_offset_2(iblk_2)
743 inblock_offset(3) = inblock_offset_3(iblk_3)
744 inblock_offset(4) = inblock_offset_4(iblk_4)
746 CALL dbt_get_block(tensor_split_in, [iblk_1, iblk_2, iblk_3, iblk_4], &
747 block_split_4d, found)
749 blk_shape(1:4) = shape(block_split_4d)
751 inblock_offset(1) + 1:inblock_offset(1) + blk_shape(1), inblock_offset(2) + 1:inblock_offset(2) +&
752 & blk_shape(2), inblock_offset(3) + 1:inblock_offset(3) + blk_shape(3), inblock_offset(4) +&
753 & 1:inblock_offset(4) + blk_shape(4)) = &
761 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_4d, summation=summation)
762 DEALLOCATE (block_4d)
768 CALL timestop(handle)
787 order, nodata1, nodata2, move_data)
788 TYPE(dbt_type),
INTENT(INOUT) :: tensor1, tensor2
789 TYPE(dbt_type),
INTENT(OUT) :: tensor1_split, tensor2_split
790 INTEGER,
DIMENSION(ndims_tensor(tensor1)), &
791 INTENT(IN),
OPTIONAL :: order
792 LOGICAL,
INTENT(IN),
OPTIONAL :: nodata1, nodata2, move_data
793 INTEGER,
DIMENSION(:),
ALLOCATABLE :: blk_size_split_1_1, blk_size_split_1_2, blk_size_split_1_3,&
794 & blk_size_split_1_4, blk_size_split_2_1, blk_size_split_2_2, blk_size_split_2_3,&
795 & blk_size_split_2_4, &
796 blk_size_d_1, blk_size_d_2, blk_size_d_split
797 INTEGER :: size_sum_1, size_sum_2, size_sum, bind_1, bind_2, isplit, bs, idim, i
798 LOGICAL :: move_prv, nodata1_prv, nodata2_prv
799 INTEGER,
DIMENSION(ndims_tensor(tensor1)) :: order_prv
801 IF (
PRESENT(move_data))
THEN
807 IF (
PRESENT(nodata1))
THEN
808 nodata1_prv = nodata1
810 nodata1_prv = .false.
812 IF (
PRESENT(nodata2))
THEN
813 nodata2_prv = nodata2
815 nodata2_prv = .false.
818 IF (
PRESENT(order))
THEN
825 CALL get_ith_array(tensor1%blk_sizes, order_prv(idim), blk_size_d_1)
827 ALLOCATE (blk_size_d_split(
SIZE(blk_size_d_1) +
SIZE(blk_size_d_2)))
835 DO WHILE (bind_1 <
SIZE(blk_size_d_1) .AND. bind_2 <
SIZE(blk_size_d_2))
836 IF (blk_size_d_1(bind_1 + 1) < blk_size_d_2(bind_2 + 1))
THEN
838 bs = blk_size_d_1(bind_1)
839 blk_size_d_2(bind_2 + 1) = blk_size_d_2(bind_2 + 1) - bs
840 size_sum = size_sum + bs
842 blk_size_d_split(isplit) = bs
843 ELSEIF (blk_size_d_1(bind_1 + 1) > blk_size_d_2(bind_2 + 1))
THEN
845 bs = blk_size_d_2(bind_2)
846 blk_size_d_1(bind_1 + 1) = blk_size_d_1(bind_1 + 1) - bs
847 size_sum = size_sum + bs
849 blk_size_d_split(isplit) = bs
853 bs = blk_size_d_1(bind_1)
854 size_sum = size_sum + bs
856 blk_size_d_split(isplit) = bs
860 IF (bind_1 <
SIZE(blk_size_d_1))
THEN
862 bs = blk_size_d_1(bind_1)
863 size_sum = size_sum + bs
865 blk_size_d_split(isplit) = bs
868 IF (bind_2 <
SIZE(blk_size_d_2))
THEN
870 bs = blk_size_d_2(bind_2)
871 size_sum = size_sum + bs
873 blk_size_d_split(isplit) = bs
876 IF (order_prv(idim) == 1)
THEN
877 ALLOCATE (blk_size_split_1_1, source=blk_size_d_split(:isplit))
879 IF (order_prv(idim) == 2)
THEN
880 ALLOCATE (blk_size_split_1_2, source=blk_size_d_split(:isplit))
882 IF (order_prv(idim) == 3)
THEN
883 ALLOCATE (blk_size_split_1_3, source=blk_size_d_split(:isplit))
885 IF (order_prv(idim) == 4)
THEN
886 ALLOCATE (blk_size_split_1_4, source=blk_size_d_split(:isplit))
890 ALLOCATE (blk_size_split_2_1, source=blk_size_d_split(:isplit))
893 ALLOCATE (blk_size_split_2_2, source=blk_size_d_split(:isplit))
896 ALLOCATE (blk_size_split_2_3, source=blk_size_d_split(:isplit))
899 ALLOCATE (blk_size_split_2_4, source=blk_size_d_split(:isplit))
902 DEALLOCATE (blk_size_d_split, blk_size_d_1, blk_size_d_2)
907 IF (move_prv .AND. .NOT. nodata1_prv)
CALL dbt_clear(tensor1)
909 IF (move_prv .AND. .NOT. nodata2_prv)
CALL dbt_clear(tensor2)
913 & blk_size_split_1_3, nodata=nodata1)
914 IF (move_prv .AND. .NOT. nodata1_prv)
CALL dbt_clear(tensor1)
916 & blk_size_split_2_3, nodata=nodata2)
917 IF (move_prv .AND. .NOT. nodata2_prv)
CALL dbt_clear(tensor2)
921 & blk_size_split_1_3, blk_size_split_1_4, nodata=nodata1)
922 IF (move_prv .AND. .NOT. nodata1_prv)
CALL dbt_clear(tensor1)
924 & blk_size_split_2_3, blk_size_split_2_4, nodata=nodata2)
925 IF (move_prv .AND. .NOT. nodata2_prv)
CALL dbt_clear(tensor2)
933 SUBROUTINE dbt_crop(tensor_in, tensor_out, bounds, move_data)
934 TYPE(dbt_type),
INTENT(INOUT) :: tensor_in
935 TYPE(dbt_type),
INTENT(OUT) :: tensor_out
936 INTEGER,
DIMENSION(2, ndims_tensor(tensor_in)),
INTENT(IN) :: bounds
937 LOGICAL,
INTENT(IN),
OPTIONAL :: move_data
939 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dbt_crop'
941 INTEGER,
DIMENSION(2, ndims_tensor(tensor_in)) :: blk_bounds
942 TYPE(dbt_iterator_type) :: iter
943 INTEGER,
DIMENSION(ndims_tensor(tensor_in)) :: blk_index, blk_size, blk_offset
944 LOGICAL :: found, move_data_prv
945 INTEGER :: handle, idim, iblk_out
946 INTEGER,
DIMENSION(:, :),
ALLOCATABLE :: blk_ind_out
947 REAL(
dp),
DIMENSION(:,:),
ALLOCATABLE :: block_2d, block_put_2d
948 REAL(
dp),
DIMENSION(:,:,:),
ALLOCATABLE :: block_3d, block_put_3d
949 REAL(
dp),
DIMENSION(:,:,:,:),
ALLOCATABLE :: block_4d, block_put_4d
951 CALL timeset(routinen, handle)
953 IF (
PRESENT(move_data))
THEN
954 move_data_prv = move_data
956 move_data_prv = .false.
959 CALL dbt_create(tensor_in, tensor_out)
968 blk_ind_out(:, :) = 0
973 IF (bounds(1, idim) > blk_offset(idim) - 1 + blk_size(idim)) cycle blk_loop
974 IF (bounds(2, idim) < blk_offset(idim)) cycle blk_loop
976 iblk_out = iblk_out + 1
977 blk_ind_out(iblk_out, :) = blk_index
981 CALL dbt_reserve_blocks(tensor_out, blk_ind_out(1:iblk_out, :))
982 DEALLOCATE (blk_ind_out)
990 blk_bounds(1, idim) = max(bounds(1, idim) - blk_offset(idim) + 1, 1)
991 blk_bounds(2, idim) = min(bounds(2, idim) - blk_offset(idim) + 1, blk_size(idim))
995 CALL dbt_get_block(tensor_in, blk_index, block_2d, found)
997 ALLOCATE (block_put_2d(blk_size(1), blk_size(2)))
998 block_put_2d = 0.0_dp
999 block_put_2d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2)) = &
1000 block_2d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2))
1001 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_put_2d)
1002 DEALLOCATE (block_2d)
1003 DEALLOCATE (block_put_2d)
1006 CALL dbt_get_block(tensor_in, blk_index, block_3d, found)
1008 ALLOCATE (block_put_3d(blk_size(1), blk_size(2), blk_size(3)))
1009 block_put_3d = 0.0_dp
1010 block_put_3d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2), blk_bounds(1, 3):blk_bounds(2,3)) = &
1011 block_3d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2), blk_bounds(1, 3):blk_bounds(2,3))
1012 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_put_3d)
1013 DEALLOCATE (block_3d)
1014 DEALLOCATE (block_put_3d)
1017 CALL dbt_get_block(tensor_in, blk_index, block_4d, found)
1019 ALLOCATE (block_put_4d(blk_size(1), blk_size(2), blk_size(3), blk_size(4)))
1020 block_put_4d = 0.0_dp
1021 block_put_4d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2), blk_bounds(1, 3):blk_bounds(2,3),&
1022 & blk_bounds(1, 4):blk_bounds(2,4)) = &
1023 block_4d(blk_bounds(1, 1):blk_bounds(2,1), blk_bounds(1, 2):blk_bounds(2,2), blk_bounds(1, 3):blk_bounds(2,3),&
1024 & blk_bounds(1, 4):blk_bounds(2,4))
1025 CALL dbt_put_block(tensor_out, blk_index, blk_size, block_put_4d)
1026 DEALLOCATE (block_4d)
1027 DEALLOCATE (block_put_4d)
1034 IF (move_data_prv)
CALL dbt_clear(tensor_in)
1039 CALL timestop(handle)
Wrapper for allocating, copying and reshaping arrays.
Representation of arbitrary number of 1d integer arrays with arbitrary sizes. This is needed for gene...
subroutine, public get_ith_array(list, i, array_size, array)
get ith array
Methods to operate on n-dimensional tensor blocks.
integer function, public dbt_iterator_num_blocks(iterator)
Generalization of block_iterator_num_blocks for tensors.
logical function, public dbt_iterator_blocks_left(iterator)
Generalization of block_iterator_blocks_left for tensors.
subroutine, public dbt_iterator_stop(iterator)
Generalization of block_iterator_stop for tensors.
subroutine, public dbt_iterator_start(iterator, tensor)
Generalization of block_iterator_start for tensors.
subroutine, public dbt_iterator_next_block(iterator, ind_nd, blk_size, blk_offset)
iterate over nd blocks of an nd rank tensor, index only (blocks must be retrieved by calling dbt_get_...
tensor index and mapping to DBM index
pure integer function, dimension(size(order)), public dbt_inverse_order(order)
Invert order.
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
Routines to split blocks and to convert between tensors with different block sizes.
subroutine, public dbt_split_blocks(tensor_in, tensor_out, block_sizes, nodata)
Split tensor blocks into smaller blocks of maximum size PRODUCT(block_sizes).
subroutine, public dbt_split_copyback(tensor_split_in, tensor_out, summation)
Copy tensor with split blocks to tensor with original block sizes.
subroutine, public dbt_make_compatible_blocks(tensor1, tensor2, tensor1_split, tensor2_split, order, nodata1, nodata2, move_data)
split two tensors with same total sizes but different block sizes such that they have equal block siz...
subroutine, public dbt_split_blocks_generic(tensor_in, tensor_out, blk_size_1, blk_size_2, blk_size_3, blk_size_4, nodata)
Split tensor blocks into smaller blocks.
subroutine, public dbt_crop(tensor_in, tensor_out, bounds, move_data)
DBT tensor framework for block-sparse tensor contraction: Types and create/destroy routines.
subroutine, public dbt_copy_contraction_storage(tensor_in, tensor_out)
subroutine, public dbt_blk_sizes(tensor, ind, blk_size)
Size of tensor block.
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
pure integer function, public dbt_get_num_blocks(tensor)
As block_get_num_blocks: get number of local blocks.
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,...
pure integer(int_8) function, public ndims_matrix_row(tensor)
how many tensor dimensions are mapped to matrix row
pure integer(int_8) function, public ndims_matrix_column(tensor)
how many tensor dimensions are mapped to matrix column
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.
Defines the basic variable types.
integer, parameter, public dp