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 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 : ! **************************************************************************************************
14 : MODULE dgemm_counter_types
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, &
27 : dgemm_counter_init, &
28 : dgemm_counter_start, &
29 : dgemm_counter_stop, &
30 : dgemm_counter_write
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 618 : 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 618 : dgemm_counter%unit_nr = unit_nr
54 618 : dgemm_counter%print_info = print_info
55 :
56 618 : END SUBROUTINE dgemm_counter_init
57 :
58 : ! **************************************************************************************************
59 : !> \brief start timer of the counter
60 : !> \param dgemm_counter ...
61 : ! **************************************************************************************************
62 14300 : SUBROUTINE dgemm_counter_start(dgemm_counter)
63 : TYPE(dgemm_counter_type), INTENT(INOUT) :: dgemm_counter
64 :
65 14300 : dgemm_counter%t_start = m_walltime()
66 :
67 14300 : 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 14300 : 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 14300 : t_end = m_walltime()
83 14300 : 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 14300 : dgemm_counter%num_dgemm_call = dgemm_counter%num_dgemm_call + 1
85 14300 : IF (dgemm_counter%unit_nr > 0 .AND. dgemm_counter%print_info) THEN
86 : WRITE (UNIT=dgemm_counter%unit_nr, FMT="(T3,A,I10)") &
87 0 : "PERFORMANCE| DGEMM call #", dgemm_counter%num_dgemm_call
88 : WRITE (UNIT=dgemm_counter%unit_nr, FMT="(T3,A,I12,A,I12,A,I12)") &
89 0 : "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 0 : "PERFORMANCE| DGEMM time (s) = ", t_end - dgemm_counter%t_start
92 : END IF
93 14300 : dgemm_counter%flop_rate = dgemm_counter%flop_rate + flop_rate
94 :
95 14300 : END SUBROUTINE dgemm_counter_stop
96 :
97 : ! **************************************************************************************************
98 : !> \brief calculate and print flop rates
99 : !> \param dgemm_counter ...
100 : !> \param para_env ...
101 : ! **************************************************************************************************
102 584 : 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 584 : 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 584 : CALL para_env%sum(dgemm_counter%flop_rate)
109 584 : dgemm_counter%flop_rate = dgemm_counter%flop_rate/(REAL(para_env%num_pe, dp)*REAL(para_env%num_pe, dp))
110 584 : IF (dgemm_counter%unit_nr > 0) WRITE (UNIT=dgemm_counter%unit_nr, FMT="(T3,A,T66,F15.2)") &
111 292 : "PERFORMANCE| Average DGEMM flop rate (Gflops / MPI rank):", dgemm_counter%flop_rate
112 :
113 584 : END SUBROUTINE dgemm_counter_write
114 :
115 0 : END MODULE dgemm_counter_types
|