#! /bin/sh
# This version puts the output from each program into a separate file.
# -mvhome is needed for the ANL SP, and is ignored by others
args="-mvhome"
device=ch_gm
if [ "$device" = "ch_p4mpd" ] ; then
    args=""
fi
STOPFILE=$HOME/.stopmpichtests
#
# Some people don't include "." in their path (! in case an ls trojan horse,
# I guess - if someone does that to you, you have bigger problems).  This
# code tests to see if you have a path to mpirun; if not, it tries ./mpirun.
#
# One particular problem is having multiple mpiruns in the path.  An
# absolute path for mpirun will fix many problems
mpirun="/usr/rels/mpich-1.2..4pre2/bin/mpirun"
if [ -z "$MPICH_USE_LIB_MPIRUN" -a ! -x "$mpirun" ] ; then
    IFS="${IFS= 	}"; saveifs="$IFS"; IFS="${IFS}:"
    for dir in $PATH ; do 
        if [ -x $dir/mpirun ] ; then
	    if [ -n "" ] ; then
		# Test that we've found the correct mpirun
		if strings $dir/mpirun | grep "MPIRUN for MPICH" > /dev/null ; then
		    :
		else
		    # echo "$dir/mpirun isn't for MPICH"
		    continue
		fi
	    fi
            mpirun="mpirun"
            break
        fi
    done
    IFS="$saveifs"
fi
if [ -z "$mpirun" -a -x "./mpirun" ] ; then
    mpirun=./mpirun
fi
#
# Here is the location of the MPICH version of mpirun
if [ -z "$mpirun" -a -x ./bin/mpirun ] ; then 
    mpirun="./bin/mpirun"
fi
if [ -z "$mpirun" ] ; then
    echo "No mpirun in path.  Testing can not proceed."
    exit 1
fi
#
runtests=1
makeeach=0
quiet=0
MAKE="make --no-print-directory"
for arg in "$@" ; do
    case $arg in 
	-checkonly )
	runtests=0
	;;
        -margs=*)
	margs=`echo $arg | sed 's/-margs=//'`
	args="$args $margs"
	;;
	-small)
	shift
	makeeach=1
	;;
	-quiet)
	shift
	quiet=1
	;;
	-help|-u)
	echo "runtests [-checkonly] [-margs='...']"
	echo "run tests in this directory.  If -checkonly set, just run"
	echo "the differences check (do NO rerun the test programs)."
	echo "If -margs is used, these options are passed to mpirun."
	echo "If -small is used, the examples are built, run, and deleted."
	exit 1
	;;
	*)
	if test -n "$arg" ; then
   	    echo "runtests: Unknown argument ($arg)"
	    exit 1
        fi
	;;
    esac
done

MakeExe() {
    if [ -s $STOPFILE ] ; then 
        echo "Found stopfile; exiting"
	exit 0
    fi
    if [ ! -x $1 ] ; then
	$MAKE $1
        if [ ! -x $1 ] ; then 
	    echo "Could not build executable $1; aborting tests"
	    exit 1
        fi
    fi
}
CleanExe() {
    if [ $makeeach = 1 ] ; then
	/bin/rm -f $1 $1.o
    fi
}
# Output marker
OutTime() {
    if [ $quiet = 0 ] ; then
	if [ -z "$hostname" ] ; then
	    hostname=`hostname`
	fi
	d=`date`
	echo "$hostname : $d"
    fi
}

# Runtest pgm-name np marker-test args outfiles
RunTest() {
    OutTime
    testfiles="$testfiles $1.out"
    /bin/rm -f $1.out
    MakeExe $1
    mname=$3
    if [ -z "$mname" ] ; then mname="*** $1 ***" ; fi
    echo "$mname" >> $1.out
    echo "$mname"
    mvarg=""
    if [ -n "$5" ] ; then rm -f $5 ; 
	if [ "$device" != "ch_p4mpd" ] ; then
             if [ -n "-mvback" ] ; then mvarg="-mvback \"$5\"" ;
fi 
	fi
    fi
    eval $mpirun $args -np $2 $mvarg $1 $4 </dev/null >> $1.out 2>&1
    if [ -n "$5" ] ; then cat $5 >> $1.out ; rm -f $5 ; fi
    echo "$mname" >> $1.out
    #CheckOutput $1
    CleanExe $1
}

# If the programs are not available, run make.
if [ ! -x coll1 -a $makeeach = 0 -a $runtests = 1 ] ; then
    $MAKE default
fi

testfiles=""
if [ $runtests = 1 ] ; then
echo '**** Testing MPI Collective routines ****'

RunTest barrier 4 "*** Barrier Test ***" "" "barrier-0.out"

if [ "$device" != "ch_p4mpd" ] ; then
RunTest bcast 4 "*** Broadcast Test ***" "" "bcast-0.out bcast-1.out bcast-2.out bcast-3.out"
fi

if [ "$device" != "ch_p4mpd" ] ; then
RunTest bcastvec 4 "*** Broadcast Datatype Test ***" "" "bcastvec-0.out bcastvec-1.out bcastvec-2.out bcastvec-3.out"
fi

RunTest coll1 4

RunTest coll2 5

RunTest coll3 5

RunTest coll4 4

RunTest coll5 4

RunTest coll6 5

RunTest coll7 5

RunTest coll8 4

RunTest coll9 4

RunTest coll10 4

RunTest coll11 4

RunTest scantst 4

RunTest coll12 4

# coll13 is very picky about arguments
RunTest coll13 4

RunTest longuser 4

# Some implementations (e.g., IBM's) forget to handle the np = 1 case.
#RunTest longuser 1 "*** longuser (np == 1) ***"
OutTime
testfiles="$testfiles longuser1.out"
/bin/rm -f longuser1.out
MakeExe longuser
echo '**** longuser (np == 1) ****'
echo '*** longuser (np == 1) ***' >> longuser1.out
$mpirun -np 1 $args longuser < /dev/null >> longuser1.out 2>&1
echo '*** longuser (np == 1) ***' >> longuser1.out
CleanExe longuser

#OutTime
#testfiles="$testfiles allredmany.out"
#/bin/rm -f allredmany.out
#MakeExe allredmany
#echo '**** allredmany ****'
#echo '*** allredmany ***' >> allredmany.out
#cnt=0
## Run several times to try and catch timing/race conditions in managing
## the flood of one-way messages.
#while [ $cnt -lt 20 ] ; do
#    echo "*** allredmany run $cnt ***" >> allredmany.out
#    $mpirun -np 2 $args allredmany >> allredmany.out 2>&1
#    cnt=`expr $cnt + 1`
#done
#echo '*** allredmany ***' >> allredmany.out
#CleanExe allredmany

RunTest grouptest 4

RunTest allred 4 "*** Allred ***"

RunTest scatterv 4 "*** Scatterv ***"

RunTest scattern 4 "*** Scattern ***"

RunTest redscat 4 "*** Reduce_scatter ***"

RunTest alltoallv 4 "*** Alltoallv ***"

#
# Run Fortran tests ONLY if Fortran available
if [ 1 = 1 ] ; then 
    echo "FORTRAN TESTS"

    RunTest allredf 4 "*** Testing allreduce from Fortran ***"

    RunTest assocf 4 "*** Testing allreduce from Fortran (2) ***"
    echo "END OF FORTRAN TESTS"
fi

else
    # Just run checks
    testfiles=`echo *.out`
    if test "$testfiles" = "*.out" ; then
	echo "No output files remain from previous test!"
	exit 1
    fi
fi

echo '*** Checking for differences from expected output ***'
/bin/rm -f coll.diff
nodiff=1
srcdir=/usr/rels/mpich-1.2..4pre2/examples/test/coll
for file in $testfiles ; do
    stdfile=$srcdir/`basename $file .out`.std
    if [ -s $stdfile ] ; then
        if diff -b $file $stdfile > /dev/null ; then
	    true
  	else
	    echo "Differences in `basename $file .out`" >> coll.diff
	    diff -b $file $stdfile >> coll.diff
	    nodiff=0
	fi
    else
        echo "Cannot find file $stdfile to compare against for test `basename $file .out`"
    fi
done
if [ -s coll.diff ] ; then
   cat coll.diff
elif [ $nodiff = 1 ] ; then
   echo "-- No differences found; test successful"
fi
exit 0



