#!/bin/bash

# bps.sh   Command-line version of bps

#Check environment variables

[ -n "$DEBUG" ] && set -vx
if [ -z "$BPS_RSH" ]
then
 rsh_method=rsh
else
 rsh_method=$BPS_RSH
fi
if [ -z "$BPS_RCP" ]
then
 rcp_method=rcp
else
 rcp_method=$BPS_RCP
fi

# defines
Version="BPS 1.4"
MachineData=machine.data
BonnieLog=bonnie.log
NetperfLog=netperf.log
NetpipeLog=netpipe.log
NetpipeData=netpipe.data
NpbLog=npb.log
StreamLog=stream.log
UnixbenchLog=unixbench.log
LMLog=lmbench.log

#prints log header

headerstart() { 
	printf "[ start $* - `date` ]\n" 
}

#prints log footer

headerend()   { 
	printf "[ end   $* - `date` ]\n" 
}

#help function
show_ver() {
	echo $Version
}
show_help() {
	printf "Usage: $0 <OPTIONS>\n\n"
	printf "Options:\n"
	printf "  -b <file system>              bonnie++\n"
	printf "  -s    	          	stream\n"
	printf "  -f <send node>,<receive node> netperf to remote node\n"
        printf "  -p <send node>,<receive node> netpipe to remote node\n"
	printf "  -n <compiler>,<#processors),  NAS parallel benchmarks\n"
	printf "     <test size>,<MPI>,         compiler={gnu/gnu4/pgi/intel/path}\n"
	printf "     <machine1,machine2,...>    test size={A,B,C,dummy}\n"
	printf "                   		MPI={lam,mpich,mpichgm,mpich2,ompi,dummy}\n"
	printf "  -k                  		keep NAS directory when finished\n"
	printf "  -u                  		unixbench\n"
	printf "  -m				lmbench\n"
	printf "  -l <log_dir>        		benchmark log directory\n"
	printf "  -w                  		preserve existing log directory\n"
	printf "  -i <mboard manufacturer>,	machine information\n"
	printf "     <mboard model>,<memory>,\n"
	printf "     <interconnect>,<linux ver>\n"
	printf "  -v                  		show version\n"
	printf "  -h                  		show this help\n"
	printf "\n"
	exit 1 
}

# the actual benchmark running functions
run_bonnie() {
	headerstart bonnie
	$BPSDIR/bin/bonnie++  -d $Bonnie_opt
	headerend bonnie
}
run_netperf() {
        local port
	node1=`printf "$*" | cut -d, -f1`
	node2=`printf "$*" | cut -d, -f2` 
	uid=`whoami`
	declare -i port
	port=$[1024+$$]
        #clean up any stray jobs on both nodes
        $rsh_method -n $node1 killall netserver "&>" /dev/null
        $rsh_method -n $node2 killall netserver "&>" /dev/null
        $rsh_method -n $node1 killall netperf "&>" /dev/null
        $rsh_method -n $node2 killall netperf "&>" /dev/null
        #Copy binaries to users bps-log directory (should be in /home)
        $rsh_method -n $node1 "mkdir -p /tmp/${uid}"
        /bin/cp  "$BPSDIR/bin/netperf" $Logdir
        /bin/cp  "$BPSDIR/bin/netserver" $Logdir
	echo "starting remote netserver on '$node2' with port $port to receive from '$node1'"
	$rsh_method -n $node2 $Logdir/netserver -p $port "&>" /dev/null "&"
	sleep 2
	headerstart netperf
	$rsh_method -n $node1 $Logdir/netperf -p $port -t UDP_STREAM -n 2 -l 60 -H $node2 -- -s 65535 -m 1472
	$rsh_method -n $node1 $Logdir/netperf -p $port -t TCP_STREAM -n 2 -l 60 -H $node2
	headerend netperf
	#cleanup
	/bin/rm $Logdir/netserver
	/bin/rm $Logdir/netperf
	$rsh_method -n $node1 killall netperf "&>" /dev/null
	$rsh_method -n $node2 killall netserver "&>" /dev/null
}
run_netpipe() {
	node1=`printf "$*" | cut -d, -f1`
        node2=`printf "$*" | cut -d, -f2`
	uid=`whoami`
	#clean up any stray jobs on both nodes
	$rsh_method -n $node1 killall NPtcp "&>" /dev/null
	$rsh_method -n $node2 killall NPtcp "&>" /dev/null
	#Copy binaries incase the do not exist on host
	/bin/cp  "$BPSDIR/bin/NPtcp" $Logdir
	
	#start the receiver
        $rsh_method -n $node2 "$Logdir/NPtcp -r &> /dev/null &"
	echo "starting NPtcp receiver on '$node2' to receive from '$node1'"
	headerstart netpipe
	#$rsh_method -n $node1 touch /tmp/${uid}/${NetpipeData} "&>" /dev/null
	#start the sender
	$rsh_method -n $node1 "$Logdir/NPtcp -t -h $node2 -P -o $Logdir/${NetpipeData}"
	headerend netpipe
	# cleanup
	$rsh_method -n $node2 killall NPtcp "&>" /dev/null
	$rsh_method -n $node1 killall NPtcp "&>" /dev/null
	/bin/rm $Logdir/NPtcp
}
run_npb() {
        compiler=`printf "$*" | cut -d, -f1`
	numproc=`printf "$*" | cut -d, -f2`
	testsize=`printf "$*" | cut -d, -f3`
	mpi=`printf "$*" | cut -d, -f4`
        headerstart NAS
	echo "Compiler: $compiler Processors: $numproc Size: $testsize MPI: $mpi"
	cd $Logdir/npb
	echo "Running: ./run_suite -c $compiler -n $numproc -t $testsize -m $mpi" 
	./run_suite -c $compiler -n $numproc -t $testsize -m $mpi 
	cat  $Logdir/npb/results/npb.$compiler.$mpi.$testsize.$numproc 
        headerend NAS
}
run_stream() {
	headerstart stream
	$BPSDIR/bin/stream-wall
	headerend stream
}
run_lmbench() {
	headerstart lmbench
	cd /tmp/$username/LMbench
	./lmexpect &> /dev/null
	cd results
	make summary-html  2>/dev/null
	make clean &>/dev/null
	headerend lmbench
}

run_unixbench() {
	headerstart unixbench
	/tmp/$username/unixbench/Run
	headerend unixbench
}

#check directory settings

if [ -z "$BPSDIR" ]
then 
	if [ -d /opt/bps ]
	then
		BPSDIR=/opt/bps
	else
		printf "Error: No BPSDIR environment variable set and bps.sh  not found in\n       /opt/bps.\n       Please set this to the location of the bps root directory.\n"
		exit 1
	fi
fi 

#check our options
declare -i optnum=0
declare -i NoOverwrite=0
while getopts "msn:kp:f:l:b:uwhvi:" opt
do
    let optnum=optnum+1
	case $opt in
		s) Stream=1 ;;
		n) Npb=1 ; Npb_opts=$OPTARG;;
		p) Netpipe=1 ; Netpipe_opts=$OPTARG ;;
		f) Netperf=1 ; Netperf_opts=$OPTARG ;;
		b) Bonnie=1 ; Bonnie_opt=$OPTARG;;
		l) Logdir=$OPTARG ; [ $Logdir != "/" ] && Logdir=${OPTARG%%/} ;;
		k) KeepNAS=1 ;;
		u) Unixbench=1 ;;
		m) lmbench=1 ;;
		w) NoOverwrite=1 ;;
		i) Information=1 ; Info_opts=$OPTARG ;;
		h) show_help ; exit 0;;
		v) show_ver ; exit 0;;
		\?) show_help; exit 1;;
	esac
done

#check user id
username=`whoami`
#[ $username = "root" ] && echo "NOTE: BPS Can not be run as root" && show_help && exit
[ $OPTIND -eq 1 ] && show_help #no options specified... give some assistance
[ $optnum -eq 1 ] && [ $NoOverwrite -eq 1 ] && show_help #-w specified but nothing else
[ $optnum -eq 1 ] && [ -n "$Logdir" ] && show_help
if [ -z "$Logdir" ]
then
	if [ -z "$BPSLOGDIR" ]
	then
		printf "Logdir defaulting to ~/bps-logs\n"
		Logdir=~/bps-logs
	else
		Logdir=$BPSLOGDIR
	fi
else
	if [ -e $Logdir ] && [ ! -w $Logdir ]
	then
		printf "No write permission on ${Logdir}\n"
		exit 1
	fi
fi

# if the logdir exists make a backup (only if user specifies with -w)
if [ $NoOverwrite -eq 1 ]
then 
	if [ -e $Logdir ] 
	then
		if [ $Logdir = $HOME ]
		then
			printf "$HOME is your home directory, it can not be backed up\n"
			exit 1
		elif [ $Logdir = "/" ]
		then
			printf "Root directory can not be backed up\n"
			exit 1
		else
			printf "$Logdir exists... backed up to ${Logdir}.`date '+%s'`\n"
			[ -e ${Logdir}.bbench.bak ] && rm -rf ${Logdir}.bbench.bak
			mv -f $Logdir ${Logdir}.`date '+%s'`
			mkdir $Logdir &> /dev/null
		fi
	else
		mkdir $Logdir &> /dev/null
	fi
else
 mkdir $Logdir &> /dev/null
fi
printf "Note: $Logdir must be mounted on all nodes (i.e. under /home)\n"
#create machinedata file for reference
uname -a > ${Logdir}/${MachineData}
grep "model name" /proc/cpuinfo >> ${Logdir}/${MachineData}
grep "cpu MHz" /proc/cpuinfo >> ${Logdir}/${MachineData}
[ -n "$Information" ] && $(echo $Info_opts | (IFS=',';read A B C D E;echo -e "Motherboard Manufacturer: ${A}\nMotherboard Model: ${B}\nMemory: ${C}\nInterconnects: ${D}\nLinux Version: ${E}">> ${Logdir}/${MachineData}))



# run the benchmarks

if [ -n "$lmbench" ] 
then
	echo "Running LMBench..."
	mkdir -p /tmp/$username
	cp -r $BPSDIR/src/lmbench-2.0-patch1.tgz /tmp/$username
	cd /tmp/$username
	tar -xzf /tmp/$username/lmbench-2.0-patch1.tgz
	run_lmbench &> ${Logdir}/${LMLog}
	rm -rf /tmp/$username
fi
[ -n "$Bonnie" ] && echo "Running Bonnie++..." && run_bonnie &> ${Logdir}/${BonnieLog} 
if [ -n "$Netperf" ]
then
	echo "Running Netperf..."
	run_netperf $Netperf_opts &> ${Logdir}/${NetperfLog} 
	rm -f /tmp/netperf.debug
fi

[ -n "$Netpipe" ] && echo "Running Netpipe..." && run_netpipe $Netpipe_opts &> ${Logdir}/${NetpipeLog} 

if [ -n "$Npb" ]
then 
	echo "Running NAS Parallel Benchmarks..."
        A=`printf "$Npb_opts" | cut -d, -f1`
	B=`printf "$Npb_opts" | cut -d, -f2`
	C=`printf "$Npb_opts" | cut -d, -f3`
	D=`printf "$Npb_opts" | cut -d, -f4`
	machines=`printf "$Npb_opts" | cut -d, -f5-`
        username=`whoami`
	tar -C $Logdir -xzf $BPSDIR/src/npb.tar.gz 
	echo $machines | sed -f /$BPSDIR/bin/sedscr > $Logdir/npb/cluster/machines 
	run_npb $Npb_opts &> $Logdir/npb.$A.$D.$C.$B
	if [ ! -n "$KeepNAS" ]
	then
		rm -rf $Logdir/npb 
	fi
fi

[ -n "$Stream" ] && echo "Running Stream..." && run_stream &> ${Logdir}/${StreamLog} 

if [ -n "$Unixbench" ] 
then
	echo "Running Unixbench..."
	username=`whoami`
	mkdir -p /tmp/$username
	cp $BPSDIR/src/unixbench.tar.gz /tmp/$username
	cd /tmp/$username
	tar -xzf /tmp/$username/unixbench.tar.gz
	cd /tmp/$username/unixbench
	run_unixbench &> ${Logdir}/${UnixbenchLog}  
	cp /tmp/$username/unixbench/results/report $Logdir/unixbench.report
	rm -rf /tmp/$username
fi

#if [ -n "$Xbench" ]
#then
#	echo 
#	echo " --> 'xhost localhost' must be set by root."
#	echo " --> Your screen will go blank while the test is running"
#	echo " --> Press Return when ready"
#	read 
#	echo "Running Xbench..." 
#	run_xbench &> ${Logdir}/${XbenchLog} 
#	run_xbench_post
#fi 
