15 character(len=LEN_SECTION_TITLE) :: title
18 integer(I4B) :: status
19 integer(I4B) :: parent_id
29 integer(I4B) :: tmr_run
30 integer(I4B) :: tmr_init
31 integer(I4B) :: tmr_update
32 integer(I4B) :: tmr_finalize
33 integer(I4B) :: tmr_prep_tstp
34 integer(I4B) :: tmr_do_tstp
35 integer(I4B) :: tmr_final_tstp
36 integer(I4B) :: tmr_output
37 integer(I4B) :: tmr_nc_export
39 integer(I4B),
private :: iout
40 integer(I4B),
private :: pr_option
41 integer(I4B),
private :: nr_sections
42 integer(I4B),
private,
dimension(3) :: top_three
43 integer(I4B),
private :: max_title_len
44 integer(I4B),
private :: root_id
79 this%tmr_finalize = -1
80 this%tmr_prep_tstp = -1
82 this%tmr_final_tstp = -1
84 this%tmr_nc_export = -1
86 call this%callstack%init()
90 this%all_sections(i)%title =
"undefined"
91 this%all_sections(i)%status = 0
92 this%all_sections(i)%walltime =
dzero
93 this%all_sections(i)%count = 0
94 this%all_sections(i)%parent_id = 0
95 call this%all_sections(i)%children%init()
100 this%top_three = [0, 0, 0]
110 character(len=*) :: title
111 integer(I4B) :: parent_id
112 integer(I4B) :: section_id
115 this%nr_sections = this%nr_sections + 1
116 section_id = this%nr_sections
117 if (section_id >
size(this%all_sections))
then
118 write (*, *)
"Internal error: Too many profiled sections, "&
119 &
"increase MAX_NR_TIMED_SECTIONS"
124 this%all_sections(section_id)%title = title
125 this%all_sections(section_id)%walltime =
dzero
126 this%all_sections(section_id)%status = 0
129 if (parent_id > 0)
then
131 this%all_sections(section_id)%parent_id = parent_id
132 call this%all_sections(parent_id)%children%push_back(section_id)
135 this%all_sections(section_id)%parent_id = 0
136 this%root_id = section_id
143 subroutine start(this, title, section_id)
145 character(len=*) :: title
146 integer(I4B) :: section_id
148 integer(I4B) :: parent_id
149 real(DP) :: start_time
152 call cpu_time(start_time)
154 if (section_id == -1)
then
157 if (this%callstack%size() > 0)
then
158 parent_id = this%callstack%top()
160 section_id = this%add_section(title, parent_id)
162 call this%callstack%push(section_id)
164 section => this%all_sections(section_id)
165 section%count = section%count + 1
167 section%walltime = section%walltime - start_time
171 subroutine stop(this, section_id)
173 integer(I4B) :: section_id
178 call cpu_time(end_time)
181 section => this%all_sections(section_id)
183 section%walltime = section%walltime + end_time
186 call this%callstack%pop()
192 integer(I4B),
intent(in) :: output_unit
194 integer(I4B) :: level, i, top_idx
195 integer(I4B),
dimension(:),
allocatable :: sorted_idxs
197 this%iout = output_unit
198 if (this%pr_option == 0)
return
202 sorted_idxs = (/(i, i=1, this%nr_sections)/)
203 call this%sort_by_walltime(sorted_idxs)
204 do i = 1, this%nr_sections
205 if (this%all_sections(sorted_idxs(i))%children%size == 0)
then
206 if (top_idx > 3)
exit
207 this%top_three(top_idx) = sorted_idxs(i)
208 top_idx = top_idx + 1
212 this%max_title_len = this%largest_title_length()
214 if (this%pr_option > 1)
then
217 write (this%iout,
'(/1x,a/)') &
218 repeat(
'-', 18)//
" Profiler: Call Stack "//repeat(
'-', 18)
219 call this%print_section(this%root_id, level)
225 write (this%iout,
'(1x,a/)') &
226 repeat(
'-', 20)//
" Profiler: Totals "//repeat(
'-', 20)
227 call this%print_total(
"Formulate")
228 call this%print_total(
"Linear solve")
229 call this%print_total(
"Calculate flows")
230 call this%print_total(
"Calculate budgets")
231 call this%print_total(
"Write output")
232 call this%print_total(
"Parallel Solution")
233 call this%print_total(
"MPI_WaitAll")
234 write (this%iout,
'(/1x,a/)') &
235 repeat(
'-', 22)//
" End Profiler "//repeat(
'-', 22)
242 integer(I4B) :: section_id
243 integer(I4B) :: level
245 integer(I4B) :: i, new_level, nr_padding, idx_top
248 character(len=:),
allocatable :: title_padded
249 character(len=LINELENGTH) :: top_marker
251 section => this%all_sections(section_id)
255 if (section%parent_id /= 0)
then
256 percent = section%walltime / this%all_sections(this%root_id)%walltime
258 percent = percent * 100.0_dp
262 idx_top =
ifind(this%top_three, section_id)
263 if (idx_top > 0)
then
264 nr_padding = max(0, 32 - level * 4)
265 write (top_marker,
'(a,i0)') repeat(
" ", nr_padding)//
"<== #", idx_top
269 nr_padding = this%max_title_len - len_trim(section%title) + 2
270 title_padded = trim(section%title)//
":"//repeat(
' ', nr_padding)
271 write (this%iout,
'(3a,f6.2,2a,f14.6,2a,i0,a,a)')
" ", &
272 repeat(
'....', level),
"[", percent,
"%] ", title_padded, &
273 section%walltime,
"s",
" (", section%count,
"x)", trim(top_marker)
276 new_level = level + 1
277 do i = 1, section%children%size
278 call this%print_section(section%children%at(i), new_level)
281 if (level == 0)
write (this%iout, *)
287 character(len=*) :: subtitle
289 integer(I4B) :: count
290 real(DP) :: walltime, percent
291 integer(I4B) :: nr_padding
292 character(len=:),
allocatable :: title_padded
295 nr_padding = this%max_title_len - len_trim(subtitle)
296 title_padded = trim(subtitle)//repeat(
' ', nr_padding)
298 count = this%aggregate_counts(subtitle)
301 percent = (walltime / this%all_sections(this%root_id)%walltime) * 100.0_dp
302 write (this%iout,
'(2a,f6.2,3a,f14.6,2a,i0,a)')
" ",
"[", percent, &
303 "%] ", title_padded,
": ", walltime,
"s",
" (", count,
"x)"
312 character(len=*) :: title
318 do i = 1, this%nr_sections
319 if (index(this%all_sections(i)%title, trim(title)) > 0)
then
320 walltime = walltime + this%all_sections(i)%walltime
330 character(len=*) :: title
331 integer(I4B) :: counts
336 do i = 1, this%nr_sections
337 if (index(this%all_sections(i)%title, trim(title)) > 0)
then
338 counts = counts + this%all_sections(i)%count
348 character(len=*),
intent(in) :: profile_option
350 select case (trim(profile_option))
370 call this%callstack%destroy()
373 call this%all_sections(i)%children%destroy()
375 deallocate (this%all_sections)
376 nullify (this%all_sections)
382 logical(LGP) :: initialized
384 initialized =
associated(this%all_sections)
392 integer(I4B) :: max_length
396 do i = 1, this%nr_sections
397 max_length = max(max_length, len_trim(this%all_sections(i)%title))
406 integer(I4B),
dimension(:),
allocatable :: idxs
407 integer(I4B) :: i, j, temp
410 do i = 1,
size(idxs) - 1
411 do j = 1,
size(idxs) - i
412 if (this%all_sections(idxs(j))%walltime < &
413 this%all_sections(idxs(j + 1))%walltime)
then
415 idxs(j) = idxs(j + 1)
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dnodata
real no data constant
real(dp), parameter dzero
real constant zero
integer(i4b), parameter lenmempath
maximum length of the memory path
This module defines variable data types.
type(profilertype), public g_prof
the global timer object (to reduce trivial lines of code)
integer(i4b) function aggregate_counts(this, title)
Aggregate counts over sections with a certain title.
real(dp) function aggregate_walltime(this, title)
Aggregate walltime over sections with a certain title.
subroutine sort_by_walltime(this, idxs)
Sort section indexes based on walltime.
integer(i4b), parameter, public len_section_title
subroutine set_print_option(this, profile_option)
Set the profile option from the user input.
subroutine print(this, output_unit)
integer(i4b), parameter max_nr_timed_sections
logical(lgp) function is_initialized(this)
integer(i4b) function largest_title_length(this)
Calculate the largest title length.
subroutine destroy(this)
Clean up the CPU timer object.
subroutine initialize(this)
integer(i4b) function add_section(this, title, parent_id)
Add a new timed section to the tree, passing the parent id will add it as a child.
recursive subroutine print_section(this, section_id, level)
subroutine start(this, title, section_id)
Start section timing, add when not exist yet (i.e. when id < 1)
subroutine stop(this, section_id)
subroutine print_total(this, subtitle)
This module contains simulation methods.
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
A public type for profiling performance in the application. The ProfilerType is used to measure and r...
A derived type representing a stack of integers.