|
3 | 3 | ## given a file of commands (one command per line), runs them in |
4 | 4 | ## parallel on cheyenne using commandfile MPMD approach |
5 | 5 |
|
6 | | -set tmp = `mktemp -d` |
7 | | -set cmd = $tmp/cmdfile |
8 | | -set out = $tmp/out |
9 | | -set err = $tmp/err |
10 | | -set pbs = $tmp/pbs |
11 | | -set job = `basename $1` |
| 6 | +set help = no |
| 7 | +set submit = yes |
| 8 | +set QUEUE = premium |
| 9 | +set WALLTIME = 00:10:00 |
12 | 10 |
|
13 | | -## commands need to be wrapped in tcsh shell invocation |
| 11 | +## Argument parsing from util-linux-ng getopt-parse.tcsh example. |
14 | 12 |
|
15 | | -sed "s|\(.*\)|tcsh -c '\1 >>\& $tmp/log'|g" $1 > $cmd |
| 13 | +# Use a temp variable b/c eval nukes getopt return value. ':q' copies |
| 14 | +# argv list w/ no substitutions |
16 | 15 |
|
17 | | -set nt = `cat $cmd | wc -l` |
18 | | -set nn = `perl -w -e "use POSIX; print ceil($nt/36)"` |
| 16 | +set temp=(`getopt -a -n vectorize -s tcsh -o d:hj:np:q:w: --long dir:,help,nosub,project:,queue:,walltime: -- $argv:q`) |
| 17 | +if ($? != 0) then |
| 18 | + echo "Terminating..." >/dev/stderr |
| 19 | + exit 1 |
| 20 | +endif |
19 | 21 |
|
20 | | -sed -e "s|NTASK|$nt|; s|NNODE|$nn|; s|JOBNAME|$job|; s|OUTFILE|$out|; s|ERRFILE|$err|; s|CMDFILE|$cmd|" ~/template.pbs > $pbs |
| 22 | +# Quote the parens b/c the result is a list, and they need to be |
| 23 | +# evaluated when eval is called. 'q' prevents substitutions. |
21 | 24 |
|
22 | | -qsub < $pbs & |
| 25 | +eval set argv=\($temp:q\) |
23 | 26 |
|
| 27 | +while (1) |
| 28 | + switch($1:q) |
| 29 | + case -d: |
| 30 | + case --dir: |
| 31 | + set dir = $2:q ; shift ; shift |
| 32 | + breaksw; |
| 33 | + case -h: |
| 34 | + set help = yes ; shift |
| 35 | + breaksw |
| 36 | + case -j: |
| 37 | + case --jobname: |
| 38 | + set JOBNAME = $2:q ; shift ; shift |
| 39 | + breaksw; |
| 40 | + case -n: |
| 41 | + case --nosub: |
| 42 | + set submit = no ; shift |
| 43 | + breaksw |
| 44 | + case -p: |
| 45 | + case --project: |
| 46 | + set PROJECT = $2:q ; shift ; shift |
| 47 | + breaksw; |
| 48 | + case -q: |
| 49 | + case --queue: |
| 50 | + set QUEUE = $2:q ; shift ; shift |
| 51 | + breaksw; |
| 52 | + case -w: |
| 53 | + case --walltime: |
| 54 | + set WALLTIME = $2:q ; shift ; shift |
| 55 | + breaksw; |
| 56 | + case --: |
| 57 | + shift |
| 58 | + break |
| 59 | + default: |
| 60 | + echo "vectorize: Internal error!" ; exit 1 |
| 61 | + endsw |
| 62 | +end |
24 | 63 |
|
25 | 64 |
|
26 | | -# Copyright 2017 Univ. Corp. for Atmos. Research |
| 65 | +if(! $?PROJECT) then |
| 66 | + set PROJECT = none |
| 67 | + echo "vectorize: ERROR: project code not defined" |
| 68 | +endif |
| 69 | + |
| 70 | +if( $#argv < 1) then |
| 71 | + echo "vectorize: ERROR: no commandfile" |
| 72 | +endif |
| 73 | + |
| 74 | +if( $#argv > 1) then |
| 75 | + echo "vectorize: ERROR: too many arguments" |
| 76 | +endif |
| 77 | + |
| 78 | +if($help == yes || $PROJECT == none || $#argv != 1) then |
| 79 | + cat <<EOUSAGE |
| 80 | +Usage: vectorize [-d dir] [-h] [-j jobname] [-n] [-p project] [-q queue] [-w walltime] cmdfile |
| 81 | + -d, --dir: directory for output; defaults to `mktemp -d` |
| 82 | + -h, --help: prints this help message |
| 83 | + -j, --jobname: qsub jobname; defaults to `basename cmdfile .txt` |
| 84 | + -n, --nosub: don't submit job, just set everything up |
| 85 | + -p, --project: project code; defaults to PROJECT envariable (if set) |
| 86 | + -q, --queue: queue to submit to; defaults to premium |
| 87 | + -w, --walltime: wallclock limit for job; defaults to 00:10:00 |
| 88 | + cmdfile: a file with one command per line, to be run in parallel |
| 89 | +
|
| 90 | + vectorize is a utility for running many independent single-threaded |
| 91 | + commands in parallel on cheyenne using MPDP parallelism. |
| 92 | +EOUSAGE |
| 93 | +exit 1 |
| 94 | +endif |
| 95 | + |
| 96 | +if ( $?dir ) then |
| 97 | + mkdir -p $dir |
| 98 | +else |
| 99 | + set dir = `mktemp -d` |
| 100 | +endif |
| 101 | + |
| 102 | +if (! $?JOBNAME ) then |
| 103 | + set JOBNAME = `basename $1 .txt` |
| 104 | +endif |
| 105 | + |
| 106 | + |
| 107 | +set CMDFILE = $dir/cmd |
| 108 | +set OUTFILE = $dir/out |
| 109 | +set ERRFILE = $dir/err |
| 110 | +set pbsfile = $dir/pbs |
| 111 | +rm -f $dir/log |
| 112 | + |
| 113 | +## commands need to be wrapped in a shell invocation |
| 114 | + |
| 115 | +#sed "s|\(.*\)|tcsh -c '\1 >>\& $dir/log'|g" $1 > $CMDFILE |
| 116 | +#sed "s|\(.*\)|bash -c '\1 2>>$dir/errerr 1>>$dir/outout'|g" $1 > $CMDFILE |
| 117 | +sed "s|\(.*\)|bash -c '\1'|g" $1 > $CMDFILE |
| 118 | + |
| 119 | +set NTASK = `cat $CMDFILE | wc -l` |
| 120 | +set NNODE = `perl -w -e "use POSIX; print ceil($NTASK/36)"` |
| 121 | +set NCPUS = `perl -w -e "use POSIX; print ceil($NTASK/$NNODE)"` |
| 122 | + |
| 123 | +cat <<EOPBS > $pbsfile |
| 124 | +#!/bin/tcsh |
| 125 | +
|
| 126 | +##### parameters for PBS scheduling via qsub |
| 127 | +##### submit jobs as "qsub scriptname" |
| 128 | +
|
| 129 | +# account code to charge to |
| 130 | +#PBS -A $PROJECT |
| 131 | +
|
| 132 | +# which queue to use |
| 133 | +#PBS -q $QUEUE |
| 134 | +
|
| 135 | +# job name |
| 136 | +#PBS -N $JOBNAME |
| 137 | +
|
| 138 | +# stdout file |
| 139 | +#PBS -o $OUTFILE |
| 140 | +
|
| 141 | +# stderr file |
| 142 | +#PBS -e $ERRFILE |
| 143 | +
|
| 144 | +# runtime limit |
| 145 | +#PBS -l walltime=$WALLTIME |
| 146 | +
|
| 147 | +# CPU resource request |
| 148 | +# ntask = number of lines in file [$NTASK] |
| 149 | +# nnode = ceiling(ntask / 36) [$NNODE] |
| 150 | +# ncpus = ceiling(ntask / nnode) [$NCPUS] |
| 151 | +# select: number of nodes |
| 152 | +# ncpus: number of cpus per node to use |
| 153 | +# mpiprocs: matches ncpus (1 process per CPU) |
| 154 | +# ompthreads: always set to 1 (1 thread per process) |
| 155 | +#PBS -l select=${NNODE}:ncpus=${NCPUS}:mpiprocs=${NCPUS}:ompthreads=1 |
| 156 | +
|
| 157 | +#source /glade/u/apps/opt/lmod/4.2.1/init/tcsh |
| 158 | +
|
| 159 | +module load mpt |
| 160 | +module load netcdf |
| 161 | +module load R |
| 162 | +module load nco |
| 163 | +module load cdo |
| 164 | +module load ncl |
| 165 | +
|
| 166 | +setenv MPI_SHEPHERD true |
| 167 | +
|
| 168 | +mpiexec_mpt -n $NTASK launch_cf.sh $CMDFILE |
| 169 | +
|
| 170 | +EOPBS |
| 171 | + |
| 172 | + |
| 173 | +if($submit == yes) then |
| 174 | + qsub $pbsfile |
| 175 | + |
| 176 | + ## PBS gets hosed if it gets more than about 1 job per second. |
| 177 | + ## Sleep 1 second so that we don't make things sad when looping over |
| 178 | + ## many commandfiles. |
| 179 | + |
| 180 | + sleep 1 |
| 181 | +endif |
| 182 | + |
| 183 | +# Copyright 2018 Univ. Corp. for Atmos. Research |
27 | 184 | # Author: Seth McGinnis, [email protected] |
| 185 | + |
0 commit comments