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

Commit

Permalink
Re-wrote the wall timer as its own module and class. Now add a file I…
Browse files Browse the repository at this point in the history
…/O timer report.
  • Loading branch information
daminton committed Sep 9, 2021
1 parent a12ad18 commit 4675c76
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 13 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
SWIFTEST_MODULES = swiftest_globals.f90 \
swiftest_operators.f90 \
lambda_function.f90\
walltime_classes.f90 \
swiftest_classes.f90 \
fraggle_classes.f90 \
whm_classes.f90 \
Expand Down
13 changes: 1 addition & 12 deletions src/io/io.f90
Original file line number Diff line number Diff line change
Expand Up @@ -275,18 +275,12 @@ module subroutine io_dump_system(self, param)
integer(I4B), save :: idx = 1 !! Index of current dump file. Output flips between 2 files for extra security
!! in case the program halts during writing
character(len=:), allocatable :: param_file_name
real(DP) :: deltawall, wallperstep, tfrac
integer(I8B) :: clock_count, count_rate, count_max
real(DP) :: tfrac
character(*), parameter :: statusfmt = '("Time = ", ES12.5, "; fraction done = ", F6.3, "; Number of active pl, tp = ", I5, ", ", I5)'
character(*), parameter :: symbastatfmt = '("Time = ", ES12.5, "; fraction done = ", F6.3, "; Number of active plm, pl, tp = ", I5, ", ", I5, ", ", I5)'
character(len=*), parameter :: walltimefmt = '(" Wall time (s): ", es12.5, "; Wall time/step in this interval (s): ", es12.5)'
logical, save :: lfirst = .true.
real(DP), save :: start, finish

if (lfirst) then
call system_clock(clock_count, count_rate, count_max)
start = clock_count / (count_rate * 1.0_DP)
finish = start
lfirst = .false.
if (param%lenergy) call self%conservation_report(param, lterminal=.false.)
else
Expand All @@ -312,17 +306,12 @@ module subroutine io_dump_system(self, param)

tfrac = (param%t - param%t0) / (param%tstop - param%t0)

call system_clock(clock_count, count_rate, count_max)
deltawall = clock_count / (count_rate * 1.0_DP) - finish
wallperstep = deltawall / param%istep_dump
finish = clock_count / (count_rate * 1.0_DP)
select type(pl => self%pl)
class is (symba_pl)
write(*, symbastatfmt) param%t, tfrac, pl%nplm, pl%nbody, self%tp%nbody
class default
write(*, statusfmt) param%t, tfrac, pl%nbody, self%tp%nbody
end select
write(*, walltimefmt) finish - start, wallperstep
end if

return
Expand Down
4 changes: 4 additions & 0 deletions src/main/swiftest_driver.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ 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

ierr = io_get_args(integrator, param_file_name)
if (ierr /= 0) then
Expand Down Expand Up @@ -69,6 +70,7 @@ program swiftest_driver
!$ write(*,'(a)') ' OpenMP parameters:'
!$ write(*,'(a)') ' ------------------'
!$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads
call timer%reset()
write(*, *) " *************** Main Loop *************** "
do iloop = 1, nloops
!> Step the system forward in time
Expand All @@ -84,7 +86,9 @@ program swiftest_driver
iout = iout - 1
if (iout == 0) then
ioutput = ioutput_t0 + iloop / istep_out
call timer%finish(nsubsteps=istep_out, message="Integration steps:")
if (t > old_t_final) call nbody_system%write_frame(param)
call timer%finish(nsubsteps=1, message="File I/O: ")
iout = istep_out
end if
end if
Expand Down
1 change: 1 addition & 0 deletions src/modules/swiftest.f90
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module swiftest
use symba_classes
use fraggle_classes
use lambda_function
use walltime_classes
!use advisor_annotate
!$ use omp_lib
implicit none
Expand Down
1 change: 0 additions & 1 deletion src/modules/swiftest_classes.f90
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module swiftest_classes
implicit none
public


type :: netcdf_parameters
integer(I4B) :: out_type !! NetCDF output type (will be assigned either NF90_DOUBLE or NF90_FLOAT, depending on the user parameter)
integer(I4B) :: ncid !! NetCDF ID for the output file
Expand Down
119 changes: 119 additions & 0 deletions src/modules/walltime_classes.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
module walltime_classes
!! author: David A. Minton
!!
!! Classes and methods used to compute elasped wall time
use swiftest_globals
implicit none
public

type :: walltimer
integer(I8B) :: count_rate !! Rate at wich the clock ticks
integer(I8B) :: count_max !! Maximum value of the clock ticker
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_finish_step !! Value of the clock ticker at the end of a timed step
logical :: lmain_is_started = .false. !! Logical flag indicating whether or not the main timer has been reset or not
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 step_start 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
end type

interface
module subroutine walltime_finish(self, nsubsteps, message)
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
end subroutine walltime_finish

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

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

contains

module subroutine walltime_finish(self, nsubsteps, message)
!! author: David A. Minton
!!
!! Ends the timer, setting step_finish to the current ticker value and printing the elapsed time information to the terminal
use swiftest_globals
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
! Internals
character(len=*), parameter :: walltimefmt = '" Wall time (s): ", es12.5, "; Wall time/step in this interval (s): ", es12.5'
character(len=STRMAX) :: fmt
integer(I8B) :: count_delta_step, count_delta_main
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
write(*,*) "Wall timer error: The step finish time cannot be calculated because the timer is not started!"
return
end if

call system_clock(self%count_finish_step)

count_delta_step = self%count_finish_step - self%count_start_step
count_delta_main = self%count_finish_step - self%count_start_main
wall_step = count_delta_step / (self%count_rate * 1.0_DP)
wall_main = count_delta_main / (self%count_rate * 1.0_DP)
wall_per_substep = wall_step / nsubsteps

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

call self%start()

return
end subroutine walltime_finish

module subroutine walltime_reset(self)
!! author: David A. Minton
!!
!! Resets the clock ticker, settting main_start to the current ticker value
use swiftest_globals
implicit none
! Arguments
class(walltimer), intent(inout) :: self

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

return
end subroutine walltime_reset


module subroutine walltime_start(self)
!! author: David A. Minton
!!
!! Starts the timer, setting step_start to the current ticker value
use swiftest_globals
implicit none
! Arguments
class(walltimer), intent(inout) :: self

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

call system_clock(self%count_start_step)

return
end subroutine walltime_start


end module walltime_classes

0 comments on commit 4675c76

Please sign in to comment.