LCOV - code coverage report
Current view: top level - src/dbt/tas - dbt_tas_base.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:15a58fb) Lines: 293 323 90.7 %
Date: 2025-02-18 08:24:35 Functions: 34 37 91.9 %

          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     5892180 :    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      841740 :       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      841740 :       CALL timeset(routineN, handle)
     134             : 
     135      841740 :       CALL dbt_tas_copy_distribution(dist, matrix%dist, own_dist)
     136      841740 :       matrix%nblkrows = row_blk_size%nmrowcol
     137      841740 :       matrix%nblkcols = col_blk_size%nmrowcol
     138             : 
     139      841740 :       CPASSERT(matrix%nblkrows == dist%row_dist%nmrowcol)
     140      841740 :       CPASSERT(matrix%nblkcols == dist%col_dist%nmrowcol)
     141             : 
     142      841740 :       matrix%nfullrows = row_blk_size%nfullrowcol
     143      841740 :       matrix%nfullcols = col_blk_size%nfullrowcol
     144             : 
     145      841740 :       ALLOCATE (matrix%row_blk_size, source=row_blk_size)
     146      841740 :       ALLOCATE (matrix%col_blk_size, source=col_blk_size)
     147             : 
     148      841740 :       info => dbt_tas_info(matrix)
     149             : 
     150     1521522 :       SELECT CASE (info%split_rowcol)
     151             :       CASE (rowsplit)
     152      679782 :          matrix%nblkrowscols_split = matrix%nblkrows
     153             : 
     154      679782 :          ASSOCIATE (rows => dist%local_rowcols)
     155      679782 :             nrows = SIZE(rows)
     156      679782 :             ncols = INT(dist%col_dist%nmrowcol)
     157     2039026 :             ALLOCATE (row_blk_size_vec(nrows))
     158     2039346 :             ALLOCATE (col_blk_size_vec(ncols))
     159     5139876 :             DO irow = 1, nrows
     160     5139876 :                row_blk_size_vec(irow) = row_blk_size%data(rows(irow))
     161             :             END DO
     162     4906907 :             DO col = 1, ncols
     163     4227125 :                col_blk_size_vec(col) = col_blk_size%data(INT(col, KIND=int_8))
     164             :             END DO
     165             :          END ASSOCIATE
     166             :       CASE (colsplit)
     167      161958 :          matrix%nblkrowscols_split = matrix%nblkcols
     168             : 
     169      841740 :          ASSOCIATE (cols => dist%local_rowcols)
     170      161958 :             ncols = SIZE(cols)
     171      161958 :             nrows = INT(dist%row_dist%nmrowcol)
     172      485874 :             ALLOCATE (row_blk_size_vec(nrows))
     173      485122 :             ALLOCATE (col_blk_size_vec(ncols))
     174     6479106 :             DO icol = 1, ncols
     175     6479106 :                col_blk_size_vec(icol) = col_blk_size%data(cols(icol))
     176             :             END DO
     177     1452881 :             DO row = 1, nrows
     178     1290923 :                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      841740 :                       col_block_sizes=col_blk_size_vec)
     188             : 
     189      841740 :       DEALLOCATE (row_blk_size_vec, col_blk_size_vec)
     190      841740 :       matrix%valid = .TRUE.
     191      841740 :       CALL timestop(handle)
     192             : 
     193      841740 :    END SUBROUTINE
     194             : 
     195             : ! **************************************************************************************************
     196             : !> \brief Create matrix from template
     197             : !> \param matrix_in ...
     198             : !> \param matrix ...
     199             : !> \param name ...
     200             : !> \author Patrick Seewald
     201             : ! **************************************************************************************************
     202     1934548 :    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      276364 :       IF (PRESENT(name)) THEN
     208      276352 :          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      276364 :       CALL dbm_finalize(matrix%matrix)
     214             : 
     215      276364 :       CALL dbt_tas_copy_distribution(matrix_in%dist, matrix%dist)
     216      276364 :       ALLOCATE (matrix%row_blk_size, source=matrix_in%row_blk_size)
     217      276364 :       ALLOCATE (matrix%col_blk_size, source=matrix_in%col_blk_size)
     218      276364 :       matrix%nblkrows = matrix_in%nblkrows
     219      276364 :       matrix%nblkcols = matrix_in%nblkcols
     220      276364 :       matrix%nblkrowscols_split = matrix_in%nblkrowscols_split
     221      276364 :       matrix%nfullrows = matrix_in%nfullrows
     222      276364 :       matrix%nfullcols = matrix_in%nfullcols
     223      276364 :       matrix%valid = .TRUE.
     224             : 
     225      276364 :    END SUBROUTINE
     226             : 
     227             : ! **************************************************************************************************
     228             : !> \brief ...
     229             : !> \param matrix ...
     230             : !> \author Patrick Seewald
     231             : ! **************************************************************************************************
     232     1118104 :    SUBROUTINE dbt_tas_destroy(matrix)
     233             :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     234             : 
     235     1118104 :       CALL dbm_release(matrix%matrix)
     236     1118104 :       CALL dbt_tas_distribution_destroy(matrix%dist)
     237     1118104 :       DEALLOCATE (matrix%row_blk_size)
     238     1118104 :       DEALLOCATE (matrix%col_blk_size)
     239     1118104 :       matrix%valid = .FALSE.
     240     1118104 :    END SUBROUTINE
     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      230960 :    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      230960 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     259             :       TYPE(dbt_tas_iterator)                             :: iter
     260             : 
     261      230960 :       CALL timeset(routineN, handle)
     262      230960 :       CPASSERT(matrix_b%valid)
     263             : 
     264      230960 :       IF (PRESENT(summation)) THEN
     265       38490 :          IF (.NOT. summation) CALL dbt_tas_clear(matrix_b)
     266             :       ELSE
     267      192470 :          CALL dbt_tas_clear(matrix_b)
     268             :       END IF
     269             : 
     270      230960 :       CALL dbt_tas_reserve_blocks(matrix_a, matrix_b)
     271             : 
     272             : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_a,matrix_b,summation) &
     273      230960 : !$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      230960 :       CALL timestop(handle)
     283      230960 :    END SUBROUTINE
     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      370552 :    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      370552 :       INTEGER(KIND=int_8), ALLOCATABLE, DIMENSION(:)     :: columns, rows
     300             :       TYPE(dbt_tas_iterator)                             :: iter
     301             : 
     302      370552 :       CALL timeset(routineN, handle)
     303             : 
     304             : !$OMP PARALLEL DEFAULT(NONE) SHARED(matrix_in,matrix_out) &
     305      370552 : !$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      370552 :       CALL timestop(handle)
     319      741104 :    END SUBROUTINE
     320             : 
     321             : ! **************************************************************************************************
     322             : !> \brief ...
     323             : !> \param matrix ...
     324             : !> \author Patrick Seewald
     325             : ! **************************************************************************************************
     326     1839494 :    SUBROUTINE dbt_tas_finalize(matrix)
     327             :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     328             : 
     329     1839494 :       CALL dbm_finalize(matrix%matrix)
     330     1839494 :    END SUBROUTINE
     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     5917352 :    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     5072016 :       TYPE(dbt_tas_split_info)                       :: split_info_prv
     356             : 
     357      845336 :       INTEGER, DIMENSION(:), POINTER, CONTIGUOUS       :: row_dist_vec
     358      845336 :       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      845336 :       CALL timeset(routineN, handle)
     365      845336 :       IF (PRESENT(split_info)) THEN
     366      574744 :          CALL dbt_tas_info_hold(split_info)
     367      574744 :          split_info_prv = split_info
     368             :       ELSE
     369             :          ! default split heuristic: split into submatrices that have roughly same block dimensions
     370      270592 :          IF (row_dist%nmrowcol >= col_dist%nmrowcol) THEN
     371      254366 :             split_rowcol = rowsplit
     372      254366 :             nsplit = INT((row_dist%nmrowcol - 1)/col_dist%nmrowcol + 1)
     373             :          ELSE
     374       16226 :             split_rowcol = colsplit
     375       16226 :             nsplit = INT((col_dist%nmrowcol - 1)/row_dist%nmrowcol + 1)
     376             :          END IF
     377      270592 :          opt_nsplit = .TRUE.
     378      270592 :          IF (PRESENT(nosplit)) THEN
     379      198644 :             IF (nosplit) THEN
     380      198644 :                nsplit = 1
     381      198644 :                opt_nsplit = .FALSE.
     382             :             END IF
     383             :          END IF
     384      270592 :          CALL dbt_tas_create_split(split_info_prv, mp_comm, split_rowcol, nsplit=nsplit, opt_nsplit=opt_nsplit)
     385             :       END IF
     386             : 
     387     1495398 :       SELECT CASE (split_info_prv%split_rowcol)
     388             :       CASE (rowsplit)
     389      650062 :          CALL group_to_mrowcol(split_info_prv, row_dist, split_info_prv%igroup, dist%local_rowcols)
     390      650062 :          nrows = SIZE(dist%local_rowcols)
     391      650062 :          ncols = INT(col_dist%nmrowcol)
     392     1949607 :          ALLOCATE (row_dist_vec(nrows))
     393     1950186 :          ALLOCATE (col_dist_vec(ncols))
     394     5167371 :          DO irow = 1, nrows
     395     5167371 :             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     5019487 :          DO col = 1, ncols
     398     4369425 :             col_dist_vec(col) = col_dist%dist(INT(col, KIND=int_8))
     399             :          END DO
     400             :       CASE (colsplit)
     401      195274 :          CALL group_to_mrowcol(split_info_prv, col_dist, split_info_prv%igroup, dist%local_rowcols)
     402      195274 :          ncols = SIZE(dist%local_rowcols)
     403      195274 :          nrows = INT(row_dist%nmrowcol)
     404      584318 :          ALLOCATE (col_dist_vec(ncols))
     405      585822 :          ALLOCATE (row_dist_vec(nrows))
     406     8463972 :          DO icol = 1, ncols
     407     8463972 :             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     2585171 :          DO row = 1, nrows
     410     1544561 :             row_dist_vec(row) = row_dist%dist(INT(row, KIND=int_8))
     411             :          END DO
     412             :       END SELECT
     413             : 
     414      845336 :       dist%info = split_info_prv
     415             : 
     416             :       CALL dbm_distribution_new(dist%dbm_dist, split_info_prv%mp_comm_group, &
     417      845336 :                                 row_dist_vec, col_dist_vec)
     418      845336 :       DEALLOCATE (row_dist_vec, col_dist_vec)
     419      845336 :       ALLOCATE (dist%row_dist, source=row_dist)
     420      845336 :       ALLOCATE (dist%col_dist, source=col_dist)
     421             : 
     422             :       !IF(PRESENT(strict_split)) dist%strict_split = strict_split
     423             : 
     424      845336 :       CALL timestop(handle)
     425     1690672 :    END SUBROUTINE
     426             : 
     427             : ! **************************************************************************************************
     428             : !> \brief ...
     429             : !> \param dist ...
     430             : !> \author Patrick Seewald
     431             : ! **************************************************************************************************
     432     1544636 :    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     1544636 :       IF (ALLOCATED(dist%local_rowcols)) THEN
     447     1544636 :          DEALLOCATE (dist%local_rowcols)
     448             :       END IF
     449     1544636 :       CALL dbt_tas_release_info(dist%info)
     450     1544636 :       CALL dbm_distribution_release(dist%dbm_dist)
     451     1544636 :    END SUBROUTINE
     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    11090316 :    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    11090316 :       pcoord(1) = matrix%dist%row_dist%dist(row)
     470    11090316 :       pcoord(2) = matrix%dist%col_dist%dist(column)
     471    11090316 :       info => dbt_tas_info(matrix)
     472             : 
     473             :       ! workaround for inefficient mpi_cart_rank
     474    11090316 :       processor = pcoord(1)*info%pdims(2) + pcoord(2)
     475             : 
     476    11090316 :    END SUBROUTINE
     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     2873118 :    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    17238708 :       TYPE(dbt_tas_split_info)                           :: info
     496             : 
     497     2873118 :       row_s = INT(row, KIND=int_8); col_s = INT(column, KIND=int_8)
     498             : 
     499     2873118 :       info = dbt_tas_info(matrix)
     500     2873118 :       pcoord(1) = matrix%dist%row_dist%dist(row_s)
     501     2873118 :       pcoord(2) = matrix%dist%col_dist%dist(col_s)
     502             : 
     503     7058156 :       DO igroup = 0, info%ngroup - 1
     504     4185038 :          CALL info%mp_comm%rank_cart(pcoord, processors(igroup + 1))
     505     2873118 :          SELECT CASE (info%split_rowcol)
     506             :          CASE (rowsplit)
     507     2720404 :             row_s = row_s + dbt_tas_nblkrows_local(matrix)
     508     2720404 :             pcoord(1) = matrix%dist%row_dist%dist(row_s)
     509             :          CASE (colsplit)
     510     1464634 :             col_s = col_s + dbt_tas_nblkcols_local(matrix)
     511     5649672 :             pcoord(2) = matrix%dist%col_dist%dist(col_s)
     512             :          END SELECT
     513             :       END DO
     514     2873118 :    END SUBROUTINE
     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
     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
     662             : 
     663             : ! **************************************************************************************************
     664             : !> \brief As dbm_iterator_start
     665             : !> \param iter ...
     666             : !> \param matrix_in ...
     667             : !> \author Patrick Seewald
     668             : ! **************************************************************************************************
     669     2924232 :    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     2924232 :       CALL dbm_iterator_start(iter%iter, matrix_in%matrix)
     674             : 
     675     2924232 :       iter%dist => matrix_in%dist
     676     2924232 :    END SUBROUTINE
     677             : 
     678             : ! **************************************************************************************************
     679             : !> \brief As dbm_iterator_num_blocks
     680             : !> \param iter ...
     681             : !> \return ...
     682             : !> \author Ole Schuett
     683             : ! **************************************************************************************************
     684      620127 :    FUNCTION dbt_tas_iterator_num_blocks(iter)
     685             :       TYPE(dbt_tas_iterator), INTENT(IN)                 :: iter
     686             :       INTEGER                                            :: dbt_tas_iterator_num_blocks
     687             : 
     688      620127 :       dbt_tas_iterator_num_blocks = dbm_iterator_num_blocks(iter%iter)
     689      620127 :    END FUNCTION
     690             : 
     691             : ! **************************************************************************************************
     692             : !> \brief As dbm_iterator_blocks_left
     693             : !> \param iter ...
     694             : !> \return ...
     695             : !> \author Patrick Seewald
     696             : ! **************************************************************************************************
     697    53338076 :    FUNCTION dbt_tas_iterator_blocks_left(iter)
     698             :       TYPE(dbt_tas_iterator), INTENT(IN)                 :: iter
     699             :       LOGICAL                                            :: dbt_tas_iterator_blocks_left
     700             : 
     701    53338076 :       dbt_tas_iterator_blocks_left = dbm_iterator_blocks_left(iter%iter)
     702    53338076 :    END FUNCTION
     703             : 
     704             : ! **************************************************************************************************
     705             : !> \brief As dbm_iterator_stop
     706             : !> \param iter ...
     707             : !> \author Patrick Seewald
     708             : ! **************************************************************************************************
     709     2924232 :    SUBROUTINE dbt_tas_iterator_stop(iter)
     710             :       TYPE(dbt_tas_iterator), INTENT(INOUT)              :: iter
     711             : 
     712     2924232 :       CALL dbm_iterator_stop(iter%iter)
     713     2924232 :    END SUBROUTINE
     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    97233688 :    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    48616844 :                                    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    48616844 :                                      row=row, column=column)
     736             : 
     737    48616844 :    END SUBROUTINE
     738             : 
     739             : ! **************************************************************************************************
     740             : !> \brief As dbm_reserve_blocks
     741             : !> \param matrix ...
     742             : !> \param rows ...
     743             : !> \param columns ...
     744             : !> \author Patrick Seewald
     745             : ! **************************************************************************************************
     746     1238335 :    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     2476670 :       INTEGER, DIMENSION(SIZE(rows))                     :: columns_group, rows_group
     754             :       TYPE(dbt_tas_split_info), POINTER                  :: info
     755             : 
     756     1238335 :       CALL timeset(routineN, handle)
     757             : 
     758     1238335 :       info => dbt_tas_info(matrix)
     759             : 
     760     1238335 :       CPASSERT(SIZE(rows) == SIZE(columns))
     761    26482197 :       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    26482197 :                                         column=columns(i), column_group=columns_group(i))
     765             :       END DO
     766             : 
     767     1238335 :       CALL dbm_reserve_blocks(matrix%matrix, rows_group, columns_group)
     768             : 
     769     1238335 :       CALL timestop(handle)
     770     1238335 :    END SUBROUTINE
     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     7826728 :    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     1118104 :       IF (PRESENT(own_dist)) THEN
     787      418804 :          own_dist_prv = own_dist
     788             :       ELSE
     789             :          own_dist_prv = .FALSE.
     790             :       END IF
     791             : 
     792      418804 :       IF (.NOT. own_dist_prv) THEN
     793      699300 :          CALL dbm_distribution_hold(dist_in%dbm_dist)
     794      699300 :          CALL dbt_tas_info_hold(dist_in%info)
     795             :       END IF
     796             : 
     797     1118104 :       dist_out = dist_in
     798     1118104 :    END SUBROUTINE
     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     4350516 :    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     4350516 :       row_size = matrix%row_blk_size%data(row)
     815     4350516 :       col_size = matrix%col_blk_size%data(col)
     816     4350516 :    END SUBROUTINE
     817             : 
     818             : ! **************************************************************************************************
     819             : !> \brief get info on mpi grid splitting
     820             : !> \param matrix ...
     821             : !> \return ...
     822             : !> \author Patrick Seewald
     823             : ! **************************************************************************************************
     824   254012638 :    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   254012638 :       dbt_tas_info => matrix%dist%info
     829   254012638 :    END FUNCTION
     830             : 
     831             : ! **************************************************************************************************
     832             : !> \brief ...
     833             : !> \param matrix ...
     834             : !> \return ...
     835             : !> \author Patrick Seewald
     836             : ! **************************************************************************************************
     837     1557884 :    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     1557884 :       nblkrows_total = matrix%nblkrows
     842     1557884 :    END FUNCTION
     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
     856             : 
     857             : ! **************************************************************************************************
     858             : !> \brief ...
     859             : !> \param matrix ...
     860             : !> \return ...
     861             : !> \author Patrick Seewald
     862             : ! **************************************************************************************************
     863     1558392 :    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     1558392 :       nblkcols_total = matrix%nblkcols
     868     1558392 :    END FUNCTION
     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
     882             : 
     883             : ! **************************************************************************************************
     884             : !> \brief ...
     885             : !> \param matrix ...
     886             : !> \return ...
     887             : !> \author Patrick Seewald
     888             : ! **************************************************************************************************
     889     1464634 :    FUNCTION dbt_tas_nblkcols_local(matrix) RESULT(nblkcols_local)
     890             :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     891             :       INTEGER                                            :: nblkcols_local
     892             : 
     893     1464634 :       nblkcols_local = SIZE(dbm_get_col_block_sizes(matrix%matrix))
     894     1464634 :    END FUNCTION
     895             : 
     896             : ! **************************************************************************************************
     897             : !> \brief ...
     898             : !> \param matrix ...
     899             : !> \return ...
     900             : !> \author Patrick Seewald
     901             : ! **************************************************************************************************
     902     2720404 :    FUNCTION dbt_tas_nblkrows_local(matrix) RESULT(nblkrows_local)
     903             :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     904             :       INTEGER                                            :: nblkrows_local
     905             : 
     906     2720404 :       nblkrows_local = SIZE(dbm_get_row_block_sizes(matrix%matrix))
     907     2720404 :    END FUNCTION
     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      992542 :    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      992542 :       num_blocks = dbm_get_num_blocks(matrix%matrix)
     920      992542 :    END FUNCTION
     921             : 
     922             : ! **************************************************************************************************
     923             : !> \brief get total number of blocks
     924             : !> \param matrix ...
     925             : !> \return ...
     926             : !> \author Patrick Seewald
     927             : ! **************************************************************************************************
     928      273776 :    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     1368880 :       TYPE(dbt_tas_split_info)                           :: info
     933             : 
     934      273776 :       info = dbt_tas_info(matrix)
     935      273776 :       num_blocks = dbt_tas_get_num_blocks(matrix)
     936      273776 :       CALL info%mp_comm%sum(num_blocks)
     937             : 
     938      273776 :    END FUNCTION
     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     1606114 :    PURE FUNCTION dbt_tas_get_nze(matrix)
     947             :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     948             :       INTEGER                                            :: dbt_tas_get_nze
     949             : 
     950     1606114 :       dbt_tas_get_nze = dbm_get_nze(matrix%matrix)
     951             : 
     952     1606114 :    END FUNCTION
     953             : 
     954             : ! **************************************************************************************************
     955             : !> \brief Get total number of non-zero elements
     956             : !> \param matrix ...
     957             : !> \return ...
     958             : !> \author Patrick Seewald
     959             : ! **************************************************************************************************
     960     1334360 :    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     6671800 :       TYPE(dbt_tas_split_info)                           :: info
     965             : 
     966     1334360 :       dbt_tas_get_nze_total = dbt_tas_get_nze(matrix)
     967     1334360 :       info = dbt_tas_info(matrix)
     968     1334360 :       CALL info%mp_comm%sum(dbt_tas_get_nze_total)
     969     1334360 :    END FUNCTION
     970             : 
     971             : ! **************************************************************************************************
     972             : !> \brief Clear matrix (erase all data)
     973             : !> \param matrix ...
     974             : !> \author Patrick Seewald
     975             : ! **************************************************************************************************
     976     1793983 :    SUBROUTINE dbt_tas_clear(matrix)
     977             :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
     978             : 
     979     1793983 :       CALL dbm_clear(matrix%matrix)
     980     1793983 :    END SUBROUTINE
     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     1341484 :    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     6707420 :       TYPE(dbt_tas_split_info)                                      :: info
    1016             :       INTEGER                                                       :: irow, icol
    1017     1341484 :       INTEGER, ALLOCATABLE, DIMENSION(:)                            :: local_rows_local, local_cols_local
    1018             : 
    1019     1341484 :       info = dbt_tas_info(matrix)
    1020             : 
    1021     1341484 :       IF (PRESENT(local_rows)) THEN
    1022      300592 :          CALL dbm_get_local_rows(matrix%matrix, local_rows_local)
    1023      901752 :          ALLOCATE (local_rows(SIZE(local_rows_local)))
    1024     3835476 :          DO irow = 1, SIZE(local_rows_local)
    1025     3835476 :             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     1341484 :       IF (PRESENT(local_cols)) THEN
    1030      109898 :          CALL dbm_get_local_cols(matrix%matrix, local_cols_local)
    1031      326570 :          ALLOCATE (local_cols(SIZE(local_cols_local)))
    1032    37447866 :          DO icol = 1, SIZE(local_cols_local)
    1033    37447866 :             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     1341484 :       IF (PRESENT(name)) name = dbm_get_name(matrix%matrix)
    1038     1341484 :       IF (PRESENT(nblkrows_total)) nblkrows_total = dbt_tas_nblkrows_total(matrix)
    1039     1341484 :       IF (PRESENT(nblkcols_total)) nblkcols_total = dbt_tas_nblkcols_total(matrix)
    1040     1341484 :       IF (PRESENT(proc_row_dist)) ALLOCATE (proc_row_dist, SOURCE=matrix%dist%row_dist)
    1041     1341484 :       IF (PRESENT(proc_col_dist)) ALLOCATE (proc_col_dist, SOURCE=matrix%dist%col_dist)
    1042     1341484 :       IF (PRESENT(row_blk_size)) ALLOCATE (row_blk_size, SOURCE=matrix%row_blk_size)
    1043     1341484 :       IF (PRESENT(col_blk_size)) ALLOCATE (col_blk_size, SOURCE=matrix%col_blk_size)
    1044     1341484 :       IF (PRESENT(distribution)) distribution = matrix%dist
    1045             : 
    1046     2682968 :    END SUBROUTINE
    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    26926118 :    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    13463059 :                                    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    13463059 :                                      row=row, column=column)
    1071             : 
    1072    13463059 :    END SUBROUTINE
    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    32180802 :    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    32180802 :                                      row_group=row_group, column_group=col_group)
    1093             : 
    1094 16507935725 :       CALL dbm_put_block(matrix%matrix, row_group, col_group, block, summation=summation)
    1095             : 
    1096    32180802 :    END SUBROUTINE
    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    45059486 :    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    22529743 :                                      row_group=row_group, column_group=col_group)
    1118             : 
    1119             :       CALL dbm_get_block_p(matrix%matrix, row_group, col_group, block, &
    1120    22529743 :                            row_size=row_size, col_size=col_size)
    1121             : 
    1122    22529743 :    END SUBROUTINE
    1123             : 
    1124             : ! **************************************************************************************************
    1125             : !> \brief As dbm_filter
    1126             : !> \param matrix ...
    1127             : !> \param eps ...
    1128             : !> \author Patrick Seewald
    1129             : ! **************************************************************************************************
    1130      378536 :    SUBROUTINE dbt_tas_filter(matrix, eps)
    1131             :       TYPE(dbt_tas_type), INTENT(INOUT)                  :: matrix
    1132             :       REAL(dp), INTENT(IN)                               :: eps
    1133             : 
    1134      378536 :       CALL dbm_filter(matrix%matrix, eps)
    1135             : 
    1136      378536 :    END SUBROUTINE
    1137             : 
    1138     5822962 : END MODULE

Generated by: LCOV version 1.15