Octopus
messages.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2021 M. Marques, A. Castro, A. Rubio, G. Bertsch, X. Andrade,
2!! Copyright (C) 2021 M. Lueders
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module messages_oct_m
23 use debug_oct_m
24 use global_oct_m
25 use io_oct_m
26 use loct_oct_m
27 use mpi_oct_m
29 use parser_oct_m
30 use string_oct_m
31 use sihash_oct_m
32 use sphash_oct_m
33 use unit_oct_m
35
36 implicit none
37
38 private
39
40 public :: &
47 print_date, &
48 time_sum, &
52#ifndef NDEBUG
53 push_sub, &
54 pop_sub, &
55#endif
69
70
71 integer, parameter :: max_lines = 20
72 character(len=256), dimension(max_lines), public :: message
73 character(len=68), parameter, public :: hyphens = &
74 '--------------------------------------------------------------------'
75 character(len=69), parameter, public :: shyphens = '*'//hyphens
76
77 character(len=512), private :: msg
78 integer, parameter, private :: SLEEPYTIME_ALL = 1, sleepytime_nonwriters = 60
79 character(len=64), private :: oct_status = 'undefined'
80
81 type(sihash_t), private :: namespace_unit
82 type(sphash_t), private :: namespace_mpi_grp
83
84 ! ---------------------------------------------------------
90 ! ---------------------------------------------------------
92 module procedure messages_print_var_valuei
93 module procedure messages_print_var_values
94 module procedure messages_print_var_valuer
95 module procedure messages_print_var_valuel
96 module procedure messages_print_var_valuear
97 end interface messages_print_var_value
98
99 interface messages_write
100 module procedure messages_write_float
101 module procedure messages_write_integer
102 module procedure messages_write_integer8
103 module procedure messages_write_str
104 module procedure messages_write_logical
105 end interface messages_write
106
109 module procedure messages_print_var_option_4
110 module procedure messages_print_var_option_8
111 end interface messages_print_var_option
112
113 integer :: warnings
114 integer :: experimentals
115 integer :: current_line
116
118 interface
119 subroutine get_signal_description(signum, signame)
120 implicit none
121 integer, intent(in) :: signum
122 character(len=*), intent(out) :: signame
123 end subroutine get_signal_description
124
125 subroutine trap_segfault()
126 implicit none
127 end subroutine trap_segfault
128 end interface
129
130
131contains
132
133 ! ---------------------------------------------------------
134 subroutine messages_init()
135
136 logical :: trap_signals
137
138 call sihash_init(namespace_unit)
139 call sphash_init(namespace_mpi_grp)
140
141 call messages_obsolete_variable(global_namespace, 'DevelVersion', 'ExperimentalFeatures')
142
143 !%Variable ExperimentalFeatures
144 !%Type logical
145 !%Default no
146 !%Section Execution::Debug
147 !%Description
148 !% If true, allows the use of certain parts of the code that are
149 !% still under development and are not suitable for production
150 !% runs. This should not be used unless you know what you are doing.
151 !% See details on
152 !% <a href=http://octopus-code.org/experimental_features>wiki page</a>.
153 !%End
154 call parse_variable(global_namespace, 'ExperimentalFeatures', .false., conf%devel_version)
155
156 call messages_obsolete_variable(global_namespace, 'DebugLevel', 'Debug')
159
160 warnings = 0
161 experimentals = 0
163 !%Variable DebugTrapSignals
164 !%Type logical
165 !%Default yes
166 !%Section Execution::Debug
167 !%Description
168 !% If true, trap signals to handle them in octopus itself and
169 !% print a custom backtrace. If false, do not trap signals; then,
170 !% core dumps can be produced or gdb can be used to stop at the
171 !% point a signal was produced (e.g. a segmentation fault).
172 !%End
173 call parse_variable(global_namespace, 'DebugTrapSignals', .true., trap_signals)
174
175 if (trap_signals) call trap_segfault()
178
179 end subroutine messages_init
180
181 ! ---------------------------------------------------------
182 subroutine messages_end()
183
184 type(sihash_iterator_t) :: it
185 integer :: iu
186
187 if (mpi_grp_is_root(mpi_world)) then
188
189 if (experimentals > 0 .or. warnings > 0) then
190 message(1) = ''
191 call messages_info(1)
192 end if
194
195 if (warnings > 0) then
196 call messages_write('Octopus emitted ')
197 call messages_write(warnings)
198 if (warnings > 1) then
199 call messages_write(' warnings.')
200 else
201 call messages_write(' warning.')
202 end if
203 call messages_info()
204 end if
205
206 if (experimentals > 0) then
207 call messages_new_line()
208 call messages_write('Octopus used ')
209 call messages_write(experimentals)
210 if (experimentals > 1) then
211 call messages_write(' experimental features:')
212 else
213 call messages_write(' experimental feature:')
214 end if
215 call messages_new_line()
216 call messages_new_line()
217 call messages_write(' Since you used one or more experimental features, results are likely')
218 call messages_new_line()
219 call messages_write(' wrong and should not be considered as valid scientific data. Check')
220 call messages_new_line()
221 call messages_new_line()
222 call messages_write(' http://octopus-code.org/experimental_features')
223 call messages_new_line()
224 call messages_new_line()
225 call messages_write(' or contact the octopus developers for details.')
226 call messages_new_line()
227 call messages_info()
228 end if
229
230 open(unit = iunit_out, file = 'exec/messages', action = 'write')
231 write(iunit_out, '(a, i9)') "warnings = ", warnings
232 write(iunit_out, '(a, i9)') "experimental = ", experimentals
233 close(iunit_out)
234
235 end if
236
237 call it%start(namespace_unit)
238 do while(it%has_next())
239 iu = it%get_next()
240 if (iu /= stderr .and. iu /= stdout) call io_close(iu)
241 end do
242
243 call sphash_end(namespace_mpi_grp)
244 call sihash_end(namespace_unit)
245
246 end subroutine messages_end
247
248 ! ---------------------------------------------------------
249 integer function messages_get_unit(namespace) result(iunit)
250 type(namespace_t), optional, intent(in) :: namespace
251
252 logical :: found
253
254 if (present(namespace)) then
255
256 if (namespace%get()=="") then
257 iunit = stdout
258 return
259 end if
260
261 iunit = sihash_lookup( namespace_unit, namespace%get(), found)
262
263 if (.not. found) then
264 call io_mkdir('', namespace)
265 iunit = io_open("log", namespace=namespace, action="write")
266
267 if(iunit > 0) then
268 call sihash_insert(namespace_unit, namespace%get(), iunit)
269 else
270 write(message(1),*) "Cannot get unit for namespace ", namespace%get()
271 call messages_fatal(1)
272 end if
273 endif
274
275 else
276 iunit = stdout
277 end if
278
279 end function messages_get_unit
280
281 ! ---------------------------------------------------------
282 subroutine messages_update_mpi_grp(namespace, mpigrp)
283 type(namespace_t), intent(in) :: namespace
284 type(mpi_grp_t), target, intent(in) :: mpigrp
285
286 call sphash_insert(namespace_mpi_grp, namespace%get(), mpigrp, clone=.true.)
287
288 end subroutine messages_update_mpi_grp
289
290 ! ---------------------------------------------------------
291 function messages_get_mpi_grp(namespace) result(grp)
292 type(namespace_t), optional, intent(in) :: namespace
293 type(mpi_grp_t) :: grp
294
295 class(*), pointer :: value
296 logical :: found
297
298 if (present(namespace)) then
299 value => sphash_lookup(namespace_mpi_grp, trim(namespace%get()), found)
300
301 if (.not.found) then
302 grp = mpi_world
303 return
304 endif
305
306 select type(value)
307 type is (mpi_grp_t)
308 grp = value
309 class default
310 write(message(1),*) "Cannot get mpi_grp for namespace ",namespace%get()
311 call messages_fatal(1)
312 end select
313 else
314 grp = mpi_world
315 end if
316
317 end function messages_get_mpi_grp
318
319 ! ---------------------------------------------------------
320 subroutine messages_fatal(no_lines, only_root_writes, namespace)
321 integer, optional, intent(in) :: no_lines
322 logical, optional, intent(in) :: only_root_writes
323 type(namespace_t), optional, intent(in) :: namespace
324
325 type(mpi_grp_t) :: msg_mpi_grp
326 integer :: ii, no_lines_
327 logical :: only_root_writes_, should_write
328 integer, allocatable :: recv_buf(:), recv_req(:)
329#ifdef HAVE_MPI
330 integer, parameter :: fatal_tag = 32767
331 logical :: received
332 integer :: send_req
333#endif
335 no_lines_ = current_line
336 if (present(no_lines)) no_lines_ = no_lines
337
338 msg_mpi_grp = messages_get_mpi_grp(namespace)
339
340 if (present(only_root_writes)) then
341 should_write = mpi_grp_is_root(msg_mpi_grp) .or. (.not. only_root_writes)
342 only_root_writes_ = only_root_writes
343 else
344 should_write = .true.
345 only_root_writes_ = .false.
346 end if
347
348 ! This is to avoid all nodes reporting an error. The root node
349 ! post a message reception to all nodes, the rest of the nodes
350 ! send a message. If the message is received, the non-root nodes
351 ! know that the root node will report the error, so they do not do
352 ! anything.
353
354 if (.not. only_root_writes_) then
355 if (msg_mpi_grp%rank == 0) then
356
357 allocate(recv_buf(1:mpi_world%size - 1))
358 allocate(recv_req(1:mpi_world%size - 1))
359 do ii = 1, mpi_world%size - 1
360#ifdef HAVE_MPI
361 call mpi_recv_init(recv_buf(ii), 1, mpi_integer, ii, fatal_tag, msg_mpi_grp%comm, recv_req(ii), mpi_err)
362#endif
363 end do
364 deallocate(recv_buf)
365 deallocate(recv_req)
366
367 else
368
369#ifdef HAVE_MPI
370 call mpi_send_init(1, 1, mpi_integer, 0, fatal_tag, msg_mpi_grp%comm, send_req, mpi_err)
371#endif
372 !sleep for a second and check
373 call loct_nanosleep(sleepytime_all, 0)
374#ifdef HAVE_MPI
375 call mpi_test(send_req, received, mpi_status_ignore, mpi_err)
376#endif
377 should_write = .false.
378
379 end if
380 end if
381
382 ! Give a moment for all standard output hopefully to be printed
383 call loct_nanosleep(sleepytime_all, 0)
384
385 ! If we are not writing wait for the root node to get here and
386 ! write the error message. If the root doesn`t get here, we all print the
387 ! error messsage anyways and die. Otherwise, no message might be written.
388 if (.not. should_write) call loct_nanosleep(sleepytime_nonwriters, 0)
389
390 call messages_print_with_emphasis(msg="FATAL ERROR", iunit=stderr)
391 write(msg, '(a)') '*** Fatal Error (description follows)'
392 call flush_msg(msg, stderr)
393
394 if (present(namespace)) then
395 if (len_trim(namespace%get()) > 0) then
396 write(msg, '(3a)') '* In namespace ', trim(namespace%get()), ':'
397 call flush_msg(msg, stderr)
398 end if
399 end if
400
401#ifdef HAVE_MPI
402 if (.not. only_root_writes_ .or. .not. mpi_grp_is_root(msg_mpi_grp)) then
403 call flush_msg(shyphens, stderr)
404 write(msg, '(a,i4)') "* From node = ", msg_mpi_grp%rank
405 call flush_msg(msg, stderr)
406 end if
407#endif
408 call flush_msg(shyphens, stderr)
409 do ii = 1, no_lines_
410 write(msg, '(a,1x,a)') '*', trim(message(ii))
411 call flush_msg(msg, stderr)
412 end do
413
414 ! We only dump the stack in debug mode because subroutine invocations
415 ! are only recorded in debug mode (via push_sub/pop_sub). Otherwise,
416 ! it is a bit confusing that the stack seems to be empty.
417 if (debug%trace) then
418 call flush_msg(shyphens, stderr)
419
420 write(msg, '(a)') '* Stack: '
421 call flush_msg(msg, stderr, adv='no')
422 do ii = 1, no_sub_stack
423 write(msg, '(a,a)') ' > ', trim(sub_stack(ii))
424 call flush_msg(msg, stderr, adv='no')
425 end do
426 call flush_msg(" ", stderr)
427 end if
428
429 if (should_write) then
430 call messages_print_with_emphasis(iunit=stderr)
431 end if
432
433 ! switch file indicator to state aborted
434 call messages_switch_status('aborted')
435
436#ifdef HAVE_MPI
437 call mpi_abort(mpi_world%comm, 999, mpi_err)
438#endif
439
440 call loct_exit_failure()
441 end subroutine messages_fatal
442
443 ! ---------------------------------------------------------
444 subroutine messages_warning(no_lines, all_nodes, namespace)
445 integer, optional, intent(in) :: no_lines
446 logical, optional, intent(in) :: all_nodes
447 type(namespace_t), optional, intent(in) :: namespace
448
449 integer :: il, no_lines_
450 integer :: iunit_namespace
451 logical :: have_to_write, all_nodes_
452 type(mpi_grp_t) :: msg_mpi_grp
453
454 no_lines_ = current_line
455 if (present(no_lines)) no_lines_ = no_lines
456
457 warnings = warnings + 1
458
459 iunit_namespace = messages_get_unit(namespace)
460 msg_mpi_grp = messages_get_mpi_grp(namespace)
461
462 have_to_write = mpi_grp_is_root(msg_mpi_grp)
463
464 all_nodes_ = .false.
465 if (present(all_nodes)) then
466 have_to_write = have_to_write .or. all_nodes
467 all_nodes_ = all_nodes
468 end if
469
470 if (have_to_write) then
471
472 call flush_msg('', stderr)
473 if (iunit_namespace /= stdout) then
474 call flush_msg('', iunit_namespace)
475 end if
476 write(msg, '(a)') '** Warning:'
477 call flush_msg(msg, stderr)
478 if (iunit_namespace /= stdout) then
479 call flush_msg(msg, iunit_namespace)
480 end if
481
482 if (present(namespace)) then
483 if (len_trim(namespace%get()) > 0) then
484 write(msg, '(3a)') '** In namespace ', trim(namespace%get()), ':'
485 call flush_msg(msg, stderr)
486 end if
487 end if
488
489#ifdef HAVE_MPI
490 if (all_nodes_) then
491 write(msg , '(a,i4)') '** From node = ', mpi_world%rank
492 call flush_msg(msg, stderr)
493 if (iunit_namespace /= stdout) then
494 call flush_msg(msg, iunit_namespace)
495 end if
496 end if
497#endif
498
499 do il = 1, no_lines_
500 write(msg , '(a,3x,a)') '**', trim(message(il))
501 call flush_msg(msg, stderr)
502 if (iunit_namespace /= stdout) then
503 call flush_msg(msg, iunit_namespace)
504 end if
505 end do
506 call flush_msg('', stderr)
507 if (iunit_namespace /= stdout) then
508 call flush_msg('', iunit_namespace)
509 end if
510
511#ifdef HAVE_FLUSH
512 call flush(stderr)
513 if (iunit_namespace /= stdout) then
514 flush(iunit_namespace)
515 end if
516#endif
517
518 end if
519
521
522 end subroutine messages_warning
523
524 ! ---------------------------------------------------------
525 subroutine messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
526 integer, optional, intent(in) :: no_lines
527 integer, optional, intent(in) :: iunit
528 logical, optional, intent(in) :: verbose_limit
529 logical, optional, intent(in) :: stress
530 logical, optional, intent(in) :: all_nodes
531 type(namespace_t), optional, intent(in) :: namespace
532
533 integer :: il, no_lines_
534 integer :: iunit_
535 type(mpi_grp_t) :: msg_mpi_grp
536
537 assert(.not. (present(iunit) .and. present(namespace)))
538
539 if (present(iunit)) then
540 iunit_ = iunit
541 else
542 iunit_ = messages_get_unit(namespace)
543 end if
544 msg_mpi_grp = messages_get_mpi_grp(namespace)
545
546 if (.not. mpi_grp_is_root(msg_mpi_grp) .and. .not. optional_default(all_nodes, .false.)) then
548 return
549 end if
550
551 no_lines_ = current_line
552 if (present(no_lines)) no_lines_ = no_lines
553
554 if (present(stress)) then
555 call messages_print_with_emphasis(iunit=iunit_)
556 end if
557
558 do il = 1, no_lines_
559 if (.not. present(verbose_limit) .or. debug%info) then
560 write(msg, '(a)') trim(message(il))
561 call flush_msg(msg, iunit_)
562 end if
563 end do
564 if (present(stress)) then
565 call messages_print_with_emphasis(iunit=iunit_)
566 end if
567
568#ifdef HAVE_FLUSH
569 call flush(iunit_)
570#endif
571
573
574 end subroutine messages_info
575
576 ! ---------------------------------------------------------
578 subroutine messages_switch_status(status)
579 character(len=*), intent(in) :: status
580
581 ! only root node is taking care of file I/O
582 if (.not. mpi_grp_is_root(mpi_world)) return
583
584 ! remove old status files first, before we switch to a new state
585 call loct_rm('exec/oct-status-running')
586 call loct_rm('exec/oct-status-finished')
587 call loct_rm('exec/oct-status-aborted')
588 if (oct_status /= 'walltimer-aborted') then
589 call loct_rm('exec/oct-status-walltimer-aborted')
590 end if
591
592 oct_status = status
593
594 ! create empty status file to indicate new state
595 open(unit=iunit_err, file='exec/oct-status-'//trim(status), &
596 action='write', status='unknown')
597 close(iunit_err)
598
599 end subroutine messages_switch_status
600
601 ! ---------------------------------------------------------
602 subroutine alloc_error(size, file, line)
603 integer(i8), intent(in) :: size
604 character(len=*), intent(in) :: file
605 integer, intent(in) :: line
606
607 write(message(1), '(a,i18,3a,i5)') "Failed to allocate ", size, " words in file '", trim(file), "' line ", line
608 call messages_fatal(1)
609
610 end subroutine alloc_error
611
612 ! ---------------------------------------------------------
613 subroutine dealloc_error(size, file, line)
614 integer(i8), intent(in) :: size
615 character(len=*), intent(in) :: file
616 integer, intent(in) :: line
617
618 write(message(1), '(a,i18,3a,i5)') "Failed to deallocate array of ", size, " words in file '", trim(file), "' line ", line
619 call messages_fatal(1)
620
621 end subroutine dealloc_error
622
623 ! ---------------------------------------------------------
624 subroutine messages_input_error(namespace, var, details, row, column)
625 type(namespace_t), intent(in) :: namespace
626 character(len=*), intent(in) :: var
627 character(len=*), optional, intent(in) :: details
628 integer, optional, intent(in) :: row
629 integer, optional, intent(in) :: column
630
631 character(len=10) :: row_str, column_str
632
633 call messages_write('Input error in the input variable '// trim(var))
634
635 if (present(row)) then
636 ! Print row and, if available, the column. We add one to both values
637 ! in order to translate from the C numbering used by the parser to a
638 ! more human-friendly numbering.
639 write(row_str, '(I10)') row + 1
640 call messages_write(' at row '//adjustl(row_str))
641 if (present(column)) then
642 write(column_str, '(I10)') column + 1
643 call messages_write(', column '//adjustl(column_str))
644 end if
645 end if
646 if (present(details)) then
647 call messages_write(':', new_line = .true.)
648 call messages_new_line()
649 call messages_write(' '//trim(details))
650 end if
651 call messages_write('.', new_line = .true.)
652
653 call messages_new_line()
654
655 call messages_write('You can get the documentation of the variable with the command:', new_line = .true.)
656 call messages_write(' oct-help -p '//trim(var))
657 call messages_fatal(namespace=namespace)
658
659 end subroutine messages_input_error
660
661 ! ---------------------------------------------------------
662 subroutine messages_print_var_valuei(var, val, iunit, namespace)
663 character(len=*), intent(in) :: var
664 integer, intent(in) :: val
665 integer, optional, intent(in) :: iunit
666 type(namespace_t), optional, intent(in) :: namespace
667
668 character(len=10) :: intstring
669
670 assert(.not. (present(iunit) .and. present(namespace)))
671
672 write(intstring,'(i10)') val
673 message(1) = 'Input: ['//trim(var)//' = '//trim(adjustl(intstring))//']'
674 call messages_info(1, iunit=iunit, namespace=namespace)
675
676 end subroutine messages_print_var_valuei
677
678 ! ---------------------------------------------------------
679 subroutine messages_print_var_values(var, val, iunit, namespace)
680 character(len=*), intent(in) :: var
681 character(len=*), intent(in) :: val
682 integer, optional, intent(in) :: iunit
683 type(namespace_t), optional, intent(in) :: namespace
684
685 assert(.not. (present(iunit) .and. present(namespace)))
686
687 message(1) = 'Input: ['//trim(var)//' = '//trim(val)//']'
688 call messages_info(1, iunit=iunit, namespace=namespace)
689
690 end subroutine messages_print_var_values
691
692 ! ---------------------------------------------------------
693 subroutine messages_print_var_valuer(var, val, unit, iunit, namespace)
694 character(len=*), intent(in) :: var
695 float, intent(in) :: val
696 type(unit_t), optional, intent(in) :: unit
697 integer, optional, intent(in) :: iunit
698 type(namespace_t), optional, intent(in) :: namespace
699
700 character(len=11) :: floatstring
701
702 assert(.not. (present(iunit) .and. present(namespace)))
703
704 if (.not. present(unit)) then
705 write(floatstring,'(g11.4)') val
706 message(1) = 'Input: ['//trim(var)//' = '//trim(adjustl(floatstring))//']'
707 else
708 write(floatstring,'(g11.4)') units_from_atomic(unit, val)
709 message(1) = 'Input: ['//trim(var)//' = '//trim(adjustl(floatstring))//' '//trim(units_abbrev(unit))//']'
710 end if
711 call messages_info(1, iunit=iunit, namespace=namespace)
712
713 end subroutine messages_print_var_valuer
714
715 ! ---------------------------------------------------------
716 subroutine messages_print_var_valuel(var, val, iunit, namespace)
717 character(len=*), intent(in) :: var
718 logical, intent(in) :: val
719 integer, optional, intent(in) :: iunit
720 type(namespace_t), optional, intent(in) :: namespace
721
722 character(len=3) :: lstring
723
724 assert(.not. (present(iunit) .and. present(namespace)))
725
726 if (val) then
727 lstring = 'yes'
728 else
729 lstring = 'no'
730 end if
731 message(1) = 'Input: ['//trim(var)//' = '//trim(lstring)//']'
732 call messages_info(1, iunit=iunit, namespace=namespace)
733
734 end subroutine messages_print_var_valuel
735
736 ! ---------------------------------------------------------
737 subroutine messages_print_var_valuear(var, val, unit, iunit, namespace)
738 character(len=*), intent(in) :: var
739 float, intent(in) :: val(:)
740 type(unit_t), optional, intent(in) :: unit
741 integer, optional, intent(in) :: iunit
742 type(namespace_t), optional, intent(in) :: namespace
743
744 integer :: ii
745 character(len=11) :: floatstring
746
747 assert(.not. (present(iunit) .and. present(namespace)))
748
749 call messages_write('Input: ['//trim(var)//' = (')
750 do ii = 1, size(val)
751 write(floatstring,'(g11.4)') val(ii)
752 call messages_write(trim(adjustl(floatstring)))
753 if (ii < size(val)) call messages_write(', ')
754 end do
755 call messages_write(')')
756 if (present(unit)) then
757 call messages_write(' '//trim(units_abbrev(unit))//']')
758 else
759 call messages_write(']')
760 end if
761 call messages_info(iunit = iunit, namespace=namespace)
762
763 end subroutine messages_print_var_valuear
765 ! ---------------------------------------------------------
766 subroutine messages_print_var_info(var, iunit, namespace)
767 character(len=*), intent(in) :: var
768 integer, optional, intent(in) :: iunit
769 type(namespace_t), optional, intent(in) :: namespace
770
771 integer :: iunit_
772 type(mpi_grp_t) :: mpi_grp
773
774 assert(.not. (present(iunit) .and. present(namespace)))
775
776 mpi_grp = messages_get_mpi_grp(namespace)
777
778 if (.not. mpi_grp_is_root(mpi_grp)) return
779
780 if (present(iunit)) then
781 iunit_ = iunit
782 else
783 iunit_ = messages_get_unit(namespace)
784 end if
785 call varinfo_print(iunit_, var)
786
787 end subroutine messages_print_var_info
788
789 ! ---------------------------------------------------------
790 subroutine messages_print_var_option_8(var, option, pre, iunit, namespace)
791 character(len=*), intent(in) :: var
792 integer(i8), intent(in) :: option
793 character(len=*), optional, intent(in) :: pre
794 integer, optional, intent(in) :: iunit
795 type(namespace_t), optional, intent(in) :: namespace
796
797 integer :: option4, iunit_
798 type(mpi_grp_t) :: mpi_grp
799
800 assert(.not. (present(iunit) .and. present(namespace)))
802 mpi_grp = messages_get_mpi_grp(namespace)
803
804 if (.not. mpi_grp_is_root(mpi_grp)) return
805
806 option4 = int(option)
807
808 if (present(iunit)) then
809 iunit_ = iunit
810 else
811 iunit_ = messages_get_unit(namespace)
812 end if
813 call varinfo_print_option(iunit_, var, option4, pre)
814
815 end subroutine messages_print_var_option_8
816
817 ! ---------------------------------------------------------
818 subroutine messages_print_var_option_4(var, option, pre, iunit, namespace)
819 character(len=*), intent(in) :: var
820 integer(i4), intent(in) :: option
821 character(len=*), optional, intent(in) :: pre
822 integer, optional, intent(in) :: iunit
823 type(namespace_t), optional, intent(in) :: namespace
824
825 assert(.not. (present(iunit) .and. present(namespace)))
826
827 call messages_print_var_option_8(var, int(option, 8), pre, iunit, namespace)
828
829 end subroutine messages_print_var_option_4
830
831 ! ---------------------------------------------------------
832 subroutine messages_print_with_emphasis(msg, iunit, namespace)
833 character(len=*), optional, intent(in) :: msg
834 integer, optional, intent(in) :: iunit
835 type(namespace_t), optional, intent(in) :: namespace
836
837 integer, parameter :: max_len = 70
838
839 integer :: ii, jj, length
840 integer :: iunit_
841 character(len=70) :: str
842 character(len=max_len) :: msg_combined
843 type(mpi_grp_t) :: msg_mpi_grp
844
845 if (present(iunit)) then
846 iunit_ = iunit
847 else
848 iunit_ = messages_get_unit(namespace)
849 end if
850 msg_mpi_grp = messages_get_mpi_grp(namespace)
852 if (.not. mpi_grp_is_root(msg_mpi_grp)) return
853
854 if (present(msg)) then
855 ! make sure we do not get a segfault for too long messages
856 if (len_trim(msg) > max_len) then
857 msg_combined = trim(msg(1:max_len))
858 else
859 msg_combined = trim(msg)
860 end if
861 length = len_trim(msg_combined)
862
863 str = ''
864 jj = 1
865
866 do ii = 1, (max_len - (length + 2))/2
867 str(jj:jj) = '*'
868 jj = jj + 1
869 end do
870
871 str(jj:jj) = ' '
872 jj = jj + 1
873
874 do ii = 1, length
875 str(jj:jj) = msg_combined(ii:ii)
876 jj = jj + 1
877 end do
878
879 str(jj:jj) = ' '
880 jj = jj + 1
881
882 do ii = jj, max_len
883 str(jj:jj) = '*'
884 jj = jj + 1
885 end do
886
887 call flush_msg('', iunit_) ! empty line
888 call flush_msg(str, iunit_) ! print out nice line with the header
889 else
890 do ii = 1, max_len
891 str(ii:ii) = '*'
892 end do
893
894 call flush_msg(str, iunit_) ! print out nice line with the header
895 call flush_msg('', iunit_) ! empty line
896 end if
897
898#ifdef HAVE_FLUSH
899 call flush(iunit_)
900#endif
901 end subroutine messages_print_with_emphasis
902
903 ! ---------------------------------------------------------
904 subroutine flush_msg(str, iunit, adv)
905 character(len = *), intent(in) :: str
906 integer, intent(in) :: iunit
907 character(len = *), optional, intent(in) :: adv
908
909 character(len = 20) :: adv_
910
911 adv_ = 'yes'
912 if (present(adv)) adv_ = trim(adv)
913
914 write(iunit, '(a)', advance=adv_) trim(str)
915
916 end subroutine flush_msg
918 ! ---------------------------------------------------------
919 subroutine print_date(str)
920 character(len = *), intent(in) :: str
921
922 integer :: val(8)
923
924 call date_and_time(values=val)
925 message(1) = ""
926 write(message(3),'(a,i4,a1,i2.2,a1,i2.2,a,i2.2,a1,i2.2,a1,i2.2)') &
927 str , val(1), "/", val(2), "/", val(3), &
928 " at ", val(5), ":", val(6), ":", val(7)
929 message(2) = str_center(trim(message(3)), 70)
930 message(3) = ""
931 call messages_info(3)
932
933 end subroutine print_date
934
935 ! ---------------------------------------------------------
938 subroutine time_sum(sec1, usec1, sec2, usec2)
939 integer, intent(in) :: sec1
940 integer, intent(in) :: usec1
941 integer, intent(inout) :: sec2
942 integer, intent(inout) :: usec2
943
945
946 sec2 = sec1 + sec2
947 usec2 = usec1 + usec2
948
949 ! Carry?
950 if (usec2 >= 1000000) then
951 sec2 = sec2 + 1
952 usec2 = usec2 - 1000000
953 end if
954
956 end subroutine time_sum
957
958#ifndef NDEBUG
959 ! ---------------------------------------------------------
960 subroutine push_sub(sub_name)
961 character(len=*), intent(in) :: sub_name
962
963 integer iunit, sec, usec
964
965 if (.not. debug%trace) return
966
967 call loct_gettimeofday(sec, usec)
968 call epoch_time_diff(sec, usec)
969
971 if (no_sub_stack > 49) then
972 sub_stack(50) = 'push_sub'
973 message(1) = 'Too many recursion levels (max=50)'
974 call messages_fatal(1)
975 end if
976
979
980 if (debug%trace_file) then
981 call debug_open_trace(iunit)
982 call push_sub_write(iunit)
983 ! close file to ensure flushing
984 close(iunit)
985 end if
986
987 if (debug%trace_term .and. mpi_grp_is_root(mpi_world)) then
988 ! write to stderr if we are node 0
989 call push_sub_write(stderr)
990 end if
991
992 contains
993
994 subroutine push_sub_write(iunit_out)
995 integer, intent(in) :: iunit_out
996
997 integer :: ii
998 character(len=1000) :: tmpstr
999
1000 write(tmpstr,'(a,i6,a,i6.6,f20.6,i8,a)') "* I ", &
1001 sec, '.', usec, &
1002 loct_clock(), &
1003 loct_get_memory_usage() / 1024, " | "
1004 do ii = no_sub_stack - 1, 1, -1
1005 write(tmpstr, '(2a)') trim(tmpstr), "..|"
1006 end do
1007 write(tmpstr, '(2a)') trim(tmpstr), trim(messages_clean_path(sub_name))
1008 call flush_msg(tmpstr, iunit_out)
1009
1010 end subroutine push_sub_write
1011
1012 end subroutine push_sub
1013
1014 ! ---------------------------------------------------------
1015 subroutine pop_sub(sub_name)
1016 character(len=*), intent(in) :: sub_name
1017
1018 character(len=80) :: sub_name_short
1019 integer iunit, sec, usec
1020
1021 if (.not. debug%trace) return
1022
1023 call loct_gettimeofday(sec, usec)
1024 call epoch_time_diff(sec, usec)
1025
1026 if (no_sub_stack <= 0) then
1027 no_sub_stack = 1
1028 sub_stack(1) = 'pop_sub'
1029 message(1) = 'Too few recursion levels.'
1030 call messages_fatal(1)
1031 end if
1032
1033 ! the name might be truncated in sub_stack, so we copy to a string
1034 ! of the same size
1035 sub_name_short = trim(messages_clean_path(sub_name))
1036
1037 if (sub_name_short /= sub_stack(no_sub_stack)) then
1038 write (message(1),'(a)') 'Wrong sub name on pop_sub :'
1039 write (message(2),'(2a)') ' got : ', sub_name_short
1040 write (message(3),'(2a)') ' expected : ', sub_stack(no_sub_stack)
1041 call messages_fatal(3)
1042 end if
1043
1044 if (debug%trace_file) then
1046 call pop_sub_write(iunit)
1047 ! close file to ensure flushing
1048 close(iunit)
1049 end if
1050
1051 if (debug%trace_term .and. mpi_grp_is_root(mpi_world)) then
1052 ! write to stderr if we are node 0
1053 call pop_sub_write(stderr)
1054 end if
1055
1057
1058 contains
1059
1060 subroutine pop_sub_write(iunit_out)
1061 integer, intent(in) :: iunit_out
1062
1063 integer :: ii
1064 character(len=1000) :: tmpstr
1065
1066 write(tmpstr,'(a,i6,a,i6.6,f20.6,i8, a)') "* O ", &
1067 sec, '.', usec, &
1069 loct_get_memory_usage() / 1024, " | "
1070 do ii = no_sub_stack - 1, 1, -1
1071 write(tmpstr,'(2a)') trim(tmpstr), "..|"
1072 end do
1073 write(tmpstr,'(2a)') trim(tmpstr), trim(sub_stack(no_sub_stack))
1074 call flush_msg(tmpstr, iunit_out)
1075
1076 end subroutine pop_sub_write
1077
1078 end subroutine pop_sub
1079#endif
1080
1081 ! ---------------------------------------------------------
1082 subroutine messages_obsolete_variable(namespace, name, rep)
1083 type(namespace_t), intent(in) :: namespace
1084 character(len=*), intent(in) :: name
1085 character(len=*), optional, intent(in) :: rep
1086
1087 if (parse_is_defined(namespace, trim(name))) then
1088
1089 write(message(1), '(a)') 'Input variable '//trim(name)//' is obsolete.'
1090
1091 if (present(rep)) then
1092 write(message(2), '(a)') ' '
1093 write(message(3), '(a)') 'Equivalent functionality can be obtained with the '//trim(rep)
1094 write(message(4), '(a)') 'variable. Check the documentation for details.'
1095 write(message(5), '(a)') '(You can use the `oct-help -p '//trim(rep)//'` command).'
1096 call messages_fatal(5, only_root_writes = .true., namespace=namespace)
1097 else
1098 call messages_fatal(1, only_root_writes = .true., namespace=namespace)
1099 end if
1101 end if
1102
1103 end subroutine messages_obsolete_variable
1104
1105 ! ---------------------------------------------------------
1106 subroutine messages_variable_is_block(namespace, name)
1107 type(namespace_t), intent(in) :: namespace
1108 character(len=*), intent(in) :: name
1109
1110 if (parse_is_defined(namespace, trim(name))) then
1111
1112 write(message(1), '(a)') 'Input variable `'//trim(name)//'` must be defined as a block.'
1113 write(message(2), '(a)') 'Please check the documentation for details.'
1114 write(message(3), '(a)') '(You can use the `oct-help -p '//trim(name)//'` command).'
1115 call messages_fatal(3, only_root_writes = .true., namespace=namespace)
1116
1117 end if
1118
1119 end subroutine messages_variable_is_block
1120
1121 ! ---------------------------------------------------------
1122 subroutine messages_experimental(name, namespace)
1123 character(len=*), intent(in) :: name
1124 type(namespace_t), optional, intent(in) :: namespace
1125
1126 experimentals = experimentals + 1
1127
1128 if (.not. conf%devel_version) then
1129 call messages_write(trim(name)//' is an experimental feature.')
1130 call messages_new_line()
1131 call messages_new_line()
1132 call messages_write('If you still want to use this feature (at your own risk), check:')
1133 call messages_new_line()
1134 call messages_new_line()
1135 call messages_write('http://octopus-code.org/experimental_features')
1136 call messages_new_line()
1137 call messages_fatal(only_root_writes = .true., namespace=namespace)
1138 else
1139 write(message(1), '(a)') trim(name)//' is under development.'
1140 write(message(2), '(a)') 'It might not work or produce wrong results.'
1141 call messages_warning(2, namespace=namespace)
1142
1143 ! remove this warning from the count
1144 warnings = warnings - 1
1145 end if
1146
1147 end subroutine messages_experimental
1148
1149 ! ------------------------------------------------------------
1150 subroutine messages_not_implemented(feature, namespace)
1151 character(len=*), intent(in) :: feature
1152 type(namespace_t), optional, intent(in) :: namespace
1153
1155
1156 message(1) = trim(feature)//" not implemented."
1157 call messages_fatal(1, only_root_writes = .true., namespace=namespace)
1158
1160 end subroutine messages_not_implemented
1161
1162 ! ------------------------------------------------------------
1163 subroutine messages_reset_lines()
1164
1165 current_line = 1
1166 message(1) = ''
1168 end subroutine messages_reset_lines
1169
1170 ! ------------------------------------------------------------
1171 subroutine messages_new_line()
1172
1173 current_line = current_line + 1
1174 message(current_line) = ''
1175
1176 if (current_line > max_lines) stop 'Too many message lines.'
1177
1178 end subroutine messages_new_line
1179
1180 ! ------------------------------------------------------------
1181 subroutine messages_write_float(val, fmt, new_line, units, align_left, print_units)
1182 float, intent(in) :: val
1183 character(len=*), optional, intent(in) :: fmt
1184 logical, optional, intent(in) :: new_line
1185 type(unit_t), optional, intent(in) :: units
1186 logical, optional, intent(in) :: align_left
1187 logical, optional, intent(in) :: print_units
1188
1189 character(len=30) :: number
1190 float :: tval
1192 tval = val
1193 if (present(units)) tval = units_from_atomic(units, val)
1194
1195 if (present(fmt)) then
1196 write(number, '('//trim(fmt)//')') tval
1197 else
1198 write(number, '(f12.6)') tval
1199 end if
1200
1201 if (optional_default(align_left, .false.)) then
1202 number = adjustl(number)
1203 number(1:len(number)) = ' '//number(1:len(number)-1)
1204 end if
1205
1206 write(message(current_line), '(a, a)') trim(message(current_line)), trim(number)
1208 if (present(units) .and. optional_default(print_units, .true.)) then
1209 write(message(current_line), '(a, a, a)') trim(message(current_line)), ' ', trim(units_abbrev(units))
1210 end if
1211
1212 if (optional_default(new_line, .false.)) call messages_new_line()
1213
1214 end subroutine messages_write_float
1215
1216 ! ------------------------------------------------------------
1217 subroutine messages_write_integer8(val, fmt, new_line, units, print_units)
1218 integer(i8), intent(in) :: val
1219 character(len=*), optional, intent(in) :: fmt
1220 logical, optional, intent(in) :: new_line
1221 type(unit_t), optional, intent(in) :: units
1222 logical, optional, intent(in) :: print_units
1223
1224 character(len=20) :: number
1225 float :: val_conv_float
1226
1227 if (present(units)) then
1228 val_conv_float = units_from_atomic(units, dble(val))
1229
1230 if (present(fmt)) then
1231 write(message(current_line), '(a, '//trim(fmt)//')') trim(message(current_line)), val_conv_float
1232 else
1233 write(number, '(f15.3)') val_conv_float
1234 write(message(current_line), '(3a)') trim(message(current_line)), ' ', trim(adjustl(number))
1235 end if
1236
1237 else
1238
1239 if (present(fmt)) then
1240 write(message(current_line), '(a, '//trim(fmt)//')') trim(message(current_line)), val
1241 else
1242 write(number, '(i12)') val
1243 write(message(current_line), '(3a)') trim(message(current_line)), ' ', trim(adjustl(number))
1244 end if
1245
1246 end if
1247
1249 if (present(units) .and. optional_default(print_units, .true.)) then
1250 write(message(current_line), '(a, a, a)') trim(message(current_line)), ' ', trim(adjustl(units_abbrev(units)))
1251 end if
1252
1253 if (present(new_line)) then
1254 if (new_line) call messages_new_line()
1255 end if
1257 end subroutine messages_write_integer8
1258
1259 ! ------------------------------------------------------------
1260 subroutine messages_write_integer(val, fmt, new_line, units, print_units)
1261 integer(i4), intent(in) :: val
1262 character(len=*), optional, intent(in) :: fmt
1263 logical, optional, intent(in) :: new_line
1264 type(unit_t), optional, intent(in) :: units
1265 logical, optional, intent(in) :: print_units
1267 call messages_write_integer8(int(val, 8), fmt, new_line, units, print_units)
1268
1269 end subroutine messages_write_integer
1270
1271 ! ------------------------------------------------------------
1272 subroutine messages_write_str(val, fmt, new_line)
1273 character(len=*), intent(in) :: val
1274 character(len=*), optional, intent(in) :: fmt
1275 logical, optional, intent(in) :: new_line
1276
1277 character(len=100) :: fmt_
1278
1279 if (len(trim(message(current_line))) + len(trim(val)) > len(message(current_line))) then
1280 ! cannot use normal message approach without interfering with message we are trying to write
1281 ! write directly in case trim(val) is itself too long
1282 write(0, *) "Exceeded message line length limit, to write string:", trim(val)
1283 else
1284 fmt_ = optional_default(fmt, '(a)')
1285 write(message(current_line), '(a, '//trim(fmt_)//')') trim(message(current_line)), trim(val)
1286 end if
1287
1288 if (present(new_line)) then
1289 if (new_line) call messages_new_line()
1290 end if
1291
1292 end subroutine messages_write_str
1293
1294 ! ------------------------------------------------------------
1295 subroutine messages_write_logical(val, new_line)
1296 logical, intent(in) :: val
1297 logical, optional, intent(in) :: new_line
1298
1299 character(len=3) :: text
1300
1301 if (val) then
1302 text = 'yes'
1303 else
1304 text = 'no'
1305 end if
1306
1307 if (len(trim(message(current_line))) + len(trim(text)) > len(message(current_line))) then
1308 write(message(current_line + 1), '(3a)') "Exceeded message line length limit, to write logical value '", trim(text), "'"
1309 call messages_fatal(current_line + 1)
1310 end if
1311
1312 write(message(current_line), '(a,1x,a)') trim(message(current_line)), trim(text)
1313
1314 if (present(new_line)) then
1315 if (new_line) call messages_new_line()
1316 end if
1317
1318 end subroutine messages_write_logical
1319
1320 ! -----------------------------------------------------------
1321 character(len=MAX_PATH_LEN) function messages_clean_path(filename) result(clean_path)
1322 character(len=*), intent(in) :: filename
1323
1324 integer :: pos, start
1325
1326 pos = index(filename, 'src/', back = .true.)
1327 if (pos == 0) then
1328 ! 'src/' does not occur
1329 start = pos + 1
1330 else
1331 ! remove 'src/'
1332 start = pos + 4
1333 end if
1334 clean_path = filename(start:)
1335 end function messages_clean_path
1336
1337 ! -----------------------------------------------------------
1338 subroutine messages_dump_stack(isignal)
1339 integer, intent(in) :: isignal
1340
1341 integer :: ii
1342 character(len=300) :: description
1343
1344 call get_signal_description(isignal, description)
1346 write(msg, '(a,i2)') ''
1347 call flush_msg(msg, stderr)
1348 write(msg, '(a,i2)') '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1349 call flush_msg(msg, stderr)
1350 write(msg, '(a,i2)') ''
1351 call flush_msg(msg, stderr)
1352 write(msg, '(a,i2,2a)') ' Octopus was killed by signal ', isignal, ': ', trim(description)
1353 call flush_msg(msg, stderr)
1354 write(msg, '(a,i2)') ''
1355 call flush_msg(msg, stderr)
1356 write(msg, '(a)') ' Note: Octopus is currently trapping signals. This might prevent the'
1357 call flush_msg(msg, stderr)
1358 write(msg, '(a)') ' use of debuggers or the generation of core dumps. To change this'
1359 call flush_msg(msg, stderr)
1360 write(msg, '(a)') ' behavior, use the DebugTrapSignals input option.'
1361 call flush_msg(msg, stderr)
1362 write(msg, '(a,i2)') ''
1363 call flush_msg(msg, stderr)
1364 write(msg, '(a,i2)') '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
1365 call flush_msg(msg, stderr)
1366
1367 if (debug%trace) then
1368 call flush_msg(shyphens, iunit=stderr)
1369
1370 write(msg, '(a)') 'Octopus debug trace: '
1371 call flush_msg(msg, stderr)
1372 do ii = 1, no_sub_stack
1373 write(msg, '(a,a)') ' > ', trim(sub_stack(ii))
1374 call flush_msg(msg, stderr, adv='no')
1375 end do
1376 call flush_msg(" ", stderr)
1377 else
1378 write(msg, '(a)') " Octopus debug trace not available. You can enable it with 'Debug = trace'."
1379 call flush_msg(msg, stderr)
1380 end if
1381
1382 end subroutine messages_dump_stack
1383
1384end module messages_oct_m
1385
1386! ---------------------------------------------------------
1390subroutine assert_die(s, f, l)
1391 use messages_oct_m
1392 use mpi_oct_m
1393
1394 implicit none
1395
1396 character(len=*), intent(in) :: s, f
1397 integer, intent(in) :: l
1398
1399 call messages_write('Node ')
1400 call messages_write(mpi_world%rank)
1401 call messages_write(':')
1402 call messages_new_line()
1403
1404 call messages_write(' Assertion "'//trim(s)//'"')
1405 call messages_new_line()
1407 call messages_write(' failed in line ')
1408 call messages_write(l)
1409 call messages_write(' of file "'//trim(messages_clean_path(f))//'".')
1410
1411 call messages_fatal()
1412
1413end subroutine assert_die
1414
1415!-------------------------------------------------------
1416subroutine handle_segv(isignal) bind(c)
1417 use messages_oct_m
1418 use iso_c_binding
1419
1420 implicit none
1421
1422 integer(c_int), intent(in) :: isignal
1424 ! Switch status to aborted
1425 call messages_switch_status('aborted')
1426
1427 ! Dump stack
1428 call messages_dump_stack(isignal)
1429
1430end subroutine handle_segv
1431
1432
1433!! Local Variables:
1434!! mode: f90
1435!! coding: utf-8
1436!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:176
subroutine handle_segv(isignal)
Definition: messages.F90:1502
subroutine push_sub_write(iunit_out)
Definition: messages.F90:1080
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...
Definition: messages.F90:1476
subroutine pop_sub_write(iunit_out)
Definition: messages.F90:1146
type(debug_t), save, public debug
Definition: debug.F90:140
subroutine, public debug_open_trace(iunit)
Definition: debug.F90:281
subroutine, public epoch_time_diff(sec, usec)
Definition: debug.F90:312
subroutine, public debug_init(this, namespace)
Definition: debug.F90:148
integer, public no_sub_stack
Definition: global.F90:214
character(len=80), dimension(50), public sub_stack
The stack.
Definition: global.F90:212
type(conf_t), public conf
Definition: global.F90:160
real(8), dimension(50), public time_stack
Definition: global.F90:213
Definition: io.F90:106
subroutine, public io_close(iunit, grp)
Definition: io.F90:460
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:346
integer, parameter, public iunit_out
Definition: io.F90:143
integer, parameter, public iunit_err
Definition: io.F90:144
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:387
subroutine, public alloc_error(size, file, line)
Definition: messages.F90:688
subroutine, public messages_end()
Definition: messages.F90:268
character(len=max_path_len) function, public messages_clean_path(filename)
Definition: messages.F90:1407
subroutine messages_write_integer8(val, fmt, new_line, units, print_units)
Definition: messages.F90:1303
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:918
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1236
subroutine messages_print_var_option_8(var, option, pre, iunit, namespace)
Definition: messages.F90:876
subroutine messages_print_var_valuear(var, val, unit, iunit, namespace)
Definition: messages.F90:823
subroutine, public messages_variable_is_block(namespace, name)
Definition: messages.F90:1192
subroutine, public push_sub(sub_name)
Definition: messages.F90:1046
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:530
subroutine messages_write_integer(val, fmt, new_line, units, print_units)
Definition: messages.F90:1346
subroutine, public time_sum(sec1, usec1, sec2, usec2)
Computes t2 <- t1+t2. Parameters as in time_diff Assert: t1,2 <= 0.
Definition: messages.F90:1024
subroutine, public messages_init()
Definition: messages.F90:220
subroutine messages_print_var_option_4(var, option, pre, iunit, namespace)
Definition: messages.F90:904
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1168
subroutine, public messages_switch_status(status)
create status file for asynchronous communication
Definition: messages.F90:664
subroutine, public print_date(str)
Definition: messages.F90:1005
subroutine flush_msg(str, iunit, adv)
Definition: messages.F90:990
subroutine, public messages_print_var_info(var, iunit, namespace)
Definition: messages.F90:852
subroutine, public messages_update_mpi_grp(namespace, mpigrp)
Definition: messages.F90:368
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:611
subroutine, public messages_new_line()
Definition: messages.F90:1257
subroutine, public dealloc_error(size, file, line)
Definition: messages.F90:699
subroutine messages_print_var_values(var, val, iunit, namespace)
Definition: messages.F90:765
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:406
subroutine, public pop_sub(sub_name)
Definition: messages.F90:1101
subroutine messages_print_var_valuei(var, val, iunit, namespace)
Definition: messages.F90:748
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:710
subroutine messages_print_var_valuer(var, val, unit, iunit, namespace)
Definition: messages.F90:779
integer, parameter, private sleepytime_nonwriters
seconds
Definition: messages.F90:163
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1208
subroutine messages_print_var_valuel(var, val, iunit, namespace)
Definition: messages.F90:802
subroutine messages_write_logical(val, new_line)
Definition: messages.F90:1381
subroutine messages_write_str(val, fmt, new_line)
Definition: messages.F90:1358
type(mpi_grp_t) function messages_get_mpi_grp(namespace)
Definition: messages.F90:377
subroutine, public messages_dump_stack(isignal)
Definition: messages.F90:1424
integer function messages_get_unit(namespace)
Definition: messages.F90:335
subroutine messages_write_float(val, fmt, new_line, units, align_left, print_units)
Definition: messages.F90:1267
subroutine messages_reset_lines()
Definition: messages.F90:1249
logical function mpi_grp_is_root(grp)
Definition: mpi.F90:374
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:247
integer, public mpi_err
used to store return values of mpi calls
Definition: mpi.F90:250
type(namespace_t), public global_namespace
Definition: namespace.F90:135
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:442
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
Definition: sihash.F90:110
subroutine, public sihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
Definition: sihash.F90:195
subroutine, public sihash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
Definition: sihash.F90:154
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...
Definition: sihash.F90:221
subroutine, public sihash_end(h)
Free a hash table.
Definition: sihash.F90:175
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
Definition: sphash.F90:110
subroutine, public sphash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
Definition: sphash.F90:215
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.
Definition: sphash.F90:279
subroutine, public sphash_end(h)
Free a hash table.
Definition: sphash.F90:236
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...
Definition: sphash.F90:311
character(len=80) function, public str_center(s_in, l_in)
puts space around string, so that it is centered
Definition: string.F90:189
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:124
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:215
subroutine, public varinfo_print_option(iunit, var, option, pre)
Definition: varinfo.F90:301
subroutine, public varinfo_print(iunit, var, ierr)
Definition: varinfo.F90:196
This is defined even when running serial.
Definition: mpi.F90:125
int true(void)
real(8) function values(xx)
Definition: test.F90:1822