]> git.donarmstrong.com Git - uiuc_igb_scripts.git/commitdiff
handle running multiple array options in each job to work around low queue limits
authorDon Armstrong <don@donarmstrong.com>
Wed, 5 Aug 2015 19:47:54 +0000 (12:47 -0700)
committerDon Armstrong <don@donarmstrong.com>
Wed, 5 Aug 2015 19:47:54 +0000 (12:47 -0700)
dqsub

diff --git a/dqsub b/dqsub
index 245f11ece72bca05abcc6736ba2c37badbaa5150..f0e515e2ee4cdd4b0d81a87b4a21c54b850a434d 100755 (executable)
--- a/dqsub
+++ b/dqsub
@@ -26,7 +26,7 @@ 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-slot-limit
+   --array-per-job number of array items to handle in each job (default 1)
    --ppn processors per node to use
    --mem memory to request
    --dir Directory to run the script in (default current directory)
@@ -80,6 +80,7 @@ dqsub
 
 use IO::File;
 use Cwd qw(getcwd abs_path);
+use POSIX qw(ceil);
 use vars qw($DEBUG);
 
 my %options = (nodes           => 1,
@@ -89,6 +90,7 @@ my %options = (nodes           => 1,
                help            => 0,
                man             => 0,
                interactive     => 0,
+               array_per_job   => 1,
               );
 
 GetOptions(\%options,
@@ -97,6 +99,7 @@ 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',
            'ppn|processors-per-node=i',
            'mem|memory=s',
@@ -137,7 +140,7 @@ 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;
+        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};
         }
@@ -207,21 +210,49 @@ sub write_qsub_script {
 # this script was written by dqsub
 EOF
     if (defined $opt->{array}) {
+        my @subshell = ('','');
         my $array_opt = join("\n",@{$array});
-        $script .= <<EOF;
+        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 * $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 p"<<'_HERE_DOC_END_'
+EOF
+        }
+        $script .= <<EOF;
 $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 {