LCOV - code coverage report
Current view: top level - src/mpiwrap - mp_perf_env.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 66 72 91.7 %
Date: 2024-11-21 06:45:46 Functions: 9 12 75.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 Defines all routines to deal with the performance of MPI routines
      10             : ! **************************************************************************************************
      11             : MODULE mp_perf_env
      12             :    ! performance gathering
      13             :    USE kinds,                           ONLY: dp
      14             : #include "../base/base_uses.f90"
      15             : 
      16             :    PRIVATE
      17             : 
      18             :    PUBLIC :: mp_perf_env_type
      19             :    PUBLIC :: mp_perf_env_retain, mp_perf_env_release
      20             :    PUBLIC :: add_mp_perf_env, rm_mp_perf_env, get_mp_perf_env, describe_mp_perf_env
      21             :    PUBLIC :: add_perf
      22             : 
      23             :    TYPE mp_perf_type
      24             :       CHARACTER(LEN=20) :: name = ""
      25             :       INTEGER :: count = 0
      26             :       REAL(KIND=dp) :: msg_size = 0.0_dp
      27             :    END TYPE mp_perf_type
      28             : 
      29             :    INTEGER, PARAMETER :: MAX_PERF = 28
      30             : 
      31             : ! **************************************************************************************************
      32             :    TYPE mp_perf_env_type
      33             :       PRIVATE
      34             :       INTEGER :: ref_count = -1
      35             :       TYPE(mp_perf_type), DIMENSION(MAX_PERF) :: mp_perfs = mp_perf_type()
      36             :    CONTAINS
      37             :       PROCEDURE, PUBLIC, PASS(perf_env), NON_OVERRIDABLE :: retain => mp_perf_env_retain
      38             :    END TYPE mp_perf_env_type
      39             : 
      40             : ! **************************************************************************************************
      41             :    TYPE mp_perf_env_p_type
      42             :       TYPE(mp_perf_env_type), POINTER         :: mp_perf_env => Null()
      43             :    END TYPE mp_perf_env_p_type
      44             : 
      45             :    ! introduce a stack of mp_perfs, first index is the stack pointer, for convenience is replacing
      46             :    INTEGER, PARAMETER :: max_stack_size = 10
      47             :    INTEGER            :: stack_pointer = 0
      48             :    TYPE(mp_perf_env_p_type), DIMENSION(max_stack_size), SAVE :: mp_perf_stack
      49             : 
      50             :    CHARACTER(LEN=20), PARAMETER :: sname(MAX_PERF) = &
      51             :                                    (/"MP_Group            ", "MP_Bcast            ", "MP_Allreduce        ", &
      52             :                                      "MP_Gather           ", "MP_Sync             ", "MP_Alltoall         ", &
      53             :                                      "MP_SendRecv         ", "MP_ISendRecv        ", "MP_Wait             ", &
      54             :                                      "MP_comm_split       ", "MP_ISend            ", "MP_IRecv            ", &
      55             :                                      "MP_Send             ", "MP_Recv             ", "MP_Memory           ", &
      56             :                                      "MP_Put              ", "MP_Get              ", "MP_Fence            ", &
      57             :                                      "MP_Win_Lock         ", "MP_Win_Create       ", "MP_Win_Free         ", &
      58             :                                      "MP_IBcast           ", "MP_IAllreduce       ", "MP_IScatter         ", &
      59             :                                      "MP_RGet             ", "MP_Isync            ", "MP_Read_All         ", &
      60             :                                      "MP_Write_All        "/)
      61             : 
      62             : CONTAINS
      63             : 
      64             : ! **************************************************************************************************
      65             : !> \brief start and stop the performance indicators
      66             : !>      for every call to start there has to be (exactly) one call to stop
      67             : !> \param perf_env ...
      68             : !> \par History
      69             : !>      2.2004 created [Joost VandeVondele]
      70             : !> \note
      71             : !>      can be used to measure performance of a sub-part of a program.
      72             : !>      timings measured here will not show up in the outer start/stops
      73             : !>      Doesn't need a fresh communicator
      74             : ! **************************************************************************************************
      75      115957 :    SUBROUTINE add_mp_perf_env(perf_env)
      76             :       TYPE(mp_perf_env_type), OPTIONAL, POINTER          :: perf_env
      77             : 
      78      115957 :       stack_pointer = stack_pointer + 1
      79      115957 :       IF (stack_pointer > max_stack_size) THEN
      80           0 :          CPABORT("stack_pointer too large : message_passing @ add_mp_perf_env")
      81             :       END IF
      82      115957 :       NULLIFY (mp_perf_stack(stack_pointer)%mp_perf_env)
      83      115957 :       IF (PRESENT(perf_env)) THEN
      84       89764 :          mp_perf_stack(stack_pointer)%mp_perf_env => perf_env
      85       89764 :          IF (ASSOCIATED(perf_env)) CALL mp_perf_env_retain(perf_env)
      86             :       END IF
      87      115957 :       IF (.NOT. ASSOCIATED(mp_perf_stack(stack_pointer)%mp_perf_env)) THEN
      88       26193 :          CALL mp_perf_env_create(mp_perf_stack(stack_pointer)%mp_perf_env)
      89             :       END IF
      90      115957 :    END SUBROUTINE add_mp_perf_env
      91             : 
      92             : ! **************************************************************************************************
      93             : !> \brief ...
      94             : !> \param perf_env ...
      95             : ! **************************************************************************************************
      96       26193 :    SUBROUTINE mp_perf_env_create(perf_env)
      97             :       TYPE(mp_perf_env_type), OPTIONAL, POINTER          :: perf_env
      98             : 
      99             :       INTEGER                                            :: i
     100             : 
     101             :       NULLIFY (perf_env)
     102      759597 :       ALLOCATE (perf_env)
     103       26193 :       perf_env%ref_count = 1
     104      759597 :       DO i = 1, MAX_PERF
     105      759597 :          perf_env%mp_perfs(i)%name = sname(i)
     106             :       END DO
     107             : 
     108       26193 :    END SUBROUTINE mp_perf_env_create
     109             : 
     110             : ! **************************************************************************************************
     111             : !> \brief ...
     112             : !> \param perf_env ...
     113             : ! **************************************************************************************************
     114      124564 :    SUBROUTINE mp_perf_env_release(perf_env)
     115             :       TYPE(mp_perf_env_type), POINTER                    :: perf_env
     116             : 
     117      124564 :       IF (ASSOCIATED(perf_env)) THEN
     118      124564 :          IF (perf_env%ref_count < 1) THEN
     119           0 :             CPABORT("invalid ref_count: message_passing @ mp_perf_env_release")
     120             :          END IF
     121      124564 :          perf_env%ref_count = perf_env%ref_count - 1
     122      124564 :          IF (perf_env%ref_count == 0) THEN
     123       26193 :             DEALLOCATE (perf_env)
     124             :          END IF
     125             :       END IF
     126      124564 :       NULLIFY (perf_env)
     127      124564 :    END SUBROUTINE mp_perf_env_release
     128             : 
     129             : ! **************************************************************************************************
     130             : !> \brief ...
     131             : !> \param perf_env ...
     132             : ! **************************************************************************************************
     133       98371 :    ELEMENTAL SUBROUTINE mp_perf_env_retain(perf_env)
     134             :       CLASS(mp_perf_env_type), INTENT(INOUT)                    :: perf_env
     135             : 
     136       98371 :       perf_env%ref_count = perf_env%ref_count + 1
     137       98371 :    END SUBROUTINE mp_perf_env_retain
     138             : 
     139             : !.. reports the performance counters for the MPI run
     140             : ! **************************************************************************************************
     141             : !> \brief ...
     142             : !> \param perf_env ...
     143             : !> \param iw ...
     144             : ! **************************************************************************************************
     145        9127 :    SUBROUTINE mp_perf_env_describe(perf_env, iw)
     146             :       TYPE(mp_perf_env_type), INTENT(IN)       :: perf_env
     147             :       INTEGER, INTENT(IN)                      :: iw
     148             : 
     149             : #if defined(__parallel)
     150             :       INTEGER                                  :: i
     151             :       REAL(KIND=dp)                            :: vol
     152             : #endif
     153             : 
     154        9127 :       IF (perf_env%ref_count < 1) THEN
     155           0 :          CPABORT("invalid perf_env%ref_count : message_passing @ mp_perf_env_describe")
     156             :       END IF
     157             : #if defined(__parallel)
     158        9127 :       IF (iw > 0) THEN
     159        4667 :          WRITE (iw, '( /, 1X, 79("-") )')
     160        4667 :          WRITE (iw, '( " -", 77X, "-" )')
     161        4667 :          WRITE (iw, '( " -", 24X, A, 24X, "-" )') ' MESSAGE PASSING PERFORMANCE '
     162        4667 :          WRITE (iw, '( " -", 77X, "-" )')
     163        4667 :          WRITE (iw, '( 1X, 79("-"), / )')
     164        4667 :          WRITE (iw, '( A, A, A )') ' ROUTINE', '             CALLS ', &
     165        9334 :             '     AVE VOLUME [Bytes]'
     166      135343 :          DO i = 1, MAX_PERF
     167             : 
     168      135343 :             IF (perf_env%mp_perfs(i)%count > 0) THEN
     169       32709 :                vol = perf_env%mp_perfs(i)%msg_size/REAL(perf_env%mp_perfs(i)%count, KIND=dp)
     170       32709 :                IF (vol < 1.0_dp) THEN
     171             :                   WRITE (iw, '(1X,A15,T17,I10)') &
     172       13807 :                      ADJUSTL(perf_env%mp_perfs(i)%name), perf_env%mp_perfs(i)%count
     173             :                ELSE
     174             :                   WRITE (iw, '(1X,A15,T17,I10,T40,F11.0)') &
     175       18902 :                      ADJUSTL(perf_env%mp_perfs(i)%name), perf_env%mp_perfs(i)%count, &
     176       37804 :                      vol
     177             :                END IF
     178             :             END IF
     179             : 
     180             :          END DO
     181        4667 :          WRITE (iw, '( 1X, 79("-"), / )')
     182             :       END IF
     183             : #else
     184             :       MARK_USED(iw)
     185             : #endif
     186        9127 :    END SUBROUTINE mp_perf_env_describe
     187             : 
     188             : ! **************************************************************************************************
     189             : !> \brief ...
     190             : ! **************************************************************************************************
     191      115957 :    SUBROUTINE rm_mp_perf_env()
     192      115957 :       IF (stack_pointer < 1) THEN
     193           0 :          CPABORT("no perf_env in the stack : message_passing @ rm_mp_perf_env")
     194             :       END IF
     195      115957 :       CALL mp_perf_env_release(mp_perf_stack(stack_pointer)%mp_perf_env)
     196      115957 :       stack_pointer = stack_pointer - 1
     197      115957 :    END SUBROUTINE rm_mp_perf_env
     198             : 
     199             : ! **************************************************************************************************
     200             : !> \brief ...
     201             : !> \return ...
     202             : ! **************************************************************************************************
     203      107498 :    FUNCTION get_mp_perf_env() RESULT(res)
     204             :       TYPE(mp_perf_env_type), POINTER                    :: res
     205             : 
     206      107498 :       IF (stack_pointer < 1) THEN
     207           0 :          CPABORT("no perf_env in the stack : message_passing @ get_mp_perf_env")
     208             :       END IF
     209      107498 :       res => mp_perf_stack(stack_pointer)%mp_perf_env
     210      107498 :    END FUNCTION get_mp_perf_env
     211             : 
     212             : ! **************************************************************************************************
     213             : !> \brief ...
     214             : !> \param scr ...
     215             : ! **************************************************************************************************
     216        9127 :    SUBROUTINE describe_mp_perf_env(scr)
     217             :       INTEGER, INTENT(in)                                :: scr
     218             : 
     219             :       TYPE(mp_perf_env_type), POINTER                    :: perf_env
     220             : 
     221        9127 :       perf_env => get_mp_perf_env()
     222        9127 :       CALL mp_perf_env_describe(perf_env, scr)
     223        9127 :    END SUBROUTINE describe_mp_perf_env
     224             : 
     225             : ! **************************************************************************************************
     226             : !> \brief adds the performance informations of one call
     227             : !> \param perf_id ...
     228             : !> \param count ...
     229             : !> \param msg_size ...
     230             : !> \author fawzi
     231             : ! **************************************************************************************************
     232    80951504 :    SUBROUTINE add_perf(perf_id, count, msg_size)
     233             :       INTEGER, INTENT(in)                      :: perf_id
     234             :       INTEGER, INTENT(in), OPTIONAL            :: count
     235             :       INTEGER, INTENT(in), OPTIONAL            :: msg_size
     236             : 
     237             : #if defined(__parallel)
     238             :       TYPE(mp_perf_type), POINTER              :: mp_perf
     239             : 
     240    80951504 :       IF (.NOT. ASSOCIATED(mp_perf_stack(stack_pointer)%mp_perf_env)) RETURN
     241             : 
     242    80951504 :       mp_perf => mp_perf_stack(stack_pointer)%mp_perf_env%mp_perfs(perf_id)
     243    80951504 :       IF (PRESENT(count)) THEN
     244    80951504 :          mp_perf%count = mp_perf%count + count
     245             :       END IF
     246    80951504 :       IF (PRESENT(msg_size)) THEN
     247    73119152 :          mp_perf%msg_size = mp_perf%msg_size + REAL(msg_size, dp)
     248             :       END IF
     249             : #else
     250             :       MARK_USED(perf_id)
     251             :       MARK_USED(count)
     252             :       MARK_USED(msg_size)
     253             : #endif
     254             : 
     255             :    END SUBROUTINE add_perf
     256             : 
     257           0 : END MODULE mp_perf_env

Generated by: LCOV version 1.15