Changeset ab81e3b for doc


Ignore:
Timestamp:
Mar 7, 2023, 3:08:52 PM (14 months ago)
Author:
caparson <caparson@…>
Branches:
ADT, ast-experimental, master
Children:
e23169b
Parents:
b86d14c
Message:

updated run script and plotting script

Location:
doc/theses/colby_parsons_MMAth/benchmarks/actors
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/colby_parsons_MMAth/benchmarks/actors/run

    • Property mode changed from 100644 to 100755
    rb86d14c rab81e3b  
    8585}
    8686
    87 numtimes=5
    88 
    89 # bench_cores='1 2 4 8 16 24 32'
    90 bench_cores='8 16 24 32 48'
    91 # bench_cores='32'
    92 
    93 # toggle benchmarks
    94 executor=${true}
    95 matrix=${true}
    96 repeat=${true}
    97 balance=${true}
    98 static=${false}
    99 dynamic=${false}
    100 
    10187# executor config
    102 batch='1'
    103 nRounds='500'
     88batch='100'
     89nRounds='400' #500
    10490
    10591# matrix config
    106 size='3000'
     92size='3072'
    10793
    10894# repeat config
    10995messages='100000'
    110 n_repeats='100'
     96n_repeats='200' #200
    11197
    11298# balance config
     
    115101
    116102# static config
    117 n_static_sends='10000000'
     103n_static_sends='100000000'
    118104
    119105# dynamic config
    120 n_dynamic_sends='10000000'
    121 
    122 # names=('NOSTEAL' 'CLOSE' 'SEARCH')
    123 # var_flags=('-D__STEAL=1 -DRAND=1' '-D__STEAL=1 -DCLOSE=1' '-D__STEAL=1 -DSEARCH=1')
    124 
    125 names=('SEARCH')
     106n_dynamic_sends='20000000'
     107
     108numtimes=5
     109
     110# bench_cores='1 2 4 8 16 24 32'
     111# bench_cores='1 2 4 8 16 24 32 48'
     112bench_cores='48'
     113
     114# toggle benchmarks
     115executor=${false}
     116matrix=${false}
     117repeat=${false}
     118balance=${false}
     119static=${true}
     120dynamic=${true}
     121
     122# names=('CFA-LV' 'CFA-NS' 'CFA-R')
     123# var_flags=('-D__STEAL=1 -DSEARCH=1' '' '-D__STEAL=1 -DRAND=1')
     124
     125# names=('CFA-NS')
     126# var_flags=('')
     127
     128names=('CFA')
    126129var_flags=('-D__STEAL=1 -DSEARCH=1')
    127130
    128 
    129 # names=('NOSTEAL' 'SEARCH' 'RAND' 'SEARCHC' 'RANDC')
    130 # var_flags=('' '-D__STEAL=1 -DSEARCH=1' '-D__STEAL=1 -DRAND=1' '-D__STEAL=1 -DSEARCH=1 -DCYCLE' '-D__STEAL=1 -DRAND=1 -DCYCLE')
    131 
    132 # names=('NOSTEAL' 'RAND' 'CLOSE' 'SEARCH')
    133 # var_flags=('' '-D__STEAL=1 -DRAND=1' '-D__STEAL=1 -DCLOSE=1' '-D__STEAL=1 -DSEARCH=1')
    134 
    135 cfa_flags='-quiet -O3 -nodebug -DNDEBUG'
     131# names=('CFA' 'CFA-STAT')
     132# var_flags=('-D__STEAL=1 -DSEARCH=1' '-D__STEAL=1 -DSTATS')
     133
     134# names=()
     135# var_flags=()
     136
     137runCAF=${true}
     138runUCPP=${true}
     139runPROTO=${true}
     140runAKKA=${true}
     141# runCAF=${false}
     142# runUCPP=${false}
     143# runPROTO=${false}
     144# runAKKA=${false}
    136145
    137146cfa=~/cfa-cc/driver/cfa
    138147
     148# Helpers to minimize code duplication
     149
     150# repeats a command ${numtimes}
    139151preprint=''
    140152repeat_command() {
     
    147159}
    148160
    149 arch nasus
    150 
     161# prints the leading info for a given run of a variant
     162print_header() {
     163    echo ${1}':'
     164    echo -e "proc\ttime (s)"
     165}
     166
     167# runs the current benchmark with provided args
     168# only works for standard-run benchmarks (not Akka)
     169# must split into pre and post args to be able to supply val of p
     170pre_args=''
     171post_args=''
     172single_run() {
     173    affinity ${1}
     174    preprint="${1}\t"
     175    repeat_command taskset -c ${taskset} ./a.${hostname} ${pre_args} ${1} ${post_args}
     176}
     177
     178# runs the current bench for all processor vals
     179# works for standard benchs that dont need to set a config file (not Akka or CAF)
     180run_bench() {
     181    for p in ${bench_cores} ; do
     182        single_run ${p}
     183    done
     184}
     185
     186set_akka_parallelism() {
     187    sed -i "s/parallelism-min = .*/parallelism-min = ${1}/g" application.conf
     188    sed -i "s/parallelism-max = .*/parallelism-max = ${1}/g" application.conf
     189}
     190
     191arch # get hostname
     192
     193# set up leading info for python script
    151194echo $numtimes
    152195echo $bench_cores
     
    155198        echo -n ${names[$i]}" "
    156199done
     200if [ ${runCAF} -eq ${true} ] ; then
     201    echo -n 'CAF '
     202fi # done CAF
     203if [ ${runAKKA} -eq ${true} ] ; then
     204    echo -n 'Akka '
     205fi # done AKKA
     206if [ ${runUCPP} -eq ${true} ] ; then
     207    echo -n 'uC++ '
     208fi # done UCPP
     209if [ ${runPROTO} -eq ${true} ] ; then
     210    echo -n 'ProtoActor '
     211fi
    157212echo ""
    158213
     214# done printing header info for output
     215
     216# cfa flags
     217cfa_flags='-quiet -O3 -nodebug -DNDEBUG'
     218
     219# CAF flags
     220prefixCAF='-O3 -Wall -std=c++17 -I/home/pabuhr/software/nasus/Actors/experiments/CAF/actor-framework/libcaf_core -I/home/pabuhr/software/nasus/Actors/experiments/CAF/actor-framework/libcaf_core/caf -I/home/pabuhr/software/nasus/Actors/experiments/CAF/actor-framework/build/libcaf_core -L/home/pabuhr/software/nasus/Actors/experiments/CAF/actor-framework/build/libcaf_core -L/home/pabuhr/software/nasus/Actors/experiments/CAF/actor-framework/build/libcaf_io'
     221suffixCAF='-lcaf_io -lcaf_core -Wl,-rpath=CAF/actor-framework/build/libcaf_core'
     222
     223# AKKA flags
     224sbtflags="--warn -J-Xmx32g"
     225
     226# UCPP flags
     227UCPPflags="-quiet -g -Wall -Wextra -O3 -nodebug -DNDEBUG -multi"
     228UCPP=~/ucpp/u++-7.0.0/bin/u++
     229
     230# run the benchmarks
     231
    159232# /usr/bin/time -f "%Uu %Ss %Er %Mkb"
    160 
    161233if [ ${executor} -eq ${true} ] ; then
    162234    echo "executor"
     235    pre_args="40000 100 ${nRounds}"
     236    post_args="${batch}"
     237    cd cfa # CFA RUN
     238    for i in ${!names[@]}; do
     239        print_header ${names[$i]}
     240        ${cfa} ${cfa_flags} ${var_flags[$i]} executor.cfa -o a.${hostname} > /dev/null 2>&1
     241        run_bench
     242        rm a.${hostname}
     243    done
     244    cd - > /dev/null # done CFA
     245    if [ ${runCAF} -eq ${true} ] ; then # CAF RUN
     246        cd caf
     247        print_header 'CAF'
     248        g++ ${prefixCAF} CAFExecutor.cpp ${suffixCAF} -o a.${hostname} > /dev/null 2>&1
     249        for p in ${bench_cores} ; do
     250            sed -i "s/max-threads = .*/max-threads = ${p}/g" caf-application.conf # set CAF parallelism
     251            single_run ${p}
     252        done
     253        rm a.${hostname}
     254        # set back parallelism
     255        sed -i "s/max-threads = .*/max-threads = 1/g" caf-application.conf
     256        cd - > /dev/null
     257    fi # done CAF
     258    if [ ${runAKKA} -eq ${true} ] ; then # AKKA RUN
     259        cd akka/Executor
     260        rm -rf project target                           # random out of memory errors without this
     261        print_header 'Akka'
     262        for p in ${bench_cores} ; do
     263            set_akka_parallelism ${p}
     264            affinity ${p}
     265            taskset -c ${taskset} sbt ${sbtflags} "run ${pre_args} ${p} ${post_args} ${numtimes}" 2>&1 | grep -v "SLF4J:" | grep -v "Slf4jLogger started" | sed -e "s/\x1b\[0J//"
     266            sbt clean > /dev/null
     267        done
     268        # set back parallelism
     269        set_akka_parallelism 1
     270        cd - > /dev/null
     271    fi # done AKKA
     272    if [ ${runUCPP} -eq ${true} ] ; then # UCPP RUN
     273        cd ucpp
     274        print_header 'uC++'
     275        ${UCPP} ${UCPPflags} uC++Executor.cc -o a.${hostname} > /dev/null 2>&1
     276        run_bench
     277        rm a.${hostname}
     278        cd - > /dev/null
     279    fi # done UCPP
     280    if [ ${runPROTO} -eq ${true} ] ; then # PROTO RUN
     281        print_header 'ProtoActor'
     282        cd proto/Executor
     283        go build -o a.${hostname} > /dev/null 2>&1
     284        run_bench
     285        rm a.${hostname}
     286        cd - > /dev/null
     287    fi # done PROTO
     288    echo ""
     289fi
     290
     291if [ ${matrix} -eq ${true} ] ; then
     292    echo "matrix"
     293    pre_args="${size} ${size} ${size}"
     294    post_args=""
     295    cd cfa
     296    for i in ${!names[@]}; do
     297        print_header ${names[$i]}
     298        ${cfa} ${cfa_flags} ${var_flags[$i]} matrix.cfa -o a.${hostname} > /dev/null 2>&1
     299        run_bench
     300        rm a.${hostname}
     301    done
     302    cd - > /dev/null
     303    if [ ${runCAF} -eq ${true} ] ; then # CAF RUN
     304        cd caf
     305        print_header 'CAF'
     306        g++ ${prefixCAF} CAFMatrix.cpp ${suffixCAF} -o a.${hostname} > /dev/null 2>&1
     307        for p in ${bench_cores} ; do
     308            sed -i "s/max-threads = .*/max-threads = ${p}/g" caf-application.conf # set CAF parallelism
     309            single_run ${p}
     310        done
     311        rm a.${hostname}
     312
     313        # set back parallelism
     314        sed -i "s/max-threads = .*/max-threads = 1/g" caf-application.conf
     315        cd - > /dev/null
     316    fi # done CAF
     317    if [ ${runAKKA} -eq ${true} ] ; then # AKKA RUN
     318        cd akka/Matrix
     319        rm -rf project target                           # random out of memory errors without this
     320        print_header 'Akka'
     321        for p in ${bench_cores} ; do
     322            set_akka_parallelism ${p}
     323            affinity ${p}
     324            repeat_command taskset -c ${taskset} sbt ${sbtflags} "run ${pre_args} ${p}" 2>&1 | grep -v "SLF4J:" | grep -v "Slf4jLogger started" | sed -e "s/\x1b\[0J//"
     325            sbt clean > /dev/null
     326        done
     327        # set back parallelism
     328        set_akka_parallelism 1
     329        cd - > /dev/null
     330    fi # done AKKA
     331    if [ ${runUCPP} -eq ${true} ] ; then # UCPP RUN
     332        cd ucpp
     333        print_header 'uC++'
     334        ${UCPP} ${UCPPflags} uC++Matrix.cc -o a.${hostname} > /dev/null 2>&1
     335        run_bench
     336        rm a.${hostname}
     337        cd - > /dev/null
     338    fi # done UCPP
     339    if [ ${runPROTO} -eq ${true} ] ; then # PROTO RUN
     340        cd proto/Matrix
     341        print_header 'ProtoActor'
     342        go build -o a.${hostname} > /dev/null 2>&1
     343        run_bench
     344        rm a.${hostname}
     345        cd - > /dev/null
     346    fi # done PROTO
     347    echo ""
     348fi
     349
     350if [ ${repeat} -eq ${true} ] ; then
     351    echo "repeat"
     352    pre_args="${messages}"
     353    post_args="${n_repeats}"
     354    cd cfa
     355    for i in ${!names[@]}; do
     356        print_header ${names[$i]}
     357        ${cfa} ${cfa_flags} ${var_flags[$i]} repeat.cfa -o a.${hostname} > /dev/null 2>&1
     358        run_bench
     359        rm a.${hostname}
     360    done
     361    cd - > /dev/null
     362    if [ ${runCAF} -eq ${true} ] ; then # CAF RUN
     363        cd caf
     364        print_header 'CAF'
     365        g++ ${prefixCAF} CAFRepeat.cpp ${suffixCAF} -o a.${hostname} > /dev/null 2>&1
     366        for p in ${bench_cores} ; do
     367            sed -i "s/max-threads = .*/max-threads = ${p}/g" caf-application.conf # set CAF parallelism
     368            single_run ${p}
     369        done
     370        rm a.${hostname}
     371
     372        # set back parallelism
     373        sed -i "s/max-threads = .*/max-threads = 1/g" caf-application.conf
     374        cd - > /dev/null
     375    fi # done CAF
     376    if [ ${runAKKA} -eq ${true} ] ; then # AKKA RUN
     377        cd akka/Repeat
     378        rm -rf project target                           # random out of memory errors without this
     379        print_header 'Akka'
     380        for p in ${bench_cores} ; do
     381            set_akka_parallelism ${p}
     382            affinity ${p}
     383            repeat_command taskset -c ${taskset} sbt ${sbtflags} "run ${pre_args} ${p} ${post_args}" 2>&1 | grep -v "SLF4J:" | grep -v "Slf4jLogger started" | sed -e "s/\x1b\[0J//"
     384            sbt clean > /dev/null
     385        done
     386        # set back parallelism
     387        set_akka_parallelism 1
     388        cd - > /dev/null
     389    fi # done AKKA
     390    if [ ${runUCPP} -eq ${true} ] ; then # UCPP RUN
     391        cd ucpp
     392        print_header 'uC++'
     393        ${UCPP} ${UCPPflags} uC++Repeat.cc -o a.${hostname} > /dev/null 2>&1
     394        run_bench
     395        rm a.${hostname}
     396        cd - > /dev/null
     397    fi # done UCPP
     398    if [ ${runPROTO} -eq ${true} ] ; then # PROTO RUN
     399        print_header 'ProtoActor'
     400        cd proto/Repeat
     401        go build -o a.${hostname} > /dev/null 2>&1
     402        run_bench
     403        rm a.${hostname}
     404        cd - > /dev/null
     405    fi # done PROTO
     406    echo ""
     407fi
     408
     409
     410if [ ${static} -eq ${true} ] ; then
     411    echo "static"
     412    preprint=''
     413    cd cfa
     414    for i in ${!names[@]}; do
     415        echo ${names[$i]}
     416        ${cfa} ${cfa_flags} ${var_flags[$i]} static.cfa -o a.${hostname} > /dev/null 2>&1
     417        repeat_command taskset -c ${startcore} ./a.${hostname} ${n_static_sends}
     418        rm a.${hostname}
     419    done
     420    cd - > /dev/null
     421    if [ ${runCAF} -eq ${true} ] ; then # CAF RUN
     422        cd caf
     423        echo 'CAF:'
     424        g++ ${prefixCAF} CAFSendStatic.cpp ${suffixCAF} -o a.${hostname} > /dev/null 2>&1
     425        sed -i "s/max-threads = .*/max-threads = 1/g" caf-application.conf # set CAF parallelism
     426        repeat_command taskset -c ${startcore} ./a.${hostname} 'd'
     427        rm a.${hostname}
     428        cd - > /dev/null
     429    fi # done CAF
     430    if [ ${runAKKA} -eq ${true} ] ; then # AKKA RUN
     431        cd akka/SendStatic
     432        rm -rf project target                           # random out of memory errors without this
     433        echo 'Akka:'
     434        set_akka_parallelism 1
     435        taskset -c ${startcore} sbt ${sbtflags} "run ${n_static_sends} ${numtimes}" 2>&1 | grep -v "SLF4J:" | grep -v "Slf4jLogger started" | sed -e "s/\x1b\[0J//"
     436        cd - > /dev/null
     437    fi # done AKKA
     438    if [ ${runUCPP} -eq ${true} ] ; then # UCPP RUN
     439        cd ucpp
     440        echo 'uC++:'
     441        ${UCPP} ${UCPPflags} uC++SendStatic.cc -o a.${hostname} > /dev/null 2>&1
     442        repeat_command taskset -c ${startcore} ./a.${hostname} ${n_static_sends}
     443        rm a.${hostname}
     444        cd - > /dev/null
     445    fi # done UCPP
     446    if [ ${runPROTO} -eq ${true} ] ; then # PROTO RUN
     447        cd proto/SendStatic
     448        echo 'ProtoActor:'
     449        go build -o a.${hostname} > /dev/null 2>&1
     450        repeat_command taskset -c ${startcore} ./a.${hostname} ${n_static_sends}
     451        rm a.${hostname}
     452        cd - > /dev/null
     453    fi # done PROTO
     454    echo ""
     455fi
     456
     457if [ ${dynamic} -eq ${true} ] ; then
     458    echo "dynamic"
     459    cd cfa
     460    for i in ${!names[@]}; do
     461        echo ${names[$i]}
     462        ${cfa} ${cfa_flags} ${var_flags[$i]} dynamic.cfa -o a.${hostname} > /dev/null 2>&1
     463        repeat_command taskset -c ${startcore} ./a.${hostname} ${n_dynamic_sends}
     464        rm a.${hostname}
     465    done
     466    cd - > /dev/null
     467    if [ ${runCAF} -eq ${true} ] ; then # CAF RUN
     468        cd caf
     469        echo 'CAF:'
     470        g++ ${prefixCAF} CAFSendDynamic.cpp ${suffixCAF} -o a.${hostname} > /dev/null 2>&1
     471        sed -i "s/max-threads = .*/max-threads = 1/g" caf-application.conf # set CAF parallelism
     472        repeat_command taskset -c ${startcore} ./a.${hostname} 'd'
     473        rm a.${hostname}
     474        cd - > /dev/null
     475    fi # done CAF
     476    if [ ${runAKKA} -eq ${true} ] ; then # AKKA RUN
     477        cd akka/SendDynamic
     478        rm -rf project target                           # random out of memory errors without this
     479        echo 'Akka:'
     480        set_akka_parallelism 1
     481        taskset -c ${startcore} sbt ${sbtflags} "run d ${numtimes}" 2>&1 | grep -v "SLF4J:" | grep -v "Slf4jLogger started" | sed -e "s/\x1b\[0J//"
     482        cd - > /dev/null
     483    fi # done AKKA
     484    if [ ${runUCPP} -eq ${true} ] ; then # UCPP RUN
     485        cd ucpp
     486        echo 'uC++:'
     487        ${UCPP} ${UCPPflags} uC++SendDynamic.cc -o a.${hostname} > /dev/null 2>&1
     488        repeat_command taskset -c ${startcore} ./a.${hostname} ${n_dynamic_sends}
     489        rm a.${hostname}
     490        cd - > /dev/null
     491    fi # done UCPP
     492    if [ ${runPROTO} -eq ${true} ] ; then # PROTO RUN
     493        cd proto/SendDynamic
     494        echo 'ProtoActor:'
     495        go build -o a.${hostname} > /dev/null 2>&1
     496        repeat_command taskset -c ${startcore} ./a.${hostname} 'd'
     497        rm a.${hostname}
     498        cd - > /dev/null
     499    fi # done PROTO
     500    echo ""
     501fi
     502
     503
     504if [ ${balance} -eq ${true} ] ; then
     505    cd cfa
     506    echo "balance_one"
    163507    for i in ${!names[@]}; do
    164508        echo ${names[$i]}':'
    165509        echo -e "proc\ttime (s)"
    166         ${cfa} ${cfa_flags} ${var_flags[$i]} executor.cfa > /dev/null 2>&1
    167         for p in ${bench_cores} ; do
    168             affinity ${p}
    169             # echo "taskset -c ${startcore}-`expr ${startcore} + ${p} - 1` ./a.out 40000 100 ${nRounds} ${p} ${batch}"
    170             preprint="${p}\t"
    171             repeat_command taskset -c ${taskset} ./a.out 40000 100 ${nRounds} ${p} ${batch}
    172         done
    173         rm a.out
    174     done
    175     echo ""
    176 fi
    177 
    178 if [ ${matrix} -eq ${true} ] ; then
    179     echo "matrix"
    180     for i in ${!names[@]}; do
    181         echo ${names[$i]}
    182         echo -e "proc\ttime (s)"
    183         ${cfa} ${cfa_flags} ${var_flags[$i]} matrix.cfa > /dev/null 2>&1
    184         for p in ${bench_cores} ; do
    185             affinity ${p}
    186             preprint="${p}\t"
    187             repeat_command taskset -c ${taskset} ./a.out ${size} ${size} ${size} ${p}
    188         done
    189         rm a.out
    190     done
    191     echo ""
    192 fi
    193 
    194 if [ ${repeat} -eq ${true} ] ; then
    195     echo "repeat"
    196     echo -e "proc\ttime (s)"
    197     for i in ${!names[@]}; do
    198         echo ${names[$i]}
    199         ${cfa} ${cfa_flags} ${var_flags[$i]} repeat.cfa > /dev/null 2>&1
     510        ${cfa} ${cfa_flags} ${var_flags[$i]} balance.cfa -o a.${hostname} > /dev/null 2>&1
    200511        for p in ${bench_cores} ; do
    201512            affinity ${p}
    202513            preprint="${p}\t"
    203             repeat_command taskset -c ${taskset} ./a.out ${messages} ${p} 256 ${n_repeats}
    204         done
    205         rm a.out
    206     done
    207     echo ""
    208 fi
    209 
    210 
    211 if [ ${static} -eq ${true} ] ; then
    212     echo "static"
    213         for i in ${!names[@]}; do
    214             echo ${names[$i]}
    215             ${cfa} ${cfa_flags} ${var_flags[$i]} static.cfa > /dev/null 2>&1
    216             repeat_command taskset -c ${startcore} ./a.out ${n_static_sends}
    217             rm a.out
    218         done
    219     echo ""
    220 fi
    221 
    222 if [ ${dynamic} -eq ${true} ] ; then
    223     echo "dynamic"
    224         for i in ${!names[@]}; do
    225             echo ${names[$i]}
    226             ${cfa} ${cfa_flags} ${var_flags[$i]} dynamic.cfa > /dev/null 2>&1
    227             repeat_command taskset -c ${startcore} ./a.out ${n_dynamic_sends}
    228         done
    229     echo ""
    230 fi
    231 
    232 
    233 if [ ${balance} -eq ${true} ] ; then
    234     echo "balance_one"
     514            repeat_command taskset -c ${taskset} ./a.${hostname} 32 32 ${nOneRounds} ${p}
     515        done
     516        rm a.${hostname}
     517    done
     518    echo ""
     519    echo "balance_multi"
    235520    for i in ${!names[@]}; do
    236521        echo ${names[$i]}':'
    237522        echo -e "proc\ttime (s)"
    238         ${cfa} ${cfa_flags} ${var_flags[$i]} balance.cfa > /dev/null 2>&1
     523        ${cfa} ${cfa_flags} ${var_flags[$i]} -DMULTI balance.cfa -o a.${hostname} > /dev/null 2>&1
    239524        for p in ${bench_cores} ; do
    240525            affinity ${p}
    241526            preprint="${p}\t"
    242             repeat_command taskset -c ${taskset} ./a.out 32 32 ${nOneRounds} ${p}
    243         done
    244         rm a.out
    245     done
    246     echo ""
    247     echo "balance_multi"
    248     for i in ${!names[@]}; do
    249         echo ${names[$i]}':'
    250         echo -e "proc\ttime (s)"
    251         ${cfa} ${cfa_flags} ${var_flags[$i]} -DMULTI balance.cfa > /dev/null 2>&1
    252         for p in ${bench_cores} ; do
    253             affinity ${p}
    254             preprint="${p}\t"
    255             repeat_command taskset -c ${taskset} ./a.out 32 32 ${nMultiRounds} ${p}
    256         done
    257         rm a.out
    258     done
    259     echo ""
    260 fi
    261 
     527            repeat_command taskset -c ${taskset} ./a.${hostname} 32 32 ${nMultiRounds} ${p}
     528        done
     529        rm a.${hostname}
     530    done
     531    echo ""
     532    cd - > /dev/null
     533fi
     534
Note: See TracChangeset for help on using the changeset viewer.