Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Improved wall timer so that file io and integration are timed separately
Browse files Browse the repository at this point in the history
  • Loading branch information
daminton committed Sep 28, 2021
1 parent decdf50 commit 528f5d9
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 37 deletions.
22 changes: 19 additions & 3 deletions src/main/swiftest_driver.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ program swiftest_driver
integer(I8B) :: ioutput_t0 !! The output frame counter at time 0
integer(I8B) :: nloops !! Number of steps to take in the simulation
real(DP) :: old_t_final = 0.0_DP !! Output time at which writing should start, in order to prevent duplicate lines being written for restarts
type(walltimer) :: timer !! Object used for computing elapsed wall time
type(walltimer) :: integration_timer !! Object used for computing elapsed wall time
type(walltimer) :: file_io_timer !! Object used for computing elapsed wall time
integer(I4B) :: nout

ierr = io_get_args(integrator, param_file_name)
if (ierr /= 0) then
Expand Down Expand Up @@ -72,11 +74,17 @@ program swiftest_driver
!$ write(*,'(a)') ' OpenMP parameters:'
!$ write(*,'(a)') ' ------------------'
!$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads
call timer%reset(param)
call integration_timer%reset()
call integration_timer%pause()
call file_io_timer%reset()
call file_io_timer%pause()
nout = 0
write(*, *) " *************** Main Loop *************** "
do iloop = 1, nloops
!> Step the system forward in time
call integration_timer%resume()
call nbody_system%step(param, t, dt)
call integration_timer%pause()

t = t0 + iloop * dt

Expand All @@ -88,7 +96,10 @@ program swiftest_driver
iout = iout - 1
if (iout == 0) then
ioutput = ioutput_t0 + iloop / istep_out
call file_io_timer%resume()
if (t > old_t_final) call nbody_system%write_frame(param)
nout = nout + 1
call file_io_timer%pause()
iout = istep_out
end if
end if
Expand All @@ -97,8 +108,13 @@ program swiftest_driver
if (istep_dump > 0) then
idump = idump - 1
if (idump == 0) then
call timer%finish(nsubsteps=istep_dump, message="Integration steps:", param=param)
call integration_timer%report(nsubsteps=istep_dump, message="Integration steps:", param=param)
call file_io_timer%resume()
call nbody_system%dump(param)
nout = nout + 1
call file_io_timer%pause()
call file_io_timer%report(nsubsteps=nout, message=" File I/O:", param=param)
nout = 0
idump = istep_dump
end if
end if
Expand Down
35 changes: 22 additions & 13 deletions src/modules/walltime_classes.f90
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ module walltime_classes
integer(I8B) :: count_start_main !! Value of the clock ticker at when the timer is first called
integer(I8B) :: count_start_step !! Value of the clock ticker at the start of a timed step
integer(I8B) :: count_stop_step !! Value of the clock ticker at the end of a timed step
integer(I8B) :: count_pause !! Value of the clock ticker at the end of a timed step
real(DP) :: wall_step !! Value of the step elapsed time
logical :: lmain_is_started = .false. !! Logical flag indicating whether or not the main timer has been reset or not
logical :: main_is_started = .false. !! Logical flag indicating whether or not the main timer has been reset or not
logical :: is_paused = .false. !! Logical flag indicating whether or not the timer is paused

contains
procedure :: reset => walltime_reset !! Resets the clock ticker, settting main_start to the current ticker value
procedure :: start => walltime_start !! Starts the timer, setting count_start_step to the current ticker value
procedure :: stop => walltime_stop !! Stops the timer, setting count_stop_step to the current ticker value
procedure :: finish => walltime_finish !! Ends the timer, setting step_finish to the current ticker value and printing the elapsed time information to the terminal
procedure :: pause => walltime_pause !! Pauses the step timer (but not the main timer). Use resume to continue.
procedure :: resume => walltime_resume !! Resumes a paused step timer.
procedure :: report => walltime_report !! Prints the elapsed time information to the terminal
end type walltimer

type, extends(walltimer) :: interaction_timer
Expand All @@ -45,34 +50,38 @@ module walltime_classes
end type interaction_timer

interface
module subroutine walltime_finish(self, nsubsteps, message, param)
module subroutine walltime_pause(self)
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
end subroutine walltime_pause

module subroutine walltime_resume(self)
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
end subroutine walltime_resume

module subroutine walltime_report(self, nsubsteps, message, param)
use swiftest_classes, only : swiftest_parameters
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
integer(I4B), intent(in) :: nsubsteps !! Number of substeps used to compute the time per step
character(len=*), intent(in) :: message !! Message to prepend to the wall time terminal output
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
end subroutine walltime_finish
end subroutine walltime_report

module subroutine walltime_reset(self, param)
use swiftest_classes, only : swiftest_parameters
module subroutine walltime_reset(self)
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
end subroutine walltime_reset

module subroutine walltime_start(self, param)
use swiftest_classes, only : swiftest_parameters
module subroutine walltime_start(self)
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
end subroutine walltime_start

module subroutine walltime_stop(self, param)
use swiftest_classes, only : swiftest_parameters
module subroutine walltime_stop(self)
implicit none
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
end subroutine walltime_stop
end interface

Expand Down
89 changes: 68 additions & 21 deletions src/walltime/walltime.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,55 @@
use swiftest
contains

module subroutine walltime_finish(self, nsubsteps, message, param)
module subroutine walltime_pause(self)
!! author: David A. Minton
!!
!! Ends the timer, setting step_finish to the current ticker value and printing the elapsed time information to the terminal
!! Pauses the step timer (but not the main timer). Use resume to continue.
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object

if (.not.self%main_is_started) then
write(*,*) "Wall timer error: Cannot pause the step time until reset is called at least once!"
return
end if

if (self%is_paused) then
write(*,*) "Wall timer error: Timer is already paused!"
return
end if

call system_clock(self%count_pause)
self%is_paused = .true.

return
end subroutine walltime_pause


module subroutine walltime_report(self, nsubsteps, message, param)
!! author: David A. Minton
!!
!! Prints the elapsed time information to the terminal
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object
integer(I4B), intent(in) :: nsubsteps !! Number of substeps used to compute the time per step
character(len=*), intent(in) :: message !! Message to prepend to the wall time terminal output
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
! Internals
character(len=*), parameter :: walltimefmt = '" Wall time (s): ", es12.5, "; Wall time/step in this interval (s): ", es12.5'
character(len=*), parameter :: walltimefmt = '" Total wall time: ", es12.5, "; Interval wall time: ", es12.5, "; Interval wall time/step: ", es12.5'
character(len=STRMAX) :: fmt
integer(I8B) :: count_delta_step, count_delta_main, count_finish_step
real(DP) :: wall_main !! Value of total elapsed time at the end of a timed step
real(DP) :: wall_step !! Value of elapsed time since the start of a timed step
real(DP) :: wall_per_substep !! Value of time per substep

if (.not.self%lmain_is_started) then
if (.not.self%main_is_started) then
write(*,*) "Wall timer error: The step finish time cannot be calculated because the timer is not started!"
return
end if

call self%stop(param)
call self%stop()
count_finish_step = self%count_stop_step

count_delta_step = count_finish_step - self%count_start_step
Expand All @@ -34,41 +59,64 @@ module subroutine walltime_finish(self, nsubsteps, message, param)
wall_per_substep = self%wall_step / nsubsteps

fmt = '("' // adjustl(message) // '",' // walltimefmt // ')'
write(*,trim(adjustl(fmt))) wall_main, wall_per_substep
write(*,trim(adjustl(fmt))) wall_main, self%wall_step, wall_per_substep

call self%start(param)
call self%start()

return
end subroutine walltime_finish
end subroutine walltime_report


module subroutine walltime_reset(self, param)
module subroutine walltime_reset(self)
!! author: David A. Minton
!!
!! Resets the clock ticker, settting main_start to the current ticker value
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters

call system_clock(self%count_start_main, self%count_rate, self%count_max)
self%lmain_is_started = .true.
call self%start(param)
self%main_is_started = .true.
call self%start()

return
end subroutine walltime_reset
end subroutine walltime_reset


module subroutine walltime_start(self, param)
module subroutine walltime_resume(self)
!! author: David A. Minton
!!
!! Resumes a paused step timer.
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object
! Internals
integer(I8B) :: count_resume, count_delta

if (.not.self%is_paused) then
write(*,*) "Wall timer error: Timer is not paused, and so cannot resume!"
return
end if

call system_clock(count_resume)
count_delta = count_resume - self%count_pause
self%count_pause = 0_I8B
self%count_start_step = self%count_start_step + count_delta
self%is_paused = .false.

return
end subroutine walltime_resume


module subroutine walltime_start(self)
!! author: David A. Minton
!!
!! Starts the timer, setting step_start to the current ticker value
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters

if (.not.self%lmain_is_started) then
if (.not.self%main_is_started) then
write(*,*) "Wall timer error: Cannot start the step time until reset is called at least once!"
return
end if
Expand All @@ -79,18 +127,17 @@ module subroutine walltime_start(self, param)
end subroutine walltime_start


module subroutine walltime_stop(self, param)
module subroutine walltime_stop(self)
!! author: David A. Minton
!!
!! Starts the timer, setting step_start to the current ticker value
implicit none
! Arguments
class(walltimer), intent(inout) :: self !! Walltimer object
class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters
! Internals
integer(I8B) :: count_delta

if (.not.self%lmain_is_started) then
if (.not.self%main_is_started) then
write(*,*) "Wall timer error: Cannot start the step time until reset is called at least once!"
return
end if
Expand Down Expand Up @@ -121,7 +168,7 @@ module subroutine walltime_interaction_adapt(self, param, pl, ninteractions)
logical :: lflatten_final

! Record the elapsed time
call self%stop(param)
call self%stop()

write(schar,'(I1)') self%stage
write(nstr,*) ninteractions
Expand Down Expand Up @@ -269,7 +316,7 @@ module subroutine walltime_interaction_time_this_loop(self, param, pl, ninteract
write(schar,'(I1)') self%stage
call io_log_one_message(INTERACTION_TIMER_LOG_OUT, trim(adjustl(self%loopname)) // ": stage " // schar )

call self%reset(param)
call self%reset()

return
end subroutine walltime_interaction_time_this_loop
Expand Down

0 comments on commit 528f5d9

Please sign in to comment.