47 logical,
public :: info
48 logical,
public :: trace
49 logical,
public :: trace_term
50 logical,
public :: trace_file
51 logical :: extra_checks
52 logical,
public :: interaction_graph
53 logical,
public :: interaction_graph_full
54 logical,
public :: propagation_graph
55 logical,
public :: instrument
57 character(len=MAX_PATH_LEN),
public :: instr_sub_name
58 integer,
public :: instr_tool
61 type(debug_t),
save :: debug
64 integer,
parameter :: unit_offset = 1000
83 type(debug_t),
intent(out) :: this
84 type(namespace_t),
intent(in) :: namespace
86 character(len=256) :: node_hook
87 logical :: file_exists, mpi_debug_hook
127 call parse_variable(namespace,
'Debug', option__debug__no, this%bits)
132 this%instr_sub_name =
''
160 if (
parse_block(namespace,
"InstrumentFunctions", blk) == 0)
then
163 write(stderr,
'(a)')
"Only single function can be instrumented!"
170 select case (this%instr_tool)
171 case (option__instrumentfunctions__verrou)
172 write(stderr,
'(a)')
"Instrumenting " // trim(this%instr_sub_name) //
" for Verrou"
173#if !defined(HAVE_VERROU)
174 write(stderr,
'(a)')
"requires VERROU but that library was not linked."
177 case (option__instrumentfunctions__fenv)
178 write(stderr,
'(a)')
"Instrumenting " // trim(this%instr_sub_name) //
" with floating-point exceptions"
184 else if (this%instrument)
then
185 write(stderr,
'(a)')
"Debug=instrument requires InstrumentFunctions block."
209 if (mpi_debug_hook)
then
212 write(stdout,
'(a,i6,a,i6.6,20x,a)')
'* I ',sec,
'.',usec,
' | MPI debug hook'
214 write(stdout,
'(a,i3,a)')
'node:',
mpi_world%rank,
' In debug hook'
216 file_exists = .false.
218 do while (.not. file_exists)
219 inquire(file=
'node_hook.'//node_hook, exist=file_exists)
221 write(stdout,
'(a,i3,a)')
'node:',
mpi_world%rank, &
222 ' - still sleeping. To release me touch: node_hook.'//trim(node_hook)
225 write(stdout,
'(a,i3,a)')
'node:',
mpi_world%rank,
' Leaving debug hook'
227 call loct_rm(
'node_hook.'//trim(node_hook))
231 write(stdout,
'(a,i6,a,i6.6,20x,a)')
'* O ', sec,
'.', usec,
' | MPI debug hook'
240 type(
debug_t),
intent(inout) :: this
244 this%trace_term = .
true.
245 this%trace_file = .
true.
246 this%interaction_graph = .
true.
247 this%interaction_graph_full = .
true.
248 this%propagation_graph = .
true.
255 type(
debug_t),
intent(inout) :: this
266 character(len=6) :: filenum
269 write(filenum,
'(i6.6)') iunit - unit_offset
271 call loct_rm(
'debug/debug_trace.node.'//filenum)
278 integer,
intent(out) :: iunit
280 character(len=6) :: filenum
283 write(filenum,
'(i6.6)') iunit - unit_offset
285 open(iunit, file =
'debug/debug_trace.node.'//filenum, &
286 action=
'write', status=
'unknown', position=
'append')
293 type(
debug_t),
intent(inout) :: this
295 this%info = (
bitand(this%bits, option__debug__info) /= 0)
296 this%trace_term = (
bitand(this%bits, option__debug__trace_term) /= 0)
297 this%trace_file = (
bitand(this%bits, option__debug__trace_file) /= 0)
298 this%trace = (
bitand(this%bits, option__debug__trace) /= 0) .or. this%trace_term .or. this%trace_file
299 this%extra_checks = (
bitand(this%bits, option__debug__extra_checks) /= 0) .or. this%trace_term .or. this%trace_file
300 this%interaction_graph = (
bitand(this%bits, option__debug__interaction_graph) /= 0)
301 this%interaction_graph_full = (
bitand(this%bits, option__debug__interaction_graph_full) /= 0)
302 this%propagation_graph = (
bitand(this%bits, option__debug__propagation_graph) /= 0)
303 this%instrument = (
bitand(this%bits, option__debug__instrument) /= 0)
310 integer,
intent(inout) :: sec
311 integer,
intent(inout) :: usec
320 subroutine time_diff(sec1, usec1, sec2, usec2)
321 integer,
intent(in) :: sec1
322 integer,
intent(in) :: usec1
323 integer,
intent(inout) :: sec2
324 integer,
intent(inout) :: usec2
329 if (usec2 - usec1 < 0)
then
330 usec2 = 1000000 + usec2
331 if (sec2 >= sec1)
then
337 if (sec2 >= sec1)
then
340 usec2 = usec2 - usec1
347 character(len=*),
intent(in) :: sub_name
349 integer,
parameter :: max_recursion_level = 50
350 integer iunit, sec, usec
352 if (debug%instrument)
then
354 select case (debug%instr_tool)
355 case (option__instrumentfunctions__verrou)
357 case (option__instrumentfunctions__fenv)
365 if (.not. debug%trace)
return
367 if (debug%trace_file .or. debug%trace_term)
then
374 sub_stack(max_recursion_level) =
'debug_push_sub'
375 write(stderr,
'(a,i3,a)')
'Too many recursion levels in debug trace (max=', max_recursion_level,
')'
376 write(stderr,
'(a,a)')
'Last sub name is ', trim(
debug_clean_path(sub_name))
383 if (debug%trace_file)
then
390 if (debug%trace_term .and.
mpi_world%is_root())
then
398 integer,
intent(in) :: iunit_out
401 character(len=1000) :: tmpstr
403 write(tmpstr,
'(a,i6,a,i6.6,f20.6,i8,a)')
"* I ", &
408 write(tmpstr,
'(2a)') trim(tmpstr),
"..|"
411 write(iunit_out,
'(a)') trim(tmpstr)
420 character(len=*),
intent(in) :: sub_name
422 character(len=80) :: sub_name_short
423 integer iunit, sec, usec
425 if (debug%instrument)
then
427 select case (debug%instr_tool)
428 case (option__instrumentfunctions__verrou)
430 case (option__instrumentfunctions__fenv)
438 if (.not. debug%trace)
return
446 write(stderr,
'(a)')
'Too few recursion levels in debug trace'
455 write(stderr,
'(a)')
'Wrong sub name on pop_sub :'
456 write(stderr,
'(2a)')
' got : ', sub_name_short
461 if (debug%trace_file)
then
468 if (debug%trace_term .and.
mpi_world%is_root())
then
478 integer,
intent(in) :: iunit_out
481 character(len=1000) :: tmpstr
483 write(tmpstr,
'(a,i6,a,i6.6,f20.6,i8, a)')
"* O ", &
488 write(tmpstr,
'(2a)') trim(tmpstr),
"..|"
492 write(iunit_out,
'(a)') trim(tmpstr)
499 character(len=MAX_PATH_LEN) function debug_clean_path(filename)
result(clean_path)
500 character(len=*),
intent(in) :: filename
504 pos = index(filename,
'src/', back = .
true.)
507 clean_path = filename
510 clean_path = filename(pos+4:)
subroutine pop_sub_write(iunit_out)
subroutine push_sub_write(iunit_out)
character(len=max_path_len) function, public debug_clean_path(filename)
Prune a filename path to only include subdirectories of the "src" directory.
subroutine, public debug_enable(this)
type(debug_t), save, public debug
subroutine, public debug_pop_sub(sub_name)
Pop a routine from the debug trace.
subroutine, public debug_open_trace(iunit)
subroutine, public epoch_time_diff(sec, usec)
subroutine from_bits(this)
subroutine, public debug_init(this, namespace)
subroutine, public debug_disable(this)
subroutine time_diff(sec1, usec1, sec2, usec2)
Computes t2 <- t2-t1.
subroutine, public debug_push_sub(sub_name)
Push a routine to the debug trace.
subroutine, public debug_delete_trace()
integer, public s_epoch_sec
global epoch time (time at startup)
integer, public no_sub_stack
real(real64), dimension(50), public time_stack
character(len=80), dimension(50), public sub_stack
The stack.
integer, public s_epoch_usec
System information (time, memory, sysname)
subroutine, public loct_rm(name)
subroutine, public loct_mkdir(name)
subroutine, public mpi_debug_init(rank, info)
type(mpi_grp_t), public mpi_world
type(namespace_t), public global_namespace
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
integer function, public parse_block(namespace, name, blk, check_varinfo_)