Ignore:
Timestamp:
Feb 18, 2016, 4:13:14 PM (9 years ago)
Author:
ldelgass
Message:

Merge UQ and fixes from 1.4 branch

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/lang/tcl/scripts/task.tcl

    r4970 r6021  
    1 # -*- mode: tcl; indent-tabs-mode: nil -*- 
     1# -*- mode: tcl; indent-tabs-mode: nil -*-
    22# ----------------------------------------------------------------------
    33#  COMPONENT: task - represents the executable part of a tool
     
    2929
    3030    public method run {args}
     31    public method get_uq {args}
    3132    public method abort {}
    3233    public method reset {}
     
    3738    protected method _output {data}
    3839    protected method _log {args}
     40    protected method _build_submit_cmd {cmd tfile params_file}
     41    protected method _get_params {varlist uq_type uq_args}
    3942
    4043    private variable _xmlobj ""      ;# XML object with inputs/outputs
     
    114117    }
    115118    return ""
     119}
     120
     121itcl::body Rappture::Task::get_uq {args} {
     122    foreach {path val} $args {
     123        if {$path == "-uq_type"} {
     124            set uq_type $val
     125        } elseif {$path == "-uq_args"} {
     126            set uq_args $val
     127        }
     128    }
     129    #set varlist [$_xmlobj uq_get_vars]
     130    foreach {varlist num} [$_xmlobj uq_get_vars] break
     131    return [Rappture::UQ ::#auto $varlist $num $uq_type $uq_args]
    116132}
    117133
     
    156172    # if there are any args, use them to override parameters
    157173    set _outputcb ""
     174    set uq_type ""
    158175    foreach {path val} $args {
    159176        if {$path == "-output"} {
    160177            set _outputcb $val
     178        } elseif {$path == "-uq_type"} {
     179            set uq_type $val
     180        } elseif {$path == "-uq_args"} {
     181            set uq_args $val
    161182        } else {
    162183            $_xmlobj put $path.current $val
     
    165186
    166187    foreach item {control output error} { set job($item) "" }
    167 
    168     # write out the driver.xml file for the tool
    169     set file "driver[pid].xml"
    170     set status [catch {
    171         set fid [open $file w]
    172         puts $fid "<?xml version=\"1.0\"?>"
    173         puts $fid [$_xmlobj xml]
    174         close $fid
    175     } result]
    176188
    177189    # Set limits for cpu time
     
    187199            set limit 10;               # lower bound is 10 seconds.
    188200        }
    189     }
    190     Rappture::rlimit set cputime $limit 
     201    }
     202    Rappture::rlimit set cputime $limit
     203
     204    # write out the driver.xml file for the tool
     205    set file "driver[pid].xml"
     206    set status [catch {
     207        set fid [open $file w]
     208        puts $fid "<?xml version=\"1.0\"?>"
     209        puts $fid [$_xmlobj xml]
     210        close $fid
     211    } result]
     212
     213    if {$uq_type != ""} {
     214        # Copy xml into a new file
     215        set tfile "template[pid].xml"
     216        set fid [open $tfile w]
     217        puts $fid "<?xml version=\"1.0\"?>"
     218        puts $fid [$_xmlobj xml]
     219        close $fid
     220
     221        # Return a list of the UQ variables and their PDFs.
     222        # Also turns $tfile into a template file.
     223        set uq_varlist [lindex [$_xmlobj uq_get_vars $tfile] 0]
     224    }
     225
     226
    191227    # execute the tool using the path from the tool description
    192228    if {$status == 0} {
    193229        set cmd [$_xmlobj get tool.command]
    194230        regsub -all @tool $cmd $_installdir cmd
    195         regsub -all @driver $cmd $file cmd
    196         regsub -all {\\} $cmd {\\\\} cmd
    197231        set cmd [string trimleft $cmd " "]
    198         if { $cmd == "" } {
    199             puts stderr "cmd is empty"
    200             return [list 1 "Command is empty.\n\nThere is no command specified by\n\n <command>\n </command>\n\nin the tool.xml file."]
    201         }
    202 
    203         switch -glob -- [resources -jobprotocol] {
    204             "submit*" {
    205                 # if job_protocol is "submit", then use use submit command
    206                 set cmd "submit --local $cmd"
    207             }
    208             "mx" {
    209                 # metachory submission
    210                 set cmd "mx $cmd"
    211             }
    212             "exec" {
    213                 # default -- nothing special
    214             }
    215         }
    216         $_xmlobj put tool.execute $cmd
     232
     233        if { $cmd == "" } {
     234            puts stderr "cmd is empty"
     235            return [list 1 "Command is empty.\n\nThere is no command specified by\n\n <command>\n </command>\n\nin the tool.xml file."]
     236        }
     237
     238        if {$uq_type == ""} {
     239            regsub -all @driver $cmd $file cmd
     240
     241            switch -glob -- [resources -jobprotocol] {
     242                "submit*" {
     243                    # if job_protocol is "submit", then use use submit command
     244                    set cmd "submit --local $cmd"
     245                }
     246                "mx" {
     247                    # metachory submission
     248                    set cmd "mx $cmd"
     249                }
     250                "exec" {
     251                    # default -- nothing special
     252                }
     253            }
     254        } else {
     255            set params_file [_get_params $uq_varlist $uq_type $uq_args]
     256            set cmd [_build_submit_cmd $cmd $tfile $params_file]
     257            file delete -force puq
     258        }
     259
     260        $_xmlobj put tool.execute $cmd
    217261
    218262        # starting job...
     
    223267        if {0 == [string compare -nocase -length 5 $cmd "ECHO "] } {
    224268            set status 0;
    225             set job(output) [string range $cmd 5 end] 
     269            set job(output) [string range $cmd 5 end]
    226270        } else {
    227271            set status [catch {
    228                 set ::Rappture::Task::job(control) ""
    229                 eval blt::bgexec \
    230                     ::Rappture::Task::job(control) \
    231                     -keepnewline yes \
    232                     -killsignal SIGTERM \
    233                     -onoutput [list [itcl::code $this _output]] \
    234                     -output ::Rappture::Task::job(output) \
    235                     -error ::Rappture::Task::job(error) \
    236                     $cmd
    237             } result]
     272                set ::Rappture::Task::job(control) ""
     273                eval blt::bgexec \
     274                ::Rappture::Task::job(control) \
     275                -keepnewline yes \
     276                -killsignal SIGTERM \
     277                -onoutput [list [itcl::code $this _output]] \
     278                -output ::Rappture::Task::job(output) \
     279                -error ::Rappture::Task::job(error) \
     280                $cmd
     281            } result]
    238282
    239283            if { $status != 0 } {
    240                 # We're here because the exec-ed program failed
    241                 set logmesg $result
    242                 if { $::Rappture::Task::job(control) ne "" } {
    243                     foreach { token pid code mesg } \
    244                         $::Rappture::Task::job(control) break
    245                     if { $token == "EXITED" } {
    246                         # This means that the program exited normally but
    247                         # returned a non-zero exitcode.  Consider this an
    248                         # invalid result from the program.  Append the stderr
    249                         # from the program to the message.
    250                         set logmesg "Program finished: exit code is $code"
    251                         set result "$logmesg\n\n$::Rappture::Task::job(error)"
    252                     } elseif { $token == "abort" }  {
    253                         # The user pressed the abort button.
     284                # We're here because the exec-ed program failed
     285                set logmesg $result
     286                if { $::Rappture::Task::job(control) ne "" } {
     287                    foreach { token pid code mesg } \
     288                    $::Rappture::Task::job(control) break
     289                    if { $token == "EXITED" } {
     290                       # This means that the program exited normally but
     291                       # returned a non-zero exitcode.  Consider this an
     292                       # invalid result from the program.  Append the stderr
     293                       # from the program to the message.
     294                       set logmesg "Program finished: exit code is $code"
     295                       set result "$logmesg\n\n$::Rappture::Task::job(error)"
     296                    } elseif { $token == "abort" }  {
     297                        # The user pressed the abort button.
    254298                        set logmesg "Program terminated by user."
    255                         set result "$logmesg\n\n$::Rappture::Task::job(output)"
    256                     } else {
    257                         # Abnormal termination
    258                         set logmesg "Abnormal program termination: $mesg"
    259                         set result "$logmesg\n\n$::Rappture::Task::job(output)"
    260                     }
    261                 }
     299                        set result "$logmesg\n\n$::Rappture::Task::job(output)"
     300                    } else {
     301                        # Abnormal termination
     302                        set logmesg "Abnormal program termination: $mesg"
     303                        set result "$logmesg\n\n$::Rappture::Task::job(output)"
     304                    }
     305                }
    262306                _log run failed [list $logmesg]
    263                 return [list $status $result]
     307                return [list $status $result]
    264308            }
    265309        }
     
    279323            if {[string length $jobstats] > 0} {
    280324                uplevel #0 $jobstats [list job [incr jobnum] \
    281                     event $simulation start $times(start) \
    282                     walltime $times(walltime) cputime $times(cputime) \
    283                     status $status]
     325                event $simulation start $times(start) \
     326                walltime $times(walltime) cputime $times(cputime) \
     327                status $status]
    284328            }
    285329
     
    340384    }
    341385    if {$status == 0} {
    342         file delete -force -- $file
     386        # file delete -force -- $file
    343387    }
    344388
     
    353397    # a reference to the run.xml file containing results.
    354398    #
     399
    355400    if {$status == 0} {
    356401        set result [string trim $job(output)]
     402
     403        if {$uq_type != ""} {
     404            # UQ. Collect data from all jobs and put it in one xml run file.
     405            file delete -force -- run_uq.xml
     406            if {[catch {exec puq_analyze.py puq_[pid].hdf5} res]} {
     407                set fp [open "uq_debug.err" r]
     408                set rdata [read $fp]
     409                close $fp
     410                puts "PUQ analysis failed: $res\n$rdata"
     411                error "UQ analysis failed: $res\n$rdata"
     412            } else {
     413                append result "\n" $res
     414            }
     415        }
    357416        if {[regexp {=RAPPTURE-RUN=>([^\n]+)} $result match file]} {
    358417            set _lastrun $file
     
    389448
    390449    return [list $status $result]
     450}
     451
     452# ----------------------------------------------------------------------
     453#  Turn the command string from tool.xml into the proper syntax to use
     454#  with a submit parameter sweep with a temlate file.  Proper quoting
     455# of the template file is necessary to prevent submit from being too smart
     456# and converting it to a full pathname.
     457# ----------------------------------------------------------------------
     458itcl::body Rappture::Task::_build_submit_cmd {cmd tfile params_file} {
     459    set quote_next 0
     460    set newcmd "submit --progress submit --runName=puq -l -i @:$tfile -d $params_file"
     461    set cmds [split $cmd " "]
     462    for {set i 0} {$i < [llength $cmds]} {incr i} {
     463        set arg [lindex $cmds $i]
     464        if {$quote_next == 1} {
     465            set nc [string range $arg 0 0]
     466            if {$nc != "\""} {
     467                set arg "\"\\\"$arg\\\"\""
     468            }
     469        }
     470        if {$arg == "--eval"} {
     471            set quote_next 1
     472        } else {
     473            set quote_next 0
     474        }
     475        if {$arg == "@driver"} {
     476            set arg "\"\\\"$tfile\\\"\""
     477        }
     478        append newcmd " " $arg
     479    }
     480    regsub -all @driver $newcmd $tfile newcmd
     481    return $newcmd
    391482}
    392483
     
    550641    puts stderr $line
    551642}
     643
     644
     645#
     646# Send the list of parameters to a python program so it can call PUQ
     647# and get a CSV file containing the parameter values to use for the runs.
     648itcl::body Rappture::Task::_get_params {varlist uq_type uq_args} {
     649    set pid [pid]
     650    # puts "get_params.py $pid $varlist $uq_type $uq_args"
     651    if {[catch {exec get_params.py $pid $varlist $uq_type $uq_args}]} {
     652        set fp [open "uq_debug.err" r]
     653        set rdata [read $fp]
     654        close $fp
     655        puts "get_params.py failed: $rdata"
     656        error "get_params.py: $rdata"
     657    }
     658    return params[pid].csv
     659}
Note: See TracChangeset for help on using the changeset viewer.