FV3 Bundle
fv_timing_nlm.F90
Go to the documentation of this file.
1 !***********************************************************************
2 !* GNU General Public License *
3 !* This file is a part of fvGFS. *
4 !* *
5 !* fvGFS is free software; you can redistribute it and/or modify it *
6 !* and are expected to follow the terms of the GNU General Public *
7 !* License as published by the Free Software Foundation; either *
8 !* version 2 of the License, or (at your option) any later version. *
9 !* *
10 !* fvGFS is distributed in the hope that it will be useful, but *
11 !* WITHOUT ANY WARRANTY; without even the implied warranty of *
12 !* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
13 !* General Public License for more details. *
14 !* *
15 !* For the full text of the GNU General Public License, *
16 !* write to: Free Software Foundation, Inc., *
17 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
18 !* or see: http://www.gnu.org/licenses/gpl.html *
19 !***********************************************************************
21 
22  use mpp_mod, only: mpp_error, fatal
23 #if defined(SPMD)
24  use fv_mp_nlm_mod, only: is_master, mp_reduce_max, mp_reduce_min, mp_barrier
25 #endif
26 !
27 ! ... Use system etime() function for timing
28 !
29  implicit none
30 
31  integer, private :: nblks
32  parameter(nblks = 100)
33 
34  character(len=20), private :: blkname(nblks)
35 
36  integer , private :: tblk
37 
38 #if defined(SPMD)
39  real(kind=8) , external :: mpi_wtime
40 #endif
41  real , private :: etime
42  real(kind=8) , private :: totim
43  real , private :: tarray(2)
44  type tms
45  private
46  real (kind=8) :: usr, sys
47  end type tms
48 
49 
50  type(tms), private :: accum(nblks), last(nblks)
51 
52  real(kind=8) , public :: comm_timer
53  real(kind=8) , public :: wait_timer
54  real , private :: us_tmp1(nblks,2)
55  real , private :: us_tmp2(nblks,2)
56 
57  logical, private :: module_initialized = .false.
58 
59  contains
60  subroutine timing_init
61 !
62 ! init
63 !
64  implicit none
65 
66  integer :: C, R, M
67  real (kind=8) :: wclk
68 
69  integer n
70 
71  if ( module_initialized ) return
72 
73  tblk=0
74  do n = 1, nblks
75  accum(n)%usr = 0.
76  accum(n)%sys = 0.
77  last(n)%usr = 0.
78  last(n)%sys = 0.
79  end do
80 !
81 ! ... To reduce the overhead for the first call
82 !
83 #if defined(SPMD)
84  wclk = mpi_wtime()
85  totim = wclk
86 #else
87 # if defined( IRIX64 ) || ( defined FFC )
88  totim = etime(tarray)
89 # else
90  CALL system_clock(count=c, count_rate=r, count_max=m)
91  wclk = REAL(C) / REAL(R)
92  totim = wclk
93 # endif
94 #endif
95 
96  module_initialized = .true.
97  end subroutine timing_init
98 
99 
100  subroutine timing_on(blk_name)
101 !
102 ! timing_on
103 !
104 
105  implicit none
106 
107  character(len=*) :: blk_name
108 
109 
110 
111  character(len=20) :: UC_blk_name
112  character(len=20) :: ctmp
113  integer i
114  integer iblk
115 
116  integer :: C, R, M
117  real (kind=8) :: wclk
118 
119  integer ierr
120 
121  if ( .not. module_initialized ) then
122  call timing_init()
123  end if
124 
125  uc_blk_name = blk_name
126 
127  call upper(uc_blk_name,len_trim(uc_blk_name))
128 !c ctmp=UC_blk_name(:len_trim(UC_blk_name))
129  ctmp=trim(uc_blk_name)
130 
131 ! write(*,*) 'timing_on ', ctmp
132  iblk=0
133  do i=1, tblk
134  if ( ctmp .EQ. blkname(i) ) then
135  iblk =i
136  endif
137  enddo
138 
139  if ( iblk .eq. 0 ) then
140  tblk=tblk+1
141  iblk=tblk
142  call upper(uc_blk_name,len_trim(uc_blk_name))
143 !C blkname(iblk)=UC_blk_name(:len_trim(UC_blk_name))
144  blkname(iblk)=trim(uc_blk_name)
145 
146  endif
147 
148 #if defined(SPMD)
149 !C WMP: let's sync up cores before timming and place load imbalances in sys time
150  wclk = mpi_wtime()
151  last(iblk)%sys = wclk
152  if (trim(uc_blk_name) == 'COMM_TOTAL') call mp_barrier()
153  wclk = mpi_wtime()
154  accum(iblk)%sys = accum(iblk)%sys + wclk - last(iblk)%sys
155  wait_timer = accum(iblk)%sys
156 !C WMP: usr time is now timing just the segment without load imbalances
157  last(iblk)%usr = wclk
158 #else
159 # if defined( IRIX64 ) || ( defined FFC )
160  totim = etime(tarray)
161  last(iblk)%usr = tarray(1)
162  last(iblk)%sys = tarray(2)
163 # else
164  CALL system_clock(count=c, count_rate=r, count_max=m)
165  wclk = REAL(C) / REAL(R)
166  last(iblk)%usr = wclk
167  last(iblk)%sys = 0.0
168 # endif
169 #endif
170 
171  end subroutine timing_on
172 
173 
174  subroutine timing_off(blk_name)
175 !
176 ! Timing_off
177 !
178 
179  implicit none
180  character(len=*) :: blk_name
181 
182  character(len=20) :: UC_blk_name
183  character(len=20) :: ctmp
184  integer i
185 
186  integer :: C, R, M
187  real (kind=8) :: wclk
188 
189  integer iblk
190 
191  uc_blk_name = blk_name
192 
193  call upper(uc_blk_name,len_trim(uc_blk_name))
194 !v ctmp=UC_blk_name(:len_trim(UC_blk_name))
195  ctmp=trim(uc_blk_name)
196 
197  iblk=0
198  do i=1, tblk
199  if ( ctmp .EQ. blkname(i) ) then
200  iblk =i
201  endif
202  enddo
203 
204 ! write(*,*) 'timing_off ', ctmp, tblk, tblk
205  if ( iblk .eq. 0 ) then
206  call mpp_error(fatal,'fv_timing_nlm_mod: timing_off called before timing_on for: '//trim(blk_name))
207 ! write(*,*) 'stop in timing off in ', ctmp
208 ! stop
209  endif
210 
211 #if defined(SPMD)
212  wclk = mpi_wtime()
213  accum(iblk)%usr = accum(iblk)%usr + wclk - last(iblk)%usr
214  last(iblk)%usr = wclk
215  if (trim(uc_blk_name) == 'COMM_TOTAL') then
216  comm_timer = accum(iblk)%usr
217  endif
218 #else
219 # if defined( IRIX64 ) || ( defined FFC )
220  totim = etime(tarray)
221  accum(iblk)%usr = accum(iblk)%usr + &
222  tarray(1) - last(iblk)%usr
223  accum(iblk)%sys = accum(iblk)%sys + &
224  tarray(2) - last(iblk)%sys
225  last(iblk)%usr = tarray(1)
226  last(iblk)%sys = tarray(2)
227 # else
228  CALL system_clock(count=c, count_rate=r, count_max=m)
229  wclk = REAL(C) / REAL(R)
230  accum(iblk)%usr = accum(iblk)%usr + wclk - last(iblk)%usr
231  accum(iblk)%sys = 0.0
232  last(iblk)%usr = wclk
233  last(iblk)%sys = 0.0
234 # endif
235 #endif
236  end subroutine timing_off
237 
238 
239  subroutine timing_clear()
240  integer n
241  do n = 1, nblks
242  accum(n)%usr = 0
243  accum(n)%sys = 0
244  enddo
245  end subroutine timing_clear
246 
247 
248  subroutine timing_prt(gid)
249 !
250 ! Timing_prt
251 !
252  implicit none
253  integer gid
254  integer n
255 
256  type(tms) :: others, tmp(nblks)
257  real :: tmpmax
258 
259 #if defined( SPMD )
260  do n = 1, nblks !will clean these later
261  tmpmax = accum(n)%usr
262  call mp_reduce_max(tmpmax)
263  tmp(n)%usr = tmpmax
264  tmpmax = accum(n)%usr
265  call mp_reduce_min(tmpmax)
266  tmp(n)%sys = tmpmax
267  enddo
268  if ( is_master() ) then
269 #else
270  do n = 1, nblks
271  tmp(n)%usr = accum(n)%usr
272  tmp(n)%sys = accum(n)%sys
273  enddo
274 #endif
275 
276  print *
277  print *, &
278  ' -----------------------------------------------------'
279  print *, &
280  ' Block Max time Min Time Load Imbalance'
281  print *, &
282  ' -----------------------------------------------------'
283 
284  do n = 1, tblk
285  print '(3x,a20,2x,3(1x,f12.4))', blkname(n), &
286  tmp(n)%usr, tmp(n)%sys, tmp(n)%usr - tmp(n)%sys
287  end do
288 
289 
290  print *
291 #if defined( SPMD )
292  endif ! masterproc
293 #endif
294 
295  end subroutine timing_prt
296 
297  subroutine upper(string,length)
299 !***********************************************************************
300 !
301 ! upper.f - change lower case letter to upper case letter *
302 ! *
303 ! George Lai Tue Jun 28 16:37:00 1994 *
304 ! *
305 !***********************************************************************
306 
307  implicit none
308 
309 ! character string(length)
310 ! character(len=20) string
311 ! character, dimension(length) :: string
312 ! character (len=*), intent(inout) :: string
313 ! character (len=*) :: string
314 ! character (len=1), intent(inout) :: string(20)
315 !ok character (len=20), intent(inout) :: string
316  character (len=*), intent(inout) :: string
317  character char1
318  integer, intent(in) :: length
319  integer i
320  integer a, z, dist
321  a = ichar('a')
322  z = ichar('z')
323  dist = ichar('A') - a
324 
325  do i = 1,length
326  char1=string(i:i)
327  if (ichar(char1) .ge. a .and. &
328  ichar(char1) .le. z) then
329  string(i:i) = char(ichar(char1)+dist)
330  endif
331  end do
332 
333  return
334  end subroutine upper
335 
336  end module fv_timing_nlm_mod
type(tms), dimension(nblks), private accum
subroutine timing_clear()
real(kind=8), public comm_timer
logical, private module_initialized
real(kind=8), public wait_timer
Definition: mpp.F90:39
subroutine upper(string, length)
subroutine timing_prt(gid)
integer, private nblks
subroutine timing_on(blk_name)
real, private etime
character(len=20), dimension(nblks), private blkname
real(kind=8), private totim
type(tms), dimension(nblks), private last
real, dimension(nblks, 2), private us_tmp1
integer, private tblk
real, dimension(2), private tarray
subroutine timing_init
real, dimension(nblks, 2), private us_tmp2
subroutine timing_off(blk_name)