Neko  0.8.99
A portable framework for high-order spectral element flow simulations
log.f90
Go to the documentation of this file.
1 ! Copyright (c) 2021-2024, The Neko Authors
2 ! All rights reserved.
3 !
4 ! Redistribution and use in source and binary forms, with or without
5 ! modification, are permitted provided that the following conditions
6 ! are met:
7 !
8 ! * Redistributions of source code must retain the above copyright
9 ! notice, this list of conditions and the following disclaimer.
10 !
11 ! * Redistributions in binary form must reproduce the above
12 ! copyright notice, this list of conditions and the following
13 ! disclaimer in the documentation and/or other materials provided
14 ! with the distribution.
15 !
16 ! * Neither the name of the authors nor the names of its
17 ! contributors may be used to endorse or promote products derived
18 ! from this software without specific prior written permission.
19 !
20 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 ! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 ! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 ! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 ! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 ! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 ! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 ! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 ! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 ! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 ! POSSIBILITY OF SUCH DAMAGE.
32 !
34 module logger
35  use comm, only : pe_rank
36  use num_types, only : rp
37  implicit none
38  private
39 
40  integer, public, parameter :: log_size = 80
41 
42  type, public :: log_t
43  integer :: indent_
44  integer :: section_id_
45  integer :: level_
46  contains
47  procedure, pass(this) :: init => log_init
48  procedure, pass(this) :: begin => log_begin
49  procedure, pass(this) :: end => log_end
50  procedure, pass(this) :: indent => log_indent
51  procedure, nopass :: newline => log_newline
52  procedure, pass(this) :: message => log_message
53  procedure, pass(this) :: section => log_section
54  procedure, pass(this) :: status => log_status
55  procedure, pass(this) :: error => log_error
56  procedure, pass(this) :: warning => log_warning
57  procedure, pass(this) :: end_section => log_end_section
58  end type log_t
59 
61  type(log_t), public :: neko_log
63  integer, public, parameter :: neko_log_quiet = 0
65  integer, public, parameter :: neko_log_info = 1
67  integer, public, parameter :: neko_log_verbose = 2
69  integer, public, parameter :: neko_log_debug = 10
70 
71 contains
72 
74  subroutine log_init(this)
75  class(log_t), intent(inout) :: this
76  character(len=255) :: log_level
77  integer :: envvar_len
78 
79  this%indent_ = 1
80  this%section_id_ = 0
81 
82  call get_environment_variable("NEKO_LOG_LEVEL", log_level, envvar_len)
83  if (envvar_len .gt. 0) then
84  read(log_level(1:envvar_len), *) this%level_
85  else
86  this%level_ = neko_log_info
87  end if
88 
89  end subroutine log_init
90 
92  subroutine log_begin(this)
93  class(log_t), intent(inout) :: this
94 
95  if (pe_rank .eq. 0) then
96  this%indent_ = this%indent_ + 1
97  end if
98 
99  end subroutine log_begin
100 
102  subroutine log_end(this)
103  class(log_t), intent(inout) :: this
104 
105  if (pe_rank .eq. 0) then
106  this%indent_ = this%indent_ - 1
107  end if
108 
109  end subroutine log_end
110 
112  subroutine log_indent(this)
113  class(log_t), intent(in) :: this
114  integer :: i
115 
116  if (pe_rank .eq. 0) then
117  do i = 1, this%indent_
118  write(*,'(A)', advance='no') ' '
119  end do
120  end if
121 
122  end subroutine log_indent
123 
125  subroutine log_newline
126 
127  if (pe_rank .eq. 0) then
128  write(*,*) ' '
129  end if
130 
131  end subroutine log_newline
132 
134  subroutine log_message(this, msg, lvl)
135  class(log_t), intent(in) :: this
136  character(len=*), intent(in) :: msg
137  integer, optional :: lvl
138  integer :: lvl_
139 
140  if (present(lvl)) then
141  lvl_ = lvl
142  else
143  lvl_ = neko_log_info
144  end if
145 
146  if (lvl_ .gt. this%level_) then
147  return
148  end if
149 
150  if (pe_rank .eq. 0) then
151  call this%indent()
152  write(*, '(A)') trim(msg)
153  end if
154 
155  end subroutine log_message
156 
158  subroutine log_error(this, msg)
159  class(log_t), intent(in) :: this
160  character(len=*), intent(in) :: msg
161 
162  if (pe_rank .eq. 0) then
163  call this%indent()
164  write(*, '(A,A,A)') '*** ERROR: ', trim(msg),' ***'
165  end if
166 
167  end subroutine log_error
168 
170  subroutine log_warning(this, msg)
171  class(log_t), intent(in) :: this
172  character(len=*), intent(in) :: msg
173 
174  if (pe_rank .eq. 0) then
175  call this%indent()
176  write(*, '(A,A,A)') '*** WARNING: ', trim(msg),' ***'
177  end if
178 
179  end subroutine log_warning
180 
182  subroutine log_section(this, msg)
183  class(log_t), intent(inout) :: this
184  character(len=*), intent(in) :: msg
185  integer :: i, pre
186 
187  if (pe_rank .eq. 0) then
188 
189  this%indent_ = this%indent_ + this%section_id_
190  this%section_id_ = this%section_id_ + 1
191 
192  pre = (30 - len_trim(msg)) / 2
193 
194  write(*,*) ' '
195  call this%indent()
196  do i = 1, pre
197  write(*,'(A)', advance='no') '-'
198  end do
199 
200  write(*,'(A)', advance='no') trim(msg)
201  do i = 1, 30 - (len_trim(msg) + pre)
202  write(*,'(A)', advance='no') '-'
203  end do
204  write(*,*) ' '
205  end if
206 
207  end subroutine log_section
208 
210  subroutine log_end_section(this, msg)
211  class(log_t), intent(inout) :: this
212  character(len=*), intent(in), optional :: msg
213 
214  if (present(msg)) then
215  call this%message(msg, neko_log_quiet)
216  end if
217 
218  if (pe_rank .eq. 0) then
219  this%section_id_ = this%section_id_ - 1
220  this%indent_ = this%indent_ - this%section_id_
221  end if
222 
223  end subroutine log_end_section
224 
227  subroutine log_status(this, t, T_end)
228  class(log_t), intent(in) :: this
229  real(kind=rp), intent(in) :: t
230  real(kind=rp), intent(in) :: t_end
231  character(len=LOG_SIZE) :: log_buf
232  real(kind=rp) :: t_prog
233 
234  t_prog = 100d0 * t / t_end
235 
236  call this%message('----------------------------------------------------------------', &
238  write(log_buf, '(A,E15.7,A,F6.2,A)') &
239  't = ', t, ' [ ',t_prog,'% ]'
240 
241  call this%message(log_buf, neko_log_quiet)
242  call this%message('----------------------------------------------------------------', &
244  end subroutine log_status
245 
246  !
247  ! Rudimentary C interface
248  !
249 
252  subroutine log_message_c(c_msg) bind(c, name='log_message')
253  use, intrinsic :: iso_c_binding
254  character(kind=c_char), dimension(*), intent(in) :: c_msg
255  character(len=LOG_SIZE) :: msg
256  integer :: len
257 
258  if (pe_rank .eq. 0) then
259  len = 0
260  do
261  if (c_msg(len+1) .eq. c_null_char) exit
262  len = len + 1
263  msg(len:len) = c_msg(len)
264  end do
265 
266  call neko_log%indent()
267  write(*, '(A)') trim(msg(1:len))
268  end if
269 
270  end subroutine log_message_c
271 
274  subroutine log_error_c(c_msg) bind(c, name="log_error")
275  use, intrinsic :: iso_c_binding
276  character(kind=c_char), dimension(*), intent(in) :: c_msg
277  character(len=LOG_SIZE) :: msg
278  integer :: len
279 
280  if (pe_rank .eq. 0) then
281  len = 0
282  do
283  if (c_msg(len+1) .eq. c_null_char) exit
284  len = len + 1
285  msg(len:len) = c_msg(len)
286  end do
287 
288  call neko_log%indent()
289  write(*, '(A,A,A)') '*** ERROR: ',trim(msg(1:len)),' ***'
290  end if
291 
292  end subroutine log_error_c
293 
296  subroutine log_warning_c(c_msg) bind(c, name="log_warning")
297  use, intrinsic :: iso_c_binding
298  character(kind=c_char), dimension(*), intent(in) :: c_msg
299  character(len=LOG_SIZE) :: msg
300  integer :: len
301 
302  if (pe_rank .eq. 0) then
303  len = 0
304  do
305  if (c_msg(len+1) .eq. c_null_char) exit
306  len = len + 1
307  msg(len:len) = c_msg(len)
308  end do
309 
310  call neko_log%indent()
311  write(*, '(A,A,A)') '*** WARNING: ',trim(msg(1:len)),' ***'
312  end if
313 
314  end subroutine log_warning_c
315 
318  subroutine log_section_c(c_msg) bind(c, name="log_section")
319  use, intrinsic :: iso_c_binding
320  character(kind=c_char), dimension(*), intent(in) :: c_msg
321  character(len=LOG_SIZE) :: msg
322  integer :: len
323 
324  if (pe_rank .eq. 0) then
325  len = 0
326  do
327  if (c_msg(len+1) .eq. c_null_char) exit
328  len = len + 1
329  msg(len:len) = c_msg(len)
330  end do
331 
332  call neko_log%section(trim(msg(1:len)))
333  end if
334 
335  end subroutine log_section_c
336 
339  subroutine log_end_section_c() bind(c, name="log_end_section")
340 
341  call neko_log%end_section()
342 
343  end subroutine log_end_section_c
344 
345 end module logger
Definition: comm.F90:1
integer pe_rank
MPI rank.
Definition: comm.F90:26
Logging routines.
Definition: log.f90:34
subroutine log_end_section_c()
End a log section (from C)
Definition: log.f90:340
subroutine log_newline
Write a new line to a log.
Definition: log.f90:126
subroutine log_status(this, t, T_end)
Write status banner.
Definition: log.f90:228
subroutine log_end(this)
Decrease indention level.
Definition: log.f90:103
integer, parameter, public neko_log_verbose
Verbose log level.
Definition: log.f90:67
subroutine log_message(this, msg, lvl)
Write a message to a log.
Definition: log.f90:135
integer, parameter, public neko_log_quiet
Always logged.
Definition: log.f90:63
subroutine log_section(this, msg)
Begin a new log section.
Definition: log.f90:183
subroutine log_begin(this)
Increase indention level.
Definition: log.f90:93
subroutine log_message_c(c_msg)
Write a message to a log (from C)
Definition: log.f90:253
subroutine log_init(this)
Initialize a log.
Definition: log.f90:75
subroutine log_warning(this, msg)
Write a warning message to a log.
Definition: log.f90:171
subroutine log_end_section(this, msg)
End a log section.
Definition: log.f90:211
subroutine log_error_c(c_msg)
Write an error message to a log (from C)
Definition: log.f90:275
subroutine log_indent(this)
Indent a log.
Definition: log.f90:113
subroutine log_warning_c(c_msg)
Write a warning message to a log (from C)
Definition: log.f90:297
subroutine log_section_c(c_msg)
Begin a new log section (from C)
Definition: log.f90:319
integer, parameter, public neko_log_debug
Debug log level.
Definition: log.f90:69
type(log_t), public neko_log
Global log stream.
Definition: log.f90:61
integer, parameter, public log_size
Definition: log.f90:40
integer, parameter, public neko_log_info
Default log level.
Definition: log.f90:65
subroutine log_error(this, msg)
Write an error message to a log.
Definition: log.f90:159
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12