]> git.donarmstrong.com Git - uiuc_igb_scripts.git/blobdiff - dqsub
automatically specify a job name (no more STDIN)
[uiuc_igb_scripts.git] / dqsub
diff --git a/dqsub b/dqsub
index 8d12b21fc6f4f9a6ec256c2e53f42aff47ff70a8..89578d0dd003f0a89c25f836bc9e0e4d29b9b1a3 100755 (executable)
--- a/dqsub
+++ b/dqsub
@@ -26,9 +26,12 @@ dqsub [options]
    --nodes nodes to use
    --array array mode (one of 'chdir' or 'xargs' or '')
    --array-from file to read arrays from (default STDIN)
+   --array-per-job number of array items to handle in each job (default 1)
+   --array-all-in-one-job Run all of the array items in one job
    --ppn processors per node to use
    --mem memory to request
    --dir Directory to run the script in (default current directory)
+   --name, -N Name of the job
    --debug, -d debugging level (Default 0)
    --help, -h display this help
    --man, -m display manual
@@ -79,6 +82,8 @@ dqsub
 
 use IO::File;
 use Cwd qw(getcwd abs_path);
+use POSIX qw(ceil);
+use List::Util qw(min);
 use vars qw($DEBUG);
 
 my %options = (nodes           => 1,
@@ -88,6 +93,7 @@ my %options = (nodes           => 1,
                help            => 0,
                man             => 0,
                interactive     => 0,
+               array_per_job   => 1,
               );
 
 GetOptions(\%options,
@@ -96,9 +102,13 @@ GetOptions(\%options,
            'nodes=i',
            'array=s',
            'array_from|array-from=s',
+           'array_per_job|array-per-job=i',
+           'array_slot_limit|array-slot-limit=i',
+           'array_all_in_one_job|array-all-in-one-job!',
            'ppn|processors-per-node=i',
            'mem|memory=s',
            'dir=s',
+           'name=s',
            'debug|d+','help|h|?','man|m');
 
 # pod2usage() if $options{help};
@@ -125,7 +135,7 @@ if ($options{interactive} and @ARGV) {
 print STDERR join("\n",@USAGE_ERRORS) and exit 1 if @USAGE_ERRORS;
 
 # OK. Generate the options to qsub which we'll be using
-my @qsub_options = generate_qsub_options(\%options);
+my @qsub_options = generate_qsub_options(\%options,\@ARGV);
 
 if ($options{interactive}) {
     print STDERR 'running: qsub '.join(' ',@qsub_options) if $DEBUG;
@@ -135,13 +145,20 @@ if ($options{interactive}) {
     if ($options{array}) {
         @array = read_array_options(\%options) if $options{array};
         # the -t option gives the range of elements for an array job
-        push @qsub_options,'-t','1-'. scalar @array;
+        if ($options{array_all_in_one_job}) {
+            $options{array_per_job} = scalar @array;
+        } else {
+            push @qsub_options,'-t','1-'. ceil(scalar @array / $options{array_per_job});
+            if ($options{array_slot_limit}) {
+                $qsub_options[$#qsub_options] .= '%'.$options{array_slot_limit};
+            }
+        }
     }
     call_qsub(\@qsub_options,write_qsub_script(\%options,\@ARGV,\@array));
 }
 
 sub generate_qsub_options{
-    my ($options) = @_;
+    my ($options,$args) = @_;
     my @qo;
     if (defined $options->{queue} and length $options->{queue}) {
         push @qo,'-q',$options->{queue};
@@ -164,6 +181,11 @@ sub generate_qsub_options{
     if ($options->{interactive}) {
         push @qo,'-I';
     }
+    if ($options->{name}) {
+        push @qo,'-N',$options->{name};
+    } else {
+        push @qo,'-N',join('_',@{$args}[0..min($#{$args},2)]);
+    }
     return @qo;
 }
 
@@ -202,21 +224,49 @@ sub write_qsub_script {
 # this script was written by dqsub
 EOF
     if (defined $opt->{array}) {
+        my @subshell = ('','');
         my $array_opt = join("\n",@{$array});
+        my $max_array = scalar @{$array};
+        my $apjm1 = $opt->{array_per_job} - 1;
+        if ($opt->{array_per_job} > 1) {
+            # we will use subshells if there are more than one array
+            # items per job
+            @subshell = ('(',')');
+            $script .= <<EOF;
+for i in \$(seq 1 $opt->{array_per_job}); do
+# in some cases, the jobs aren't going to come out evenly. Handle that.
+JOBNUM=\$(( \${PBS_ARRAYID:=1} * $opt->{array_per_job} + \$i - $opt->{array_per_job} ))
+if [ \$JOBNUM -le $max_array ]; then 
+OPT=\$(sed -n -e "\$JOBNUM p"<<'_HERE_DOC_END_'
+EOF
+        } else {
+            $script .= <<EOF;
+OPT=\$(sed -n -e "\${PBS_ARRAYID:=1} p"<<'_HERE_DOC_END_'
+EOF
+        }
         $script .= <<EOF;
-OPT=\$(sed -n -e "\$PBS_ARRAYID p"<<'_HERE_DOC_END_'
 $array_opt
 _HERE_DOC_END_
 )
 EOF
         if ($opt->{array} eq 'chdir') {
             $script .= <<EOF;
+$subshell[0]
 cd "\$OPT";
-exec $command;
+exec ${command};
+$subshell[1]
 EOF
         } else {
             $script .= <<EOF;
-exec $command "\$OPT";
+$subshell[0]
+exec ${command} "\$OPT";
+$subshell[1]
+EOF
+        }
+        if ($opt->{array_per_job} > 1) {
+            $script .= <<EOF
+fi;
+done;
 EOF
         }
     } else {