[4842] | 1 | #!/bin/bash |
---|
| 2 | |
---|
| 3 | # --------------------------------------------------------------------- |
---|
| 4 | # |
---|
| 5 | # process's mapping |
---|
| 6 | # *********************** |
---|
| 7 | # |
---|
| 8 | # PURPOSE : |
---|
| 9 | # --------- |
---|
| 10 | # The execution time si also influenced by the internode |
---|
| 11 | # communications and by the memory contention between parallel MPI tasks. |
---|
| 12 | # This program aims at creating a suitable map of the MPI processes |
---|
| 13 | # to the computing NODE according to different mapping strategies. |
---|
| 14 | # It acts only on the local scheduler configuration and does not modify |
---|
| 15 | # the parallel algorithm neither the domain decomposition. |
---|
| 16 | # The following strategies have been implemented: |
---|
| 17 | |
---|
| 18 | # - com: the mapping will reduce the internode communications. The |
---|
| 19 | # communication pattern defines a graph where each vertex |
---|
| 20 | # represents an MPI task and an edge is a communication between |
---|
| 21 | # two tasks. The mapping is obtained by partitioning the graph |
---|
| 22 | # in a number of subgraph equal to the number of computing nodes; |
---|
| 23 | # the partitioning minimizes the total number of cutting edges. |
---|
| 24 | |
---|
| 25 | # - mem: the mapping will reduce the memory contention between processes |
---|
| 26 | # by evenly distributing the total amount of allocated memory |
---|
| 27 | # among the computing nodes. The amount of memory allocated in a |
---|
| 28 | # computing node is equal to the memory allocated in the other |
---|
| 29 | # nodes. |
---|
| 30 | |
---|
| 31 | # - away: a process will not be mapped to the same node of any of |
---|
| 32 | # its neighbours |
---|
| 33 | |
---|
| 34 | # INPUT : |
---|
| 35 | # ------------- |
---|
| 36 | |
---|
| 37 | # This script requires the following external package: |
---|
| 38 | # - scotch library: http://www.labri.fr/perso/pelegrin/scotch/ (for the com mapping) |
---|
| 39 | # - the file "background.png" (that can be extracted from the bathimetry) to visualize the mapping |
---|
| 40 | |
---|
| 41 | # npart: number of partitions i.e. number of nodes |
---|
| 42 | |
---|
| 43 | # processes layout: the file reports how the MPI processes are disposed on the |
---|
| 44 | # parallel subdomains. This file is an output of the |
---|
| 45 | # "cmcc_mppopt_showproc" script (matrix.in) |
---|
| 46 | |
---|
| 47 | # processes coordinates: the file reports the cartesian coordinates of the |
---|
| 48 | # processes subdomain. It is used for the visualization. |
---|
| 49 | # The file is an output of the |
---|
| 50 | # "cmcc_mppopt_showproc" script ( typical name: <confname>-<decomposition>_<num_sub_domain> example: nemo025-019x045_672 ) |
---|
| 51 | |
---|
| 52 | # number of ocean points: this file reports for each subdomain the number of ocean points |
---|
| 53 | # and an estimation of the amount of memory required for |
---|
| 54 | # each subdomain. The file is an output of the |
---|
| 55 | # "cmcc_mpp_optimizer" script with extension *.layout |
---|
| 56 | |
---|
| 57 | |
---|
| 58 | # MODIFICATIONS: |
---|
| 59 | # -------------- |
---|
| 60 | # v1.0: Nov 2014 (I.Epicoco, F.Macchia - CMCC) |
---|
| 61 | # ---------------------------------------------------------------------- |
---|
| 62 | |
---|
| 63 | |
---|
| 64 | #Warning !!! |
---|
| 65 | # check $procxnode variable that must be set to the number of cores per node. |
---|
| 66 | # It also represents the cardinality of each partition |
---|
| 67 | |
---|
| 68 | procxnode=16 |
---|
| 69 | |
---|
| 70 | |
---|
| 71 | echo "Usage: partition.sh <proc layout file> <num partitions> <coordinates file> <num ocean point file> <type_of_mapping: {mem, comm, away}>" |
---|
| 72 | |
---|
| 73 | matrix=$1 |
---|
| 74 | #matrix="matrix.in" |
---|
| 75 | |
---|
| 76 | #check for the processes layout file |
---|
| 77 | if [ ! -f $matrix ]; then |
---|
| 78 | echo "file with process layout not found" |
---|
| 79 | exit 1 |
---|
| 80 | fi |
---|
| 81 | |
---|
| 82 | maptype=$5 |
---|
| 83 | if [ -z $maptype ]; then |
---|
| 84 | maptype="comm" |
---|
| 85 | fi |
---|
| 86 | npart=$2 |
---|
| 87 | #npart=21 |
---|
| 88 | |
---|
| 89 | gridfile=$3 |
---|
| 90 | #gridfile="./nemo116-019x045_672" |
---|
| 91 | |
---|
| 92 | #check the process coordinate file |
---|
| 93 | if [ ! -f $gridfile ]; then |
---|
| 94 | echo "processes coordinates file not found" |
---|
| 95 | exit 1 |
---|
| 96 | fi |
---|
| 97 | |
---|
| 98 | layoutfile=$4 |
---|
| 99 | #layoutfile="./0672_CMCC.layout" |
---|
| 100 | |
---|
| 101 | #check the .layout |
---|
| 102 | if [ ! -f $layoutfile ]; then |
---|
| 103 | echo "num ocean points file not found" |
---|
| 104 | exit 1 |
---|
| 105 | fi |
---|
| 106 | |
---|
| 107 | #output file for the for the mapping |
---|
| 108 | parmetisfile=$maptype.mapping.$npart |
---|
| 109 | |
---|
| 110 | #output file with the TASK GEOMETRY definition |
---|
| 111 | geometry_var=$maptype.geometry.$npart |
---|
| 112 | |
---|
| 113 | #output file for BG/Q settings |
---|
| 114 | bg_geometry=$maptype.bggeometry.$npart |
---|
| 115 | |
---|
| 116 | #Extract the number of rows and columns of the domain decomposition |
---|
| 117 | nline=$(cat $matrix | wc -l) |
---|
| 118 | echo "rows= $nline" |
---|
| 119 | ncol=$(($(cat $matrix | wc -w)/$nline)) |
---|
| 120 | echo "columns= $ncol" |
---|
| 121 | |
---|
| 122 | dim=$((procxnode * npart)) |
---|
| 123 | decomp="$ncol x $nline" #Be aware of the white spaces |
---|
| 124 | #decomp="8 x 37" #be aware of the white spaces |
---|
| 125 | |
---|
| 126 | ############################################################# |
---|
| 127 | # mapping based on cardinal order |
---|
| 128 | ############################################################# |
---|
| 129 | |
---|
| 130 | if [ $maptype = "card" ]; then |
---|
| 131 | |
---|
| 132 | rm $parmetisfile >& /dev/null |
---|
| 133 | |
---|
| 134 | for i in `seq 0 $((npart - 1))`; do |
---|
| 135 | for j in `seq 1 $procxnode`; do |
---|
| 136 | echo $i >> $parmetisfile |
---|
| 137 | done |
---|
| 138 | done |
---|
| 139 | fi |
---|
| 140 | |
---|
| 141 | ############################################################# |
---|
| 142 | # mapping based on calc2 strategy |
---|
| 143 | ############################################################# |
---|
| 144 | |
---|
| 145 | if [ $maptype = "calc2" ]; then |
---|
| 146 | |
---|
| 147 | grep -A $((dim+1)) "$decomp" $layoutfile | grep -v Total | awk '{print $2 " - " $1}' | sort -n -r > oceanpt.def |
---|
| 148 | rm mapping.tmp >& /dev/null |
---|
| 149 | for i in `seq 0 $((dim-1))`; do |
---|
| 150 | line=`sed -n "$((i+1)),$((i+1)) p" oceanpt.def` |
---|
| 151 | echo "$((i % npart)) - $line" >> mapping.tmp |
---|
| 152 | done |
---|
| 153 | |
---|
| 154 | cat mapping.tmp | awk '{print $5 " " $1}' | sort -n | cut -d " " -f 2 > $parmetisfile |
---|
| 155 | |
---|
| 156 | fi |
---|
| 157 | |
---|
| 158 | ############################################################# |
---|
| 159 | # mapping based on memory |
---|
| 160 | ############################################################# |
---|
| 161 | if [ $maptype = "calc" -o $maptype = "mem" ]; then |
---|
| 162 | |
---|
| 163 | rm oceanpt.* >& /dev/null |
---|
| 164 | |
---|
| 165 | #reading the ocean points memory usage |
---|
| 166 | if [ $maptype = "calc" ]; then |
---|
| 167 | grep -A $((dim+1)) "$decomp" $layoutfile | grep -v Total | awk '{print $2 " - " $1}' | sort -n -r > oceanpt.def |
---|
| 168 | else |
---|
| 169 | grep -A $((dim+1)) "$decomp" $layoutfile | grep -v Total | awk '{print $3 " - " $1}' | sort -n -r > oceanpt.def |
---|
| 170 | fi |
---|
| 171 | |
---|
| 172 | i=0 |
---|
| 173 | for node in `cat oceanpt.def | cut -d "-" -f 1 | sed -e "s/\.//" -e "s/^0*//"`; do |
---|
| 174 | ocnpnt[i]=$node |
---|
| 175 | ((i++)) |
---|
| 176 | done; |
---|
| 177 | |
---|
| 178 | i=0 |
---|
| 179 | for node in `cat oceanpt.def | cut -d "-" -f 2`; do |
---|
| 180 | rank[i]=$node |
---|
| 181 | ((i++)) |
---|
| 182 | done; |
---|
| 183 | |
---|
| 184 | rm weight* mapp_* >& /dev/null |
---|
| 185 | |
---|
| 186 | |
---|
| 187 | for i in `seq 0 $(($npart-1))`; do |
---|
| 188 | echo "0 - $i" >> weight |
---|
| 189 | done |
---|
| 190 | |
---|
| 191 | for i in `seq 0 $(($dim - 1))`; do |
---|
| 192 | minrow="`sort -n weight| head -1`" |
---|
| 193 | minocn=`echo $minrow | cut -d "-" -f 1 | sed -e "s/ //g"` |
---|
| 194 | minnode=`echo $minrow | cut -d "-" -f 2 | sed -e "s/ //g"` |
---|
| 195 | |
---|
| 196 | printf "\r Processing node $((i+1)) of $dim \t" |
---|
| 197 | |
---|
| 198 | echo "${rank[$i]}" >> mapp_$minnode |
---|
| 199 | newvalue=$(($minocn + ${ocnpnt[$i]})) |
---|
| 200 | if [ `wc -l mapp_$minnode | cut -d " " -f 1` -eq $procxnode ]; then |
---|
| 201 | grep -v "${minrow}$" weight > weight.new |
---|
| 202 | echo "$newvalue - $minnode" >> weight.final |
---|
| 203 | else |
---|
| 204 | sed -e "s/${minrow}$/$newvalue - $minnode/" weight > weight.new |
---|
| 205 | fi |
---|
| 206 | mv weight.new weight |
---|
| 207 | done |
---|
| 208 | echo " " |
---|
| 209 | |
---|
| 210 | for i in `ls mapp_*`; do |
---|
| 211 | idx=`echo $i|cut -d "_" -f 2` |
---|
| 212 | sed -e "s/^\(.*\)/\1 $idx/" $i >> metis.part.memory.temp |
---|
| 213 | done |
---|
| 214 | |
---|
| 215 | rm $parmetisfile >& /dev/null |
---|
| 216 | |
---|
| 217 | sort -n metis.part.memory.temp | cut -d " " -f 2 >> $parmetisfile |
---|
| 218 | rm metis.part.memory.temp |
---|
| 219 | |
---|
| 220 | rm oceanpt.* weight* mapp_* >& /dev/null |
---|
| 221 | |
---|
| 222 | fi |
---|
| 223 | |
---|
| 224 | ############################################################# |
---|
| 225 | # Creation of the graph file in parmetis format |
---|
| 226 | ############################################################# |
---|
| 227 | |
---|
| 228 | |
---|
| 229 | el=0 |
---|
| 230 | #for i in `tail -r $matrix`; do |
---|
| 231 | for i in `tac $matrix`; do |
---|
| 232 | m[el]=$(($i+1)) |
---|
| 233 | ((el++)) |
---|
| 234 | done; |
---|
| 235 | |
---|
| 236 | |
---|
| 237 | if [ $el -ne $(($nline*$ncol)) ] ; then |
---|
| 238 | echo "ERROR" |
---|
| 239 | exit 1 |
---|
| 240 | fi |
---|
| 241 | |
---|
| 242 | for((i=0;i<${#m[@]};i++)) ; do |
---|
| 243 | if [ ${m[$i]} -ne 0 ] ; then |
---|
| 244 | |
---|
| 245 | up=${m[(($i+$ncol))]} ; if [[ $up -ne 0 ]] ; then echo -n "$up " >> $outdir"parmetis.part"; fi |
---|
| 246 | |
---|
| 247 | if [ $((i - ncol )) -ge 0 ]; then |
---|
| 248 | down=${m[(($i-$ncol))]} ; if [[ $down -ne 0 ]] ; then echo -n "$down " >> $outdir"parmetis.part"; fi |
---|
| 249 | fi |
---|
| 250 | |
---|
| 251 | #left boundary |
---|
| 252 | if [[ $(($i%$ncol)) -eq 0 ]] ; then |
---|
| 253 | left=${m[(($i+$ncol-1))]} |
---|
| 254 | else |
---|
| 255 | left=${m[(($i-1))]} |
---|
| 256 | fi |
---|
| 257 | if [[ $left -ne 0 ]] ; then echo -n "$left " >> $outdir"parmetis.part"; fi |
---|
| 258 | |
---|
| 259 | #right boundary |
---|
| 260 | if [[ $(($(($i+1))%$ncol)) -eq 0 ]] ; then |
---|
| 261 | right=${m[(($i-$ncol+1))]} |
---|
| 262 | else |
---|
| 263 | right=${m[(($i+1))]} ; |
---|
| 264 | fi |
---|
| 265 | if [[ $right -ne 0 ]] ; then echo -n "$right " >> $outdir"parmetis.part"; fi |
---|
| 266 | |
---|
| 267 | #north pole domains |
---|
| 268 | if [[ $i -ge $(($nline*$ncol-$ncol)) ]] ; then |
---|
| 269 | near1=${m[(($ncol*((2*$nline-1))-$i-2))]} ; if [[ ( $near1 != 0 ) && ( $near1 != $up ) && ( $near1 != $down ) && ( $near1 != $left ) && ( $near1 != $right ) && ( $near1 != ${m[$i]} ) ]] ; then echo -n "$near1 " >> $outdir"parmetis.part"; fi |
---|
| 270 | near2=${m[(($ncol*((2*$nline-1))-$i-1))]} ; if [[ $near2 -ne 0 && ( $near2 != $up ) && ( $near2 != $down ) && ( $near2 != $left ) && ( $near2 != $right ) && ( $near2 != $near1 ) && ( $near2 != ${m[$i]} ) ]] ; then echo -n "$near2 " >> $outdir"parmetis.part"; fi |
---|
| 271 | near3=${m[(($ncol*((2*$nline-1))-$i))]} ; if [[ $near3 -ne 0 && ( $near3 != $up ) && ( $near3 != $down ) && ( $near3 != $left ) && ( $near3 != $right ) && ( $near3 != $near1 ) && ( $near3 != $near2) && ( $near3 != ${m[$i]} ) ]] ; then echo -n "$near3 " >> $outdir"parmetis.part"; fi |
---|
| 272 | fi |
---|
| 273 | |
---|
| 274 | echo "" >> $outdir"parmetis.part" |
---|
| 275 | fi |
---|
| 276 | done; |
---|
| 277 | |
---|
| 278 | node=$(cat $outdir"parmetis.part" | wc -l) |
---|
| 279 | edge=$(cat $outdir"parmetis.part" | wc -w) |
---|
| 280 | edge=$(($edge/2)) |
---|
| 281 | |
---|
| 282 | echo "$node $edge"> $outdir"parmetis.in" |
---|
| 283 | while read line; do |
---|
| 284 | echo "${line}" >> $outdir"parmetis.in" |
---|
| 285 | done < $outdir"parmetis.part" |
---|
| 286 | |
---|
| 287 | rm $outdir"parmetis.part" |
---|
| 288 | |
---|
| 289 | ############################################################# |
---|
| 290 | # mapping based on communication |
---|
| 291 | ############################################################# |
---|
| 292 | |
---|
| 293 | if [ $maptype = "comm" ]; then |
---|
| 294 | #execution of scotch (gpart num_part [input graph file] [output map file] -b0) |
---|
| 295 | |
---|
| 296 | #translate the parmetis format file into the scotch format file |
---|
| 297 | gcv parmetis.in scotch.in -ic -os |
---|
| 298 | |
---|
| 299 | #partitioning with scotch |
---|
| 300 | gpart $npart scotch.in scotch.map -b0 |
---|
| 301 | |
---|
| 302 | #translate the output file format |
---|
| 303 | sed -n "s/\t/ /p" scotch.map | cut -d " " -f 2 > $parmetisfile |
---|
| 304 | |
---|
| 305 | rm scotch.map scotch.in |
---|
| 306 | |
---|
| 307 | #lancia metis (gpmetis [options] graphfile nparts) |
---|
| 308 | |
---|
| 309 | #gpmetis -ptype=kway -objtype=vol parmetis.in $npart |
---|
| 310 | #gpmetis -contig -ufactor=1 -ncuts=50 -niter=200 -ptype=kway -objtype=cut parmetis.in $npart |
---|
| 311 | |
---|
| 312 | fi # end maptype==comm |
---|
| 313 | |
---|
| 314 | |
---|
| 315 | ############################################################# |
---|
| 316 | # Mapping based on neighbour-away algorithm |
---|
| 317 | ############################################################# |
---|
| 318 | |
---|
| 319 | if [ $maptype = "away" ]; then |
---|
| 320 | |
---|
| 321 | # the script partitions the input nodes of the graph into "npart" sets. One node is requested to belong |
---|
| 322 | # to a partition different from each of its neighbours |
---|
| 323 | |
---|
| 324 | #input file describing the dependency graph. Format used is ParMetis adiacency list file |
---|
| 325 | graphfile="parmetis.in" |
---|
| 326 | |
---|
| 327 | # create npart temporary files |
---|
| 328 | for i in `seq 0 $((npart - 1))`; do |
---|
| 329 | p_filename=`printf "p_%04d" $i` |
---|
| 330 | rm $p_filename >& /dev/null |
---|
| 331 | touch $p_filename |
---|
| 332 | done |
---|
| 333 | num_nodes=`sed -n "1,1 s/[0-9]*$//p" $graphfile` |
---|
| 334 | for i in `seq 1 $num_nodes`; do |
---|
| 335 | # processing node $i |
---|
| 336 | printf "\r Processing node $i of $num_nodes \t" |
---|
| 337 | # sort the current partitions |
---|
| 338 | ordered_file="p_ordered" |
---|
| 339 | wc -l p_*[0-9] | sed -n "1,$npart s/^ *//p" | sort -n > $ordered_file |
---|
| 340 | |
---|
| 341 | # insert the current node $i into a partition where none of its neighbours is present |
---|
| 342 | neighbour_list=`sed -n "$((i+1)),$((i+1)) p" $graphfile` |
---|
| 343 | placed=0 |
---|
| 344 | for j in `seq 1 $npart`; do |
---|
| 345 | p_filename=`sed -n "$j,$j p" $ordered_file | cut -d " " -f 2` |
---|
| 346 | insert=1 |
---|
| 347 | for k in $neighbour_list; do |
---|
| 348 | flag=`grep "^$k$" $p_filename | wc -l` |
---|
| 349 | if [ $flag != 0 ]; then |
---|
| 350 | insert=0 |
---|
| 351 | break |
---|
| 352 | fi |
---|
| 353 | done |
---|
| 354 | if [ $insert == 0 ]; then |
---|
| 355 | continue |
---|
| 356 | fi |
---|
| 357 | echo $i >> $p_filename |
---|
| 358 | placed=1 |
---|
| 359 | break |
---|
| 360 | done |
---|
| 361 | if [ $placed == 0 ]; then |
---|
| 362 | echo "Error node $i can not be placed in any of the partitions" |
---|
| 363 | exit 1 |
---|
| 364 | fi |
---|
| 365 | done |
---|
| 366 | printf "\n" |
---|
| 367 | |
---|
| 368 | rm $ordered_file |
---|
| 369 | |
---|
| 370 | # merging of the entire temporary partions files |
---|
| 371 | rm $parmetisfile >& /dev/null |
---|
| 372 | for i in `seq 1 $num_nodes`; do |
---|
| 373 | part=`grep "^$i$" p_*[0-9] | cut -d "_" -f 2 | cut -d ":" -f 1 | sed "s/^0*//"` |
---|
| 374 | if [ x$part == "x" ]; then |
---|
| 375 | part=0 |
---|
| 376 | fi |
---|
| 377 | printf "%d\n" $part >> $parmetisfile |
---|
| 378 | done |
---|
| 379 | |
---|
| 380 | rm p_*[0-9] |
---|
| 381 | |
---|
| 382 | fi # end maptype = "away" |
---|
| 383 | |
---|
| 384 | ############################################################# |
---|
| 385 | # Check for correctness |
---|
| 386 | ############################################################# |
---|
| 387 | |
---|
| 388 | #check if each partition has the same number of elements |
---|
| 389 | for i in `eval echo {0..$(($npart-1))}`; do |
---|
| 390 | n=`grep "^$i$" $parmetisfile | wc -l` |
---|
| 391 | if [ $n -ne $procxnode ] ; then |
---|
| 392 | echo "ERROR! Node $i has $n proc!" |
---|
| 393 | fi |
---|
| 394 | done |
---|
| 395 | |
---|
| 396 | ############################################################# |
---|
| 397 | # Diagnostic |
---|
| 398 | ############################################################# |
---|
| 399 | |
---|
| 400 | # Memory needed for each partitions |
---|
| 401 | echo "*******************" |
---|
| 402 | echo "Memory Distribution" |
---|
| 403 | echo "*******************" |
---|
| 404 | grep -A $((dim+1)) "$decomp" $layoutfile | grep -v Total | awk '{print $3}' > oceanpt.tmp |
---|
| 405 | |
---|
| 406 | for i in `seq 1 $dim`; do |
---|
| 407 | p=`sed -n "$i,$i p" $parmetisfile` |
---|
| 408 | weight=`sed -n "$i,$i p" oceanpt.tmp` |
---|
| 409 | w[p]=`echo 0${w[$p]} + $weight | bc` |
---|
| 410 | done |
---|
| 411 | |
---|
| 412 | rm oceanpt.tmp |
---|
| 413 | |
---|
| 414 | max=${w[0]} |
---|
| 415 | min=${w[0]} |
---|
| 416 | tot=${w[0]} |
---|
| 417 | min_p=0 |
---|
| 418 | max_p=0 |
---|
| 419 | echo "0 - ${w[0]} GB" |
---|
| 420 | for i in `seq 1 $((npart-1))`; do |
---|
| 421 | echo "$i - ${w[$i]} GB" |
---|
| 422 | t=`echo "${w[$i]} > $max" | bc` |
---|
| 423 | if [ $t == 1 ]; then max=${w[$i]}; max_p=$i; fi |
---|
| 424 | t=`echo "${w[$i]} < $min" | bc` |
---|
| 425 | if [ $t == 1 ]; then min=${w[$i]}; min_p=$i; fi |
---|
| 426 | tot=`echo "$tot + ${w[$i]}" | bc` |
---|
| 427 | done |
---|
| 428 | mean=`echo "scale = 3; $tot/$npart"|bc ` |
---|
| 429 | echo "Max memory $max GB on partition $max_p" |
---|
| 430 | echo "Min memory $min GB on partition $min_p" |
---|
| 431 | echo "Mean memory $mean GB" |
---|
| 432 | echo "Memory unbalance (Max/Mean)" `echo "scale = 2; $max/$mean" |bc` "%" |
---|
| 433 | |
---|
| 434 | # Number of interconnection (intra- and inter- node) between processes |
---|
| 435 | echo "*********************************" |
---|
| 436 | echo "Interconnection between processes" |
---|
| 437 | echo "*********************************" |
---|
| 438 | |
---|
| 439 | com=0 |
---|
| 440 | comtot=0 |
---|
| 441 | |
---|
| 442 | i=1 |
---|
| 443 | while read p; do |
---|
| 444 | part[i]=$p |
---|
| 445 | ((i++)) |
---|
| 446 | done < $parmetisfile |
---|
| 447 | |
---|
| 448 | l=0 |
---|
| 449 | while read line; do |
---|
| 450 | if [[ l -ne 0 ]] ; then |
---|
| 451 | for i in `echo $line`; do |
---|
| 452 | if [[ ${part[$i]} -ne ${part[$l]} ]] ; then |
---|
| 453 | ((com++)) |
---|
| 454 | fi |
---|
| 455 | ((comtot++)) |
---|
| 456 | done |
---|
| 457 | fi |
---|
| 458 | ((l++)) |
---|
| 459 | done < $outdir"parmetis.in" |
---|
| 460 | |
---|
| 461 | echo "Tot comunicazioni: $comtot" |
---|
| 462 | echo "Tot comunicazioni internodo: $com" |
---|
| 463 | |
---|
| 464 | |
---|
| 465 | ############################################################# |
---|
| 466 | #writing the TASK_GEOMETRY |
---|
| 467 | ############################################################# |
---|
| 468 | |
---|
| 469 | number_of_groups=`cat $parmetisfile | sort -u | wc -l` |
---|
| 470 | |
---|
| 471 | echo -n 'export LSB_PJL_TASK_GEOMETRY="{' > $geometry_var |
---|
| 472 | #for j in `seq 0 $((number_of_groups - 1))`; do |
---|
| 473 | for j in `eval echo {0..$((number_of_groups - 1))}`; do |
---|
| 474 | echo -n "(" >> $geometry_var |
---|
| 475 | for i in `grep -n "^$j$" $parmetisfile | cut -d : -f 1`; do |
---|
| 476 | echo -n $((i-1)), |
---|
| 477 | done | sed s/.$// >> $geometry_var |
---|
| 478 | echo -n ")" >> $geometry_var |
---|
| 479 | done; |
---|
| 480 | echo '}"' >> $geometry_var |
---|
| 481 | |
---|
| 482 | #cat $geometry_var |
---|
| 483 | |
---|
| 484 | |
---|
| 485 | ############################################################# |
---|
| 486 | #writing the geometry for BG/Q architecture |
---|
| 487 | ############################################################# |
---|
| 488 | |
---|
| 489 | # each row contains the position of the process in the torus |
---|
| 490 | # the shape of the torus is defined by the 6 parameters A, B, C, D, E, T |
---|
| 491 | |
---|
| 492 | tor_a=2 |
---|
| 493 | tor_b=2 |
---|
| 494 | tor_c=4 |
---|
| 495 | tor_d=4 |
---|
| 496 | tor_e=2 |
---|
| 497 | tor_t=16 |
---|
| 498 | |
---|
| 499 | cat -n $parmetisfile | awk '{print $2 " " $1}'| sort -n | cat -n | awk -v val=$tor_t '{print $3 " " $2 " " ($1-1) % val}' | sort -n | awk -v val_a=$tor_a -v val_b=$tor_b -v val_c=$tor_c -v val_d=$tor_d -v val_e=$val_e '{print int($2/(val_b*val_c*val_d*val_e)) " " int($2/(val_c*val_d*val_e)) % val_b " " int($2/(val_d*val_e)) % val_c " " int($2/val_e) % val_d " " $2 % val_e " " $3}' > $bg_geometry |
---|
| 500 | |
---|
| 501 | |
---|
| 502 | ############################################################# |
---|
| 503 | #writing svg |
---|
| 504 | ############################################################# |
---|
| 505 | #load the mapping file |
---|
| 506 | |
---|
| 507 | i=1 |
---|
| 508 | for node in `cat $parmetisfile`; do |
---|
| 509 | map[i]=$node |
---|
| 510 | ((i++)) |
---|
| 511 | done; |
---|
| 512 | |
---|
| 513 | #loading of the number of ocean points and memory usage |
---|
| 514 | decomp=`grep "Decomp" $gridfile | cut -d : -f 3` |
---|
| 515 | k=0 |
---|
| 516 | for oceanpt in `grep -A ${#map[*]} "$decomp" $layoutfile | grep -v Total | awk '{print $2}'` ; do |
---|
| 517 | oceanptvett[k]=$oceanpt |
---|
| 518 | ((k++)) |
---|
| 519 | done; |
---|
| 520 | k=0 |
---|
| 521 | for mempt in `grep -A ${#map[*]} "$decomp" $layoutfile | grep -v Total | awk '{print $3}'` ; do |
---|
| 522 | memptvett[k]=$mempt |
---|
| 523 | ((k++)) |
---|
| 524 | done; |
---|
| 525 | |
---|
| 526 | #creation of the color map |
---|
| 527 | |
---|
| 528 | num_col=$npart |
---|
| 529 | for((i=0;i<$num_col;i++)) ; do |
---|
| 530 | colourvett[i]="rgb($(($RANDOM%256)),$(($RANDOM%256)),$(($RANDOM%256)))" |
---|
| 531 | done; |
---|
| 532 | |
---|
| 533 | outfile=$maptype.display.$npart.svg |
---|
| 534 | |
---|
| 535 | #extract the grid dimension |
---|
| 536 | width=0 ; height=0; |
---|
| 537 | for i in `grep -A4 "# [ 0-9]" $gridfile | grep -v \- | grep -v \# | sed "s/^[ \t]*//;s/[ \t]*$//" | sed "s/ */ /g" |sed "s/ /,/g" | cut -f 1 -d ,`; do |
---|
| 538 | if [[ $i -gt $width ]]; then |
---|
| 539 | width=$i |
---|
| 540 | fi |
---|
| 541 | done; |
---|
| 542 | for i in `grep -A4 "# [ 0-9]" $gridfile | grep -v \- | grep -v \# | sed "s/^[ \t]*//;s/[ \t]*$//" | sed "s/ */ /g" |sed "s/ /,/g" | cut -f 2 -d ,`; do |
---|
| 543 | if [[ $i -gt $height ]]; then |
---|
| 544 | height=$i |
---|
| 545 | fi |
---|
| 546 | done; |
---|
| 547 | |
---|
| 548 | #writing the header |
---|
| 549 | echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?> " > $outfile |
---|
| 550 | echo "<!DOCTYPE svg PUBLIC \"-//W3C//Dtd SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/Dtd/svg11.dtd\">" >> $outfile |
---|
| 551 | echo "<svg width=\"$(($width+150))\" height=\"$(($height+100))\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" >> $outfile |
---|
| 552 | |
---|
| 553 | #background image. It can be derived from the bathimetry |
---|
| 554 | echo "<image x=\"0\" y=\"0\" width=\"$width\" height=\"$height\" xlink:href=\"background.png\"/>" >> $outfile |
---|
| 555 | |
---|
| 556 | #writing the subdomain rectangles with additional information about process ID and color |
---|
| 557 | j=0; |
---|
| 558 | for i in `grep -A4 "# [ 0-9]" $gridfile | grep -v \- | sed "s/#/ /g" | sed "s/^[ \t]*//;s/[ \t]*$//" | sed "s/ */ /g" |sed "s/ /,/g" | sed '1d'`; do |
---|
| 559 | case $j in |
---|
| 560 | 0) |
---|
| 561 | proc=$(($i-1)); |
---|
| 562 | nodeid=node_$proc |
---|
| 563 | col_index=${map[$i]} |
---|
| 564 | echo -n "<polygon id=\"$nodeid\" points=\"" >> $outfile |
---|
| 565 | ((j++)); |
---|
| 566 | printf "\rGenerating SVG ... %3d%% " $(( (($proc + 1 ) * 100) / $dim )) |
---|
| 567 | ;; |
---|
| 568 | 1) |
---|
| 569 | ((j++)); |
---|
| 570 | x=$(echo $i | cut -f 1 -d ,); |
---|
| 571 | y=$(($height-$(echo $i | cut -f 2 -d ,))); |
---|
| 572 | xtxt=$(($x+3)) |
---|
| 573 | ytxt=$(($y-3)) |
---|
| 574 | echo -n "$x,$y " >> $outfile |
---|
| 575 | ;; |
---|
| 576 | [2-3]) |
---|
| 577 | ((j++)); |
---|
| 578 | x=$(echo $i | cut -f 1 -d ,); |
---|
| 579 | y=$(($height-$(echo $i | cut -f 2 -d ,))); |
---|
| 580 | echo -n "$x,$y " >> $outfile |
---|
| 581 | ;; |
---|
| 582 | 4) |
---|
| 583 | j=0; |
---|
| 584 | x=$(echo $i | cut -f 1 -d ,); |
---|
| 585 | y=$(($height-$(echo $i | cut -f 2 -d ,))); |
---|
| 586 | echo "$x,$y\" style=\"stroke:white;fill:${colourvett[$col_index]};fill-opacity:0.7\" />" >> $outfile |
---|
| 587 | echo "<text x=\"$xtxt\" y=\"$ytxt\" fill=\"white\" >$proc</text>" >> $outfile |
---|
| 588 | echo "<g visibility=\"hidden\" font-family =\"sans-serif\" fill=\"black\" font-size = \"12\">" >> $outfile |
---|
| 589 | echo "<rect x=\"$xtxt\" y=\"$ytxt\" rx=\"2\" ry=\"2\" width=\"175\" height=\"95\" style=\"stroke:black;fill:lightgray\">" >> $outfile |
---|
| 590 | echo "<set attributeName=\"visibility\" from=\"hidden\" to=\"visible\" begin=\"$nodeid.mousedown\" end=\"$nodeid.mouseout\"/></rect>" >> $outfile |
---|
| 591 | echo "<text x=\"$(($xtxt+10))\" y=\"$(($ytxt+20))\" font-weight=\"bold\">Ocean Sub-domain : $proc<set attributeName=\"visibility\" from=\"hidden\" to=\"visible\" begin=\"$nodeid.mousedown\" end=\"$nodeid.mouseout\"/></text> " >> $outfile |
---|
| 592 | echo "<text x=\"$(($xtxt+10))\" y=\"$(($ytxt+40))\">Total ocepts : ${oceanptvett[$proc]}<set attributeName=\"visibility\" from=\"hidden\" to=\"visible\" begin=\"$nodeid.mousedown\" end=\"$nodeid.mouseout\"/></text> " >> $outfile |
---|
| 593 | echo "<text x=\"$(($xtxt+10))\" y=\"$(($ytxt+60))\">Memory in Gb : ${memptvett[$proc]}<set attributeName=\"visibility\" from=\"hidden\" to=\"visible\" begin=\"$nodeid.mousedown\" end=\"$nodeid.mouseout\"/></text> " >> $outfile |
---|
| 594 | echo "<text x=\"$(($xtxt+10))\" y=\"$(($ytxt+80))\">Color : $col_index<set attributeName=\"visibility\" from=\"hidden\" to=\"visible\" begin=\"$nodeid.mousedown\" end=\"$nodeid.mouseout\"/></text> " >> $outfile |
---|
| 595 | echo "</g>" >> $outfile |
---|
| 596 | ;; |
---|
| 597 | *) |
---|
| 598 | echo "ERROR" |
---|
| 599 | ;; |
---|
| 600 | esac; |
---|
| 601 | done; |
---|
| 602 | |
---|
| 603 | #chiudo il file svg |
---|
| 604 | echo "</svg>" >> $outfile |
---|
| 605 | |
---|
| 606 | printf " Done\n" |
---|