Skip to content

Commit

Permalink
clear timer.f90
Browse files Browse the repository at this point in the history
Signed-off-by: albert <92109627+Albkat@users.noreply.github.com>
  • Loading branch information
Albkat committed May 26, 2023
1 parent 3775b7a commit 19306e6
Showing 1 changed file with 144 additions and 5 deletions.
149 changes: 144 additions & 5 deletions src/type/timer.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ module xtb_type_timer

type :: tb_timer
integer, private :: n = 0
!! number of timers
logical, private :: verbose = .false.
!! printlevel
real(wp),private :: totwall = 0.0_wp
real(wp),private :: totcpu = 0.0_wp
logical, private,allocatable :: running(:)
Expand All @@ -45,99 +47,164 @@ module xtb_type_timer

contains

!--------------------------------------------
!> To initialize timer
!--------------------------------------------
subroutine allocate_timer(self,n,verbose)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer, intent(in) :: n
!! number of timers
logical, intent(in), optional :: verbose
!! if verbose

!> local vars
real(wp) :: time_cpu
real(wp) :: time_wall

call self%deallocate
if (n < 1) return
call timing(time_cpu,time_wall)
!! capture negative values

self%n = n
if (present(verbose)) self%verbose = verbose
allocate( self%twall(0:n), source = 0.0_wp )
allocate( self%tcpu(0:n), source = 0.0_wp )
allocate( self%running(n), source =.false. )
allocate( self%tag(n) ); self%tag = ' '

call self%start_timing(0)
!! launch timer

end subroutine allocate_timer

!--------------------------------------------
!> To deallocate memory
!--------------------------------------------
subroutine deallocate_timer(self)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer

self%n = 0
self%totwall = 0
self%totcpu = 0
self%verbose = .false.
if (allocated(self%twall)) deallocate(self%twall)
if (allocated(self%tcpu)) deallocate(self%tcpu)
if (allocated(self%running)) deallocate(self%running)

end subroutine deallocate_timer

!--------------------------------------------
!> To obtain current elapsed time
!--------------------------------------------
function get_timer(self,i) result(time)

!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer,intent(in),optional :: i
!! specific timer

!> local vars
integer :: it
real(wp) :: tcpu,twall
real(wp) :: time
logical :: running

!> if i is not given, calculate overall elapsed time
if (present(i)) then
it = i
else
it = 0
endif

if (it > 0) then
running = self%running(it)
else
running = .true.
endif

if (running) then
call timing(tcpu,twall)
time = self%twall(it) + twall
else
time = self%twall(it)
endif

end function get_timer

!--------------------------------------------
!> To write timing for specific timer
!--------------------------------------------
subroutine write_timing(self,iunit,i,inmsg,verbose)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer,intent(in) :: iunit
!! I/O unit
integer,intent(in) :: i
logical,intent(in),optional :: verbose
!! index
character(len=*),intent(in),optional :: inmsg
!! raw message text
logical,intent(in),optional :: verbose
!! if verbose

!> local vars
character(len=26) :: msg
real(wp) :: cputime,walltime
integer(int64) :: cpudays, cpuhours, cpumins
integer(int64) :: walldays,wallhours,wallmins
logical :: lverbose

! '(1x,a,1x,"time:",1x,a)'
!> check if a tag should be added
if (present(inmsg)) then
msg = inmsg
else
msg = self%tag(i)
endif

!> verbosity settings
if (present(verbose)) then
lverbose = verbose
else
lverbose = self%verbose
endif

! DAYS HOURS MINUTES SECONDS
! DAYS 1 1/24 1/1440 1/86400
! HOURS 24 1 1/60 1/3600
! MINUTES 1440 60 1 1/60
! SECONDS 86400 3600 60 1

!> convert elapsed CPU time into days, hours, minutes
cputime = self%tcpu (i)
cpudays = int(cputime/86400._wp)
cputime = cputime - cpudays*86400._wp
cpuhours = int(cputime/3600._wp)
cputime = cputime - cpuhours*3600._wp
cpumins = int(cputime/60._wp)
cputime = cputime - cpumins*60._wp

!> convert elapsed wall time into days, hours, minutes
walltime = self%twall(i)
walldays = int(walltime/86400._wp)
walltime = walltime - walldays*86400._wp
wallhours = int(walltime/3600._wp)
walltime = walltime - wallhours*3600._wp
wallmins = int(walltime/60._wp)
walltime = walltime - wallmins*60._wp

!> printout
if (lverbose) then
write(iunit,'(1x,a)') msg
write(iunit,'(" * wall-time: ",i5," d, ",i2," h, ",i2," min, ",f6.3," sec")') &
Expand All @@ -149,13 +216,24 @@ subroutine write_timing(self,iunit,i,inmsg,verbose)
write(iunit,'(1x,a30,1x,"...",i9," min, ",f6.3," sec")') &
msg, wallmins, walltime
endif

end subroutine write_timing

!--------------------------------------------
!> To write timing for all timers
!--------------------------------------------
subroutine write_all_timings(self,iunit,inmsg)

implicit none
!> dummy args list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer,intent(in) :: iunit
!! I/O unit
character(len=*),intent(in),optional :: inmsg
!! message

!> local vars
character(len=26) :: msg
real(wp) :: cputime,walltime
integer :: i
Expand All @@ -165,6 +243,7 @@ subroutine write_all_timings(self,iunit,inmsg)
call self%stop_timing(0)

! '(1x,a,1x,"time:",1x,a)'
!> check if an external message should be added
if (present(inmsg)) then
msg = inmsg // " (total)"
else
Expand All @@ -175,6 +254,8 @@ subroutine write_all_timings(self,iunit,inmsg)
! HOURS 24 1 1/60 1/3600
! MINUTES 1440 60 1 1/60
! SECONDS 86400 3600 60 1

!> convert overall elapsed CPU time into days, hours, minutes
cputime = self%tcpu (0)
cpudays = int(cputime/86400._wp)
cputime = cputime - cpudays*86400._wp
Expand All @@ -183,6 +264,7 @@ subroutine write_all_timings(self,iunit,inmsg)
cpumins = int(cputime/60._wp)
cputime = cputime - cpumins*60._wp

!> convert overall elapsed wall time into days, hours, minutes
walltime = self%twall(0)
walldays = int(walltime/86400._wp)
walltime = walltime - walldays*86400._wp
Expand All @@ -191,6 +273,7 @@ subroutine write_all_timings(self,iunit,inmsg)
wallmins = int(walltime/60._wp)
walltime = walltime - wallmins*60._wp

!> overall printout
write(iunit,'(a)')
if (self%verbose) then
write(iunit,'(1x,a,":")') msg
Expand All @@ -203,6 +286,8 @@ subroutine write_all_timings(self,iunit,inmsg)
write(iunit,'(1x,a26,i5," d, ",i2," h, ",i2," min, ",f6.3," sec")') &
msg,walldays,wallhours,wallmins,walltime
endif

!> printout every timer and corresponding speedup
do i = 1, self%n
walltime = self%twall(i)
wallmins = int(walltime/60._wp)
Expand All @@ -211,53 +296,107 @@ subroutine write_all_timings(self,iunit,inmsg)
self%tag(i), wallmins, walltime, 100*self%twall(i)/self%twall(0)
enddo
write(iunit,'(a)')

end subroutine write_all_timings

!--------------------------------------------
!> start/stop button
!--------------------------------------------
subroutine timer(self,i,inmsg)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
character(len=*),intent(in),optional :: inmsg
!! instance of timer
integer,intent(in) :: i
!! index
character(len=*),intent(in),optional :: inmsg
!! raw message text

if (i > self%n .or. i < 1) return
!! check if appropriate index is given

!> switcher between start/stop status
if (self%running(i)) then
call self%stop_timing(i)
else
call self%start_timing(i)
endif
if (present(inmsg)) self%tag(i) = trim(inmsg)
self%running(i) = .not.self%running(i)
!! update status

if (present(inmsg)) self%tag(i) = trim(inmsg)
!! assign tag to specific timer

end subroutine timer

!--------------------------------------------
!> To start counting
!--------------------------------------------
subroutine start_timing(self,i)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer,intent(in) :: i
!! specific timer index

!> local vars
real(wp) :: time_cpu
real(wp) :: time_wall

call timing(time_cpu,time_wall)
self%tcpu (i) = self%tcpu (i) - time_cpu
self%twall(i) = self%twall(i) - time_wall

end subroutine start_timing

!--------------------------------------------
!> To stop counting
!--------------------------------------------
subroutine stop_timing(self,i)

implicit none
!> dummy arg list
class(tb_timer),intent(inout) :: self
!! instance of timer
integer,intent(in) :: i
!! specific timer index

!> local vars
real(wp) :: time_cpu
real(wp) :: time_wall

call timing(time_cpu,time_wall)
self%tcpu (i) = self%tcpu (i) + time_cpu
self%twall(i) = self%twall(i) + time_wall

end subroutine stop_timing

!--------------------------------------------
!> To retrieve the current CPU and wall time
!--------------------------------------------
subroutine timing(time_cpu,time_wall)

implicit none
!> dummy arg list
real(wp),intent(out) :: time_cpu
real(wp),intent(out) :: time_wall
integer(int64) :: time_count,time_rate,time_max

!> local vars
integer(int64) :: time_count
!! current value of system clock (time passed from arbitary point)
integer(int64) :: time_rate
!! number of clock ticks per second (conversion factor b/n ticks and seconds)
integer(int64) :: time_max

call system_clock(time_count,time_rate,time_max)
call cpu_time(time_cpu)

time_wall = real(time_count,wp)/real(time_rate,wp)
!! elapsed time in seconds

end subroutine timing

end module xtb_type_timer

0 comments on commit 19306e6

Please sign in to comment.