X-Git-Url: https://git.donarmstrong.com/?p=uiuc_igb_scripts.git;a=blobdiff_plain;f=dqsub;h=27b8b39c5b43e97a0da442b65e241fd9aa247438;hp=e0b9744405f90e3495aacfee6bd55062b4b49a98;hb=e6e19e0274ff4ce9fe45ae9debfd5eebd40a5d69;hpb=846133dbbe4ef3aa625c07c9df9ddc453f12069c diff --git a/dqsub b/dqsub old mode 100644 new mode 100755 index e0b9744..27b8b39 --- a/dqsub +++ b/dqsub @@ -10,7 +10,7 @@ use warnings; use strict; use Getopt::Long; -use Pod::Usage; +# use Pod::Usage; =head1 NAME @@ -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,13 +102,21 @@ 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', + 'time|walltime=s','cputime|cput=s','host=s', + 'pmem|process_mem|process-mem=s', + 'pvmem|process_virtual_mem|process-virtiual-mem=s', + 'max_file|max-file|file=s', 'dir=s', + 'name=s', 'debug|d+','help|h|?','man|m'); -pod2usage() if $options{help}; -pod2usage({verbose=>2}) if $options{man}; +# pod2usage() if $options{help}; +# pod2usage({verbose=>2}) if $options{man}; $DEBUG = $options{debug}; @@ -121,10 +135,11 @@ if ($options{interactive} and @ARGV) { push @USAGE_ERRORS,"Don't provide commands when you're asking for an interactive shell"; } -pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS; +# pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS; +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; @@ -134,13 +149,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}; @@ -156,10 +178,30 @@ sub generate_qsub_options{ if (defined $options->{ppn}) { $l[$#l] .= ':ppn='.$options->{ppn}; } - if ($options->{mem}) { - push @l,'mem=',$options->{mem}; + my %l_options = + (mem => 'vmem', + time => 'walltime', + cputime => 'cput', + host => 'host', + pmem => 'pmem', + pvmem => 'pvmem', + max_file => 'file', + ); + for my $k (keys %l_options) { + if ($options->{$k}) { + push @l,$l_options{$k}.'='.$options{$k}; + } } push @qo,'-l',join(',',@l) if @l; + 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; } sub read_array_options{ @@ -197,7 +239,51 @@ sub write_qsub_script { # this script was written by dqsub EOF if (defined $opt->{array}) { - die "--array is currently not implemented"; + 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 .= <{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 .= <{array} eq 'chdir') { + $script .= <{array_per_job} > 1) { + $script .= <