Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
fleur
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
51
Issues
51
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
fleur
fleur
Commits
7f919dd2
Commit
7f919dd2
authored
Jul 12, 2016
by
Daniel Wortmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated timing routines
parent
57254036
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
469 additions
and
479 deletions
+469
-479
io/w_inpXML.f90
io/w_inpXML.f90
+1
-1
juDFT/CMakeLists.txt
juDFT/CMakeLists.txt
+1
-0
juDFT/init.F90
juDFT/init.F90
+2
-21
juDFT/juDFT.F90
juDFT/juDFT.F90
+1
-0
juDFT/time.F90
juDFT/time.F90
+464
-457
No files found.
io/w_inpXML.f90
View file @
7f919dd2
...
...
@@ -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
...
...
juDFT/CMakeLists.txt
View file @
7f919dd2
...
...
@@ -16,4 +16,5 @@ juDFT/init.F90
juDFT/juDFT.F90
juDFT/stop.F90
juDFT/time.F90
juDFT/args.F90
)
juDFT/init.F90
View file @
7f919dd2
...
...
@@ -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
...
...
juDFT/juDFT.F90
View file @
7f919dd2
...
...
@@ -8,5 +8,6 @@
USE
m_juDFT_stop
USE
m_juDFT_time
USE
m_juDFT_init
USE
m_judft_args
END
MODULE
m_juDFT
juDFT/time.F90
View file @
7f919dd2
...
...
@@ -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
,
" at:"
,
cputime
()
#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