TABLE OF CONTENTS
::pwtk::checkForError
SYNOPSIS
proc ::pwtk::checkForError {outputFile prog {_stopOnError 0} {_silent 0}} {
PURPOSE
Check for error in the pw.x, ph.x, ... output file, and depending on the error type and value of _stopOnError the aplication may exit.
The "exit" statement will be executed only if (i) _stopOnError > 0 or (ii) (_stopOnError < 0 and error type is "runtime error" or "hard error")
The presence of error is checked as follows: We check for one of the error strings, however the output might be appended from the previous run, so we check for error string after the last "Program PWSCF" string !!!
ARGUMENTS
- outputFile -- name of output file
- prog -- name of executable (i.e., name of QE program: pw.x, ph.x, ...)
- _stopOnError -- if _stopOnError > 0, the application will exit upon error detection; if _stopOnError < 0, the application will exit only upon detection of "runtime error" or "hard error"
- _silent -- if true, do not print error message
RETURN VALUE
- 1 -- if error is found
- 0 otherwise
SOURCE
variable error fileMustExist $outputFile "output file" set fid [open $outputFile r] # this is list of error stings + types set errorPatternAndType { {*convergence NOT achieved after*} {convergence failure} {*scf convergence NOT achieved*} {convergence failure} {*No convergence has been achieved*} {convergence failure} {*reached the maximum number of steps*} {convergence failure} {*Signal Received, stopping ...*} {interrupt signal received} {*Maximum CPU time exceeded*} {maximum cpu time exceeded} {*Program stopped by user request*} {soft exit} {*Fortran runtime error*} {runtime error} {*Per user-direction, the job has been aborted.*} {MPI error} {*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*} {hard error} } # this is equivalent to: setErrorInfo_ {} {} -1 set error(type) "" set error(line) "" set error(line_number) -1 # MPI errors are handled a bit differently set mpi_error 0 set mpi_line {} set mpi_line_number -1 set ind 1 set marker 0 while { ! [eof $fid] } { # gets $fid line if { [regexp -- {^ Program} $line] && [regexp -- {starts} $line] } { set marker $ind } else { foreach {pattern type} $errorPatternAndType { if { [string match $pattern $line] } { if { $type == "hard error" } { # special handling of hard error: check that # the next line contains "Error" string gets $fid line2 if { [string match {* Error in*} $line2] } { gets $fid line3 setErrorInfo_ "hard error" $line\n$line2\n$line3 $ind } } elseif { $type == "MPI error" } { # N.B. MPI error is reported only if other error is not detected set mpi_error 1 set mpi_line $line set mpi_line_number $ind } else { setErrorInfo_ $type $line $ind } } } } incr ind } close $fid if { $mpi_line_number > $marker && !($error(line_number) > $marker) } { # only MPI error was detected setErrorInfo_ "MPI error" $mpi_line $mpi_line_number } if { $error(line_number) > $marker } { if { $_stopOnError < 0 } { if { $error(type) == "runtime error" || $error(type) == "hard error" } { set _stopOnError 1 } else { set _stopOnError 0 } } set msg "An error occurred during the $prog run !!! For details see the output file: [file join [pwd] $outputFile] Error INFO: error detected on line number: $error(line_number) error type : $error(type) error string: $error(line)" if { ! $_silent } { # print the error message ::pwtk::error $msg $_stopOnError } return 1 } else { # BEWARE: "error" variable may be used from other procs to # further query the status of error, hence clear the error # variable, because the run was OK. setErrorInfo_ {} {} -1 } return 0 }