#!/usr/bin/perl use Getopt::Long; # # Given an executable, and 1 or more namelist read input files, submit multiple # runs under either LSF (e.g., bluevista or lightning), or LL (e.g., bluesky). # $progname = $0; # my $wallclock = "00:30"; # 30-minute default wall clock limit my $nosubmit = 0; # default is to submit the jobs my $nnodes = 1; # default number of nodes (LL only) my $ntasks = 4; # default total number of MPI tasks my $interactive = 0; # default is to submit to batch system &GetOptions( "x|exec=s" => \$exec, "bn|basename=s" => \$basename, "wc|wallclock=s" => \$wallclock, "q|queue=s" => \$queue, "nn|nnodes=i" => \$nnodes, "nt|ntasks=i" => \$ntasks, "ns|nosubmit" => \$nosubmit, "I|interactive" => \$interactive, "h|help" => \$help, ) or usage(); if ($help) { usage(); } # provide usage if help was requested # # Must provide an executable: # if (! $exec) { print "\n>>> $progname: Please provide an executable file.\n"; print "(Use the command \"$progname -h\" for a usage message)\n\n"; exit; } else { $exec = glob($exec); } if (! -x $exec) { print "\n>>> $progname: Executable $exec must have execution permission.\n"; print "(Use the command \"$progname -h\" for a usage message)\n\n"; exit; } # # Remaining args are input files (must provide at least one): # if (! @ARGV) { print "\n>>> $progname: Please provide at least one namelist input file.\n"; print "(Use the command \"$progname -h\" for a usage message)\n\n"; exit; } # # Save input file names in @infiles: # while (@ARGV) { push @infiles, shift @ARGV; } # while @ARGV # # Get nodename (may be needed to set #BSUB -a): # $nodename = `uname -n`; chop $nodename; # # Determine batch system type and set submit command accordingly: # $LoadShare = $ENV{"LSF_ENVDIR"}; if ($LoadShare) { # LSF system $batchsys = "LSF"; $submitcommand = "bsub < "; if (! $basename) { $basename = "LSF"; } if (! $queue) { $queue = "regular"; } print " Batch system: Load Sharing Facility ($batchsys)\n"; if ($interactive) { print "\n>>> Can execute interactively only under LoadLeveler.\n\n"; exit; } } elsif (-d "/usr/lpp/LoadL") { # LoadLeveler system $batchsys = "LL"; $submitcommand = "llsubmit "; if (! $basename) { $basename = "LL"; } if (! $queue) { $queue = "com_rg8"; } print " Batch system: LoadLeveler ($batchsys)\n"; } else { # unknown batch system print "\n>>> $progname: cannot determine batch system:\n"; print "I can submit to either Load Sharing Facility (LSF), or LoadLeveler (LL):\n"; print " Is not Load Share Facility (LSF), because env var LSF_ENVDIR does not exist.\n"; print " Is not LoadLeveler because directory /usr/lpp/LoadL does not exist.\n\n"; exit; } # # Report to stdout before input file loop: # print "\n$progname:\n"; print " Exec file: $exec\n"; print " Input files: @infiles\n"; print " Submit command: \"$submitcommand\"\n"; print " Base name: \"$basename\"\n"; print " Wallclock: \"$wallclock\"\n"; print " Queue: \"$queue\"\n"; print " Nnodes: \"$nnodes\"\n"; print " Ntasks: \"$ntasks\"\n"; print " Nosubmit: $nosubmit\n"; print " Interactive: $interactive\n"; # # Loop through input files: # $i = 1; print "\n"; foreach $infile (@infiles) { # # Make batch job script: # $job_csh = mkjob($batchsys,$exec,$infile,$queue,$wallclock,$nnodes,$ntasks, $interactive,$i); print"Input file $i: $infile Job script: $job_csh\n"; # # Submit current job (unless nosubmit is set): # if (! $nosubmit) { # # Submit to batch system: if (! $interactive) { $command = "$submitcommand $job_csh"; $stat = system($command); if ($stat) { die ">>> Error executing \"$command\"\n"; } # # Execute interactively (under LL system only, e.g., bluesky): } else { my $outfile = "${basename}_$i.out"; # stdout of model run print "Submitting $job_csh interacively in background...\n"; $stat = system("$job_csh &"); if ($stat) { die ">>> Error executing $job_csh\n"; } } } # # Increment job counter: # $i++; } # foreach $infile exit; # #------------------------------------------------------------------------- sub mkjob { # # Build job script for current job: # my ($batchsys,$exec,$infile,$queue,$wallclock,$nnodes,$ntasks,$ia,$ijob) = @_; # my $jobscript = "${basename}_$ijob.job"; # job script returned by this function my $outfile = "${basename}_$ijob.out"; # stdout of model run my $jobname = "${basename}_$ijob"; # step or job name passed to batch sys # open (JOBSCRIPT,"> $jobscript") || die "make_default cannot open file $file"; # # - - - - - - - - - - - - Build LoadLeveler job script - - - - - - - - - - if ($batchsys eq "LL") { # Load Leveler print JOBSCRIPT <&! $outfile || \\ echo ">>> Execution of $exec FAILED at `date`" && echo "See output in $outfile" EOF # - - - - - - - - - - - - - - Build LSF job script - - - - - - - - - - - - } elsif ($batchsys eq "LSF") { $bsub_a = "poe"; if ($nodename =~ "ln*") { $bsub_a = "mpich_gm"; } # lightning print JOBSCRIPT <&! $outfile || \\ echo ">>> Execution (mpirun.lsf) of $exec FAILED at `date`" && echo "See output in $outfile" EOF1 # - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - } else { print "\n>>> mkjob: unknown batch system: $batchsys\n\n"; exit; } # # Return executable csh script: # chmod 0755, $jobscript; return $jobscript; } #------------------------------------------------------------------------- # sub usage { die <