65 integer,
parameter :: max_lines = 20
66 character(len=256),
dimension(max_lines),
public :: message
67 character(len=68),
parameter,
public :: hyphens = &
68 '--------------------------------------------------------------------'
69 character(len=69),
parameter,
public :: shyphens =
'*'//hyphens
71 character(len=512),
private :: msg
73 character(len=64),
private :: oct_status =
'undefined'
75 type(sihash_t),
private :: namespace_unit
76 type(sphash_t),
private :: namespace_mpi_grp
77 character(len=256),
private :: msg_dir =
'exec'
109 integer :: experimentals
110 integer :: current_line
124 character(len=*),
intent(in),
optional :: output_dir
126 logical :: trap_signals
128 if (
present(output_dir))
then
129 msg_dir = trim(output_dir)
183 if (experimentals > 0 .or. warnings > 0)
then
189 if (warnings > 0)
then
192 if (warnings > 1)
then
200 if (experimentals > 0)
then
204 if (experimentals > 1)
then
211 call messages_write(
' Since you used one or more experimental features, results are likely')
213 call messages_write(
' wrong and should not be considered as valid scientific data. Check')
216 call messages_write(
' https://www.octopus-code.org/documentation/main/variables/execution/debug/experimentalfeatures')
219 call messages_write(
' or contact the octopus developers for details.')
224 open(unit =
iunit_out, file = trim(msg_dir) //
'/messages', action =
'write')
225 write(
iunit_out,
'(a, i9)')
"warnings = ", warnings
226 write(
iunit_out,
'(a, i9)')
"experimental = ", experimentals
231 call it%start(namespace_unit)
232 do while(it%has_next())
234 if (iu /= stderr .and. iu /= stdout)
call io_close(iu)
244 type(
namespace_t),
optional,
intent(in) :: namespace
248 if (
present(namespace))
then
250 if (namespace%get()==
"")
then
255 iunit =
sihash_lookup( namespace_unit, namespace%get(), found)
257 if (.not. found)
then
259 iunit =
io_open(
"log", namespace=namespace, action=
"write")
272 type(
mpi_grp_t),
target,
intent(in) :: mpigrp
275 assert(namespace_mpi_grp%is_associated())
282 type(
namespace_t),
optional,
intent(in) :: namespace
285 class(*),
pointer :: value
288 if (
present(namespace))
then
290 assert(namespace_mpi_grp%is_associated())
292 value =>
sphash_lookup(namespace_mpi_grp, trim(namespace%get()), found)
303 write(message(1),*)
"Cannot get mpi_grp for namespace ",namespace%get()
314 integer,
optional,
intent(in) :: no_lines
315 logical,
optional,
intent(in) :: only_root_writes
316 type(
namespace_t),
optional,
intent(in) :: namespace
319 integer :: ii, no_lines_
320 logical :: only_root_writes_, should_write
321 integer,
allocatable :: recv_buf(:)
322 type(mpi_request),
allocatable :: recv_req(:)
324 integer,
parameter :: fatal_tag = 32767
326 type(mpi_request) :: send_req
329 no_lines_ = current_line
330 if (
present(no_lines)) no_lines_ = no_lines
334 if (
present(only_root_writes))
then
335 should_write = msg_mpi_grp%is_root() .or. (.not. only_root_writes)
336 only_root_writes_ = only_root_writes
339 only_root_writes_ = .false.
348 if (.not. only_root_writes_)
then
349 if (msg_mpi_grp%is_root())
then
355 call mpi_recv_init(recv_buf(ii), 1, mpi_integer, ii, fatal_tag, msg_mpi_grp%comm, recv_req(ii))
364 call mpi_send_init(1, 1, mpi_integer, 0, fatal_tag, msg_mpi_grp%comm, send_req)
369 call mpi_test(send_req, received, mpi_status_ignore)
371 should_write = .false.
385 write(msg,
'(a)')
'*** Fatal Error (description follows)'
388 if (
present(namespace))
then
389 if (len_trim(namespace%get()) > 0)
then
390 write(msg,
'(3a)')
'* In namespace ', trim(namespace%get()),
':'
396 if (.not. only_root_writes_ .or. .not. msg_mpi_grp%is_root())
then
398 write(msg,
'(a,i4)')
"* From node = ", msg_mpi_grp%rank
404 write(msg,
'(a,1x,a)')
'*', trim(message(ii))
411 if (
debug%trace)
then
414 write(msg,
'(a)')
'* Stack: '
417 write(msg,
'(a,a)')
' > ', trim(
sub_stack(ii))
423 if (should_write)
then
436 integer,
optional,
intent(in) :: no_lines
437 logical,
optional,
intent(in) :: all_nodes
438 type(
namespace_t),
optional,
intent(in) :: namespace
440 integer :: il, no_lines_
441 integer :: iunit_namespace
442 logical :: have_to_write, all_nodes_
445 no_lines_ = current_line
446 if (
present(no_lines)) no_lines_ = no_lines
448 warnings = warnings + 1
453 have_to_write = msg_mpi_grp%is_root()
456 if (
present(all_nodes))
then
457 have_to_write = have_to_write .or. all_nodes
458 all_nodes_ = all_nodes
461 if (have_to_write)
then
464 if (iunit_namespace /= stdout)
then
467 write(msg,
'(a)')
'** Warning:'
469 if (iunit_namespace /= stdout)
then
473 if (
present(namespace))
then
474 if (len_trim(namespace%get()) > 0)
then
475 write(msg,
'(3a)')
'** In namespace ', trim(namespace%get()),
':'
482 write(msg ,
'(a,i4)')
'** From node = ',
mpi_world%rank
484 if (iunit_namespace /= stdout)
then
491 write(msg ,
'(a,3x,a)')
'**', trim(message(il))
493 if (iunit_namespace /= stdout)
then
498 if (iunit_namespace /= stdout)
then
503 if (iunit_namespace /= stdout)
then
504 flush(iunit_namespace)
514 subroutine messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
515 integer,
optional,
intent(in) :: no_lines
516 integer,
optional,
intent(in) :: iunit
517 logical,
optional,
intent(in) :: debug_only
518 logical,
optional,
intent(in) :: stress
519 logical,
optional,
intent(in) :: all_nodes
520 type(
namespace_t),
optional,
intent(in) :: namespace
522 integer :: il, no_lines_
526 assert(.not. (
present(iunit) .and.
present(namespace)))
528 if (
present(iunit))
then
535 if (.not. msg_mpi_grp%is_root() .and. .not.
optional_default(all_nodes, .false.))
then
540 no_lines_ = current_line
541 if (
present(no_lines)) no_lines_ = no_lines
543 if (
present(stress))
then
549 write(msg,
'(a)') trim(message(il))
553 if (
present(stress))
then
566 character(len=*),
intent(in) :: status
572 call loct_rm(trim(msg_dir) //
'/oct-status-running')
573 call loct_rm(trim(msg_dir) //
'/oct-status-finished')
574 call loct_rm(trim(msg_dir) //
'/oct-status-aborted')
575 if (oct_status /=
'walltimer-aborted')
then
576 call loct_rm(trim(msg_dir) //
'/oct-status-walltimer-aborted')
582 open(unit=
iunit_err, file=trim(msg_dir) //
'/oct-status-'//trim(status), &
583 action=
'write', status=
'unknown')
590 integer(int64),
intent(in) :: size
591 character(len=*),
intent(in) :: file
592 integer,
intent(in) :: line
594 write(message(1),
'(a,i18,3a,i5)')
"Failed to allocate ",
size,
" words in file '", trim(file),
"' line ", line
601 integer(int64),
intent(in) :: size
602 character(len=*),
intent(in) :: file
603 integer,
intent(in) :: line
605 write(message(1),
'(a,i18,3a,i5)')
"Failed to deallocate array of ",
size,
" words in file '", trim(file),
"' line ", line
613 character(len=*),
intent(in) :: var
614 character(len=*),
optional,
intent(in) :: details
615 integer,
optional,
intent(in) :: row
616 integer,
optional,
intent(in) :: column
618 character(len=10) :: row_str, column_str
620 call messages_write(
'Input error in the input variable '// trim(var))
622 if (
present(row))
then
626 write(row_str,
'(I10)') row + 1
628 if (
present(column))
then
629 write(column_str,
'(I10)') column + 1
633 if (
present(details))
then
642 call messages_write(
'You can get the documentation of the variable with the command:', new_line = .
true.)
650 character(len=*),
intent(in) :: var
651 integer,
intent(in) :: val
652 integer,
optional,
intent(in) :: iunit
653 type(
namespace_t),
optional,
intent(in) :: namespace
655 character(len=10) :: intstring
657 assert(.not. (
present(iunit) .and.
present(namespace)))
659 write(intstring,
'(i10)') val
660 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(intstring))//
']'
667 character(len=*),
intent(in) :: var
668 character(len=*),
intent(in) :: val
669 integer,
optional,
intent(in) :: iunit
670 type(
namespace_t),
optional,
intent(in) :: namespace
672 assert(.not. (
present(iunit) .and.
present(namespace)))
674 message(1) =
'Input: ['//trim(var)//
' = '//trim(val)//
']'
681 character(len=*),
intent(in) :: var
682 real(real64),
intent(in) :: val
683 type(
unit_t),
optional,
intent(in) :: unit
684 integer,
optional,
intent(in) :: iunit
685 type(
namespace_t),
optional,
intent(in) :: namespace
687 character(len=11) :: floatstring
689 assert(.not. (
present(iunit) .and.
present(namespace)))
691 if (.not.
present(unit))
then
692 write(floatstring,
'(g11.4)') val
693 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(floatstring))//
']'
696 message(1) =
'Input: ['//trim(var)//
' = '//trim(adjustl(floatstring))//
' '//trim(
units_abbrev(unit))//
']'
704 character(len=*),
intent(in) :: var
705 logical,
intent(in) :: val
706 integer,
optional,
intent(in) :: iunit
707 type(
namespace_t),
optional,
intent(in) :: namespace
709 character(len=3) :: lstring
711 assert(.not. (
present(iunit) .and.
present(namespace)))
718 message(1) =
'Input: ['//trim(var)//
' = '//trim(lstring)//
']'
725 character(len=*),
intent(in) :: var
726 real(real64),
intent(in) :: val(:)
727 type(
unit_t),
optional,
intent(in) :: unit
728 integer,
optional,
intent(in) :: iunit
729 type(
namespace_t),
optional,
intent(in) :: namespace
732 character(len=11) :: floatstring
734 assert(.not. (
present(iunit) .and.
present(namespace)))
738 write(floatstring,
'(g11.4)') val(ii)
743 if (
present(unit))
then
754 character(len=*),
intent(in) :: var
755 integer,
optional,
intent(in) :: iunit
756 type(
namespace_t),
optional,
intent(in) :: namespace
761 assert(.not. (
present(iunit) .and.
present(namespace)))
765 if (.not. mpi_grp%is_root())
return
767 if (
present(iunit))
then
778 character(len=*),
intent(in) :: var
779 integer(int64),
intent(in) :: option
780 character(len=*),
optional,
intent(in) :: pre
781 integer,
optional,
intent(in) :: iunit
782 type(
namespace_t),
optional,
intent(in) :: namespace
784 integer :: option4, iunit_
787 assert(.not. (
present(iunit) .and.
present(namespace)))
790 if (.not. mpi_grp%is_root())
return
792 option4 = int(option, int32)
794 if (
present(iunit))
then
805 character(len=*),
intent(in) :: var
806 integer(int32),
intent(in) :: option
807 character(len=*),
optional,
intent(in) :: pre
808 integer,
optional,
intent(in) :: iunit
809 type(
namespace_t),
optional,
intent(in) :: namespace
811 assert(.not. (
present(iunit) .and.
present(namespace)))
819 character(len=*),
optional,
intent(in) :: msg
820 integer,
optional,
intent(in) :: iunit
821 type(
namespace_t),
optional,
intent(in) :: namespace
823 integer,
parameter :: max_len = 70
825 integer :: ii, jj, length
827 character(len=70) :: str
828 character(len=max_len) :: msg_combined
831 if (
present(iunit))
then
838 if (.not. msg_mpi_grp%is_root())
return
840 if (
present(msg))
then
842 if (len_trim(msg) > max_len)
then
843 msg_combined = trim(msg(1:max_len))
845 msg_combined = trim(msg)
847 length = len_trim(msg_combined)
852 do ii = 1, (max_len - (length + 2))/2
861 str(jj:jj) = msg_combined(ii:ii)
889 character(len = *),
intent(in) :: str
890 integer,
intent(in) :: iunit
891 character(len = *),
optional,
intent(in) :: adv
893 character(len = 20) :: adv_
896 if (
present(adv)) adv_ = trim(adv)
898 write(iunit,
'(a)', advance=adv_) trim(str)
904 character(len = *),
intent(in) :: str
908 call date_and_time(
values=val)
910 write(message(3),
'(a,i4,a1,i2.2,a1,i2.2,a,i2.2,a1,i2.2,a1,i2.2)') &
911 str , val(1),
"/", val(2),
"/", val(3), &
912 " at ", val(5),
":", val(6),
":", val(7)
922 character(len=*),
intent(in) :: name
923 character(len=*),
optional,
intent(in) :: rep
927 write(message(1),
'(a)')
'Input variable '//trim(name)//
' is obsolete.'
929 if (
present(rep))
then
930 write(message(2),
'(a)')
' '
931 write(message(3),
'(a)')
'Equivalent functionality can be obtained with the '//trim(rep)
932 write(message(4),
'(a)')
'variable. Check the documentation for details.'
933 write(message(5),
'(a)')
'(You can use the `oct-help -p '//trim(rep)//
'` command).'
946 character(len=*),
intent(in) :: name
950 write(message(1),
'(a)')
'Input variable `'//trim(name)//
'` must be defined as a block.'
951 write(message(2),
'(a)')
'Please check the documentation for details.'
952 write(message(3),
'(a)')
'(You can use the `oct-help -p '//trim(name)//
'` command).'
961 character(len=*),
intent(in) :: name
962 type(
namespace_t),
optional,
intent(in) :: namespace
964 experimentals = experimentals + 1
966 if (.not.
conf%devel_version)
then
970 call messages_write(
'If you still want to use this feature (at your own risk), check:')
973 call messages_write(
'https://www.octopus-code.org/documentation/main/variables/execution/debug/experimentalfeatures')
977 write(message(1),
'(a)') trim(name)//
' is under development.'
978 write(message(2),
'(a)')
'It might not work or produce wrong results.'
982 warnings = warnings - 1
989 character(len=*),
intent(in) :: feature
990 type(
namespace_t),
optional,
intent(in) :: namespace
994 message(1) = trim(feature)//
" not implemented."
1011 current_line = current_line + 1
1012 message(current_line) =
''
1014 if (current_line > max_lines) stop
'Too many message lines.'
1020 real(real64),
intent(in) :: val
1021 character(len=*),
optional,
intent(in) :: fmt
1022 logical,
optional,
intent(in) :: new_line
1023 type(
unit_t),
optional,
intent(in) :: units
1024 logical,
optional,
intent(in) :: align_left
1025 logical,
optional,
intent(in) :: print_units
1027 character(len=30) :: number
1028 real(real64) :: tval
1033 if (
present(fmt))
then
1034 write(number,
'('//trim(fmt)//
')') tval
1036 write(number,
'(f12.6)') tval
1040 number = adjustl(number)
1041 number(1:len(number)) =
' '//number(1:len(number)-1)
1044 write(message(current_line),
'(a, a)') trim(message(current_line)), trim(number)
1047 write(message(current_line),
'(a, a, a)') trim(message(current_line)),
' ', trim(
units_abbrev(units))
1056 integer(int64),
intent(in) :: val
1057 character(len=*),
optional,
intent(in) :: fmt
1058 logical,
optional,
intent(in) :: new_line
1059 type(
unit_t),
optional,
intent(in) :: units
1060 logical,
optional,
intent(in) :: print_units
1062 character(len=20) :: number
1063 real(real64) :: val_conv_float
1065 if (
present(units))
then
1068 if (
present(fmt))
then
1069 write(message(current_line),
'(a, '//trim(fmt)//
')') trim(message(current_line)), val_conv_float
1071 write(number,
'(f15.3)') val_conv_float
1072 write(message(current_line),
'(3a)') trim(message(current_line)),
' ', trim(adjustl(number))
1077 if (
present(fmt))
then
1078 write(message(current_line),
'(a, '//trim(fmt)//
')') trim(message(current_line)), val
1080 write(number,
'(i12)') val
1081 write(message(current_line),
'(3a)') trim(message(current_line)),
' ', trim(adjustl(number))
1088 write(message(current_line),
'(a, a, a)') trim(message(current_line)),
' ', trim(adjustl(
units_abbrev(units)))
1091 if (
present(new_line))
then
1099 integer(int32),
intent(in) :: val
1100 character(len=*),
optional,
intent(in) :: fmt
1101 logical,
optional,
intent(in) :: new_line
1102 type(
unit_t),
optional,
intent(in) :: units
1103 logical,
optional,
intent(in) :: print_units
1111 character(len=*),
intent(in) :: val
1112 character(len=*),
optional,
intent(in) :: fmt
1113 logical,
optional,
intent(in) :: new_line
1115 character(len=100) :: fmt_
1117 if (len(trim(message(current_line))) + len(trim(val)) > len(message(current_line)))
then
1120 write(0, *)
"Exceeded message line length limit, to write string:", trim(val)
1123 write(message(current_line),
'(a, '//trim(fmt_)//
')') trim(message(current_line)), trim(val)
1126 if (
present(new_line))
then
1134 logical,
intent(in) :: val
1135 logical,
optional,
intent(in) :: new_line
1137 character(len=3) :: text
1145 if (len(trim(message(current_line))) + len(trim(text)) > len(message(current_line)))
then
1146 write(message(current_line + 1),
'(3a)')
"Exceeded message line length limit, to write logical value '", trim(text),
"'"
1150 write(message(current_line),
'(a,1x,a)') trim(message(current_line)), trim(text)
1152 if (
present(new_line))
then
1160 integer,
intent(in) :: isignal
1163 character(len=300) :: description
1164 character(kind=c_char) :: cstr(301)
1170 integer,
intent(in) :: signum
1171 character(kind=c_char),
intent(out) :: signame(*)
1179 write(msg,
'(a,i2)')
''
1181 write(msg,
'(a,i2)')
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1183 write(msg,
'(a,i2)')
''
1185 write(msg,
'(a,i2,2a)')
' Octopus was killed by signal ', isignal,
': ', trim(description)
1187 write(msg,
'(a,i2)')
''
1189 write(msg,
'(a)')
' Note: Octopus is currently trapping signals. This might prevent the'
1191 write(msg,
'(a)')
' use of debuggers or the generation of core dumps. To change this'
1193 write(msg,
'(a)')
' behavior, use the DebugTrapSignals input option.'
1195 write(msg,
'(a,i2)')
''
1197 write(msg,
'(a,i2)')
'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1200 if (
debug%trace)
then
1203 write(msg,
'(a)')
'Octopus debug trace: '
1206 write(msg,
'(a,a)')
' > ', trim(
sub_stack(ii))
1211 write(msg,
'(a)')
" Octopus debug trace not available. You can enable it with 'Debug = trace'."
1230 character(len=*),
intent(in) :: s, f
1231 integer,
intent(in) :: l
1246 call messages_write(
'This should not happen and is likely a bug in the code.')
1248 call messages_write(
'Please contact the developers and report how this occurred.')
1250 call messages_write(
'You can open an issue on gitlab as described in Contributing.md.')
1264 integer(c_int),
intent(in) :: isignal
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
subroutine handle_segv(isignal)
subroutine assert_die(s, f, l)
This subroutine is called by the assert macro, it is not in a module so it can be called from any fil...
character(len=max_path_len) function, public debug_clean_path(filename)
Prune a filename path to only include subdirectories of the "src" directory.
type(debug_t), save, public debug
subroutine, public debug_init(this, namespace)
integer, public no_sub_stack
character(len=80), dimension(50), public sub_stack
The stack.
type(conf_t), public conf
Global instance of Octopus configuration.
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer, parameter, public iunit_out
integer, parameter, public iunit_err
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
System information (time, memory, sysname)
subroutine, public loct_rm(name)
subroutine string_c_to_f(c_string, f_string)
convert a C string to a Fortran string
subroutine, public alloc_error(size, file, line)
subroutine, public messages_end()
subroutine messages_write_integer8(val, fmt, new_line, units, print_units)
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
subroutine, public messages_init(output_dir)
subroutine messages_print_var_option_8(var, option, pre, iunit, namespace)
subroutine messages_print_var_valuear(var, val, unit, iunit, namespace)
subroutine, public messages_variable_is_block(namespace, name)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine messages_write_integer(val, fmt, new_line, units, print_units)
subroutine messages_print_var_option_4(var, option, pre, iunit, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
subroutine, public messages_switch_status(status)
create status file for asynchronous communication
subroutine, public print_date(str)
subroutine flush_msg(str, iunit, adv)
subroutine, public messages_print_var_info(var, iunit, namespace)
subroutine, public messages_update_mpi_grp(namespace, mpigrp)
subroutine, public messages_new_line()
subroutine, public dealloc_error(size, file, line)
subroutine messages_print_var_values(var, val, iunit, namespace)
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine messages_print_var_valuei(var, val, iunit, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine messages_print_var_valuer(var, val, unit, iunit, namespace)
integer, parameter, private sleepytime_nonwriters
seconds
subroutine, public messages_experimental(name, namespace)
subroutine messages_print_var_valuel(var, val, iunit, namespace)
subroutine messages_write_logical(val, new_line)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine messages_write_str(val, fmt, new_line)
type(mpi_grp_t) function messages_get_mpi_grp(namespace)
subroutine, public messages_dump_stack(isignal)
integer function messages_get_unit(namespace)
subroutine messages_write_float(val, fmt, new_line, units, align_left, print_units)
subroutine messages_reset_lines()
type(mpi_grp_t), public mpi_world
type(namespace_t), public global_namespace
logical function, public parse_is_defined(namespace, name)
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
subroutine, public sihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
subroutine, public sihash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
integer function, public sihash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
subroutine, public sihash_end(h)
Free a hash table.
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
subroutine, public sphash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
subroutine, public sphash_insert(h, key, val, clone)
Insert a (key, val) pair into the hash table h. If clone=.true., the object will be copied.
subroutine, public sphash_end(h)
Free a hash table.
class(*) function, pointer, public sphash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
character(len=80) function, public str_center(s_in, l_in)
puts space around string, so that it is centered
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
subroutine, public varinfo_print_option(iunit, var, option, pre)
subroutine, public varinfo_print(iunit, var, ierr)
void get_signal_description(fint *signum, char *signame)
This is defined even when running serial.
real(real64) function values(xx)