(git:ccc2433)
dgemm_counter_types.F
Go to the documentation of this file.
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 Counters to determine the performance of parallel DGEMMs
10 !> \par History
11 !> 2022.05 created [Mauro Del Ben]
12 !> \author FS, Refactored from mp2_types
13 ! **************************************************************************************************
15  USE kinds, ONLY: dp
16  USE machine, ONLY: m_walltime
17  USE message_passing, ONLY: mp_para_env_type
18 #include "./base/base_uses.f90"
19 
20  IMPLICIT NONE
21 
22  PRIVATE
23 
24  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'dgemm_counter_types'
25 
26  PUBLIC :: dgemm_counter_type, &
31 
32  TYPE dgemm_counter_type
33  PRIVATE
34  REAL(KIND=dp) :: flop_rate = 0.0_dp, t_start = 0.0_dp
35  INTEGER :: num_dgemm_call = 0
36  INTEGER :: unit_nr = -1
37  LOGICAL :: print_info = .false.
38  END TYPE
39 
40 CONTAINS
41 
42 ! **************************************************************************************************
43 !> \brief Initialize a dgemm_counter
44 !> \param dgemm_counter ...
45 !> \param unit_nr ...
46 !> \param print_info ...
47 ! **************************************************************************************************
48  ELEMENTAL SUBROUTINE dgemm_counter_init(dgemm_counter, unit_nr, print_info)
49  TYPE(dgemm_counter_type), INTENT(OUT) :: dgemm_counter
50  INTEGER, INTENT(IN) :: unit_nr
51  LOGICAL, INTENT(IN) :: print_info
52 
53  dgemm_counter%unit_nr = unit_nr
54  dgemm_counter%print_info = print_info
55 
56  END SUBROUTINE dgemm_counter_init
57 
58 ! **************************************************************************************************
59 !> \brief start timer of the counter
60 !> \param dgemm_counter ...
61 ! **************************************************************************************************
62  SUBROUTINE dgemm_counter_start(dgemm_counter)
63  TYPE(dgemm_counter_type), INTENT(INOUT) :: dgemm_counter
64 
65  dgemm_counter%t_start = m_walltime()
66 
67  END SUBROUTINE dgemm_counter_start
68 
69 ! **************************************************************************************************
70 !> \brief stop timer of the counter and provide matrix sizes
71 !> \param dgemm_counter ...
72 !> \param size1 ...
73 !> \param size2 ...
74 !> \param size3 ...
75 ! **************************************************************************************************
76  SUBROUTINE dgemm_counter_stop(dgemm_counter, size1, size2, size3)
77  TYPE(dgemm_counter_type), INTENT(INOUT) :: dgemm_counter
78  INTEGER, INTENT(IN) :: size1, size2, size3
79 
80  REAL(kind=dp) :: flop_rate, t_end
81 
82  t_end = m_walltime()
83  flop_rate = 2.0_dp*real(size1, dp)*real(size2, dp)*real(size3, dp)/max(0.001_dp, t_end - dgemm_counter%t_start)
84  dgemm_counter%num_dgemm_call = dgemm_counter%num_dgemm_call + 1
85  IF (dgemm_counter%unit_nr > 0 .AND. dgemm_counter%print_info) THEN
86  WRITE (unit=dgemm_counter%unit_nr, fmt="(T3,A,I10)") &
87  "PERFORMANCE| DGEMM call #", dgemm_counter%num_dgemm_call
88  WRITE (unit=dgemm_counter%unit_nr, fmt="(T3,A,I12,A,I12,A,I12)") &
89  "PERFORMANCE| DGEMM size (M x N x K) = ", size1, " x ", size2, " x ", size3
90  WRITE (unit=dgemm_counter%unit_nr, fmt="(T3,A,F15.5)") &
91  "PERFORMANCE| DGEMM time (s) = ", t_end - dgemm_counter%t_start
92  END IF
93  dgemm_counter%flop_rate = dgemm_counter%flop_rate + flop_rate
94 
95  END SUBROUTINE dgemm_counter_stop
96 
97 ! **************************************************************************************************
98 !> \brief calculate and print flop rates
99 !> \param dgemm_counter ...
100 !> \param para_env ...
101 ! **************************************************************************************************
102  SUBROUTINE dgemm_counter_write(dgemm_counter, para_env)
103  TYPE(dgemm_counter_type), INTENT(INOUT) :: dgemm_counter
104  TYPE(mp_para_env_type), INTENT(IN) :: para_env
105 
106  dgemm_counter%flop_rate = dgemm_counter%flop_rate/real(max(dgemm_counter%num_dgemm_call, 1), dp)/1.0e9_dp
107  ! Average over all ranks
108  CALL para_env%sum(dgemm_counter%flop_rate)
109  dgemm_counter%flop_rate = dgemm_counter%flop_rate/(real(para_env%num_pe, dp)*real(para_env%num_pe, dp))
110  IF (dgemm_counter%unit_nr > 0) WRITE (unit=dgemm_counter%unit_nr, fmt="(T3,A,T66,F15.2)") &
111  "PERFORMANCE| Average DGEMM flop rate (Gflops / MPI rank):", dgemm_counter%flop_rate
112 
113  END SUBROUTINE dgemm_counter_write
114 
115 END MODULE dgemm_counter_types
Counters to determine the performance of parallel DGEMMs.
elemental subroutine, public dgemm_counter_init(dgemm_counter, unit_nr, print_info)
Initialize a dgemm_counter.
subroutine, public dgemm_counter_write(dgemm_counter, para_env)
calculate and print flop rates
subroutine, public dgemm_counter_start(dgemm_counter)
start timer of the counter
subroutine, public dgemm_counter_stop(dgemm_counter, size1, size2, size3)
stop timer of the counter and provide matrix sizes
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Machine interface based on Fortran 2003 and POSIX.
Definition: machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition: machine.F:123
Interface to the message passing library MPI.