#! /bin/sh
#
# This shell script performs a basic set of tests on a system
#
graph="-gnuplot -givedy"
plotext="x"
maxnp=4
gnuplot="gnuplot"
chatty=1
mpirun=mpirun
cachesize=4194304
dolong=0
outputdir="."
#ttime="0:10"
#
for arg in "$@" ; do
    case $arg in 
	-maxnp=*)
	maxnp="`echo $arg|sed 's/-maxnp=//'`"
	;;

	-cachesize=*)
	cachesize="`echo $arg|sed 's/-cachesize=//'`"
	;;

        -ttime=*)
	ttime="`echo $arg|sed 's/-ttime=//'`"
	;;

	-silent)
	chatty=0
	;;

	-gnuplot=*)
	gnuplot="`echo $arg|sed 's/-gnuplot=//'`"
	;;

	-noplot)
	gnuplot=""
	;;

	-mpirun=*)
	mpirun="`echo $arg|sed 's/-mpirun=//'`"
	;;

	-outputdir=*)
	outputdir="`echo $arg|sed 's/-outputdir=//'`"
	;;

	-long)
	dolong=1
	;;

	-echo)
	set -x
	;;
	
	-eps)
	graph="-gnuploteps -givedy"
	plotext="eps"
	;;

	-ps)
	graph="-gnuplotps -givedy"
	plotext="ps"
	;;

	-help)
	echo "basttest [ -maxnp=nn ] [ -ttime=hh:mm ] [ -silent ] "
	echo "         [ -gnuplot=program ] [ -echo ]"
	echo "         [ -mpirun=mpirun_program ] [ -cachesize=nn ]"
	echo "         [ -long ] [ -eps ] [ -ps ]"
	echo "         [ -noplot ]"
	echo " "
	echo "Run performance test programs and generate graphics output."
	echo " -maxnp=nn    - sets the maximum number of processes to use."
	echo "                The default is $maxnp ."
 	echo " -ttime=hh:mm - Run the stress test for hh hours and mm minutes."
	echo "                If not specified, stress is NOT run."
	echo " -silent      - Operate quietly (suppresses output about "
	echo "                progress)."
	echo " -gnuplot=program - Give the location of gnuplot.  If no"
	echo "                gnuplot is available, the output is placed in"
	echo "                the tar file base.tar ."
	echo " -echo        - Echo what this script is doing."
	echo " -mpirun=program - Give the program used to run MPI jobs."
 	echo " -cachesize=n - Give a size for the data cache; should be at"
	echo "                at least as large as the actual cache.  The "
	echo "                default is $cachesize ."
	echo " -long        - Run the long message tests (they take longer)"
	echo " -eps         - Prepare output in Encapsulated Postscript"
	echo "                (for including in documents)."
	echo " -ps          - Prepare output in Postscript (for printing)"
	echo " -noplot      - Do not run GNUPLOT; instead, create a tar file"
	echo "                basetest.tar containing the data."
	exit 1
	;;

	*)
	if test -n "$arg" ; then
   	    echo "port: Unknown argument ($arg)"
	    exit 1
        fi
	;;
    esac
done

#
# Check that environment is ready.  Check everything before exiting.
if [ ! -x mpptest -o ! -x goptest ] ; then
    echo "You must first build the executables mpptest and goptest"
    mustexit=1
fi
if [ -n "$ttime" -a ! -x stress ] ; then
    echo "You must first build the executables stress"
    mustexit=1
fi
if [ "$mustexit" = 1 ] ; then
    exit 1
fi
#
# Setup
temp=`which $gnuplot | head -1`
if [ ! -x "$temp" ] ; then
    if [ $chatty = 1 ] ; then
	echo "Gnuplot is not available on this machine; a tar file"
	echo "containing the data will be created."
    fi
    gnuplot=""
fi
#
ReportProgress() {
    if [ $chatty = 1 ] ; then
	echo $*
    fi
    }
#
# Informational header (date, etc)
/bin/rm -f info.txt
echo "Peformance results with mpptest and goptest for up to $maxnp processes" \
	> info.txt
date >> info.txt
#
# Correctness
if [ -n "$ttime" ] ; then
    ReportProgress "Starting stress tests..."
    # short messages
    $mpirun -np $maxnp stress -ttime $ttime
    # long messages
    $mpirun -np $maxnp stress -ttime $ttime -size 0 65536 2048
fi
#
# Performance tests
#
ReportProgress "Starting performance tests..."
perfiles=""
PLOTFILE=""
#
# Point-to-point performance
ReportProgress "Short messages"
/bin/rm -f short.gcm short.gpl
$mpirun -np 2 mpptest -auto $graph -fname $outputdir/short.gcm
perfiles="$perfiles short.gcm short.gpl"
PLOTFILE="$PLOTFILE short.gcm"
#
if [ $dolong = 1 ] ; then 
    ReportProgress "Long messages"
    /bin/rm -f long.gcm long.gpl
    $mpirun -np 2 mpptest -size 262144 1048576 32768 $graph \
	-fname $outputdir/long.gcm \
	    -reps 25 -tgoal 1.0 -autoreps -sample_reps 5
    perfiles="$perfiles long.gcm long.gpl"
    PLOTFILE="$PLOTFILE long.gcm"
    /bin/rm -f longnb.gcm longnb.gpl
    $mpirun -np 2 mpptest -async -size 262144 1048576 32768 $graph \
	-fname $outputdir/longnb.gcm \
	    -reps 25 -tgoal 1.0 -autoreps -sample_reps 5
    perfiles="$perfiles longnb.gcm longnb.gpl"
    PLOTFILE="$PLOTFILE longnb.gcm"
fi
#
ReportProgress "Short messages out of cache"
/bin/rm -f shortc.gcm shortc.gpl
$mpirun -np 2 mpptest $graph -cachesize $cachesize \
	-fname $outputdir/shortc.gcm
perfiles="$perfiles shortc.gcm shortc.gpl"
PLOTFILE="$PLOTFILE shortc.gcm"
#
#
ReportProgress "Short messages with vectors"
/bin/rm -f shortv.gcm shortv.gpl
$mpirun -np 2 mpptest $graph -vector -vstride 128 -fname $outputdir/shortv.gcm
perfiles="$perfiles shortv.gcm shortv.gpl"
PLOTFILE="$PLOTFILE shortv.gcm"
#
# bisection and other collective tests
#
ReportProgress "Collective tests"
NPLIST="4"
if [ 32 -le $maxnp ] ; then 
    NPLIST="$NPLIST 32"
elif [ 4 -lt $maxnp ] ; then
    NPLIST="$NPLIST $maxnp"
elif [ 4 -gt $maxnp ] ; then
    NPLIST="2"
else
    NPLIST="2 $NPLIST"
fi
/bin/rm -f bcast.gpl dsum.gpl
for NP in $NPLIST ; do 
    ReportProgress "Bisection for $NP (short)"
    /bin/rm -f bshort$NP.gcm bshort$NP.gpl
    $mpirun -np $NP mpptest -auto -bisect $graph \
	-fname $outputdir/bshort$NP.gcm 
    perfiles="$perfiles bshort$NP.gcm bshort$NP.gpl"

    if [ $dolong = 1 ] ; then
        ReportProgress "Bisection for $NP (long)"
        /bin/rm -f blong$NP.gcm blong$NP.gpl
        $mpirun -np 2 mpptest -size 262144 1048576 32768 $graph \
	        -reps 25 -tgoal 1.0 -autoreps -sample_reps 5 \
	        -bisect -fname $outputdir/blong$NP.gcm
        perfiles="$perfiles blong$NP.gcm blong$NP.gpl"
        PLOTFILE="$PLOTFILE blong$NP.gcm"
    fi
    #
    # Collective operations; these are formed by running the
    # same test with different numbers of processors
    #
    /bin/rm -f bcast.gcm
    ReportProgress "Broadcast for $NP (short)"
    $mpirun -np $NP goptest $graph -bcast -fname bcast.gcm 

    /bin/rm -f dsum.gcm
    ReportProgress "Reduction for $NP (short)"
    $mpirun -np $NP goptest $graph -dsum -size 0 1024 256 -fname dsum.gcm
done
perfiles="$perfiles bcast.gcm bcast.gpl dsum.gcm dsum.gpl"
PLOTFILE="$PLOTFILE bcast.gcm dsum.gcm"
#
# Generate Postscript plots OR tar file containing data
#
ReportProgress "Assembling output"
#
# Text summary
# (This is done by reading the individual files and extracting data from them)
#
# point to point parameters
if [ -r short.gcm ] ; then
    latency1="`grep 'startup' short.gcm | cut -d' ' -f 4,5`"
    rate1="`grep 'startup' short.gcm | cut -d' ' -f 10,11`"
fi
if [ -r shortc.gcm ] ; then
    latency2="`grep 'startup' shortc.gcm | cut -d' ' -f 4,5`"
    rate2="`grep 'startup' shortc.gcm | cut -d' ' -f 10,11`"
fi
if [ -r shortv.gcm ] ; then
    latency3="`grep 'startup' shortv.gcm | cut -d' ' -f 4,5`"
    rate3="`grep 'startup' shortv.gcm | cut -d' ' -f 10,11`"
fi
if [ -r long.gcm ] ; then
    latency4="`grep 'startup' long.gcm | cut -d' ' -f 4,5`"
    rate4="`grep 'startup' long.gcm | cut -d' ' -f 10,11`"
fi
if [ -r longnb.gcm ] ; then
    latency5="`grep 'startup' longnb.gcm | cut -d' ' -f 4,5`"
    rate5="`grep 'startup' longnb.gcm | cut -d' ' -f 10,11`"
fi
# Collective parameters
outcnt=1
for NP in $NPLIST ; do
    if [ -r bshort$NP.gcm ] ; then
	file=bshort$NP.gcm
        lat="`grep 'startup' $file | cut -d' ' -f 4,5`"
	eval blatency$outcnt=\""$lat"\"
        rat="`grep 'startup' $file | cut -d' ' -f 10,11`"
	eval brate$outcnt=\""$rat"\"
	eval np$outcnt=$NP
    fi
    if [ -r blong$NP.gcm ] ; then
	file=blong$NP.gcm
        lat="`grep 'startup' $file | cut -d' ' -f 4,5`"
	eval bllatency$outcnt=\""$lat"\"
        rat="`grep 'startup' $file | cut -d' ' -f 10,11`"
	eval blrate$outcnt=\""$rat"\"
	eval np$outcnt=$NP
    fi
    outcnt=`expr $outcnt + 1`
done
#
# Still need to get something from the dsum output.
# Still need to generate in a "nice" form (fixed length latency and rate)
cat >>info.txt <<EOF
Results from fit to measured data.  Please check the graphs to understand
the actual performance.

Point to Point results:
                            latency           bandwidth
short messages (blocking)   $latency1         $rate1
 not in cache               $latency2         $rate2
 strides of 128             $latency3         $rate3
EOF
if [ $dolong = 1 ] ; then
    cat >>info.txt <<EOF
long messages               $latency4         $rate4
long messages (nonblocking) $latency5         $rate5
EOF
fi
cat >>info.txt <<EOF
Collective results:
Bisection tests
EOF
# Add the collective results
i=1
while [ $i -lt $outcnt ] ; do
    eval np=$"np$i"
    eval blatency=$"blatency$i"
    eval brate=$"brate$i"
    if [ -n "$blatency" ] ; then
        echo " short ($np)                $blatency         $brate" >> info.txt
    fi
    i=`expr $i + 1`
done
i=1
while [ $i -lt $outcnt ] ; do
    eval np=$"np$i"
    eval blatency=$"bllatency$i"
    eval brate=$"blrate$i"
    if [ -n "$blatency" ] ; then
        echo " long ($np)                 $blatency         $brate" >> info.txt
    fi
    i=`expr $i + 1`
done
#
if [ $chatty = 1 ] ; then 
   cat info.txt
fi
#
# Graphics output
if [ -n "$gnuplot" ] ; then
    if [ "$plotext" != "x" ] ; then
        for plotfile in $PLOTFILE ; do 
	    destfile=`basename $plotfile .gcm`
	    gnuplot $outputdir/$plotfile > $outputdir/$destfile.$plotext
        done 
    else 
	# The user desires x output
	if [ $chatty = 1 ] ; then
	    echo "Run gnuplot on the files $PLOTFILE in $outputdir."
	fi
    fi
else
    if [ -r basetest.tar ] ; then
	echo "Output file basetest.tar already exists. Cannot make "
	echo "tar file with "
	if [ "$outputdir" = "." ] ; then
    	    echo "tar cf basetest.tar $perfiles"
	else
	    actfiles=""
	    for f in $perfiles ; do
		actfiles="$actfiles $outputdir/$f"
	    done
    	    echo "tar cf basetest.tar $actfiles"
        fi
    else
        # Add program to build plots when file is unpacked later
	/bin/rm -f makeplots
        cat > makeplots <<EOF
#! /bin/sh
if [ "\$1" = "-print" ] ; then 
    for plotfile in $PLOTFILE ; do
        destfile=\`basename $plotfile .gcm\`
	# Just in case eps format ... 
        cat $outputdir/\$plotfile | sed \
	 -e 's/terminal postscript eps/terminal postscript/g' | gnuplot \
		> $outputdir/\$destfile.ps
	lpr $outputdir/\$destfile.ps
    done
else
    for plotfile in $PLOTFILE ; do
        destfile=`basename $plotfile .gcm`
        gnuplot $outputdir/\$plotfile > $outputdir/\$destfile.$plotext
    done
fi
EOF
	chmod a+x makeplots
	if [ "$outputdir" = "." ] ; then
            tar cf basetest.tar makeplots info.txt $perfiles
	else
	    actfiles=""
	    for f in $perfiles ; do
		actfiles="$actfiles $outputdir/$f"
	    done
            tar cf basetest.tar makeplots info.txt $actfiles
	fi
    fi
fi


