| 181 | |
| 182 | == Scaling Tests scripts == |
| 183 | |
| 184 | [[CollapsibleStart(Weak Scaling Scripts)]] |
| 185 | For weak scaling we need to specify the dimensions of each problem and the number of processors we want to use. Then separate directories are created along with customized job scripts which are then submitted to the queue. The job scripts are customized by echoing modified PBS directives along with any other necessary variables needed by the pbs script (in this case nproc, base_resx, and base_resy) |
| 186 | |
| 187 | {{{ |
| 188 | #!/bin/bash |
| 189 | NP=(256 128 64 32 16 8) |
| 190 | base_resx=(724 512 362 256 180 128) |
| 191 | base_resy=(724 512 362 256 180 128) |
| 192 | for (( j=0;j<${#NP[@]};j++)); do |
| 193 | nproc=${NP[j]} |
| 194 | mkdir $nproc |
| 195 | cp *.data $nproc |
| 196 | cd $nproc |
| 197 | mkdir out |
| 198 | nodes=`expr $nproc / 8` |
| 199 | echo "#!/bin/bash" > scrambler.pbs |
| 200 | echo "#PBS -q debug" >> scrambler.pbs |
| 201 | echo "#PBS -l nodes=$nodes:ppn=8,pvmem=1000mb,walltime=1:00:00" >> scrambler.pbs |
| 202 | echo "#PBS -N weakscalingtest-$nproc" >> scrambler.pbs |
| 203 | echo "nProcs=$nproc" >> scrambler.pbs |
| 204 | echo "base_resx=${base_resx[j]}" >> scrambler.pbs |
| 205 | echo "base_resy=${base_resy[j]}" >> scrambler.pbs |
| 206 | cat ../scrambler.pbs >> scrambler.pbs |
| 207 | # qsub scrambler.pbs |
| 208 | cd .. |
| 209 | done |
| 210 | }}} |
| 211 | |
| 212 | This then adds the following |
| 213 | {{{ |
| 214 | #!/bin/bash |
| 215 | #PBS -q debug |
| 216 | #PBS -l nodes=1:ppn=8,pvmem=1000mb,walltime=1:00:00 |
| 217 | #PBS -N weakscalingtest-8 |
| 218 | nProcs=8 |
| 219 | base_resx=128 |
| 220 | base_resy=128 |
| 221 | }}} |
| 222 | to the beginning of the default scrambler.pbs script |
| 223 | {{{ |
| 224 | echo "===========" |
| 225 | echo "Running on:" |
| 226 | cat $PBS_NODEFILE |
| 227 | echo "===========" |
| 228 | |
| 229 | cd $PBS_O_WORKDIR |
| 230 | |
| 231 | f=(.25 .5 .75) |
| 232 | maxlevel=(0 1 2 3 4) |
| 233 | threaded=(-1 0) |
| 234 | mv data.out data.out.old |
| 235 | ../subst.s Gmx $base_resx,$base_resy,1 global.data |
| 236 | ../subst.s domain%mGlobal 1,1,1,$base_resx,$base_resy,1 global.data |
| 237 | |
| 238 | for (( l=0;l<${#maxlevel[@]};l++)); do |
| 239 | ../subst.s MaxLevel ${maxlevel[l]} global.data |
| 240 | for (( k=0;k<${#threaded[@]};k++)); do |
| 241 | ../subst.s iThreaded ${threaded[k]} global.data |
| 242 | for (( i=0;i<${#f[@]};i++)); do |
| 243 | ../subst.s filling_fractions ${f[i]} problem.data |
| 244 | echo ${maxlevel[l]} ${threaded[k]} ${f[i]} ${NP[j]} |
| 245 | mpirun -n $nProcs ../astrobear > output.out |
| 246 | grep scale_data output.out >> data.out |
| 247 | done |
| 248 | done |
| 249 | done |
| 250 | }}} |
| 251 | |
| 252 | Then when the job runs, the scrambler.pbs script can modify the various data files using the subst.s script to swap out different parameters and peform the various different runs all with the same number of processors. The only requirement is that the values of a namelist variable appear on the same line as the namelist variable. |
| 253 | |
| 254 | For example |
| 255 | |
| 256 | {{{ |
| 257 | Gmx = 64,64,1 !Base resolution |
| 258 | }}} |
| 259 | |
| 260 | instead of |
| 261 | {{{ |
| 262 | Gmx = 64, ! cells in x |
| 263 | 64, ! cells in y |
| 264 | 1, ! cells in z |
| 265 | }}} |
| 266 | |
| 267 | Here is the subst.s script |
| 268 | {{{ |
| 269 | #!/bin/bash |
| 270 | # "subst", a script that substitutes one pattern for |
| 271 | # another in a file, |
| 272 | # i.e., "subst Smith Jones letter.txt". |
| 273 | ARGS=3 |
| 274 | E_BADARGS=65 # Wrong number of arguments passed to script. |
| 275 | if [ $# -ne "$ARGS" ] |
| 276 | # Test number of arguments to script (always a good idea). |
| 277 | then |
| 278 | echo "Usage: `basename $0` variable new-value filename" |
| 279 | exit $E_BADARGS |
| 280 | fi |
| 281 | |
| 282 | var_pattern=$1 |
| 283 | new_value=$2 |
| 284 | |
| 285 | if [ -f "$3" ] |
| 286 | then |
| 287 | file_name=$3 |
| 288 | else |
| 289 | echo "File \"$3\" does not exist." |
| 290 | exit $E_BADARGS |
| 291 | fi |
| 292 | |
| 293 | # Here is where the heavy work gets done. |
| 294 | newfile="$file_name""2" |
| 295 | |
| 296 | sed -e "s/$var_pattern\(\s*=\s*\)\S*/$var_pattern\1$new_value/i" $file_name | uniq > $newfile |
| 297 | mv $newfile $file_name |
| 298 | |
| 299 | # I'm sure there is a better way then to pipe the output through unique but I got frustrated trying JJC |
| 300 | # 's' is, of course, the substitute command in sed, |
| 301 | # and /pattern/ invokes address matching. |
| 302 | # The (\s*=\s*\) matches (and saves) all of the white space on either side of the equals sign |
| 303 | # The \S* terminates at the first non-white space character which is presumably the end of the variable value |
| 304 | # Note for array definitions like qTolerance = 1e-3 1e-3 1e-3, this will replace only the first value. |
| 305 | # This can be avoided by editing your data files to remove white space in array declarations (ie qTolerance = 1e-3,1e-3,1e-3) |
| 306 | |
| 307 | exit 0 # Successful invocation of the script returns 0. |
| 308 | |
| 309 | }}} |
| 310 | |
| 311 | [[CollapsibleEnd]] |