From 4705c9bb326ccf6bab6a7b18dbe4534689e88096 Mon Sep 17 00:00:00 2001 From: Adriano Amaricci Date: Fri, 13 Sep 2024 16:02:46 +0200 Subject: [PATCH] 4.11.0 MINOR UPDATE * SF_TIMER has been upgraded to use cpu_time system_clock date_and_time so to provide cpu and wall times from start/stop clock TODO: add MPI awareness so to . avoid if(master)start_timer in the calling program . use MPI_WTIME to get wall time and gather cpu_time to measure total used CPU time (it matters for HPC) --- CMakeLists.txt | 13 +- src/SF_TIMER/SF_TIMER.f90 | 467 ++++++++++++++++--------- test/src/SF_TIMER/01_test_sf_timer.f90 | 27 +- test/test.sh | 2 +- 4 files changed, 330 insertions(+), 179 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5e7edd72..8bae59384 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,10 @@ ADD_SUBDIRECTORY(${SRC_DIR_MINPACK}) SET(SRC_DIR_QUADPACK ${LIB_SRC}/quadpack) ADD_SUBDIRECTORY(${SRC_DIR_QUADPACK}) + +SET(SRC_DIR_SF_MPI ${LIB_SRC}/SF_MPI) +ADD_SUBDIRECTORY(${SRC_DIR_SF_MPI}) + ######################################### SET(SRC_DIR_SF_ARRAYS ${LIB_SRC}/SF_ARRAYS) @@ -174,9 +178,6 @@ ADD_SUBDIRECTORY(${SRC_DIR_SF_TIMER}) ######################################### -SET(SRC_DIR_SF_MPI ${LIB_SRC}/SF_MPI) -ADD_SUBDIRECTORY(${SRC_DIR_SF_MPI}) - SET(SRC_DIR_SF_IOTOOLS ${LIB_SRC}/SF_IOTOOLS) ADD_SUBDIRECTORY(${SRC_DIR_SF_IOTOOLS}) @@ -238,6 +239,7 @@ IF(WITH_BLAS_LAPACK) $ $ $ + $ $ $ $ @@ -248,7 +250,6 @@ IF(WITH_BLAS_LAPACK) $ $ $ - $ $ ) ELSE() @@ -265,6 +266,7 @@ ELSE() $ $ $ + $ $ $ $ @@ -274,7 +276,6 @@ ELSE() $ $ $ - $ $ ) ENDIF() @@ -304,6 +305,7 @@ ADD_DEPENDENCIES(SCIFORLIB SF_TIMERLIB SF_MPILIB SF_IOTOOLSLIB + SF_PARSE_INPUTLIB SF_DERIVATELIB SF_LINALGLIB SF_OPTIMIZELIB @@ -313,7 +315,6 @@ ADD_DEPENDENCIES(SCIFORLIB SF_RANDOMLIB SF_FFTLIB SF_SP_LINALGLIB - SF_PARSE_INPUTLIB ) diff --git a/src/SF_TIMER/SF_TIMER.f90 b/src/SF_TIMER/SF_TIMER.f90 index 2018c9124..a37a9bbac 100644 --- a/src/SF_TIMER/SF_TIMER.f90 +++ b/src/SF_TIMER/SF_TIMER.f90 @@ -2,10 +2,25 @@ module SF_TIMER implicit none private + !The months of the year: character(len=9),parameter,dimension(12) :: month = (/ & - 'January ', 'February ', 'March ', 'April ', & - 'May ', 'June ', 'July ', 'August ', & - 'September', 'October ', 'November ', 'December ' /) + 'January ', & + 'February ', & + 'March ', & + 'April ', & + 'May ', & + 'June ', & + 'July ', & + 'August ', & + 'September', & + 'October ', & + 'November ', & + 'December ' /) + !from secs to day, hour, min + integer,parameter :: secs_in_one_day=86400 + integer,parameter :: secs_in_one_hour=3600 + integer,parameter :: secs_in_one_min=60 + ! integer(4),dimension(8),save :: data integer(4),save :: year integer(4),save :: mese @@ -14,144 +29,145 @@ module SF_TIMER integer(4),save :: m integer(4),save :: s integer(4),save :: ms - integer,save :: timer_index=0 - real,dimension(100),save :: timer_start,timer_stop,timer0,timer1 - real,save :: time,old_time,dtime,elapsed_time,eta_time - integer,parameter :: secs_in_one_day=86400 - integer,parameter :: secs_in_one_hour=3600 - integer,parameter :: secs_in_one_min=60 + !Counter of the started timers: + integer,save :: Tindex=0 + integer,parameter :: Tmax=100! + ! + real,save :: time + real,save :: old_time + real,save :: dtime + real,save :: elapsed_time + real,save :: eta_time integer :: Funit + integer(8) :: st_rate + ! + !Using Date and Time: + integer,dimension(Tmax,8),save :: dt_T_start, dt_T_stop, dt_T0, dt_T1 + !Using Cpu_time + real,dimension(Tmax),save :: ct_T_start, ct_T_stop, ct_T0, ct_T1 + !Using System_clock + integer(8),dimension(Tmax),save :: st_T_start, st_T_stop, st_T0, st_T1 - public :: start_timer + + + interface start_progress + module procedure :: start_timer + end interface start_progress + + interface stop_progress + module procedure :: stop_timer + end interface stop_progress + + public :: start_timer,start_progress + public :: stop_timer ,stop_progress public :: eta - public :: stop_timer - ! - public :: start_progress - public :: stop_progress public :: progress - public :: progress_bar - public :: progress_bar_eta + + contains !+-------------------------------------------------------------------+ !PURPOSE : start a timer to measure elapsed time between two call !+-------------------------------------------------------------------+ - subroutine start_timer(title) + subroutine start_timer(title,unit) character(len=*),optional :: title - if(present(title))write(*,"(A)")trim(title)//":" - timer_index=timer_index+1 - if(timer_index>size(timer_start,1))then - stop "Error in cronograph: too many timers started" - endif - call cpu_time(timer_start(timer_index)) !time in seconds - timer0(timer_index)=timer_start(timer_index) + integer,optional :: unit ! - !init variables for ETA: - elapsed_time =0.0 - old_time =0.0 - time =0.0 + funit=6;if(present(unit))funit=unit + if(funit==5)funit=6 !do not write to stdin + ! + if(present(title))write(funit,"(1x,A)")trim(title) ! + Tindex=Tindex+1 + if(Tindex>Tmax)stop "start_timer error: too many timers started" + ! + call system_clock(count_rate=st_rate) + ! + call system_clock(count=st_T_start(Tindex)) + call cpu_time(ct_T_start(Tindex)) + call date_and_time(values=dt_T_start(Tindex,:)) + st_T0 = st_T_start + ct_T0 = ct_T_start + dt_T0 = dt_T_start + ! + !init variables for ETA: + elapsed_time = 0.0 + old_time = 0.0 + time = 0.0 end subroutine start_timer - ! - subroutine start_progress(title,unit) - character(len=*),optional :: title - integer,optional :: unit - funit=6;if(present(unit))funit=unit - if(present(title))write(funit,"(A)")trim(title)//":" - !open(funit,carriagecontrol='fortran') - if(funit/=6)open(funit) - call start_timer - end subroutine start_progress + !+-------------------------------------------------------------------+ !PURPOSE : stop the timer and get the partial time !+-------------------------------------------------------------------+ - subroutine stop_timer(title,unit) - character(len=*),optional :: title - integer,optional :: unit - integer :: unit_ - ! integer,dimension(8) :: itimer - real :: itimer - unit_=6;if(present(unit))unit_=unit - call cpu_time(timer_stop(timer_index)) - itimer=timer_stop(timer_index)-timer_start(timer_index) - if(present(title))then - call print_total_time(itimer,unit,title) + subroutine stop_timer(msg) + character(len=*),optional :: msg + real :: ct_T + real :: st_T + integer,dimension(8) :: dt_T + ! + ! + call system_clock(count=st_T_stop(Tindex)) + call cpu_time(ct_T_stop(Tindex)) + call date_and_time(values=dt_T_stop(Tindex,:)) + ct_T = ct_time_difference(ct_T_stop(Tindex),ct_T_start(Tindex)) + st_T = st_time_difference(st_T_stop(Tindex),st_T_start(Tindex)) + dt_T = dt_time_difference(dt_T_stop(Tindex,:),dt_T_start(Tindex,:)) + ! + if(present(msg))then + call print_total_time(ct_T,st_T,dt_T,msg) else - call print_total_time(itimer,unit) + call print_total_time(ct_T,st_T,dt_T) endif - timer_start(timer_index)=0 - timer_stop(timer_index)=0 - if(timer_index>1)then - timer_index=timer_index-1 + ct_T_start(Tindex) = 0 + st_T_start(Tindex) = 0 + dt_T_start(Tindex,:) = 0 + ct_T_stop(Tindex) = 0 + st_T_stop(Tindex) = 0 + dt_T_stop(Tindex,:) = 0 + ! + if(Tindex>1)then + Tindex=Tindex-1 else - timer_index=0 + Tindex=0 endif end subroutine stop_timer - ! - subroutine stop_progress(title) - character(len=*),optional :: title - if(present(title))write(funit,"(A)")trim(title)//":" - if(funit/=6)close(funit) - call stop_timer - end subroutine stop_progress - subroutine print_total_time(dummy,unit,title) - ! integer(4),dimension(8) :: dummy - real :: dummy - integer,optional :: unit - character(len=*),optional :: title - integer :: unit_ - unit_=6;if(present(unit))unit_=unit - ms=int(fraction(dummy)*1000.0) - h =int(dummy/secs_in_one_hour) - m =int((dummy - h*secs_in_one_hour)/secs_in_one_min) - s =int(dummy - h*secs_in_one_hour - m*secs_in_one_min) - ! - if(present(title))then - write(unit_,"(a,i3,a1,i2.2,a1,i2.2,a1,i3.3,A2,A)")"Total time [h:m:s.ms]: ",h,":",m,":",s,".",ms," :",trim(title) - else - write(unit_,"(a,i3,a1,i2.2,a1,i2.2,a1,i3.3)")"Total time [h:m:s.ms]: ",h,":",m,":",s,".",ms - endif - !write(unit_,*)"" - end subroutine print_total_time + + !+-------------------------------------------------------------------+ !PURPOSE : get Expected Time of Arrival !+-------------------------------------------------------------------+ - subroutine eta(i,L,unit,file,step) - integer :: i,L + subroutine eta(i,L,step,method) + integer :: i + integer :: L integer,optional :: step + character(len=*),optional :: method + ! integer,save :: mod_print integer :: percent,iprint integer,save :: older=0,oldiprint=0 logical :: esc,fullprint integer(4),dimension(8) :: dummy - integer,optional :: unit - integer,save :: unit_ - character(len=*),optional :: file character(len=16) :: string + character(len=1) :: method_ character(len=80) :: message logical,save :: lentry=.true. + ! + method_='c';if(present(method))method_=trim(method) !s=system_clock(wall_time),c=cpu_time,d=date_and_time + ! !Preambolo: if(lentry)then - unit_=6 ; if(present(unit))unit_=unit mod_print=10;if(present(step))mod_print=step - if(unit_==5)unit_=6 !do not write to stdin - if(present(file))then - unit_=719 - open(unit_,file=trim(adjustl(trim(file)))) - write(*,"(2x,A)")"+ETA --> "//trim(adjustl(trim(file))) - else - if(unit_/=6)then - write(string,"(I4)")unit_ - write(*,"(2x,A,I3)")"+ETA --> fort."//trim(adjustl(trim(string))) - endif + if(funit/=6)then + write(string,"(I4)")funit + write(*,"(2x,A,I3)")"+ETA --> unit:"//trim(adjustl(trim(string))) endif lentry=.false. endif @@ -159,7 +175,7 @@ subroutine eta(i,L,unit,file,step) if(i==L)lentry=.true. ! !avoid repetition of percentage (within the error) - percent=100*i/L + percent=int(100.0*i/L) if(percent==0)return if(percent==older)return if(percent