LCOV - code coverage report
Current view: top level - src/dbt/tas - dbt_tas_io.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 78.7 % 108 85
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 4 4

            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: Input / Output
      10              : !> \author Patrick Seewald
      11              : ! **************************************************************************************************
      12              : MODULE dbt_tas_io
      13              :    USE dbm_api,                         ONLY: dbm_distribution_col_dist,&
      14              :                                               dbm_distribution_obj,&
      15              :                                               dbm_distribution_row_dist,&
      16              :                                               dbm_get_distribution
      17              :    USE dbt_tas_base,                    ONLY: dbt_tas_get_info,&
      18              :                                               dbt_tas_get_num_blocks,&
      19              :                                               dbt_tas_get_num_blocks_total,&
      20              :                                               dbt_tas_get_nze,&
      21              :                                               dbt_tas_get_nze_total,&
      22              :                                               dbt_tas_nblkcols_total,&
      23              :                                               dbt_tas_nblkrows_total
      24              :    USE dbt_tas_global,                  ONLY: dbt_tas_distribution,&
      25              :                                               dbt_tas_rowcol_data
      26              :    USE dbt_tas_split,                   ONLY: colsplit,&
      27              :                                               dbt_tas_get_split_info,&
      28              :                                               rowsplit
      29              :    USE dbt_tas_types,                   ONLY: dbt_tas_split_info,&
      30              :                                               dbt_tas_type
      31              :    USE kinds,                           ONLY: default_string_length,&
      32              :                                               dp,&
      33              :                                               int_8
      34              :    USE message_passing,                 ONLY: mp_cart_type
      35              : #include "../../base/base_uses.f90"
      36              : 
      37              :    IMPLICIT NONE
      38              :    PRIVATE
      39              : 
      40              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dbt_tas_io'
      41              : 
      42              :    PUBLIC :: &
      43              :       dbt_tas_write_dist, &
      44              :       dbt_tas_write_matrix_info, &
      45              :       dbt_tas_write_split_info, &
      46              :       prep_output_unit
      47              : 
      48              : CONTAINS
      49              : 
      50              : ! **************************************************************************************************
      51              : !> \brief Write basic infos of tall-and-skinny matrix:
      52              : !>        block dimensions, full dimensions, process grid dimensions
      53              : !> \param matrix ...
      54              : !> \param unit_nr ...
      55              : !> \param full_info Whether to print distribution and block size vectors
      56              : !> \author Patrick Seewald
      57              : ! **************************************************************************************************
      58       142950 :    SUBROUTINE dbt_tas_write_matrix_info(matrix, unit_nr, full_info)
      59              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
      60              :       INTEGER, INTENT(IN)                                :: unit_nr
      61              :       LOGICAL, INTENT(IN), OPTIONAL                      :: full_info
      62              : 
      63              :       INTEGER                                            :: unit_nr_prv
      64              :       INTEGER(KIND=int_8)                                :: nblkcols_total, nblkrows_total
      65              : 
      66       428850 :       CLASS(dbt_tas_distribution), ALLOCATABLE :: proc_row_dist, proc_col_dist
      67       428850 :       CLASS(dbt_tas_rowcol_data), ALLOCATABLE  :: row_blk_size, col_blk_size
      68              :       INTEGER(KIND=int_8)                      :: iblk
      69              :       CHARACTER(default_string_length)         :: name
      70              : 
      71       142950 :       unit_nr_prv = prep_output_unit(unit_nr)
      72       142950 :       IF (unit_nr_prv == 0) RETURN
      73              : 
      74              :       CALL dbt_tas_get_info(matrix, nblkrows_total=nblkrows_total, nblkcols_total=nblkcols_total, &
      75              :                             proc_row_dist=proc_row_dist, proc_col_dist=proc_col_dist, &
      76       142950 :                             row_blk_size=row_blk_size, col_blk_size=col_blk_size, name=name)
      77              : 
      78       142950 :       IF (unit_nr_prv > 0) THEN
      79          102 :          WRITE (unit_nr_prv, "(T2,A)") "GLOBAL INFO OF "//TRIM(name)
      80          102 :          WRITE (unit_nr_prv, "(T4,A,1X)", advance="no") "block dimensions:"
      81          102 :          WRITE (unit_nr_prv, "(I12,I12)", advance="no") nblkrows_total, nblkcols_total
      82          102 :          WRITE (unit_nr_prv, "(/T4,A,1X)", advance="no") "full dimensions:"
      83          102 :          WRITE (unit_nr_prv, "(I14,I14)", advance="no") row_blk_size%nfullrowcol, col_blk_size%nfullrowcol
      84          102 :          WRITE (unit_nr_prv, "(/T4,A,1X)", advance="no") "process grid dimensions:"
      85          102 :          WRITE (unit_nr_prv, "(I10,I10)", advance="no") proc_row_dist%nprowcol, proc_col_dist%nprowcol
      86          102 :          IF (PRESENT(full_info)) THEN
      87           30 :             IF (full_info) THEN
      88            0 :                WRITE (unit_nr_prv, '(/T4,A)', advance='no') "Block sizes:"
      89            0 :                WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Row:'
      90            0 :                DO iblk = 1, row_blk_size%nmrowcol
      91            0 :                   WRITE (unit_nr_prv, '(I4,1X)', advance='no') row_blk_size%data(iblk)
      92              :                END DO
      93            0 :                WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Column:'
      94            0 :                DO iblk = 1, col_blk_size%nmrowcol
      95            0 :                   WRITE (unit_nr_prv, '(I4,1X)', advance='no') col_blk_size%data(iblk)
      96              :                END DO
      97            0 :                WRITE (unit_nr_prv, '(/T4,A)', advance='no') "Block distribution:"
      98            0 :                WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Row:'
      99            0 :                DO iblk = 1, proc_row_dist%nmrowcol
     100            0 :                   WRITE (unit_nr_prv, '(I4,1X)', advance='no') proc_row_dist%dist(iblk)
     101              :                END DO
     102            0 :                WRITE (unit_nr_prv, '(/T8,A)', advance='no') 'Column:'
     103            0 :                DO iblk = 1, proc_col_dist%nmrowcol
     104            0 :                   WRITE (unit_nr_prv, '(I4,1X)', advance='no') proc_col_dist%dist(iblk)
     105              :                END DO
     106              : 
     107              :             END IF
     108              :          END IF
     109          102 :          WRITE (unit_nr_prv, *)
     110              :       END IF
     111              : 
     112       714558 :    END SUBROUTINE
     113              : 
     114              : ! **************************************************************************************************
     115              : !> \brief Write info on tall-and-skinny matrix distribution & load balance
     116              : !> \param matrix ...
     117              : !> \param unit_nr ...
     118              : !> \param full_info Whether to print subgroup DBM distribution
     119              : !> \author Patrick Seewald
     120              : ! **************************************************************************************************
     121       156456 :    SUBROUTINE dbt_tas_write_dist(matrix, unit_nr, full_info)
     122              :       TYPE(dbt_tas_type), INTENT(IN)                     :: matrix
     123              :       INTEGER, INTENT(IN)                                :: unit_nr
     124              :       LOGICAL, INTENT(IN), OPTIONAL                      :: full_info
     125              : 
     126              :       CHARACTER(default_string_length)                   :: name
     127              :       INTEGER                                            :: icol, igroup, irow, nblock, ndbt_p_max, &
     128              :                                                             nelement, nelement_p_max, ngroup, &
     129              :                                                             nproc, split_rowcol, unit_nr_prv
     130              :       INTEGER(KIND=int_8)                                :: ndbt_p_sum, ndbt_s, ndbt_s_max, &
     131              :                                                             ndbt_tot, nelement_p_sum, nelement_s, &
     132              :                                                             nelement_s_max
     133              :       INTEGER(KIND=int_8), DIMENSION(2)                  :: tmp_i8
     134              :       INTEGER, DIMENSION(2)                              :: tmp
     135       156456 :       INTEGER, DIMENSION(:), POINTER                     :: coldist, rowdist
     136              :       REAL(KIND=dp)                                      :: occupation
     137              :       TYPE(dbm_distribution_obj)                         :: dist
     138       156456 :       TYPE(mp_cart_type)                                 :: mp_comm, mp_comm_group
     139              : 
     140       156456 :       unit_nr_prv = prep_output_unit(unit_nr)
     141       156456 :       IF (unit_nr_prv == 0) RETURN
     142              : 
     143       156456 :       CALL dbt_tas_get_split_info(matrix%dist%info, mp_comm, ngroup, igroup, mp_comm_group, split_rowcol)
     144       156456 :       CALL dbt_tas_get_info(matrix, name=name)
     145       156456 :       nproc = mp_comm%num_pe
     146              : 
     147       156456 :       nblock = dbt_tas_get_num_blocks(matrix)
     148       156456 :       nelement = dbt_tas_get_nze(matrix)
     149              : 
     150       156456 :       ndbt_p_sum = dbt_tas_get_num_blocks_total(matrix)
     151       156456 :       nelement_p_sum = dbt_tas_get_nze_total(matrix)
     152              : 
     153       469368 :       tmp = (/nblock, nelement/)
     154       156456 :       CALL mp_comm%max(tmp)
     155       156456 :       ndbt_p_max = tmp(1); nelement_p_max = tmp(2)
     156              : 
     157       156456 :       ndbt_s = nblock
     158       156456 :       nelement_s = nelement
     159              : 
     160       156456 :       CALL mp_comm_group%sum(ndbt_s)
     161       156456 :       CALL mp_comm_group%sum(nelement_s)
     162              : 
     163       469368 :       tmp_i8 = (/ndbt_s, nelement_s/)
     164       156456 :       CALL mp_comm%max(tmp_i8)
     165       156456 :       ndbt_s_max = tmp_i8(1); nelement_s_max = tmp_i8(2)
     166              : 
     167       156456 :       ndbt_tot = dbt_tas_nblkrows_total(matrix)*dbt_tas_nblkcols_total(matrix)
     168       156456 :       occupation = -1.0_dp
     169       156456 :       IF (ndbt_tot .NE. 0) occupation = 100.0_dp*REAL(ndbt_p_sum, dp)/REAL(ndbt_tot, dp)
     170              : 
     171       156456 :       dist = dbm_get_distribution(matrix%matrix)
     172       156456 :       rowdist => dbm_distribution_row_dist(dist)
     173       156456 :       coldist => dbm_distribution_col_dist(dist)
     174              : 
     175       156456 :       IF (unit_nr_prv > 0) THEN
     176              :          WRITE (unit_nr_prv, "(T2,A)") &
     177          102 :             "DISTRIBUTION OF "//TRIM(name)
     178          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Number of non-zero blocks:", ndbt_p_sum
     179          102 :          WRITE (unit_nr_prv, "(T15,A,T75,F6.2)") "Percentage of non-zero blocks:", occupation
     180          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of blocks per group:", (ndbt_p_sum + ngroup - 1)/ngroup
     181          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of blocks per group:", ndbt_s_max
     182          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of matrix elements per group:", (nelement_p_sum + ngroup - 1)/ngroup
     183          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of matrix elements per group:", nelement_s_max
     184          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of blocks per CPU:", (ndbt_p_sum + nproc - 1)/nproc
     185          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of blocks per CPU:", ndbt_p_max
     186          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Average number of matrix elements per CPU:", (nelement_p_sum + nproc - 1)/nproc
     187          102 :          WRITE (unit_nr_prv, "(T15,A,T68,I13)") "Maximum number of matrix elements per CPU:", nelement_p_max
     188          102 :          IF (PRESENT(full_info)) THEN
     189           10 :             IF (full_info) THEN
     190            0 :                WRITE (unit_nr_prv, "(T15,A)") "Row distribution on subgroup:"
     191            0 :                WRITE (unit_nr_prv, '(T15)', advance='no')
     192            0 :                DO irow = 1, SIZE(rowdist)
     193            0 :                   WRITE (unit_nr_prv, '(I3, 1X)', advance='no') rowdist(irow)
     194              :                END DO
     195            0 :                WRITE (unit_nr_prv, "(/T15,A)") "Column distribution on subgroup:"
     196            0 :                WRITE (unit_nr_prv, '(T15)', advance='no')
     197            0 :                DO icol = 1, SIZE(coldist)
     198            0 :                   WRITE (unit_nr_prv, '(I3, 1X)', advance='no') coldist(icol)
     199              :                END DO
     200            0 :                WRITE (unit_nr_prv, *)
     201              :             END IF
     202              :          END IF
     203              :       END IF
     204       312912 :    END SUBROUTINE
     205              : 
     206              : ! **************************************************************************************************
     207              : !> \brief Print info on how matrix is split
     208              : !> \param info ...
     209              : !> \param unit_nr ...
     210              : !> \param name ...
     211              : !> \author Patrick Seewald
     212              : ! **************************************************************************************************
     213        52164 :    SUBROUTINE dbt_tas_write_split_info(info, unit_nr, name)
     214              :       TYPE(dbt_tas_split_info), INTENT(IN)               :: info
     215              :       INTEGER, INTENT(IN)                                :: unit_nr
     216              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: name
     217              : 
     218        52164 :       CHARACTER(len=:), ALLOCATABLE                      :: name_prv
     219              :       INTEGER                                            :: igroup, mynode, nsplit, split_rowcol, &
     220              :                                                             unit_nr_prv
     221              :       INTEGER, DIMENSION(2)                              :: dims, groupdims, pgrid_offset
     222        52164 :       TYPE(mp_cart_type)                                 :: mp_comm, mp_comm_group
     223              : 
     224        52164 :       unit_nr_prv = prep_output_unit(unit_nr)
     225        52164 :       IF (unit_nr_prv == 0) RETURN
     226              : 
     227        52164 :       IF (PRESENT(name)) THEN
     228           12 :          ALLOCATE (name_prv, SOURCE=TRIM(name))
     229              :       ELSE
     230        52152 :          ALLOCATE (name_prv, SOURCE="")
     231              :       END IF
     232              : 
     233        52164 :       CALL dbt_tas_get_split_info(info, mp_comm, nsplit, igroup, mp_comm_group, split_rowcol, pgrid_offset)
     234              : 
     235        52164 :       mynode = mp_comm%mepos
     236       156492 :       dims = mp_comm%num_pe_cart
     237       156492 :       groupdims = mp_comm_group%num_pe_cart
     238              : 
     239        52164 :       IF (unit_nr_prv > 0) THEN
     240           35 :          SELECT CASE (split_rowcol)
     241              :          CASE (rowsplit)
     242           35 :             WRITE (unit_nr_prv, "(T4,A,I4,1X,A,I4)") name_prv//"splitting rows by factor", nsplit
     243              :          CASE (colsplit)
     244           40 :             WRITE (unit_nr_prv, "(T4,A,I4,1X,A,I4)") name_prv//"splitting columns by factor", nsplit
     245              :          END SELECT
     246           40 :          WRITE (unit_nr_prv, "(T4,A,I4,A1,I4)") name_prv//"global grid sizes:", dims(1), "x", dims(2)
     247              :       END IF
     248              : 
     249              :       IF (unit_nr_prv > 0) THEN
     250              :          WRITE (unit_nr_prv, "(T4,A,I4,A1,I4)") &
     251           40 :             name_prv//"grid sizes on subgroups:", &
     252           80 :             groupdims(1), "x", groupdims(2)
     253              :       END IF
     254              : 
     255        52164 :    END SUBROUTINE
     256              : 
     257              : ! **************************************************************************************************
     258              : !> \brief ...
     259              : !> \param unit_nr ...
     260              : !> \return ...
     261              : !> \author Patrick Seewald
     262              : ! **************************************************************************************************
     263       976896 :    FUNCTION prep_output_unit(unit_nr) RESULT(unit_nr_out)
     264              :       INTEGER, INTENT(IN), OPTIONAL                      :: unit_nr
     265              :       INTEGER                                            :: unit_nr_out
     266              : 
     267       976896 :       IF (PRESENT(unit_nr)) THEN
     268       711892 :          unit_nr_out = unit_nr
     269              :       ELSE
     270              :          unit_nr_out = 0
     271              :       END IF
     272              : 
     273       976896 :    END FUNCTION
     274              : 
     275              : END MODULE
     276              : 
        

Generated by: LCOV version 2.0-1