LCOV - code coverage report
Current view: top level - src/dbt/tas - dbt_tas_base.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 90.7 % 323 293
Test Date: 2025-12-04 06:27:48 Functions: 91.9 % 37 34

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Tall-and-skinny matrices: base routines similar to DBM API,
      10              : !>        mostly wrappers around existing DBM routines.
      11              : !> \author Patrick Seewald
      12              : ! **************************************************************************************************
      13              : MODULE dbt_tas_base
      14              :    USE dbm_api,                         ONLY: &
      15              :         dbm_clear, dbm_create, dbm_create_from_template, dbm_distribution_col_dist, &
      16              :         dbm_distribution_hold, dbm_distribution_new, dbm_distribution_obj, &
      17              :         dbm_distribution_release, dbm_distribution_row_dist, dbm_filter, dbm_finalize, &
      18              :         dbm_get_block_p, dbm_get_col_block_sizes, dbm_get_distribution, dbm_get_local_cols, &
      19              :         dbm_get_local_rows, dbm_get_name, dbm_get_num_blocks, dbm_get_nze, &
      20              :         dbm_get_row_block_sizes, dbm_iterator, dbm_iterator_blocks_left, dbm_iterator_next_block, &
      21              :         dbm_iterator_num_blocks, dbm_iterator_start, dbm_iterator_stop, dbm_put_block, &
      22              :         dbm_release, dbm_reserve_blocks, dbm_type
      23              :    USE dbt_tas_global,                  ONLY: dbt_tas_blk_size_arb,&
      24              :                                               dbt_tas_dist_arb,&
      25              :                                               dbt_tas_distribution,&
      26              :                                               dbt_tas_rowcol_data
      27              :    USE dbt_tas_split,                   ONLY: colsplit,&
      28              :                                               dbt_index_global_to_local,&
      29              :                                               dbt_index_local_to_global,&
      30              :                                               dbt_tas_create_split,&
      31              :                                               dbt_tas_info_hold,&
      32              :                                               dbt_tas_release_info,&
      33              :                                               group_to_mrowcol,&
      34              :                                               rowsplit
      35              :    USE dbt_tas_types,                   ONLY: dbt_tas_distribution_type,&
      36              :                                               dbt_tas_iterator,&
      37              :                                               dbt_tas_split_info,&
      38              :                                               dbt_tas_type
      39              :    USE kinds,                           ONLY: default_string_length,&
      40              :                                               dp,&
      41              :                                               int_8
      42              :    USE message_passing,                 ONLY: mp_cart_type
      43              : #include "../../base/base_uses.f90"
      44              : 
      45              :    IMPLICIT NONE
      46              :    PRIVATE
      47              : 
      48              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dbt_tas_base'
      49              : 
      50              :    ! DBM wrappers / interface routines
      51              :    PUBLIC :: &
      52              :       dbt_tas_blk_sizes, &
      53              :       dbt_tas_clear, &
      54              :       dbt_tas_copy, &
      55              :       dbt_tas_create, &
      56              :       dbt_tas_destroy, &
      57              :       dbt_tas_distribution_destroy, &
      58              :       dbt_tas_distribution_new, &
      59              :       dbt_tas_filter, &
      60              :       dbt_tas_finalize, &
      61              :       dbt_tas_get_block_p, &
      62              :       dbt_tas_get_info, &
      63              :       dbt_tas_get_num_blocks, &
      64              :       dbt_tas_get_nze, &
      65              :       dbt_tas_get_nze_total, &
      66              :       dbt_tas_get_num_blocks_total, &
      67              :       dbt_tas_get_stored_coordinates, &
      68              :       dbt_tas_info, &
      69              :       dbt_tas_iterator_num_blocks, &
      70              :       dbt_tas_iterator_blocks_left, &
      71              :       dbt_tas_iterator_next_block, &
      72              :       dbt_tas_iterator_start, &
      73              :       dbt_tas_iterator_stop, &
      74              :       dbt_tas_nblkcols_local, &
      75              :       dbt_tas_nblkcols_total, &
      76              :       dbt_tas_nblkrows_local, &
      77              :       dbt_tas_nblkrows_total, &
      78              :       dbt_tas_nfullrows_total, &
      79              :       dbt_tas_nfullcols_total, &
      80              :       dbt_tas_put_block, &
      81              :       dbt_tas_reserve_blocks, &
      82              :       dbt_repl_get_stored_coordinates
      83              : 
      84              :    ! conversion routines
      85              :    PUBLIC :: &
      86              :       dbt_tas_convert_to_dbm, &
      87              :       dbt_tas_convert_to_tas
      88              : 
      89              :    INTERFACE dbt_tas_create
      90              :       MODULE PROCEDURE dbt_tas_create_new
      91              :       MODULE PROCEDURE dbt_tas_create_template
      92              :    END INTERFACE
      93              : 
      94              :    INTERFACE dbt_tas_reserve_blocks
      95              :       MODULE PROCEDURE dbt_tas_reserve_blocks_template
      96              :       MODULE PROCEDURE dbt_tas_reserve_blocks_index
      97              :    END INTERFACE
      98              : 
      99              :    INTERFACE dbt_tas_iterator_next_block
     100              :       MODULE PROCEDURE dbt_tas_iterator_next_block_d
     101              :       MODULE PROCEDURE dbt_tas_iterator_next_block_index
     102              :    END INTERFACE
     103              : 
     104              : CONTAINS
     105              : 
     106              : ! **************************************************************************************************
     107              : !> \brief Create new tall-and-skinny matrix.
     108              : !>        Exactly like dbt_create_new but with custom types for row_blk_size and col_blk_size
     109              : !>        instead of arrays.
     110              : !> \param matrix ...
     111              : !> \param name ...
     112              : !> \param dist ...
     113              : !> \param row_blk_size ...
     114              : !> \param col_blk_size ...
     115              : !> \param own_dist whether matrix should own distribution
     116              : !> \author Patrick Seewald
     117              : ! **************************************************************************************************
     118      5499221 :    SUBROUTINE dbt_tas_create_new(matrix, name, dist, row_blk_size, col_blk_size, own_dist)
     119              :       TYPE(dbt_tas_type), INTENT(OUT)                    :: matrix
     120              :       CHARACTER(len=*), INTENT(IN)                       :: name
     121              :       TYPE(dbt_tas_distribution_type), INTENT(INOUT)     :: dist
     122              : 
     123              :       CLASS(dbt_tas_rowcol_data), INTENT(IN)         :: row_blk_size, col_blk_size
     124              :       LOGICAL, INTENT(IN), OPTIONAL                  :: own_dist
     125              : 
     126              :       TYPE(dbt_tas_split_info), POINTER              :: info
     127              : 
     128       785603 :       INTEGER, DIMENSION(:), POINTER, CONTIGUOUS     :: row_blk_size_vec, col_blk_size_vec
     129              :       INTEGER                                        :: nrows, ncols, irow, col, icol, row
     130              :       CHARACTER(LEN=*), PARAMETER                    :: routineN = 'dbt_tas_create_new'
     131              :       INTEGER                                        :: handle
     132              : 
     133       785603 :       CALL timeset(routineN, handle)
     134              : 
     135       785603 :       CALL dbt_tas_copy_distribution(dist, matrix%dist, own_dist)
     136       785603 :       matrix%nblkrows = row_blk_size%nmrowcol
     137       785603 :       matrix%nblkcols = col_blk_size%nmrowcol
     138              : 
     139       785603 :       CPASSERT(matrix%nblkrows == dist%row_dist%nmrowcol)
     140       785603 :       CPASSERT(matrix%nblkcols == dist%col_dist%nmrowcol)
     141              : 
     142       785603 :       matrix%nfullrows = row_blk_size%nfullrowcol
     143       785603 :       matrix%nfullcols = col_blk_size%nfullrowcol
     144              : 
     145       785603 :       ALLOCATE (matrix%row_blk_size, source=row_blk_size)
     146       785603 :       ALLOCATE (matrix%col_blk_size, source=col_blk_size)
     147              : 
     148       785603 :       info => dbt_tas_info(matrix)
     149              : 
     150      1409261 :       SELECT CASE (info%split_rowcol)
     151              :       CASE (rowsplit)
     152       623658 :          matrix%nblkrowscols_split = matrix%nblkrows
     153              : 
     154       623658 :          ASSOCIATE (rows => dist%local_rowcols)
     155       623658 :             nrows = SIZE(rows)
     156       623658 :             ncols = INT(dist%col_dist%nmrowcol)
     157      1870508 :             ALLOCATE (row_blk_size_vec(nrows))
     158      1870974 :             ALLOCATE (col_blk_size_vec(ncols))
     159      5058896 :             DO irow = 1, nrows
     160      5058896 :                row_blk_size_vec(irow) = row_blk_size%data(rows(irow))
     161              :             END DO
     162      4848144 :             DO col = 1, ncols
     163      4224486 :                col_blk_size_vec(col) = col_blk_size%data(INT(col, KIND=int_8))
     164              :             END DO
     165              :          END ASSOCIATE
     166              :       CASE (colsplit)
     167       161945 :          matrix%nblkrowscols_split = matrix%nblkcols
     168              : 
     169       785603 :          ASSOCIATE (cols => dist%local_rowcols)
     170       161945 :             ncols = SIZE(cols)
     171       161945 :             nrows = INT(dist%row_dist%nmrowcol)
     172       485835 :             ALLOCATE (row_blk_size_vec(nrows))
     173       484835 :             ALLOCATE (col_blk_size_vec(ncols))
     174      6127594 :             DO icol = 1, ncols
     175      6127594 :                col_blk_size_vec(icol) = col_blk_size%data(cols(icol))
     176              :             END DO
     177      1559342 :             DO row = 1, nrows
     178      1397397 :                row_blk_size_vec(row) = row_blk_size%data(INT(row, KIND=int_8))
     179              :             END DO
     180              :          END ASSOCIATE
     181              :       END SELECT
     182              : 
     183              :       CALL dbm_create(matrix=matrix%matrix, &
     184              :                       name=name, &
     185              :                       dist=dist%dbm_dist, &
     186              :                       row_block_sizes=row_blk_size_vec, &
     187       785603 :                       col_block_sizes=col_blk_size_vec)
     188              : 
     189       785603 :       DEALLOCATE (row_blk_size_vec, col_blk_size_vec)
     190       785603 :       matrix%valid = .TRUE.
     191       785603 :       CALL timestop(handle)
     192              : 
     193       785603 :    END SUBROUTINE dbt_tas_create_new
     194              : 
     195              : ! **************************************************************************************************
     196              : !> \brief Create matrix from template
     197              : !> \param matrix_in ...
     198              : !> \param matrix ...
     199              : !> \param name ...
     200              : !> \author Patrick Seewald
     201              : ! **************************************************************************************************
     202      2046093 :    SUBROUTINE dbt_tas_create_template(matrix_in, matrix, name)
     203              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix_in
     204              :       TYPE(dbt_tas_type), INTENT(OUT)                    :: matrix
     205              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: name
     206              : 
     207       292299 :       IF (PRESENT(name)) THEN
     208       292287 :          CALL dbm_create_from_template(matrix%matrix, name=name, template=matrix_in%matrix)
     209              :       ELSE
     210              :          CALL dbm_create_from_template(matrix%matrix, name=dbm_get_name(matrix_in%matrix), &
     211           12 :                                        template=matrix_in%matrix)
     212              :       END IF
     213       292299 :       CALL dbm_finalize(matrix%matrix)
     214              : 
     215       292299 :       CALL dbt_tas_copy_distribution(matrix_in%dist, matrix%dist)
     216       292299 :       ALLOCATE (matrix%row_blk_size, source=matrix_in%row_blk_size)
     217       292299 :       ALLOCATE (matrix%col_blk_size, source=matrix_in%col_blk_size)
     218       292299 :       matrix%nblkrows = matrix_in%nblkrows
     219       292299 :       matrix%nblkcols = matrix_in%nblkcols
     220       292299 :       matrix%nblkrowscols_split = matrix_in%nblkrowscols_split
     221       292299 :       matrix%nfullrows = matrix_in%nfullrows
     222       292299 :       matrix%nfullcols = matrix_in%nfullcols
     223       292299 :       matrix%valid = .TRUE.
     224              : 
     225       292299 :    END SUBROUTINE dbt_tas_create_template
     226              : 
     227              : ! **************************************************************************************************
     228              : !> \brief ...
     229              : !> \param matrix ...
     230              : !> \author Patrick Seewald
     231              : ! **************************************************************************************************
     232      1077902 :    SUBROUTINE dbt_tas_destroy(matrix)
     233              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     234              : 
     235      1077902 :       CALL dbm_release(matrix%matrix)
     236      1077902 :       CALL dbt_tas_distribution_destroy(matrix%dist)
     237      1077902 :       DEALLOCATE (matrix%row_blk_size)
     238      1077902 :       DEALLOCATE (matrix%col_blk_size)
     239      1077902 :       matrix%valid = .FALSE.
     240      1077902 :    END SUBROUTINE dbt_tas_destroy
     241              : 
     242              : ! **************************************************************************************************
     243              : !> \brief Copy matrix_a to matrix_b
     244              : !> \param matrix_b ...
     245              : !> \param matrix_a ...
     246              : !> \param summation Whether to sum matrices b = a + b
     247              : !> \author Patrick Seewald
     248              : ! **************************************************************************************************
     249       264188 :    SUBROUTINE dbt_tas_copy(matrix_b, matrix_a, summation)
     250              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix_b
     251              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix_a
     252              :       LOGICAL, INTENT(IN), OPTIONAL                      :: summation
     253              : 
     254              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'dbt_tas_copy'
     255              : 
     256              :       INTEGER                                            :: handle
     257              :       INTEGER(KIND=int_8)                                :: column, row
     258       264188 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     259              :       TYPE(dbt_tas_iterator)                             :: iter
     260              : 
     261       264188 :       CALL timeset(routineN, handle)
     262       264188 :       CPASSERT(matrix_b%valid)
     263              : 
     264       264188 :       IF (PRESENT(summation)) THEN
     265        45396 :          IF (.NOT. summation) CALL dbt_tas_clear(matrix_b)
     266              :       ELSE
     267       218792 :          CALL dbt_tas_clear(matrix_b)
     268              :       END IF
     269              : 
     270       264188 :       CALL dbt_tas_reserve_blocks(matrix_a, matrix_b)
     271              : 
     272              : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_a,matrix_b,summation) &
     273       264188 : !$OMP PRIVATE(iter,row,column,block)
     274              :       CALL dbt_tas_iterator_start(iter, matrix_a)
     275              :       DO WHILE (dbt_tas_iterator_blocks_left(iter))
     276              :          CALL dbt_tas_iterator_next_block(iter, row, column, block)
     277              :          CALL dbt_tas_put_block(matrix_b, row, column, block, summation=summation)
     278              :       END DO
     279              :       CALL dbt_tas_iterator_stop(iter)
     280              : !$OMP END PARALLEL
     281              : 
     282       264188 :       CALL timestop(handle)
     283       264188 :    END SUBROUTINE dbt_tas_copy
     284              : 
     285              : ! **************************************************************************************************
     286              : !> \brief Make sure that matrix_out has same blocks reserved as matrix_in.
     287              : !>         This assumes that both matrices have same number of block rows and block columns.
     288              : !> \param matrix_in ...
     289              : !> \param matrix_out ...
     290              : !> \author Patrick Seewald
     291              : ! **************************************************************************************************
     292       382092 :    SUBROUTINE dbt_tas_reserve_blocks_template(matrix_in, matrix_out)
     293              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix_in
     294              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix_out
     295              : 
     296              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_tas_reserve_blocks_template'
     297              : 
     298              :       INTEGER                                            :: handle, iblk, nblk
     299       382092 :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:)     :: columns, rows
     300              :       TYPE(dbt_tas_iterator)                             :: iter
     301              : 
     302       382092 :       CALL timeset(routineN, handle)
     303              : 
     304              : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_in,matrix_out) &
     305       382092 : !$OMP PRIVATE(iter,nblk,rows,columns)
     306              :       CALL dbt_tas_iterator_start(iter, matrix_in)
     307              :       nblk = dbt_tas_iterator_num_blocks(iter)
     308              :       ALLOCATE (rows(nblk), columns(nblk))
     309              :       DO iblk = 1, nblk
     310              :          CALL dbt_tas_iterator_next_block(iter, row=rows(iblk), column=columns(iblk))
     311              :       END DO
     312              :       CPASSERT(.NOT. dbt_tas_iterator_blocks_left(iter))
     313              :       CALL dbt_tas_iterator_stop(iter)
     314              : 
     315              :       CALL dbt_tas_reserve_blocks_index(matrix_out, rows=rows, columns=columns)
     316              : !$OMP END PARALLEL
     317              : 
     318       382092 :       CALL timestop(handle)
     319       764184 :    END SUBROUTINE dbt_tas_reserve_blocks_template
     320              : 
     321              : ! **************************************************************************************************
     322              : !> \brief ...
     323              : !> \param matrix ...
     324              : !> \author Patrick Seewald
     325              : ! **************************************************************************************************
     326      1893670 :    SUBROUTINE dbt_tas_finalize(matrix)
     327              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     328              : 
     329      1893670 :       CALL dbm_finalize(matrix%matrix)
     330      1893670 :    END SUBROUTINE dbt_tas_finalize
     331              : 
     332              : ! **************************************************************************************************
     333              : !> \brief create new distribution.
     334              : !>        Exactly like dbm_distribution_new but with custom types for row_dist and col_dist
     335              : !>        instead of arrays.
     336              : !> \param dist ...
     337              : !> \param mp_comm ...
     338              : !> \param row_dist ...
     339              : !> \param col_dist ...
     340              : !> \param split_info Strategy of how to split process grid (optional).
     341              : !>        If not present a default split heuristic is applied.
     342              : !> \param nosplit if .TRUE. don't split process grid (optional)
     343              : !> \author Patrick Seewald
     344              : ! **************************************************************************************************
     345      5816818 :    SUBROUTINE dbt_tas_distribution_new(dist, mp_comm, row_dist, col_dist, split_info, nosplit)
     346              :       TYPE(dbt_tas_distribution_type), INTENT(OUT)       :: dist
     347              :       TYPE(mp_cart_type), INTENT(IN)                     :: mp_comm
     348              : 
     349              :       CLASS(dbt_tas_distribution), INTENT(IN)        :: row_dist, col_dist
     350              :       TYPE(dbt_tas_split_info), INTENT(IN), OPTIONAL :: split_info
     351              :       !!
     352              :       LOGICAL, INTENT(IN), OPTIONAL                    :: nosplit
     353              :       !LOGICAL, INTENT(IN), OPTIONAL                    :: strict_split
     354              : 
     355      4985844 :       TYPE(dbt_tas_split_info)                       :: split_info_prv
     356              : 
     357       830974 :       INTEGER, DIMENSION(:), POINTER, CONTIGUOUS       :: row_dist_vec
     358       830974 :       INTEGER, DIMENSION(:), POINTER, CONTIGUOUS       :: col_dist_vec
     359              :       INTEGER                                          :: nrows, ncols, irow, col, icol, row, &
     360              :                                                           split_rowcol, nsplit, handle
     361              :       LOGICAL                                          :: opt_nsplit
     362              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_tas_distribution_new'
     363              : 
     364       830974 :       CALL timeset(routineN, handle)
     365       830974 :       IF (PRESENT(split_info)) THEN
     366       572311 :          CALL dbt_tas_info_hold(split_info)
     367       572311 :          split_info_prv = split_info
     368              :       ELSE
     369              :          ! default split heuristic: split into submatrices that have roughly same block dimensions
     370       258663 :          IF (row_dist%nmrowcol >= col_dist%nmrowcol) THEN
     371       239611 :             split_rowcol = rowsplit
     372       239611 :             nsplit = INT((row_dist%nmrowcol - 1)/col_dist%nmrowcol + 1)
     373              :          ELSE
     374        19052 :             split_rowcol = colsplit
     375        19052 :             nsplit = INT((col_dist%nmrowcol - 1)/row_dist%nmrowcol + 1)
     376              :          END IF
     377       258663 :          opt_nsplit = .TRUE.
     378       258663 :          IF (PRESENT(nosplit)) THEN
     379       182690 :             IF (nosplit) THEN
     380       182690 :                nsplit = 1
     381       182690 :                opt_nsplit = .FALSE.
     382              :             END IF
     383              :          END IF
     384       258663 :          CALL dbt_tas_create_split(split_info_prv, mp_comm, split_rowcol, nsplit=nsplit, opt_nsplit=opt_nsplit)
     385              :       END IF
     386              : 
     387      1465138 :       SELECT CASE (split_info_prv%split_rowcol)
     388              :       CASE (rowsplit)
     389       634164 :          CALL group_to_mrowcol(split_info_prv, row_dist, split_info_prv%igroup, dist%local_rowcols)
     390       634164 :          nrows = SIZE(dist%local_rowcols)
     391       634164 :          ncols = INT(col_dist%nmrowcol)
     392      1901621 :          ALLOCATE (row_dist_vec(nrows))
     393      1902492 :          ALLOCATE (col_dist_vec(ncols))
     394      5490905 :          DO irow = 1, nrows
     395      5490905 :             row_dist_vec(irow) = row_dist%dist(dist%local_rowcols(irow)) - split_info_prv%pgrid_split_size*split_info_prv%igroup
     396              :          END DO
     397      5212468 :          DO col = 1, ncols
     398      4578304 :             col_dist_vec(col) = col_dist%dist(INT(col, KIND=int_8))
     399              :          END DO
     400              :       CASE (colsplit)
     401       196810 :          CALL group_to_mrowcol(split_info_prv, col_dist, split_info_prv%igroup, dist%local_rowcols)
     402       196810 :          ncols = SIZE(dist%local_rowcols)
     403       196810 :          nrows = INT(row_dist%nmrowcol)
     404       588430 :          ALLOCATE (col_dist_vec(ncols))
     405       590430 :          ALLOCATE (row_dist_vec(nrows))
     406      9385943 :          DO icol = 1, ncols
     407      9385943 :             col_dist_vec(icol) = col_dist%dist(dist%local_rowcols(icol)) - split_info_prv%pgrid_split_size*split_info_prv%igroup
     408              :          END DO
     409      2699640 :          DO row = 1, nrows
     410      1671856 :             row_dist_vec(row) = row_dist%dist(INT(row, KIND=int_8))
     411              :          END DO
     412              :       END SELECT
     413              : 
     414       830974 :       dist%info = split_info_prv
     415              : 
     416              :       CALL dbm_distribution_new(dist%dbm_dist, split_info_prv%mp_comm_group, &
     417       830974 :                                 row_dist_vec, col_dist_vec)
     418       830974 :       DEALLOCATE (row_dist_vec, col_dist_vec)
     419       830974 :       ALLOCATE (dist%row_dist, source=row_dist)
     420       830974 :       ALLOCATE (dist%col_dist, source=col_dist)
     421              : 
     422              :       !IF(PRESENT(strict_split)) dist%strict_split = strict_split
     423              : 
     424       830974 :       CALL timestop(handle)
     425      1661948 :    END SUBROUTINE dbt_tas_distribution_new
     426              : 
     427              : ! **************************************************************************************************
     428              : !> \brief ...
     429              : !> \param dist ...
     430              : !> \author Patrick Seewald
     431              : ! **************************************************************************************************
     432      1522864 :    SUBROUTINE dbt_tas_distribution_destroy(dist)
     433              :       TYPE(dbt_tas_distribution_type), INTENT(INOUT)     :: dist
     434              : 
     435              :       ! Note: Issue with Cray CCE compiler
     436              :       ! commented out the following deallocate statements on polymorphic variables,
     437              :       ! these cause segfaults with CCE compiler at a later point
     438              : 
     439              :       !IF (ALLOCATED(dist%row_dist)) THEN
     440              :       !   DEALLOCATE (dist%row_dist)
     441              :       !ENDIF
     442              :       !IF (ALLOCATED(dist%col_dist)) THEN
     443              :       !   DEALLOCATE (dist%col_dist)
     444              :       !ENDIF
     445              : 
     446      1522864 :       IF (ALLOCATED(dist%local_rowcols)) THEN
     447      1522864 :          DEALLOCATE (dist%local_rowcols)
     448              :       END IF
     449      1522864 :       CALL dbt_tas_release_info(dist%info)
     450      1522864 :       CALL dbm_distribution_release(dist%dbm_dist)
     451      1522864 :    END SUBROUTINE dbt_tas_distribution_destroy
     452              : 
     453              : ! **************************************************************************************************
     454              : !> \brief As dbt_get_stored_coordinates
     455              : !> \param matrix ...
     456              : !> \param row global matrix blocked row
     457              : !> \param column global matrix blocked column
     458              : !> \param processor process ID
     459              : !> \author Patrick Seewald
     460              : ! **************************************************************************************************
     461     12649956 :    SUBROUTINE dbt_tas_get_stored_coordinates(matrix, row, column, processor)
     462              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     463              :       INTEGER(KIND=int_8), INTENT(IN)                    :: row, column
     464              :       INTEGER, INTENT(OUT)                               :: processor
     465              : 
     466              :       INTEGER, DIMENSION(2)                              :: pcoord
     467              :       TYPE(dbt_tas_split_info), POINTER                  :: info
     468              : 
     469     12649956 :       pcoord(1) = matrix%dist%row_dist%dist(row)
     470     12649956 :       pcoord(2) = matrix%dist%col_dist%dist(column)
     471     12649956 :       info => dbt_tas_info(matrix)
     472              : 
     473              :       ! workaround for inefficient mpi_cart_rank
     474     12649956 :       processor = pcoord(1)*info%pdims(2) + pcoord(2)
     475              : 
     476     12649956 :    END SUBROUTINE dbt_tas_get_stored_coordinates
     477              : 
     478              : ! **************************************************************************************************
     479              : !> \brief Get all processors for a given row/col combination if matrix is replicated on each process
     480              : !>        subgroup.
     481              : !> \param matrix tall-and-skinny matrix whose DBM submatrices are replicated matrices
     482              : !> \param row row of a submatrix
     483              : !> \param column column of a submatrix
     484              : !> \param processors ...
     485              : !> \author Patrick Seewald
     486              : ! **************************************************************************************************
     487      2916552 :    SUBROUTINE dbt_repl_get_stored_coordinates(matrix, row, column, processors)
     488              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     489              :       INTEGER, INTENT(IN)                                :: row, column
     490              :       INTEGER, DIMENSION(:), INTENT(OUT)                 :: processors
     491              : 
     492              :       INTEGER                                            :: igroup
     493              :       INTEGER(KIND=int_8)                                :: col_s, row_s
     494              :       INTEGER, DIMENSION(2)                              :: pcoord
     495     17499312 :       TYPE(dbt_tas_split_info)                           :: info
     496              : 
     497      2916552 :       row_s = INT(row, KIND=int_8); col_s = INT(column, KIND=int_8)
     498              : 
     499      2916552 :       info = dbt_tas_info(matrix)
     500      2916552 :       pcoord(1) = matrix%dist%row_dist%dist(row_s)
     501      2916552 :       pcoord(2) = matrix%dist%col_dist%dist(col_s)
     502              : 
     503      7099850 :       DO igroup = 0, info%ngroup - 1
     504      4183298 :          CALL info%mp_comm%rank_cart(pcoord, processors(igroup + 1))
     505      2916552 :          SELECT CASE (info%split_rowcol)
     506              :          CASE (rowsplit)
     507      2711276 :             row_s = row_s + dbt_tas_nblkrows_local(matrix)
     508      2711276 :             pcoord(1) = matrix%dist%row_dist%dist(row_s)
     509              :          CASE (colsplit)
     510      1472022 :             col_s = col_s + dbt_tas_nblkcols_local(matrix)
     511      5655320 :             pcoord(2) = matrix%dist%col_dist%dist(col_s)
     512              :          END SELECT
     513              :       END DO
     514      2916552 :    END SUBROUTINE dbt_repl_get_stored_coordinates
     515              : 
     516              : ! **************************************************************************************************
     517              : !> \brief Convert a tall-and-skinny matrix into a normal DBM matrix.
     518              : !>        This is not recommended for matrices with a very large dimension.
     519              : !> \param matrix_rect ...
     520              : !> \param matrix_dbm ...
     521              : !> \author Patrick Seewald
     522              : ! **************************************************************************************************
     523          448 :    SUBROUTINE dbt_tas_convert_to_dbm(matrix_rect, matrix_dbm)
     524              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix_rect
     525              :       TYPE(dbm_type), INTENT(OUT)                        :: matrix_dbm
     526              : 
     527              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_tas_convert_to_dbm'
     528              : 
     529              :       INTEGER                                            :: handle, nblks_local, rb_count
     530              :       INTEGER(KIND=int_8)                                :: col, row
     531          224 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: nz_cols, nz_rows
     532          224 :       INTEGER, CONTIGUOUS, DIMENSION(:), POINTER         :: col_dist_vec, col_size_vec, &
     533          224 :                                                             row_dist_vec, row_size_vec
     534          224 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     535              :       TYPE(dbm_distribution_obj)                         :: dist
     536              :       TYPE(dbt_tas_iterator)                             :: iter
     537         1344 :       TYPE(dbt_tas_split_info)                           :: info
     538              : 
     539          224 :       CALL timeset(routineN, handle)
     540              : 
     541          224 :       info = dbt_tas_info(matrix_rect)
     542              : 
     543          672 :       ALLOCATE (row_dist_vec(matrix_rect%nblkrows))
     544          448 :       ALLOCATE (row_size_vec(matrix_rect%nblkrows))
     545          672 :       ALLOCATE (col_dist_vec(matrix_rect%nblkcols))
     546          448 :       ALLOCATE (col_size_vec(matrix_rect%nblkcols))
     547              : 
     548         8944 :       DO row = 1, matrix_rect%nblkrows
     549         8720 :          row_dist_vec(row) = matrix_rect%dist%row_dist%dist(row)
     550         8944 :          row_size_vec(row) = matrix_rect%row_blk_size%data(row)
     551              :       END DO
     552              : 
     553         7998 :       DO col = 1, matrix_rect%nblkcols
     554         7774 :          col_dist_vec(col) = matrix_rect%dist%col_dist%dist(col)
     555         7998 :          col_size_vec(col) = matrix_rect%col_blk_size%data(col)
     556              :       END DO
     557              : 
     558          224 :       CALL dbm_distribution_new(dist, info%mp_comm, row_dist_vec, col_dist_vec)
     559          224 :       DEALLOCATE (row_dist_vec, col_dist_vec)
     560              : 
     561              :       CALL dbm_create(matrix=matrix_dbm, &
     562              :                       name=TRIM(dbm_get_name(matrix_rect%matrix)), &
     563              :                       dist=dist, &
     564              :                       row_block_sizes=row_size_vec, &
     565          224 :                       col_block_sizes=col_size_vec)
     566              : 
     567          224 :       CALL dbm_distribution_release(dist)
     568              : 
     569          224 :       DEALLOCATE (row_size_vec, col_size_vec)
     570              : 
     571              : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_rect,matrix_dbm) &
     572          224 : !$OMP PRIVATE(iter,nblks_local,nz_rows,nz_cols,rb_count,row,col,block)
     573              :       CALL dbt_tas_iterator_start(iter, matrix_rect)
     574              :       nblks_local = dbt_tas_iterator_num_blocks(iter)
     575              :       ALLOCATE (nz_rows(nblks_local), nz_cols(nblks_local))
     576              :       rb_count = 0
     577              :       DO WHILE (dbt_tas_iterator_blocks_left(iter))
     578              :          CALL dbt_tas_iterator_next_block(iter, row, col)
     579              :          rb_count = rb_count + 1
     580              :          nz_rows(rb_count) = INT(row)
     581              :          nz_cols(rb_count) = INT(col)
     582              :       END DO
     583              :       CALL dbt_tas_iterator_stop(iter)
     584              : 
     585              :       CALL dbm_reserve_blocks(matrix_dbm, nz_rows, nz_cols)
     586              : 
     587              :       CALL dbt_tas_iterator_start(iter, matrix_rect)
     588              :       DO WHILE (dbt_tas_iterator_blocks_left(iter))
     589              :          CALL dbt_tas_iterator_next_block(iter, row, col, block)
     590              :          CALL dbm_put_block(matrix_dbm, INT(row), INT(col), block)
     591              :       END DO
     592              :       CALL dbt_tas_iterator_stop(iter)
     593              : !$OMP END PARALLEL
     594              : 
     595          224 :       CALL dbm_finalize(matrix_dbm)
     596              : 
     597          224 :       CALL timestop(handle)
     598          672 :    END SUBROUTINE dbt_tas_convert_to_dbm
     599              : 
     600              : ! **************************************************************************************************
     601              : !> \brief Converts a DBM matrix into the tall-and-skinny matrix type.
     602              : !> \param info Strategy of how to split process grid
     603              : !> \param matrix_rect ...
     604              : !> \param matrix_dbm ...
     605              : !> \author Patrick Seewald
     606              : ! **************************************************************************************************
     607            0 :    SUBROUTINE dbt_tas_convert_to_tas(info, matrix_rect, matrix_dbm)
     608              :       TYPE(dbt_tas_split_info), INTENT(IN)               :: info
     609              :       TYPE(dbt_tas_type), INTENT(OUT)                    :: matrix_rect
     610              :       TYPE(dbm_type), INTENT(IN)                         :: matrix_dbm
     611              : 
     612              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_tas_convert_to_tas'
     613              : 
     614              :       CHARACTER(len=default_string_length)               :: name
     615              :       INTEGER                                            :: col, handle, row
     616              :       INTEGER(KIND=int_8)                                :: nbcols, nbrows
     617            0 :       INTEGER, CONTIGUOUS, DIMENSION(:), POINTER         :: col_blk_size, row_blk_size
     618              :       INTEGER, DIMENSION(2)                              :: pdims
     619            0 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     620              :       TYPE(dbm_distribution_obj)                         :: dbm_dist
     621              :       TYPE(dbm_iterator)                                 :: iter
     622            0 :       TYPE(dbt_tas_blk_size_arb)                         :: col_blk_size_obj, row_blk_size_obj
     623            0 :       TYPE(dbt_tas_dist_arb)                             :: col_dist_obj, row_dist_obj
     624            0 :       TYPE(dbt_tas_distribution_type)                    :: dist
     625              : 
     626              :       NULLIFY (col_blk_size, row_blk_size)
     627            0 :       CALL timeset(routineN, handle)
     628            0 :       pdims = info%mp_comm%num_pe_cart
     629              : 
     630            0 :       name = dbm_get_name(matrix_dbm)
     631            0 :       row_blk_size => dbm_get_row_block_sizes(matrix_dbm)
     632            0 :       col_blk_size => dbm_get_col_block_sizes(matrix_dbm)
     633              : 
     634            0 :       nbrows = SIZE(row_blk_size)
     635            0 :       nbcols = SIZE(col_blk_size)
     636              : 
     637            0 :       dbm_dist = dbm_get_distribution(matrix_dbm)
     638            0 :       row_dist_obj = dbt_tas_dist_arb(dbm_distribution_row_dist(dbm_dist), pdims(1), nbrows)
     639            0 :       col_dist_obj = dbt_tas_dist_arb(dbm_distribution_col_dist(dbm_dist), pdims(2), nbcols)
     640              : 
     641            0 :       row_blk_size_obj = dbt_tas_blk_size_arb(row_blk_size)
     642            0 :       col_blk_size_obj = dbt_tas_blk_size_arb(col_blk_size)
     643              : 
     644            0 :       CALL dbt_tas_distribution_new(dist, info%mp_comm, row_dist_obj, col_dist_obj)
     645              : 
     646              :       CALL dbt_tas_create(matrix_rect, TRIM(name)//"_compressed", &
     647            0 :                           dist, row_blk_size_obj, col_blk_size_obj)
     648              : 
     649            0 : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_dbm,matrix_rect) PRIVATE(iter,row,col,block)
     650              :       CALL dbm_iterator_start(iter, matrix_dbm)
     651              :       DO WHILE (dbm_iterator_blocks_left(iter))
     652              :          CALL dbm_iterator_next_block(iter, row, col, block)
     653              :          CALL dbt_tas_put_block(matrix_rect, INT(row, KIND=int_8), INT(col, KIND=int_8), block)
     654              :       END DO
     655              :       CALL dbm_iterator_stop(iter)
     656              : !$OMP END PARALLEL
     657              : 
     658            0 :       CALL dbt_tas_finalize(matrix_rect)
     659              : 
     660            0 :       CALL timestop(handle)
     661            0 :    END SUBROUTINE dbt_tas_convert_to_tas
     662              : 
     663              : ! **************************************************************************************************
     664              : !> \brief As dbm_iterator_start
     665              : !> \param iter ...
     666              : !> \param matrix_in ...
     667              : !> \author Patrick Seewald
     668              : ! **************************************************************************************************
     669      3019690 :    SUBROUTINE dbt_tas_iterator_start(iter, matrix_in)
     670              :       TYPE(dbt_tas_iterator), INTENT(INOUT)              :: iter
     671              :       TYPE(dbt_tas_type), INTENT(IN), TARGET             :: matrix_in
     672              : 
     673      3019690 :       CALL dbm_iterator_start(iter%iter, matrix_in%matrix)
     674              : 
     675      3019690 :       iter%dist => matrix_in%dist
     676      3019690 :    END SUBROUTINE dbt_tas_iterator_start
     677              : 
     678              : ! **************************************************************************************************
     679              : !> \brief As dbm_iterator_num_blocks
     680              : !> \param iter ...
     681              : !> \return ...
     682              : !> \author Ole Schuett
     683              : ! **************************************************************************************************
     684       639233 :    FUNCTION dbt_tas_iterator_num_blocks(iter)
     685              :       TYPE(dbt_tas_iterator), INTENT(IN)                 :: iter
     686              :       INTEGER                                            :: dbt_tas_iterator_num_blocks
     687              : 
     688       639233 :       dbt_tas_iterator_num_blocks = dbm_iterator_num_blocks(iter%iter)
     689       639233 :    END FUNCTION dbt_tas_iterator_num_blocks
     690              : 
     691              : ! **************************************************************************************************
     692              : !> \brief As dbm_iterator_blocks_left
     693              : !> \param iter ...
     694              : !> \return ...
     695              : !> \author Patrick Seewald
     696              : ! **************************************************************************************************
     697     54528168 :    FUNCTION dbt_tas_iterator_blocks_left(iter)
     698              :       TYPE(dbt_tas_iterator), INTENT(IN)                 :: iter
     699              :       LOGICAL                                            :: dbt_tas_iterator_blocks_left
     700              : 
     701     54528168 :       dbt_tas_iterator_blocks_left = dbm_iterator_blocks_left(iter%iter)
     702     54528168 :    END FUNCTION dbt_tas_iterator_blocks_left
     703              : 
     704              : ! **************************************************************************************************
     705              : !> \brief As dbm_iterator_stop
     706              : !> \param iter ...
     707              : !> \author Patrick Seewald
     708              : ! **************************************************************************************************
     709      3019690 :    SUBROUTINE dbt_tas_iterator_stop(iter)
     710              :       TYPE(dbt_tas_iterator), INTENT(INOUT)              :: iter
     711              : 
     712      3019690 :       CALL dbm_iterator_stop(iter%iter)
     713      3019690 :    END SUBROUTINE dbt_tas_iterator_stop
     714              : 
     715              : ! **************************************************************************************************
     716              : !> \brief As dbm_iterator_next_block
     717              : !> \param iterator ...
     718              : !> \param row global block row
     719              : !> \param column global block column
     720              : !> \param row_size ...
     721              : !> \param col_size ...
     722              : !> \author Patrick Seewald
     723              : ! **************************************************************************************************
     724     99186698 :    SUBROUTINE dbt_tas_iterator_next_block_index(iterator, row, column, row_size, col_size)
     725              :       TYPE(dbt_tas_iterator), INTENT(INOUT)              :: iterator
     726              :       INTEGER(KIND=int_8), INTENT(OUT)                   :: row, column
     727              :       INTEGER, INTENT(OUT), OPTIONAL                     :: row_size, col_size
     728              : 
     729              :       INTEGER                                            :: column_group, row_group
     730              : 
     731              :       CALL dbm_iterator_next_block(iterator%iter, row=row_group, column=column_group, &
     732     49593349 :                                    row_size=row_size, col_size=col_size)
     733              : 
     734              :       CALL dbt_index_local_to_global(iterator%dist%info, iterator%dist, row_group=row_group, column_group=column_group, &
     735     49593349 :                                      row=row, column=column)
     736              : 
     737     49593349 :    END SUBROUTINE dbt_tas_iterator_next_block_index
     738              : 
     739              : ! **************************************************************************************************
     740              : !> \brief As dbm_reserve_blocks
     741              : !> \param matrix ...
     742              : !> \param rows ...
     743              : !> \param columns ...
     744              : !> \author Patrick Seewald
     745              : ! **************************************************************************************************
     746      1262753 :    SUBROUTINE dbt_tas_reserve_blocks_index(matrix, rows, columns)
     747              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     748              :       INTEGER(KIND=int_8), DIMENSION(:), INTENT(IN)      :: rows, columns
     749              : 
     750              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'dbt_tas_reserve_blocks_index'
     751              : 
     752              :       INTEGER                                            :: handle, i
     753      2525506 :       INTEGER, DIMENSION(SIZE(rows))                     :: columns_group, rows_group
     754              :       TYPE(dbt_tas_split_info), POINTER                  :: info
     755              : 
     756      1262753 :       CALL timeset(routineN, handle)
     757              : 
     758      1262753 :       info => dbt_tas_info(matrix)
     759              : 
     760      1262753 :       CPASSERT(SIZE(rows) == SIZE(columns))
     761     27125596 :       DO i = 1, SIZE(rows)
     762              :          CALL dbt_index_global_to_local(info, matrix%dist, &
     763              :                                         row=rows(i), row_group=rows_group(i), &
     764     27125596 :                                         column=columns(i), column_group=columns_group(i))
     765              :       END DO
     766              : 
     767      1262753 :       CALL dbm_reserve_blocks(matrix%matrix, rows_group, columns_group)
     768              : 
     769      1262753 :       CALL timestop(handle)
     770      1262753 :    END SUBROUTINE dbt_tas_reserve_blocks_index
     771              : 
     772              : ! **************************************************************************************************
     773              : !> \brief Copy a distribution
     774              : !> \param dist_in ...
     775              : !> \param dist_out ...
     776              : !> \param own_dist Whether distribution should be owned by dist_out
     777              : !> \author Patrick Seewald
     778              : ! **************************************************************************************************
     779      7545314 :    SUBROUTINE dbt_tas_copy_distribution(dist_in, dist_out, own_dist)
     780              :       TYPE(dbt_tas_distribution_type), INTENT(INOUT)     :: dist_in
     781              :       TYPE(dbt_tas_distribution_type), INTENT(OUT)       :: dist_out
     782              :       LOGICAL, INTENT(IN), OPTIONAL                      :: own_dist
     783              : 
     784              :       LOGICAL                                            :: own_dist_prv
     785              : 
     786      1077902 :       IF (PRESENT(own_dist)) THEN
     787       386012 :          own_dist_prv = own_dist
     788              :       ELSE
     789              :          own_dist_prv = .FALSE.
     790              :       END IF
     791              : 
     792       386012 :       IF (.NOT. own_dist_prv) THEN
     793       691890 :          CALL dbm_distribution_hold(dist_in%dbm_dist)
     794       691890 :          CALL dbt_tas_info_hold(dist_in%info)
     795              :       END IF
     796              : 
     797      1077902 :       dist_out = dist_in
     798      1077902 :    END SUBROUTINE dbt_tas_copy_distribution
     799              : 
     800              : ! **************************************************************************************************
     801              : !> \brief Get block size for a given row & column
     802              : !> \param matrix ...
     803              : !> \param row ...
     804              : !> \param col ...
     805              : !> \param row_size ...
     806              : !> \param col_size ...
     807              : !> \author Patrick Seewald
     808              : ! **************************************************************************************************
     809      4596085 :    SUBROUTINE dbt_tas_blk_sizes(matrix, row, col, row_size, col_size)
     810              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     811              :       INTEGER(KIND=int_8), INTENT(IN)                    :: row, col
     812              :       INTEGER, INTENT(OUT)                               :: row_size, col_size
     813              : 
     814      4596085 :       row_size = matrix%row_blk_size%data(row)
     815      4596085 :       col_size = matrix%col_blk_size%data(col)
     816      4596085 :    END SUBROUTINE dbt_tas_blk_sizes
     817              : 
     818              : ! **************************************************************************************************
     819              : !> \brief get info on mpi grid splitting
     820              : !> \param matrix ...
     821              : !> \return ...
     822              : !> \author Patrick Seewald
     823              : ! **************************************************************************************************
     824    256904722 :    FUNCTION dbt_tas_info(matrix)
     825              :       TYPE(dbt_tas_type), INTENT(IN), TARGET             :: matrix
     826              :       TYPE(dbt_tas_split_info), POINTER                  :: dbt_tas_info
     827              : 
     828    256904722 :       dbt_tas_info => matrix%dist%info
     829    256904722 :    END FUNCTION dbt_tas_info
     830              : 
     831              : ! **************************************************************************************************
     832              : !> \brief ...
     833              : !> \param matrix ...
     834              : !> \return ...
     835              : !> \author Patrick Seewald
     836              : ! **************************************************************************************************
     837      1511678 :    PURE FUNCTION dbt_tas_nblkrows_total(matrix) RESULT(nblkrows_total)
     838              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     839              :       INTEGER(KIND=int_8)                                :: nblkrows_total
     840              : 
     841      1511678 :       nblkrows_total = matrix%nblkrows
     842      1511678 :    END FUNCTION dbt_tas_nblkrows_total
     843              : 
     844              : ! **************************************************************************************************
     845              : !> \brief ...
     846              : !> \param matrix ...
     847              : !> \return ...
     848              : !> \author Patrick Seewald
     849              : ! **************************************************************************************************
     850            0 :    PURE FUNCTION dbt_tas_nfullrows_total(matrix) RESULT(nfullrows_total)
     851              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     852              :       INTEGER(KIND=int_8)                                :: nfullrows_total
     853              : 
     854            0 :       nfullrows_total = matrix%nfullrows
     855            0 :    END FUNCTION dbt_tas_nfullrows_total
     856              : 
     857              : ! **************************************************************************************************
     858              : !> \brief ...
     859              : !> \param matrix ...
     860              : !> \return ...
     861              : !> \author Patrick Seewald
     862              : ! **************************************************************************************************
     863      1512186 :    PURE FUNCTION dbt_tas_nblkcols_total(matrix) RESULT(nblkcols_total)
     864              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     865              :       INTEGER(KIND=int_8)                                :: nblkcols_total
     866              : 
     867      1512186 :       nblkcols_total = matrix%nblkcols
     868      1512186 :    END FUNCTION dbt_tas_nblkcols_total
     869              : 
     870              : ! **************************************************************************************************
     871              : !> \brief ...
     872              : !> \param matrix ...
     873              : !> \return ...
     874              : !> \author Patrick Seewald
     875              : ! **************************************************************************************************
     876            0 :    PURE FUNCTION dbt_tas_nfullcols_total(matrix) RESULT(nfullcols_total)
     877              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     878              :       INTEGER(KIND=int_8)                                :: nfullcols_total
     879              : 
     880            0 :       nfullcols_total = matrix%nfullcols
     881            0 :    END FUNCTION dbt_tas_nfullcols_total
     882              : 
     883              : ! **************************************************************************************************
     884              : !> \brief ...
     885              : !> \param matrix ...
     886              : !> \return ...
     887              : !> \author Patrick Seewald
     888              : ! **************************************************************************************************
     889      1472022 :    FUNCTION dbt_tas_nblkcols_local(matrix) RESULT(nblkcols_local)
     890              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     891              :       INTEGER                                            :: nblkcols_local
     892              : 
     893      1472022 :       nblkcols_local = SIZE(dbm_get_col_block_sizes(matrix%matrix))
     894      1472022 :    END FUNCTION dbt_tas_nblkcols_local
     895              : 
     896              : ! **************************************************************************************************
     897              : !> \brief ...
     898              : !> \param matrix ...
     899              : !> \return ...
     900              : !> \author Patrick Seewald
     901              : ! **************************************************************************************************
     902      2711276 :    FUNCTION dbt_tas_nblkrows_local(matrix) RESULT(nblkrows_local)
     903              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     904              :       INTEGER                                            :: nblkrows_local
     905              : 
     906      2711276 :       nblkrows_local = SIZE(dbm_get_row_block_sizes(matrix%matrix))
     907      2711276 :    END FUNCTION dbt_tas_nblkrows_local
     908              : 
     909              : ! **************************************************************************************************
     910              : !> \brief As dbt_get_num_blocks: get number of local blocks
     911              : !> \param matrix ...
     912              : !> \return ...
     913              : !> \author Patrick Seewald
     914              : ! **************************************************************************************************
     915      1029546 :    PURE FUNCTION dbt_tas_get_num_blocks(matrix) RESULT(num_blocks)
     916              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     917              :       INTEGER                                            :: num_blocks
     918              : 
     919      1029546 :       num_blocks = dbm_get_num_blocks(matrix%matrix)
     920      1029546 :    END FUNCTION dbt_tas_get_num_blocks
     921              : 
     922              : ! **************************************************************************************************
     923              : !> \brief get total number of blocks
     924              : !> \param matrix ...
     925              : !> \return ...
     926              : !> \author Patrick Seewald
     927              : ! **************************************************************************************************
     928       309860 :    FUNCTION dbt_tas_get_num_blocks_total(matrix) RESULT(num_blocks)
     929              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     930              :       INTEGER(KIND=int_8)                                :: num_blocks
     931              : 
     932      1549300 :       TYPE(dbt_tas_split_info)                           :: info
     933              : 
     934       309860 :       info = dbt_tas_info(matrix)
     935       309860 :       num_blocks = dbt_tas_get_num_blocks(matrix)
     936       309860 :       CALL info%mp_comm%sum(num_blocks)
     937              : 
     938       309860 :    END FUNCTION dbt_tas_get_num_blocks_total
     939              : 
     940              : ! **************************************************************************************************
     941              : !> \brief As dbt_get_nze: get number of local non-zero elements
     942              : !> \param matrix ...
     943              : !> \return ...
     944              : !> \author Patrick Seewald
     945              : ! **************************************************************************************************
     946      1672520 :    PURE FUNCTION dbt_tas_get_nze(matrix)
     947              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     948              :       INTEGER                                            :: dbt_tas_get_nze
     949              : 
     950      1672520 :       dbt_tas_get_nze = dbm_get_nze(matrix%matrix)
     951              : 
     952      1672520 :    END FUNCTION dbt_tas_get_nze
     953              : 
     954              : ! **************************************************************************************************
     955              : !> \brief Get total number of non-zero elements
     956              : !> \param matrix ...
     957              : !> \return ...
     958              : !> \author Patrick Seewald
     959              : ! **************************************************************************************************
     960      1365122 :    FUNCTION dbt_tas_get_nze_total(matrix)
     961              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     962              :       INTEGER(KIND=int_8)                                :: dbt_tas_get_nze_total
     963              : 
     964      6825610 :       TYPE(dbt_tas_split_info)                           :: info
     965              : 
     966      1365122 :       dbt_tas_get_nze_total = dbt_tas_get_nze(matrix)
     967      1365122 :       info = dbt_tas_info(matrix)
     968      1365122 :       CALL info%mp_comm%sum(dbt_tas_get_nze_total)
     969      1365122 :    END FUNCTION dbt_tas_get_nze_total
     970              : 
     971              : ! **************************************************************************************************
     972              : !> \brief Clear matrix (erase all data)
     973              : !> \param matrix ...
     974              : !> \author Patrick Seewald
     975              : ! **************************************************************************************************
     976      1737774 :    SUBROUTINE dbt_tas_clear(matrix)
     977              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     978              : 
     979      1737774 :       CALL dbm_clear(matrix%matrix)
     980      1737774 :    END SUBROUTINE dbt_tas_clear
     981              : 
     982              : ! **************************************************************************************************
     983              : !> \brief ...
     984              : !> \param matrix ...
     985              : !> \param nblkrows_total ...
     986              : !> \param nblkcols_total ...
     987              : !> \param local_rows ...
     988              : !> \param local_cols ...
     989              : !> \param proc_row_dist ...
     990              : !> \param proc_col_dist ...
     991              : !> \param row_blk_size ...
     992              : !> \param col_blk_size ...
     993              : !> \param distribution ...
     994              : !> \param name ...
     995              : !> \author Patrick Seewald
     996              : ! **************************************************************************************************
     997      1326313 :    SUBROUTINE dbt_tas_get_info(matrix, &
     998              :                                nblkrows_total, nblkcols_total, &
     999              :                                local_rows, local_cols, &
    1000              :                                proc_row_dist, proc_col_dist, &
    1001              :                                row_blk_size, col_blk_size, distribution, name)
    1002              : 
    1003              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
    1004              :       INTEGER(KIND=int_8), INTENT(OUT), OPTIONAL         :: nblkrows_total, nblkcols_total
    1005              :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:), &
    1006              :          OPTIONAL                                        :: local_rows, local_cols
    1007              : 
    1008              :       CLASS(dbt_tas_distribution), ALLOCATABLE, OPTIONAL, &
    1009              :          INTENT(OUT)                                                :: proc_row_dist, proc_col_dist
    1010              :       CLASS(dbt_tas_rowcol_data), ALLOCATABLE, OPTIONAL, &
    1011              :          INTENT(OUT)                                                :: row_blk_size, col_blk_size
    1012              :       TYPE(dbt_tas_distribution_type), OPTIONAL                     :: distribution
    1013              :       CHARACTER(len=*), INTENT(OUT), OPTIONAL                       :: name
    1014              : 
    1015      6631565 :       TYPE(dbt_tas_split_info)                                      :: info
    1016              :       INTEGER                                                       :: irow, icol
    1017      1326313 :       INTEGER, ALLOCATABLE, DIMENSION(:)                            :: local_rows_local, local_cols_local
    1018              : 
    1019      1326313 :       info = dbt_tas_info(matrix)
    1020              : 
    1021      1326313 :       IF (PRESENT(local_rows)) THEN
    1022       271476 :          CALL dbm_get_local_rows(matrix%matrix, local_rows_local)
    1023       814404 :          ALLOCATE (local_rows(SIZE(local_rows_local)))
    1024      3731798 :          DO irow = 1, SIZE(local_rows_local)
    1025      3731798 :             CALL dbt_index_local_to_global(info, matrix%dist, row_group=local_rows_local(irow), row=local_rows(irow))
    1026              :          END DO
    1027              :       END IF
    1028              : 
    1029      1326313 :       IF (PRESENT(local_cols)) THEN
    1030       125400 :          CALL dbm_get_local_cols(matrix%matrix, local_cols_local)
    1031       373036 :          ALLOCATE (local_cols(SIZE(local_cols_local)))
    1032     29273790 :          DO icol = 1, SIZE(local_cols_local)
    1033     29273790 :             CALL dbt_index_local_to_global(info, matrix%dist, column_group=local_cols_local(icol), column=local_cols(icol))
    1034              :          END DO
    1035              :       END IF
    1036              : 
    1037      1326313 :       IF (PRESENT(name)) name = dbm_get_name(matrix%matrix)
    1038      1326313 :       IF (PRESENT(nblkrows_total)) nblkrows_total = dbt_tas_nblkrows_total(matrix)
    1039      1326313 :       IF (PRESENT(nblkcols_total)) nblkcols_total = dbt_tas_nblkcols_total(matrix)
    1040      1326313 :       IF (PRESENT(proc_row_dist)) ALLOCATE (proc_row_dist, SOURCE=matrix%dist%row_dist)
    1041      1326313 :       IF (PRESENT(proc_col_dist)) ALLOCATE (proc_col_dist, SOURCE=matrix%dist%col_dist)
    1042      1326313 :       IF (PRESENT(row_blk_size)) ALLOCATE (row_blk_size, SOURCE=matrix%row_blk_size)
    1043      1326313 :       IF (PRESENT(col_blk_size)) ALLOCATE (col_blk_size, SOURCE=matrix%col_blk_size)
    1044      1326313 :       IF (PRESENT(distribution)) distribution = matrix%dist
    1045              : 
    1046      2652626 :    END SUBROUTINE dbt_tas_get_info
    1047              : 
    1048              : ! **************************************************************************************************
    1049              : !> \brief As dbm_iterator_next_block
    1050              : !> \param iterator ...
    1051              : !> \param row ...
    1052              : !> \param column ...
    1053              : !> \param block ...
    1054              : !> \param row_size ...
    1055              : !> \param col_size ...
    1056              : !> \author Patrick Seewald
    1057              : ! **************************************************************************************************
    1058     23893368 :    SUBROUTINE dbt_tas_iterator_next_block_d(iterator, row, column, block, row_size, col_size)
    1059              :       TYPE(dbt_tas_iterator), INTENT(INOUT)              :: iterator
    1060              :       INTEGER(KIND=int_8), INTENT(OUT)                   :: row, column
    1061              :       REAL(dp), DIMENSION(:, :), POINTER                 :: block
    1062              :       INTEGER, INTENT(OUT), OPTIONAL                     :: row_size, col_size
    1063              : 
    1064              :       INTEGER                                            :: column_group, row_group
    1065              : 
    1066              :       CALL dbm_iterator_next_block(iterator%iter, row_group, column_group, block, &
    1067     11946684 :                                    row_size=row_size, col_size=col_size)
    1068              : 
    1069              :       CALL dbt_index_local_to_global(iterator%dist%info, iterator%dist, row_group=row_group, column_group=column_group, &
    1070     11946684 :                                      row=row, column=column)
    1071              : 
    1072     11946684 :    END SUBROUTINE dbt_tas_iterator_next_block_d
    1073              : 
    1074              : ! **************************************************************************************************
    1075              : !> \brief As dbm_put_block
    1076              : !> \param matrix ...
    1077              : !> \param row ...
    1078              : !> \param col ...
    1079              : !> \param block ...
    1080              : !> \param summation ...
    1081              : !> \author Patrick Seewald
    1082              : ! **************************************************************************************************
    1083     30647330 :    SUBROUTINE dbt_tas_put_block(matrix, row, col, block, summation)
    1084              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
    1085              :       INTEGER(KIND=int_8), INTENT(IN)                    :: row, col
    1086              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: block
    1087              :       LOGICAL, INTENT(IN), OPTIONAL                      :: summation
    1088              : 
    1089              :       INTEGER                                            :: col_group, row_group
    1090              : 
    1091              :       CALL dbt_index_global_to_local(matrix%dist%info, matrix%dist, row=row, column=col, &
    1092     30647330 :                                      row_group=row_group, column_group=col_group)
    1093              : 
    1094  13582612201 :       CALL dbm_put_block(matrix%matrix, row_group, col_group, block, summation=summation)
    1095              : 
    1096     30647330 :    END SUBROUTINE dbt_tas_put_block
    1097              : 
    1098              : ! **************************************************************************************************
    1099              : !> \brief As dbm_get_block_p
    1100              : !> \param matrix ...
    1101              : !> \param row ...
    1102              : !> \param col ...
    1103              : !> \param block ...
    1104              : !> \param row_size ...
    1105              : !> \param col_size ...
    1106              : !> \author Patrick Seewald
    1107              : ! **************************************************************************************************
    1108     42795466 :    SUBROUTINE dbt_tas_get_block_p(matrix, row, col, block, row_size, col_size)
    1109              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
    1110              :       INTEGER(KIND=int_8), INTENT(IN)                    :: row, col
    1111              :       REAL(dp), DIMENSION(:, :), POINTER                 :: block
    1112              :       INTEGER, INTENT(OUT), OPTIONAL                     :: row_size, col_size
    1113              : 
    1114              :       INTEGER                                            :: col_group, row_group
    1115              : 
    1116              :       CALL dbt_index_global_to_local(matrix%dist%info, matrix%dist, row=row, column=col, &
    1117     21397733 :                                      row_group=row_group, column_group=col_group)
    1118              : 
    1119              :       CALL dbm_get_block_p(matrix%matrix, row_group, col_group, block, &
    1120     21397733 :                            row_size=row_size, col_size=col_size)
    1121              : 
    1122     21397733 :    END SUBROUTINE dbt_tas_get_block_p
    1123              : 
    1124              : ! **************************************************************************************************
    1125              : !> \brief As dbm_filter
    1126              : !> \param matrix ...
    1127              : !> \param eps ...
    1128              : !> \author Patrick Seewald
    1129              : ! **************************************************************************************************
    1130       394673 :    SUBROUTINE dbt_tas_filter(matrix, eps)
    1131              :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
    1132              :       REAL(dp), INTENT(IN)                               :: eps
    1133              : 
    1134       394673 :       CALL dbm_filter(matrix%matrix, eps)
    1135              : 
    1136       394673 :    END SUBROUTINE dbt_tas_filter
    1137              : 
    1138      5918071 : END MODULE dbt_tas_base
        

Generated by: LCOV version 2.0-1