Oasis3 4.0.2
|
00001 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00002 ! 00003 ! This module uses F90 cpu time routines to allowing setting of 00004 ! multiple CPU timers. 00005 ! 00006 !----------------------------------------------------------------------- 00007 ! 00008 ! CVS:$Id: timers.f 2826 2010-12-10 11:14:21Z valcke $ 00009 ! 00010 ! Copyright (c) 1997, 1998 the Regents of the University of 00011 ! California. 00012 ! 00013 ! This software and ancillary information (herein called software) 00014 ! called SCRIP is made available under the terms described here. 00015 ! The software has been approved for release with associated 00016 ! LA-CC Number 98-45. 00017 ! 00018 ! Unless otherwise indicated, this software has been authored 00019 ! by an employee or employees of the University of California, 00020 ! operator of the Los Alamos National Laboratory under Contract 00021 ! No. W-7405-ENG-36 with the U.S. Department of Energy. The U.S. 00022 ! Government has rights to use, reproduce, and distribute this 00023 ! software. The public may copy and use this software without 00024 ! charge, provided that this Notice and any statement of authorship 00025 ! are reproduced on all copies. Neither the Government nor the 00026 ! University makes any warranty, express or implied, or assumes 00027 ! any liability or responsibility for the use of this software. 00028 ! 00029 ! If software is modified to produce derivative works, such modified 00030 ! software should be clearly marked, so as not to confuse it with 00031 ! the version available from Los Alamos National Laboratory. 00032 ! 00033 !*********************************************************************** 00034 00035 module timers 00036 00037 !----------------------------------------------------------------------- 00038 00039 use kinds_mod 00040 USE mod_unit 00041 00042 implicit none 00043 00044 integer (kind=int_kind), parameter :: 00045 & max_timers = 99 ! max number of timers allowed 00046 00047 integer (kind=int_kind), save :: 00048 & cycles_max ! max value of clock allowed by system 00049 00050 integer (kind=int_kind), dimension(max_timers), save :: 00051 & cycles1, ! cycle number at start for each timer 00052 & cycles2 ! cycle number at stop for each timer 00053 00054 real (kind=real_kind), save :: 00055 & clock_rate ! clock_rate in seconds for each cycle 00056 00057 real (kind=real_kind), dimension(max_timers), save :: 00058 & cputime ! accumulated cpu time in each timer 00059 00060 character (len=8), dimension(max_timers), save :: 00061 & status ! timer status string 00062 00063 !*********************************************************************** 00064 00065 contains 00066 00067 !*********************************************************************** 00068 00069 subroutine timer_check(timer) 00070 00071 !----------------------------------------------------------------------- 00072 ! 00073 ! This routine checks a given timer. This is primarily used to 00074 ! periodically accumulate time in the timer to prevent timer cycles 00075 ! from wrapping around max_cycles. 00076 ! 00077 !----------------------------------------------------------------------- 00078 00079 !----------------------------------------------------------------------- 00080 ! 00081 ! Input Variables: 00082 ! 00083 !----------------------------------------------------------------------- 00084 00085 integer (kind=int_kind), intent(in) :: 00086 & timer ! timer number 00087 00088 !----------------------------------------------------------------------- 00089 00090 if (status(timer) .eq. 'running') then 00091 call timer_stop (timer) 00092 call timer_start(timer) 00093 endif 00094 00095 !----------------------------------------------------------------------- 00096 00097 end subroutine timer_check 00098 00099 !*********************************************************************** 00100 00101 subroutine timer_clear(timer) 00102 00103 !----------------------------------------------------------------------- 00104 ! 00105 ! This routine resets a given timer. 00106 ! 00107 !----------------------------------------------------------------------- 00108 00109 !----------------------------------------------------------------------- 00110 ! 00111 ! Input Variables: 00112 ! 00113 !----------------------------------------------------------------------- 00114 00115 integer (kind=int_kind), intent(in) :: 00116 & timer ! timer number 00117 00118 !----------------------------------------------------------------------- 00119 00120 cputime(timer) = 0.0_real_kind ! clear the timer 00121 00122 !----------------------------------------------------------------------- 00123 00124 end subroutine timer_clear 00125 00126 !*********************************************************************** 00127 00128 function timer_get(timer) 00129 00130 !----------------------------------------------------------------------- 00131 ! 00132 ! This routine returns the result of a given timer. This can be 00133 ! called instead of timer_print so that the calling routine can 00134 ! print it in desired format. 00135 ! 00136 !----------------------------------------------------------------------- 00137 00138 !----------------------------------------------------------------------- 00139 ! 00140 ! Input Variables: 00141 ! 00142 !----------------------------------------------------------------------- 00143 00144 integer (kind=int_kind), intent(in) :: 00145 & timer ! timer number 00146 00147 !----------------------------------------------------------------------- 00148 ! 00149 ! Output Variables: 00150 ! 00151 !----------------------------------------------------------------------- 00152 00153 real (kind=real_kind) :: 00154 & timer_get ! accumulated cputime in given timer 00155 00156 !----------------------------------------------------------------------- 00157 00158 if (status(timer) .eq. 'stopped') then 00159 timer_get = cputime(timer) 00160 else 00161 call timer_stop(timer) 00162 timer_get = cputime(timer) 00163 call timer_start(timer) 00164 endif 00165 00166 !----------------------------------------------------------------------- 00167 00168 end function timer_get 00169 00170 !*********************************************************************** 00171 00172 subroutine timer_print(timer) 00173 00174 !----------------------------------------------------------------------- 00175 ! 00176 ! This routine prints the accumulated cpu time in given timer. 00177 ! 00178 !----------------------------------------------------------------------- 00179 00180 !----------------------------------------------------------------------- 00181 ! 00182 ! Input Variables: 00183 ! 00184 !----------------------------------------------------------------------- 00185 00186 integer (kind=int_kind), intent(in) :: 00187 & timer ! timer number 00188 00189 !----------------------------------------------------------------------- 00190 00191 !--- 00192 !--- print the cputime accumulated for timer 00193 !--- make sure timer is stopped 00194 !--- 00195 00196 if (status(timer) .eq. 'stopped') then 00197 write(nulou,"(' CPU time for timer',i3,':',1p,e16.8)") 00198 & timer,cputime(timer) 00199 else 00200 call timer_stop(timer) 00201 write(nulou,"(' CPU time for timer',i3,':',1p,e16.8)") 00202 & timer,cputime(timer) 00203 call timer_start(timer) 00204 endif 00205 00206 !----------------------------------------------------------------------- 00207 00208 end subroutine timer_print 00209 00210 !*********************************************************************** 00211 00212 subroutine timer_start(timer) 00213 00214 !----------------------------------------------------------------------- 00215 ! 00216 ! This routine starts a given timer. 00217 ! 00218 !----------------------------------------------------------------------- 00219 00220 !----------------------------------------------------------------------- 00221 ! 00222 ! Input Variables: 00223 ! 00224 !----------------------------------------------------------------------- 00225 00226 integer (kind=int_kind), intent(in) :: 00227 & timer ! timer number 00228 00229 !----------------------------------------------------------------------- 00230 00231 !--- 00232 !--- Start the timer and change timer status. 00233 !--- 00234 00235 if (status(timer) .eq. 'stopped') then 00236 call system_clock(count=cycles1(timer)) 00237 status(timer) = 'running' 00238 endif 00239 00240 !----------------------------------------------------------------------- 00241 00242 end subroutine timer_start 00243 00244 !*********************************************************************** 00245 00246 subroutine timer_stop(timer) 00247 00248 !----------------------------------------------------------------------- 00249 ! 00250 ! This routine stops a given timer. 00251 ! 00252 !----------------------------------------------------------------------- 00253 00254 !----------------------------------------------------------------------- 00255 ! 00256 ! Input Variables: 00257 ! 00258 !----------------------------------------------------------------------- 00259 00260 integer (kind=int_kind), intent(in) :: 00261 & timer ! timer number 00262 00263 !----------------------------------------------------------------------- 00264 00265 if (status(timer) .eq. 'running') then 00266 00267 !--- 00268 !--- Stop the desired timer. 00269 !--- 00270 00271 call system_clock(count=cycles2(timer)) 00272 00273 !--- 00274 !--- check and correct for cycle wrapping 00275 !--- 00276 00277 if (cycles2(timer) .ge. cycles1(timer)) then 00278 cputime(timer) = cputime(timer) + clock_rate* 00279 & (cycles2(timer) - cycles1(timer)) 00280 else 00281 cputime(timer) = cputime(timer) + clock_rate* 00282 & (cycles2(timer) - cycles1(timer) + cycles_max) 00283 endif 00284 00285 !--- 00286 !--- Change timer status. 00287 !--- 00288 00289 status(timer)='stopped' 00290 00291 endif 00292 00293 !----------------------------------------------------------------------- 00294 00295 end subroutine timer_stop 00296 00297 !*********************************************************************** 00298 00299 subroutine timers_init 00300 00301 !----------------------------------------------------------------------- 00302 ! 00303 ! This routine initializes some machine parameters necessary for 00304 ! computing cpu time from F90 intrinsics. 00305 ! 00306 !----------------------------------------------------------------------- 00307 00308 integer (kind=int_kind) :: cycles ! count rate return by sys_clock 00309 00310 !----------------------------------------------------------------------- 00311 00312 !--- 00313 !--- Initialize timer arrays and clock_rate. 00314 !--- 00315 00316 clock_rate = 0.0_real_kind 00317 cycles1 = 0 00318 cycles2 = 0 00319 cputime = 0.0_real_kind 00320 status = 'stopped' 00321 00322 !--- 00323 !--- Call F90 intrinsic system_clock to determine clock rate 00324 !--- and maximum cycles. If no clock available, print message. 00325 !--- 00326 00327 call system_clock(count_rate=cycles, count_max=cycles_max) 00328 00329 if (cycles /= 0) then 00330 clock_rate = 1.0_real_kind/real(cycles) 00331 else 00332 clock_rate = 0.0_real_kind 00333 WRITE(nulou,*) '--- No system clock available ---' 00334 endif 00335 00336 !----------------------------------------------------------------------- 00337 00338 end subroutine timers_init 00339 00340 !*********************************************************************** 00341 00342 end module timers 00343 00344 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!