LCOV - code coverage report
Current view: top level - src/dbt/tas - dbt_tas_io.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 85 108 78.7 %
Date: 2024-12-21 06:28:57 Functions: 4 4 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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      125340 :    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      376020 :       CLASS(dbt_tas_distribution), ALLOCATABLE :: proc_row_dist, proc_col_dist
      67      376020 :       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      125340 :       unit_nr_prv = prep_output_unit(unit_nr)
      72      125340 :       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      125340 :                             row_blk_size=row_blk_size, col_blk_size=col_blk_size, name=name)
      77             : 
      78      125340 :       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      626508 :    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      137190 :    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      137190 :       INTEGER, DIMENSION(:), POINTER                     :: coldist, rowdist
     136             :       REAL(KIND=dp)                                      :: occupation
     137             :       TYPE(dbm_distribution_obj)                         :: dist
     138      137190 :       TYPE(mp_cart_type)                                 :: mp_comm, mp_comm_group
     139             : 
     140      137190 :       unit_nr_prv = prep_output_unit(unit_nr)
     141      137190 :       IF (unit_nr_prv == 0) RETURN
     142             : 
     143      137190 :       CALL dbt_tas_get_split_info(matrix%dist%info, mp_comm, ngroup, igroup, mp_comm_group, split_rowcol)
     144      137190 :       CALL dbt_tas_get_info(matrix, name=name)
     145      137190 :       nproc = mp_comm%num_pe
     146             : 
     147      137190 :       nblock = dbt_tas_get_num_blocks(matrix)
     148      137190 :       nelement = dbt_tas_get_nze(matrix)
     149             : 
     150      137190 :       ndbt_p_sum = dbt_tas_get_num_blocks_total(matrix)
     151      137190 :       nelement_p_sum = dbt_tas_get_nze_total(matrix)
     152             : 
     153      411570 :       tmp = (/nblock, nelement/)
     154      137190 :       CALL mp_comm%max(tmp)
     155      137190 :       ndbt_p_max = tmp(1); nelement_p_max = tmp(2)
     156             : 
     157      137190 :       ndbt_s = nblock
     158      137190 :       nelement_s = nelement
     159             : 
     160      137190 :       CALL mp_comm_group%sum(ndbt_s)
     161      137190 :       CALL mp_comm_group%sum(nelement_s)
     162             : 
     163      411570 :       tmp_i8 = (/ndbt_s, nelement_s/)
     164      137190 :       CALL mp_comm%max(tmp_i8)
     165      137190 :       ndbt_s_max = tmp_i8(1); nelement_s_max = tmp_i8(2)
     166             : 
     167      137190 :       ndbt_tot = dbt_tas_nblkrows_total(matrix)*dbt_tas_nblkcols_total(matrix)
     168      137190 :       occupation = -1.0_dp
     169      137190 :       IF (ndbt_tot .NE. 0) occupation = 100.0_dp*REAL(ndbt_p_sum, dp)/REAL(ndbt_tot, dp)
     170             : 
     171      137190 :       dist = dbm_get_distribution(matrix%matrix)
     172      137190 :       rowdist => dbm_distribution_row_dist(dist)
     173      137190 :       coldist => dbm_distribution_col_dist(dist)
     174             : 
     175      137190 :       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      274380 :    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       45742 :    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       45742 :       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       45742 :       TYPE(mp_cart_type)                                 :: mp_comm, mp_comm_group
     223             : 
     224       45742 :       unit_nr_prv = prep_output_unit(unit_nr)
     225       45742 :       IF (unit_nr_prv == 0) RETURN
     226             : 
     227       45742 :       IF (PRESENT(name)) THEN
     228          12 :          ALLOCATE (name_prv, SOURCE=TRIM(name))
     229             :       ELSE
     230       45730 :          ALLOCATE (name_prv, SOURCE="")
     231             :       END IF
     232             : 
     233       45742 :       CALL dbt_tas_get_split_info(info, mp_comm, nsplit, igroup, mp_comm_group, split_rowcol, pgrid_offset)
     234             : 
     235       45742 :       mynode = mp_comm%mepos
     236      137226 :       dims = mp_comm%num_pe_cart
     237      137226 :       groupdims = mp_comm_group%num_pe_cart
     238             : 
     239       45742 :       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       45742 :    END SUBROUTINE
     256             : 
     257             : ! **************************************************************************************************
     258             : !> \brief ...
     259             : !> \param unit_nr ...
     260             : !> \return ...
     261             : !> \author Patrick Seewald
     262             : ! **************************************************************************************************
     263      913879 :    FUNCTION prep_output_unit(unit_nr) RESULT(unit_nr_out)
     264             :       INTEGER, INTENT(IN), OPTIONAL                      :: unit_nr
     265             :       INTEGER                                            :: unit_nr_out
     266             : 
     267      913879 :       IF (PRESENT(unit_nr)) THEN
     268      651715 :          unit_nr_out = unit_nr
     269             :       ELSE
     270             :          unit_nr_out = 0
     271             :       END IF
     272             : 
     273      913879 :    END FUNCTION
     274             : 
     275             : END MODULE
     276             : 

Generated by: LCOV version 1.15