4 MODULE module_wrf_error
5 INTEGER :: wrf_debug_level = 0
6 CHARACTER*256 :: wrf_err_message
8 ! LOGICAL silence -- if TRUE (non-zero), this MPI rank does not send
9 ! messages via wrf_message, end_timing, wrf_debug, atm_announce,
10 ! cmp_announce, non-fatal glob_abort, or the like. If FALSE, this
11 ! MPI rank DOES send messages. Regardless of this setting, fatal
12 ! errors (wrf_error_fatal or fatal glob_aborts) and anything sent to
13 ! write or print will be sent.
14 #if defined(DM_PARALLEL)
15 integer, save :: silence=0
17 integer, PARAMETER :: silence=0 ! Per-rank silence requires MPI
20 ! LOGICAL buffered -- if TRUE, messages are buffered via clog_write.
21 ! Once the buffer is full, messages are sent to stdout. This does
22 ! not apply to WRF_MESSAGE2, WRF_ERROR_FATAL, or anything sent to
23 ! write or print. The buffering implementation will not write
24 ! partial lines, and buffer size is specified via namelist (see
25 ! init_module_wrf_error).
26 ! If FALSE, messages are send directly to WRITE.
28 ! This must be enabled at compile time by setting $WRF_LOG_BUFFERING
30 #if defined(WRF_LOG_BUFFERING)
33 integer, PARAMETER :: buffered=0 ! buffering disabled at compile time
36 ! LOGICAL stderrlog -- if TRUE, messages are sent to stderr via
37 ! write(0,...). If FALSE, messages are not sent to stderr.
38 ! This is set to FALSE automatically when buffering is enabled.
40 ! Defaults: Non-MPI configurations turn OFF stderr.
41 ! MPI configurations turn ON stderr.
43 #if defined( DM_PARALLEL ) && ! defined( STUBMPI )
44 integer :: stderrlog=1 ! 1/T = send to write(0,...) if buffered=0
46 integer :: stderrlog=0 ! 1/T = send to write(0,...) if buffered=0
49 INTEGER, PARAMETER :: wrf_log_flush=0, wrf_log_set_buffer_size=1, &
52 !NOTE: Make sure silence, buffered and stderrlog defaults here match
53 ! the namelist defaults in init_module_wrf_error.
55 ! min_allowed_buffer_size: requested buffer sizes smaller than this
56 ! will simply result in disabling of log file buffering. This number
57 ! should be larger than any line WRF prints frequently. If you set it
58 ! too small, the buffering code will still work. However, any line
59 ! that is larger than the buffer may result in two writes: one for
60 ! the message and one for the end-of-line character at the end (if the
61 ! message didn't already have one).
62 integer, parameter :: min_allowed_buffer_size=200
64 !$OMP THREADPRIVATE (wrf_err_message)
67 ! ------------------------------------------------------------------------------
69 LOGICAL FUNCTION wrf_at_debug_level ( level )
71 INTEGER , INTENT(IN) :: level
72 wrf_at_debug_level = ( level .LE. wrf_debug_level )
74 END FUNCTION wrf_at_debug_level
76 ! ------------------------------------------------------------------------------
78 SUBROUTINE init_module_wrf_error(on_io_server)
80 LOGICAL,OPTIONAL,INTENT(IN) :: on_io_server
81 #if defined(DM_PARALLEL)
82 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
84 LOGICAL :: compute_tasks_silent
85 LOGICAL :: io_servers_silent
86 INTEGER :: buffer_size,iostat,stderr_logging
87 namelist /logging/ buffer_size,compute_tasks_silent, &
88 io_servers_silent,stderr_logging
90 ! MAKE SURE THE NAMELIST DEFAULTS MATCH THE DEFAULT VALUES
93 ! Default: original behavior. No buffering, all ranks talk
94 compute_tasks_silent=.false.
95 io_servers_silent=.false.
98 ! MPI configurations default to stderr logging.
99 ! Non-MPI does not log to stderr. (Note that fatal errors always
100 ! are sent to both stdout and stderr regardless of config.)
101 #if defined( DM_PARALLEL ) && ! defined( STUBMPI )
107 ! Open namelist.input using the same unit used by module_io_wrf
108 ! since we know nobody else will use that unit:
109 OPEN(unit=27, file="namelist.input", form="formatted", status="old")
110 READ(27,nml=logging,iostat=iostat)
113 CALL wrf_debug ( 1 , 'Namelist logging not found in namelist.input. ' )
114 CALL wrf_debug ( 1 , ' --> Using registry defaults for variables in logging.' )
116 write(0,*) 'Namelist logging not found in namelist.input. Using registry defaults for variables in logging.'
117 write(6,*) 'Namelist logging not found in namelist.input. Using registry defaults for variables in logging.'
127 #if defined(WRF_LOG_BUFFERING)
128 ! Forbid small buffers. See the comment above for min_allowed_buffer_size:
129 if(buffer_size>=min_allowed_buffer_size) then
130 call wrf_log_action(wrf_log_set_buffer_size,buffer_size,' ')
136 if(buffer_size>=min_allowed_buffer_size) then
137 write(0,500) 'Forcing disabling of buffering due to compile-time configuration.'
138 write(6,500) 'Forcing disabling of buffering due to compile-time configuration.'
142 stderrlog=stderr_logging
143 if(buffered/=0 .and. stderrlog/=0) then
144 write(0,500) 'Disabling stderr logging since buffering is enabled.'
145 write(6,500) 'Disabling stderr logging since buffering is enabled.'
152 #if defined(DM_PARALLEL)
154 if(present(on_io_server)) then
155 if(on_io_server) then
156 if(io_servers_silent) &
161 if(compute_tasks_silent) then
162 if(wrf_dm_on_monitor()) then
169 END SUBROUTINE init_module_wrf_error
171 END MODULE module_wrf_error
173 ! ------------------------------------------------------------------------------
174 ! ------------------------ GLOBAL SCOPE SUBROUTINES --------------------------
175 ! ------------------------------------------------------------------------------
176 #if defined(WRF_LOG_BUFFERING)
177 SUBROUTINE wrf_log_action( act,int,str )
178 ! The underlying clog.c is not thread-safe, so this wrapper subroutine
179 ! ensures that only one thread accesses clog.c at a time.
181 ! NOTE: This routine only exists if WRF_LOG_BUFFERING is defined at
185 integer, intent(in) :: int,act
186 character(*), intent(in) :: str
187 !$OMP CRITICAL(wrf_log_action_critical)
188 if(act==wrf_log_flush) then
190 elseif(act==wrf_log_set_buffer_size) then
191 call clog_set_buffer_len(int)
192 elseif(act==wrf_log_write) then
193 call clog_write(int,str)
195 !$OMP END CRITICAL(wrf_log_action_critical)
196 END SUBROUTINE wrf_log_action
198 ! ------------------------------------------------------------------------------
200 ! wrf_message: ordinary message
201 ! Write to stderr if stderrlog=T to ensure immediate output
202 ! Write to stdout for buffered output.
203 SUBROUTINE wrf_message( str )
207 use module_wrf_error, only: silence, buffered, stderrlog, wrf_log_write
211 if(silence/=0) return
213 #if defined(WRF_LOG_BUFFERING)
214 call wrf_log_action(wrf_log_write,len_trim(str),str)
218 if(stderrlog/=0) then
220 write(0,300) trim(str)
230 CALL ESMF_LogWrite(TRIM(str),ESMF_LOGMSG_INFO)
232 END SUBROUTINE wrf_message
234 ! ------------------------------------------------------------------------------
236 ! Intentionally write to stderr only
237 ! This is set to stderr, even in silent mode, because
238 ! it is used for potentially fatal error or warning messages and
239 ! we want the message to get to the log file before any crash
240 ! or MPI_Abort happens.
241 SUBROUTINE wrf_message2( str )
255 CALL ESMF_LogWrite(TRIM(str),ESMF_LOGMSG_INFO)
257 END SUBROUTINE wrf_message2
259 ! ------------------------------------------------------------------------------
261 SUBROUTINE wrf_error_fatal3( file_str, line, str )
264 ! 5.2.0r USE ESMF_Mod
268 CHARACTER*(*) file_str
269 INTEGER , INTENT (IN) :: line ! only print file and line if line > 0
271 CHARACTER*256 :: line_str
273 write(line_str,'(i6)') line
275 ! Fatal errors are printed to stdout and stderr regardless of
276 ! any &logging namelist settings.
278 CALL wrf_message( '-------------- FATAL CALLED ---------------' )
279 ! only print file and line if line is positive
281 CALL wrf_message( 'FATAL CALLED FROM FILE: '//file_str//' LINE: '//TRIM(line_str) )
283 CALL wrf_message( str )
284 CALL wrf_message( '-------------------------------------------' )
286 force_stderr: if(stderrlog==0) then
287 CALL wrf_message2( '-------------- FATAL CALLED ---------------' )
288 ! only print file and line if line is positive
290 CALL wrf_message2( 'FATAL CALLED FROM FILE: '//file_str//' LINE: '//TRIM(line_str) )
292 CALL wrf_message2( trim(str) )
293 CALL wrf_message2( '-------------------------------------------' )
298 #if defined(WRF_LOG_BUFFERING)
299 if(buffered/=0) call wrf_log_action(wrf_log_flush,1,' ')
304 ! 5.2.0r CALL esmf_finalize(terminationflag=ESMF_ABORT)
305 CALL esmf_finalize(endflag=ESMF_END_ABORT)
312 END SUBROUTINE wrf_error_fatal3
314 ! ------------------------------------------------------------------------------
316 SUBROUTINE wrf_error_fatal( str )
320 CALL wrf_error_fatal3 ( ' ', 0, str )
321 END SUBROUTINE wrf_error_fatal
323 ! ------------------------------------------------------------------------------
325 ! Check to see if expected value == actual value
326 ! If not, print message and exit.
327 SUBROUTINE wrf_check_error( expected, actual, str, file_str, line )
330 INTEGER , INTENT (IN) :: expected
331 INTEGER , INTENT (IN) :: actual
333 CHARACTER*(*) file_str
334 INTEGER , INTENT (IN) :: line
335 CHARACTER (LEN=512) :: rc_str
336 CHARACTER (LEN=512) :: str_with_rc
338 IF ( expected .ne. actual ) THEN
339 WRITE (rc_str,*) ' Routine returned error code = ',actual
340 str_with_rc = TRIM(str // rc_str)
341 CALL wrf_error_fatal3 ( file_str, line, str_with_rc )
343 END SUBROUTINE wrf_check_error
345 ! ------------------------------------------------------------------------------
347 ! Some compilers do not yet support the entirety of the Fortran 2003 standard.
348 ! This is a small patch to pick up the two most common events. Most xlf
349 ! compilers have an extension fflush. That is available here. For other older
350 ! compilers with no flush capability at all, we just stub it out completely.
351 ! These CPP ifdefs are defined in the configure file.
354 SUBROUTINE flush ( iunit )
357 CALL fflush ( iunit )
361 #ifdef NO_FLUSH_SUPPORT
362 SUBROUTINE flush ( iunit )