Commit 15a23533 authored by Uliana Alekseeva's avatar Uliana Alekseeva

Merge branch 'develop' of ifflinux.iff.kfa-juelich.de:fleur into develop

Conflicts:
	juDFT/time.F90
parents 48113773 4601aaea
......@@ -25,7 +25,7 @@ SUBROUTINE w_inpXML(&
& numSpecies,enpara)
USE m_types
USE m_juDFT_init
USE m_juDFT
USE m_constants
USE m_xmlOutput
......
......@@ -16,4 +16,5 @@ juDFT/init.F90
juDFT/juDFT.F90
juDFT/stop.F90
juDFT/time.F90
juDFT/args.F90
)
......@@ -8,28 +8,9 @@
USE m_judft_time
IMPLICIT NONE
PRIVATE
PUBLIC juDFT_init,juDFT_was_argument
PUBLIC juDFT_init
CONTAINS
FUNCTION juDFT_was_argument(arg) RESULT(OK)
IMPLICIT NONE
CHARACTER(len=*),INTENT(IN)::arg
LOGICAL ok
INTEGER:: i
CHARACTER(LEN=30)::str
ok=.false.
DO i=1,command_argument_count()
CALL get_command_argument(i,str)
IF(adjustl(str)==adjustl(arg)) ok=.true.
ENDDO
IF (ok) return
!Test for environment variable as well
CALL get_environment_variable("juDFT",str,status=i)
IF (i==0) ok=index(str,adjustl(arg))>0
END FUNCTION
SUBROUTINE juDFT_init()
CALL signal_handler()
END SUBROUTINE juDFT_init
......
......@@ -8,5 +8,6 @@
USE m_juDFT_stop
USE m_juDFT_time
USE m_juDFT_init
USE m_judft_args
END MODULE m_juDFT
......@@ -4,494 +4,501 @@
! of the MIT license as expressed in the LICENSE file in more detail.
!--------------------------------------------------------------------------------
MODULE m_juDFT_time
!*****************************************************************
! DESC:Timer module for measuring the execution times of different
! parts of the code
! timestart and timestop should be
! called with suitable names for timers
! Daniel Wortmann, Fri Sep 6 11:53:08 2002
!*****************************************************************
USE m_xmlOutput
IMPLICIT NONE
! List of different timers
PRIVATE
INTEGER,PARAMETER :: max_subtimer=5 ! blocks of subtimers are allocated in this size
REAL :: min_time=0.02 ! minimal time to display in output (part of total)
TYPE t_p
TYPE(t_timer),POINTER:: p
END TYPE
TYPE t_timer
REAL :: starttime
REAL :: time
CHARACTER(LEN=60) :: name
INTEGER :: n_subtimers
TYPE(t_p),ALLOCATABLE :: subtimer(:)
TYPE(t_timer),POINTER :: parenttimer
END TYPE
TYPE(t_timer),POINTER,SAVE:: globaltimer=>NULL()
TYPE(t_timer),POINTER,SAVE:: current_timer=>NULL()
CHARACTER(LEN=256),SAVE :: lastfile=""
INTEGER ,SAVE :: lastline=0
PUBLIC timestart,timestop,writetimes,writelocation,writeTimesXML
PUBLIC resetIterationDependentTimers
PUBLIC juDFT_time_lastlocation !should not be used
CONTAINS
SUBROUTINE priv_new_timer(name)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) ::name
TYPE(t_timer),POINTER ::t
TYPE(t_p),ALLOCATABLE :: tmp(:)
ALLOCATE(t)
t%starttime=cputime()
t%time=0.0
t%name=name
t%n_subtimers=0
ALLOCATE(t%subtimer(max_subtimer))
IF (associated(current_timer)) THEN
ALLOCATE(t%parenttimer)
t%parenttimer=>current_timer
!now add timer to list of subtimers of parenttimer
IF (current_timer%n_subtimers+1>size(current_timer%subtimer)) THEN
ALLOCATE(tmp(size(current_timer%subtimer)))
tmp=current_timer%subtimer
DEALLOCATE(current_timer%subtimer)
ALLOCATE(current_timer%subtimer(size(tmp)+max_subtimer))
current_timer%subtimer(:size(tmp))=tmp
DEALLOCATE(tmp)
ENDIF
current_timer%n_subtimers=current_timer%n_subtimers+1
current_timer%subtimer(current_timer%n_subtimers)%p => t
ELSE
globaltimer=>t
ENDIF
current_timer=>t
END SUBROUTINE priv_new_timer
!<-- S: timestart(timer)
SUBROUTINE timestart(ttimer,file,line)
IMPLICIT NONE
CHARACTER(LEN =*),INTENT(IN) :: ttimer
CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: file
INTEGER,INTENT(IN),OPTIONAL :: line
INTEGER::n
MODULE m_juDFT_time
!*****************************************************************
! DESC:Timer module for measuring the execution times of different
! parts of the code
! timestart and timestop should be
! called with suitable names for timers
! Daniel Wortmann, Fri Sep 6 11:53:08 2002
!*****************************************************************
USE m_xmlOutput
IMPLICIT NONE
! List of different timers
PRIVATE
INTEGER,PARAMETER :: max_subtimer=5 ! blocks of subtimers are allocated in this size
REAL :: min_time=0.02 ! minimal time to display in output (part of total)
LOGICAL :: l_debug !write out each start& stop of timer
TYPE t_p
TYPE(t_timer),POINTER:: p
END TYPE t_p
TYPE t_timer
REAL :: starttime
REAL :: time
CHARACTER(LEN=60) :: name
INTEGER :: n_subtimers
TYPE(t_p),ALLOCATABLE :: subtimer(:)
TYPE(t_timer),POINTER :: parenttimer
END TYPE t_timer
TYPE(t_timer),POINTER,SAVE:: globaltimer=>NULL()
TYPE(t_timer),POINTER,SAVE:: current_timer=>NULL()
CHARACTER(LEN=256),SAVE :: lastfile=""
INTEGER ,SAVE :: lastline=0
PUBLIC timestart,timestop,writetimes,writelocation,writeTimesXML
PUBLIC resetIterationDependentTimers
PUBLIC juDFT_time_lastlocation !should not be used
CONTAINS
SUBROUTINE priv_new_timer(name)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN) ::name
TYPE(t_timer),POINTER ::t
TYPE(t_p),ALLOCATABLE :: tmp(:)
ALLOCATE(t)
t%starttime=cputime()
t%time=0.0
t%name=name
t%n_subtimers=0
ALLOCATE(t%subtimer(max_subtimer))
IF (ASSOCIATED(current_timer)) THEN
ALLOCATE(t%parenttimer)
t%parenttimer=>current_timer
!now add timer to list of subtimers of parenttimer
IF (current_timer%n_subtimers+1>SIZE(current_timer%subtimer)) THEN
ALLOCATE(tmp(SIZE(current_timer%subtimer)))
tmp=current_timer%subtimer
DEALLOCATE(current_timer%subtimer)
ALLOCATE(current_timer%subtimer(SIZE(tmp)+max_subtimer))
current_timer%subtimer(:SIZE(tmp))=tmp
DEALLOCATE(tmp)
ENDIF
current_timer%n_subtimers=current_timer%n_subtimers+1
current_timer%subtimer(current_timer%n_subtimers)%p => t
ELSE
globaltimer=>t
ENDIF
current_timer=>t
END SUBROUTINE priv_new_timer
!<-- S: timestart(timer)
SUBROUTINE timestart(ttimer,file,line)
USE m_judft_args
IMPLICIT NONE
CHARACTER(LEN =*),INTENT(IN) :: ttimer
CHARACTER(LEN=*),INTENT(IN),OPTIONAL :: file
INTEGER,INTENT(IN),OPTIONAL :: line
INTEGER::n
#ifdef CPP_MPI
INTEGER::irank,ierr
include 'mpif.h'
INTEGER::irank,ierr
INCLUDE 'mpif.h'
#endif
IF (present(file)) lastfile=file
IF (present(line)) lastline=line
IF (.NOT.associated(current_timer)) THEN
CALL priv_new_timer("Total Run")
ENDIF
DO n=1,current_timer%n_subtimers
IF (trim(ttimer)==trim(current_timer%subtimer(n)%p%name)) THEN
current_timer=>current_timer%subtimer(n)%p
IF (current_timer%starttime>0) THEN
WRITE(*,*) "Timer already running:",ttimer
STOP "BUG:starttime"
ENDIF
current_timer%starttime=cputime()
#ifdef CPP_DEBUG
IF (PRESENT(file)) lastfile=file
IF (PRESENT(line)) lastline=line
IF (.NOT.ASSOCIATED(current_timer)) THEN
CALL priv_new_timer("Total Run")
l_debug=judft_was_Argument("-debugtime")
ENDIF
DO n=1,current_timer%n_subtimers
IF (TRIM(ttimer)==TRIM(current_timer%subtimer(n)%p%name)) THEN
current_timer=>current_timer%subtimer(n)%p
IF (current_timer%starttime>0) THEN
WRITE(*,*) "Timer already running:",ttimer
STOP "BUG:starttime"
ENDIF
current_timer%starttime=cputime()
CALL priv_debug_output(" started ",current_timer%name)
RETURN
ENDIF
ENDDO
!new subtimer
CALL priv_new_timer(ttimer)
CALL priv_debug_output(" started ",current_timer%name)
END SUBROUTINE timestart
!>
!<-- S:timestop(timer)
SUBROUTINE timestop(ttimer)
CHARACTER(LEN =*),INTENT(IN) :: ttimer
IF (.NOT.TRIM(ttimer)==TRIM(current_timer%name)) THEN
WRITE(*,*)"Current timer:",current_timer%name," could not stop:",ttimer
STOP "BUG:timestop"
ENDIF
IF (current_timer%starttime<0) THEN
WRITE(*,*) "Timer not initialized:"//ttimer
STOP "BUG:timestop"
ENDIF
current_timer%time=current_timer%time+cputime()-current_timer%starttime
current_timer%starttime=-1
CALL priv_debug_output(" stopped ",current_timer%name)
current_timer=>current_timer%parenttimer
END SUBROUTINE timestop
!>
SUBROUTINE priv_debug_output(startstop,name)
IMPLICIT NONE
CHARACTER(LEN=*),INTENT(IN):: startstop,name
#ifdef CPP_MPI
CALL MPI_COMM_RANK(MPI_COMM_WORLD,irank,ierr)
INTEGER::irank,ierr
INCLUDE 'mpif.h'
#endif
WRITE(*,"(i3,3a,i10)") irank," started: ",current_timer%name
#endif
RETURN
ENDIF
ENDDO
!new subtimer
CALL priv_new_timer(ttimer)
#ifdef CPP_DEBUG
IF (.NOT.l_debug) RETURN
#ifdef CPP_MPI
CALL MPI_COMM_RANK(MPI_COMM_WORLD,irank,ierr)
#endif
WRITE(*,*) irank," started: ",current_timer%name
#endif
END SUBROUTINE timestart
!>
!<-- S:timestop(timer)
SUBROUTINE timestop(ttimer)
CHARACTER(LEN =*),INTENT(IN) :: ttimer
IF (.NOT.trim(ttimer)==trim(current_timer%name)) THEN
WRITE(*,*)"Current timer:",current_timer%name," could not stop:",ttimer
STOP "BUG:timestop"
ENDIF
IF (current_timer%starttime<0) THEN
WRITE(*,*) "Timer not initialized:"//ttimer
STOP "BUG:timestop"
ENDIF
current_timer%time=current_timer%time+cputime()-current_timer%starttime
current_timer%starttime=-1
#ifdef CPP_DEBUG
CALL priv_writetimes(current_timer,5,6)
#endif
current_timer=>current_timer%parenttimer
END SUBROUTINE timestop
!>
RECURSIVE SUBROUTINE priv_writetimes_longest(timer,fid,timernames,timertimes)
IMPLICIT NONE
TYPE(t_timer),INTENT(IN) :: timer
INTEGER,INTENT(IN),OPTIONAL :: fid
CHARACTER(LEN=60),INTENT(INOUT),OPTIONAL ::timernames(10)
REAL,INTENT(INOUT),OPTIONAL ::timertimes(10)
REAL,ALLOCATABLE ::times(:)
CHARACTER(LEN=60),ALLOCATABLE ::names(:)
real ::sum_time
integer :: n,i
IF (.NOT.present(timernames)) THEN
ALLOCATE(times(10),names(10))
times=0.0
names=""
CALL priv_writetimes_longest(timer,timernames=names,timertimes=times)
WRITE(fid,*)
WRITE(fid,*) "-------------------------------------------------"
WRITE(fid,*)
WRITE(fid,*) "most relevant subroutines:"
sum_time=0.0
DO n=1,10
IF (maxval(times)<1E-4) exit
i=maxloc(times,dim=1)
WRITE(fid,"(a,T7,a,T46,a)") " ",trim(names(i)),timestring(times(i),timer%time,2)
sum_time=sum_time+times(i)
times(i)=0.0
ENDDO
WRITE(fid,"(t77,'Sum: ',f4.1,'%')") sum_time/timer%time*100.
WRITE(fid,*)
WRITE(fid,*) "-------------------------------------------------"
WRITE(fid,*)
RETURN
ENDIF
sum_time=timer%time
DO n=1,timer%n_subtimers
CALL priv_writetimes_longest(timer%subtimer(n)%p,timernames=timernames,timertimes=timertimes)
sum_time=sum_time-timer%subtimer(n)%p%time
ENDDO
IF (sum_time>minval(timertimes)) THEN
i=minloc(timertimes,dim=1)
if (associated(timer%parenttimer)) THEN
write(timernames(i),"(a18,'->',a40)") timer%parenttimer%name,timer%name
else
timernames(i)=timer%name
endif
timertimes(i)=sum_time
ENDIF
END SUBROUTINE
RECURSIVE SUBROUTINE priv_writetimes(timer,level,fid,debug)
IMPLICIT NONE
TYPE(t_timer),INTENT(IN) :: timer
INTEGER,INTENT(IN) :: level,fid
LOGICAL,INTENT(IN),OPTIONAL ::debug
INTEGER :: n
REAL :: time
CHARACTER(LEN=30):: timername,indentstring
WRITE(timername,"(i0)") level-1
WRITE(indentstring,"(100a)") (" ",n=2,(min(level,5))),trim(timername)
IF (timer%starttime>0) THEN
time=timer%time+cputime()-timer%starttime
timername=timer%name//" not term."
ELSE
time=timer%time
timername=timer%name
ENDIF
IF (time<min_time*globaltimer%time) RETURN !do not print parts that take less than min_time
WRITE(fid,"(a,T7,a,T46,a)") trim(indentstring),trim(timername),timestring(time,globaltimer%time,level)
flush(fid)
IF (present(debug).OR.timer%n_subtimers==0) RETURN
time=0
DO n=1,timer%n_subtimers
time=time+timer%subtimer(n)%p%time
ENDDO
WRITE(fid,"(a,a,T46,a)") trim(indentstring)," measured in submodules:",timestring(time,-.1,level)
flush(fid)
DO n=1,timer%n_subtimers
CALL priv_writetimes(timer%subtimer(n)%p,level+1,fid)
ENDDO
END SUBROUTINE priv_writetimes
!<-- S:writetimes()
RECURSIVE SUBROUTINE writelocation(location)
!writes the stack of current timers to std-out
!usefull for debugging and error messages
IMPLICIT NONE
TYPE(t_timer),INTENT(IN),OPTIONAL::location
IF (.NOT.present(location)) THEN
IF (associated(current_timer)) CALL writelocation(current_timer)
ELSE
WRITE(*,*) "Timer:",location%name
IF (associated(location%parenttimer)) CALL writelocation(location%parenttimer)
ENDIF
END SUBROUTINE writelocation
! writes all times to file
SUBROUTINE writetimes(stdout)
IMPLICIT NONE
LOGICAL,INTENT(IN),OPTIONAL::stdout
INTEGER :: fn,irank=0
LOGICAL :: l_out
CALL MPI_COMM_RANK(MPI_COMM_WORLD,irank,ierr)
WRITE(*,"(i3,3a,f10.3)") irank,startstop,name," at:",cputime()
#else
WRITE(*,"(3a,f10.3)") startstop,name," at:",cputime()
#endif
END SUBROUTINE priv_debug_output
RECURSIVE SUBROUTINE priv_writetimes_longest(timer,fid,timernames,timertimes)
IMPLICIT NONE
TYPE(t_timer),INTENT(IN) :: timer
INTEGER,INTENT(IN),OPTIONAL :: fid
CHARACTER(LEN=60),INTENT(INOUT),OPTIONAL ::timernames(10)
REAL,INTENT(INOUT),OPTIONAL ::timertimes(10)
REAL,ALLOCATABLE ::times(:)
CHARACTER(LEN=60),ALLOCATABLE ::names(:)
REAL ::sum_time
INTEGER :: n,i
IF (.NOT.PRESENT(timernames)) THEN
ALLOCATE(times(10),names(10))
times=0.0
names=""
CALL priv_writetimes_longest(timer,timernames=names,timertimes=times)
WRITE(fid,*)
WRITE(fid,*) "-------------------------------------------------"
WRITE(fid,*)
WRITE(fid,*) "most relevant subroutines:"
sum_time=0.0
DO n=1,10
IF (MAXVAL(times)<1E-4) EXIT
i=MAXLOC(times,dim=1)
WRITE(fid,"(a,T7,a,T46,a)") " ",TRIM(names(i)),timestring(times(i),timer%time,2)
sum_time=sum_time+times(i)
times(i)=0.0
ENDDO
WRITE(fid,"(t77,'Sum: ',f4.1,'%')") sum_time/timer%time*100.
WRITE(fid,*)
WRITE(fid,*) "-------------------------------------------------"
WRITE(fid,*)
RETURN
ENDIF
sum_time=timer%time
DO n=1,timer%n_subtimers
CALL priv_writetimes_longest(timer%subtimer(n)%p,timernames=timernames,timertimes=timertimes)
sum_time=sum_time-timer%subtimer(n)%p%time
ENDDO
IF (sum_time>MINVAL(timertimes)) THEN
i=MINLOC(timertimes,dim=1)
IF (ASSOCIATED(timer%parenttimer)) THEN
WRITE(timernames(i),"(a18,'->',a40)") timer%parenttimer%name,timer%name
ELSE
timernames(i)=timer%name
ENDIF
timertimes(i)=sum_time
ENDIF
END SUBROUTINE priv_writetimes_longest
RECURSIVE SUBROUTINE priv_writetimes(timer,level,fid,debug)
IMPLICIT NONE
TYPE(t_timer),INTENT(IN) :: timer
INTEGER,INTENT(IN) :: level,fid
LOGICAL,INTENT(IN),OPTIONAL ::debug
INTEGER :: n
REAL :: time
CHARACTER(LEN=30):: timername,indentstring
WRITE(timername,"(i0)") level-1
WRITE(indentstring,"(100a)") (" ",n=2,(MIN(level,5))),TRIM(timername)
IF (timer%starttime>0) THEN
time=timer%time+cputime()-timer%starttime
timername=timer%name//" not term."
ELSE
time=timer%time
timername=timer%name
ENDIF
IF (time<min_time*globaltimer%time) RETURN !do not print parts that take less than min_time
WRITE(fid,"(a,T7,a,T46,a)") TRIM(indentstring),TRIM(timername),timestring(time,globaltimer%time,level)
FLUSH(fid)
IF (PRESENT(debug).OR.timer%n_subtimers==0) RETURN
time=0
DO n=1,timer%n_subtimers
time=time+timer%subtimer(n)%p%time
ENDDO
WRITE(fid,"(a,a,T46,a)") TRIM(indentstring)," measured in submodules:",timestring(time,-.1,level)
FLUSH(fid)
DO n=1,timer%n_subtimers
CALL priv_writetimes(timer%subtimer(n)%p,level+1,fid)
ENDDO
END SUBROUTINE priv_writetimes
!<-- S:writetimes()
RECURSIVE SUBROUTINE writelocation(location)
!writes the stack of current timers to std-out
!usefull for debugging and error messages
IMPLICIT NONE
TYPE(t_timer),INTENT(IN),OPTIONAL::location
IF (.NOT.PRESENT(location)) THEN
IF (ASSOCIATED(current_timer)) CALL writelocation(current_timer)
ELSE
WRITE(*,*) "Timer:",location%name
IF (ASSOCIATED(location%parenttimer)) CALL writelocation(location%parenttimer)
ENDIF
END SUBROUTINE writelocation
! writes all times to file
SUBROUTINE writetimes(stdout)
IMPLICIT NONE
LOGICAL,INTENT(IN),OPTIONAL::stdout
INTEGER :: fn,irank=0
LOGICAL :: l_out
#ifdef CPP_MPI
include "mpif.h"
INTEGER::err,isize
INCLUDE "mpif.h"
INTEGER::err,isize
CALL MPI_COMM_RANK(MPI_COMM_WORLD,irank,err)
CALL MPI_COMM_RANK(MPI_COMM_WORLD,irank,err)
#endif
IF (.NOT.associated(globaltimer)) RETURN !write nothing if no timing recorded
l_out=.FALSE.
IF (present(stdout)) l_out=stdout
IF (l_out) THEN
fn=6
ELSE
IF (irank>0) RETURN
fn=2
OPEN(2,FILE ='juDFT_times',STATUS="replace")
ENDIF
!Stop globaltimer if still running
IF (globaltimer%starttime>-1) THEN
globaltimer%time=cputime()-globaltimer%starttime
globaltimer%starttime=-1
ENDIF
write(fn,"('Total execution time: ',i0,'sec')") int(globaltimer%time)
CALL priv_writetimes_longest(globaltimer,fid=fn)
WRITE(fn,"('Total execution time: ',i0,'sec, minimal timing printed:',i0,'sec')") &
int(globaltimer%time),int(min_time*globaltimer%time)
IF (.NOT.ASSOCIATED(globaltimer)) RETURN !write nothing if no timing recorded
l_out=.FALSE.
IF (PRESENT(stdout)) l_out=stdout
IF (l_out) THEN
fn=6
ELSE
IF (irank>0) RETURN
fn=2
OPEN(2,FILE ='juDFT_times',STATUS="replace")
ENDIF
!Stop globaltimer if still running
IF (globaltimer%starttime>-1) THEN
globaltimer%time=cputime()-globaltimer%starttime
globaltimer%starttime=-1
ENDIF
WRITE(fn,"('Total execution time: ',i0,'sec')") INT(globaltimer%time)
CALL priv_writetimes_longest(globaltimer,fid=fn)
WRITE(fn,"('Total execution time: ',i0,'sec, minimal timing printed:',i0,'sec')") &
INT(globaltimer%time),INT(min_time*globaltimer%time)
#ifdef CPP_MPI
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,isize,err)
WRITE(fn,*) "Program used ",isize," PE"
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,isize,err)
WRITE(fn,*) "Program used ",isize," PE"
#endif
CALL priv_writetimes(globaltimer,1,fn)
CALL priv_writetimes(globaltimer,1,fn)
WRITE(fn,*)
WRITE(fn,*) "-------------------------------------------------"
WRITE(fn,*)
WRITE(fn,*) "Total timings:"
min_time=0.0
CALL priv_writetimes(globaltimer,1,fn)
flush(fn)
IF (.NOT.l_out) CLOSE(2)
WRITE(fn,*)
WRITE(fn,*) "-------------------------------------------------"
WRITE(fn,*)
WRITE(fn,*) "Total timings:"
min_time=0.0
CALL priv_writetimes(globaltimer,1,fn)
FLUSH(fn)
IF (.NOT.l_out) CLOSE(2)
END SUBROUTINE writetimes
END SUBROUTINE writetimes
! writes all times to out.xml file
SUBROUTINE writeTimesXML()
! writes all times to out.xml file
SUBROUTINE writeTimesXML()