package Submit; ############################################################################### # IRIX LSF 5.1 # # based on a prototype version for IRIX LSF 4.2 # ############################################################################### require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(submit); use File::Path qw(mkpath); use POSIX qw(ceil); use Reporting qw(debug_report failed_report ok_report start_report command_report report_and_die); use strict; # Submit the script to the BSS # arg 1 = The script (this is called because the script contains the string "#TSI_SUBMIT"); # # Returns void to TSI # on success returns the BSS identifier assigned to the job # on fail return a message # BEGIN { # -------------------------------------------------------------------- # Create a file name to which scripts are written for the submits to # the batch sub-system. This needs to be unique as there may be # more than one TSI running, so base on the process id. $Submit::tsi_unique_file_name = "TSI_temp_file_$$"; # Always cd to some neutral place when not doing something $Submit::neutral_dir = $ENV{PWD}; if($Submit::neutral_dir =~ m/(.*)/s) { $Submit::neutral_dir = $1; } } sub submit { my $from_njs = shift; # Correction for $HOME or $USER in root directories SvdB 11 Feb 2002 # Substitute for these values as the executed script's # environment will not (and if it did the values will # be wrong). This is safe as thes script seen here is # completely generated by the NJS and so we will not be # messing with any user created code. $from_njs =~ s/\$USER/$ENV{USER}/g; $from_njs =~ s/\$HOME/$ENV{HOME}/g; # Get the information from the NJS (embedded as comments) # # Not picking up defnitions of Software Resources sent as: # #TSI_SWR # First clear all command line sections from previous iterations my $jobname = ""; my $outcome_dir = ""; my $uspace_dir = ""; my $time = ""; my $memory = ""; my $nodes = ""; my $processors = ""; my $fast_fs = ""; my $large_fs = ""; my $home_fast_fs = ""; my $home_large_fs = ""; my $queue = ""; my $email = ""; my $interactive = ""; $_ = $from_njs; while(/#TSI_(\S+) (.*)\n/g) { $jobname = $2 if $1 eq "JOBNAME"; $outcome_dir = $2 if $1 eq "OUTCOME_DIR"; #$uspace_dir = $2 if $1 eq "USPACE_DIR"; $uspace_dir = $2 if $1 eq "OUTCOME_DIR"; $time = $2 if $1 eq "TIME"; $memory = $2 if $1 eq "MEMORY"; $nodes = $2 if $1 eq "NODES"; $processors = $2 if $1 eq "PROCESSORS"; $fast_fs = $2 if $1 eq "FASTFS"; $large_fs = $2 if $1 eq "LARGEFS"; $home_fast_fs = $2 if $1 eq "HOMEFASTFS"; $home_large_fs = $2 if $1 eq "HOMELARGEFS"; $queue = $2 if $1 eq "QUEUE"; $email = $2 if $1 eq "EMAIL"; $interactive = $2 if $1 eq "PREFER_INTERACTIVE"; } if($interactive eq "true") { start_report("Interactively executing a job"); } else { start_report("Submitting a job to the BSS"); } # Jobname (source man page) if($jobname eq "NONE" ) { $jobname = "-J $main::default_job_name"; } else { $jobname = "-J $jobname"; } # Queue (source man page) # # The IDB will send the queue name of NONE if it is # set up with a single queue whose name is "noname" if($queue eq "NONE" ) { $queue = "-q small_10m"; } else { $queue = "-q $queue"; } # Job memory requirements in kilobytes, this can be # either for the whole job, for each processor or # for each node depending on how the IDB is set up # (see PER_xxxx_LIMITS) $memory = $memory*1000; if($main::is_pvp) { $memory = "-M $memory"; } else { $memory = "-M $memory"; } $memory = ""; # $time = Job time requirement. Wallclock time in seconds. # Nodes count, NONE implies serial, otherwise a valid number # # $nodes is number of nodes required # # $processors (processors per node) is 1 if the system # is not an SMP # # Syntax of time limits change depending on if executed on application or # command processors. # Calculate minutes from seconds my $minutes = $time / 60.0; if($nodes eq "NONE" || $main::is_pvp) { # PVP or Single processor job, nothing parallel requested, run on command procs $nodes = ""; } else { # Some sort of parallel resource asked for (including single proc jobs) # so run on application procs. $nodes = $nodes*$processors; # Distribute required CPU time over cpus $minutes = $minutes / $nodes; $nodes = "-n $nodes,$nodes" ; # Note that this makes no allowance for # the time spent on the command processor, it may be necessary to add # a field for this e.g. -Txxxx where xxxxx is large enough to prevent # jobs being killed for exceeding this limit. } # Round minutes to next upper integer $minutes = ceil($minutes); $time = "-c $minutes"; # Email source: HS if($email eq "NONE") { $email = ""; } else { $email = "-B -N -u $email " ; } # Tell the BSS to put the batch job's stdout and stderr # into these files my $stdout_loc = "-o $outcome_dir/stdout "; my $stderr_loc = "-e $outcome_dir/stderr "; # cd to the Uspace directory, will write a file soon and # this means that there does not need to be a TSI working # directory if(chdir($uspace_dir) == 0) { failed_report("Could not cd to Uspace $uspace_dir because $!"); return 0; } # Make sure that the Outcome directory is there for the stdout and stderr files mkpath $outcome_dir, 0, 0700 unless -e $outcome_dir; chmod 0700, $outcome_dir; # Ignoring all other fields open(EMSCRIPT,">$Submit::tsi_unique_file_name"); print EMSCRIPT $from_njs; close(EMSCRIPT); if ($interactive eq "true"){ my $command = "$Submit::tsi_unique_file_name"; chmod 0700, $command; command_report($command); `./$command > $outcome_dir/stdout 2> $outcome_dir/stderr`; ok_report(); } else { #my $command = "$main::submit_cmd $queue $nodes $email $memory $time $jobname -R linux $stdout_loc $stderr_loc < $uspace_dir/$Submit::tsi_unique_file_name"; my $command = "$main::submit_cmd $queue -n 4,10 $email $memory $time $jobname -R linux $stdout_loc $stderr_loc < $uspace_dir/$Submit::tsi_unique_file_name"; command_report($command); chmod 0700, $Submit::tsi_unique_file_name; # and execute the command my $output = `($command) 2>&1`; # Parse output if($? != 0) { failed_report($output); } else { # Succeeded, return Job Identifier # looking for line "Job " submitted successfully (want the xxxx) # note: ? => minimal match in case other "." in string if($output =~ /Job *<(\d+)>/) { my $jobid = $1; # bsub does not report a failure code so we need to # check here that we got an integer. If we did assume # OK, otherwise report a failure my $res = $jobid; $res =~ s/[0-9]//g; if (length($res) == 0 ) { debug_report("Job submitted OK. Identifier: $jobid"); print main::CMD_SOCK "$jobid\n"; } else { failed_report("Job submit failed?: $jobid $output"); } } else { failed_report("Request id not found in: $output"); } } } # Do not delete the script file which was submitted into the BSS, # some BSS do not create an internal copy and read from it later on. # The script is deleted by the clean-up of the Uspace anyway. unlink $Submit::tsi_unique_file_name; chdir $Submit::neutral_dir; } # # Copyright (c) Fujitsu Ltd 2000 - 2004 # # Use and distribution is subject a License. # A copy was supplied with the distribution (see documentation or the jar file). # # This product includes software developed by Fujitsu Limited (http://www.fujitsu.com).