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

RETURN VALUE

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
}