#!/bin/bash
# Run stream benchmark via VMRegress

P=vmr-stream
LIBHUGETLBFS_VERSION=2.9
ARRAYBACKING=static,malloc
RELINK=old
NOCHECK_DEVIATION=
INCREMENT=3
. $SHELLPACK_INCLUDE/common.sh

# Basic arguement parser
while [ "$1" != "" ]; do
	case "$1" in
		--backing)    ARRAYBACKING=$2; shift 2;;
		--hpages)     REQUIRED_HPAGES=$2; shift 2;;
		--smallonly)  SMALLONLY=yes; shift;;
		--hugeonly)   HUGEONLY=yes; shift;;
		--new-relink) RELINK=new; shift;;
		--increments) INCREMENT=$2; shift 2;;
		--no-check-deviation)
			      NOCHECK_DEVIATION=--no-check-deviation
			      shift
			      ;;
		--) shift; break;;
	esac
done

# Check for libhugetlbfs support files
USE_LARGE_PAGES=yes
. $SHELLPACK_INCLUDE/include-libhugetlbfs.sh

# Prepare the benchmark
if [ -e "$LOGDIR_RESULTS" ]; then
	echo Cleaning up old results
	rm -rf $LOGDIR_RESULTS
fi

# Run the benchmark
echo "Starting bench-stream test"

RUNBENCH="$SHELLPACK_TOPLEVEL/vmr/bin/bench-stream.sh --libhugetlbfs-root $LIBHUGETLBFS_ROOT $NOCHECK_DEVIATION --increments $INCREMENT"
LIBHUGESTACK="--libhugetlbfs-root $LIBHUGETLBFS_ROOT --use-libhugetlbfs-stack"
LIBHUGEMALLOC="--libhugetlbfs-root $LIBHUGETLBFS_ROOT --use-libhugetlbfs-malloc"
LIBHUGEBDT="--libhugetlbfs-root $LIBHUGETLBFS_ROOT --use-libhugetlbfs-bdt"
LIBHUGEB="--libhugetlbfs-root $LIBHUGETLBFS_ROOT --use-libhugetlbfs-b"
LIBHUGEALIGN="--libhugetlbfs-root $LIBHUGETLBFS_ROOT --use-libhugetlbfs-align"

BACKINGLIST=
if [ "$HUGEONLY" != "yes" ]; then
	for i in `echo $ARRAYBACKING | tr , " "`; do
		BACKINGLIST="$BACKINGLIST $i-small"
	done
fi
if [ "$SMALLONLY" != "yes" ]; then
	for i in `echo $ARRAYBACKING | tr , " "`; do
		BACKINGLIST="$BACKINGLIST $i-huge"
	done
fi
for backing in $BACKINGLIST; do
	echo 0 > /proc/sys/vm/nr_hugepages
	case "$backing" in
		static-small)
			save_rc $RUNBENCH -r $LOGDIR_RESULTS/stream-static-small 2>&1
			recover_rc
			check_status "$P: stream-static-small"
			;;
		static-huge)
			if [ "$RELINK" = "old" ]; then
				save_rc $RUNBENCH -r $LOGDIR_RESULTS/stream-static-largeBDT $LIBHUGEBDT 2>&1
				recover_rc
				check_status "$P: stream-static-largeBDT"
			else
				save_rc $RUNBENCH -r $LOGDIR_RESULTS/stream-static-largeAlign $LIBHUGEALIGN 2>&1
				recover_rc
				check_status "$P: stream-static-largeAlign"
			fi
			;;
		malloc-small)
			save_rc $RUNBENCH -r $LOGDIR_RESULTS/stream-malloc-small --use-malloc-array 2>&1
			recover_rc
			check_status "$P: stream-malloc-small"
			;;
		malloc-huge)
			save_rc $RUNBENCH -r $LOGDIR_RESULTS/stream-malloc-large --use-malloc-array $LIBHUGEMALLOC  2>&1
			recover_rc
			check_status "$P: stream-malloc-large"
			;;
		stack-small)
			save_rc $RUNBENCH -m 27 -r $LOGDIR_RESULTS/stream-stack-small --use-stack-array 2>&1
			recover_rc
			check_status "$P: stream-stack-small"
			;;
		static-huge)
			save_rc $RUNBENCH -m 27 -r $LOGDIR_RESULTS/stream-stack-large --use-stack-array $LIBHUGESTACK  2>&1
			recover_rc
			check_status "$P: stream-stack-large"
			;;
	esac

	recover_rc
	RET=$?
done

# Check for errors
for i in stream-static-small stream-static-largeBDT stream-malloc-small stream-malloc-large stream-stack-small stream-stack-large; do
	TEST=`grep ERROR $LOGDIR_RESULTS/$i/log.txt 2> /dev/null`
	if [ "$TEST" != "" ]; then
		die libhugetlbfs reported an error: $TEST
		RET=$SHELLPACK_ERROR
	fi
done

# Generate graphs
print_stream_header() {
	echo "set terminal postscript color
		set output '$2'
		set xlabel \"working set size\"
		set ylabel \"Throughput MB/s\"
		set format x \"2**%g\"
		" > $1

}

# Do malloc/static comparisons
for OP in Add Copy Scale Triad; do
	print_stream_header $LOGDIR_RESULTS/mallocstatic-small-$OP.plot $LOGDIR_RESULTS/mallocstatic-small-$OP.ps
	echo "plot 'stream-static-small/stream-$OP.avg' with lines, \
	     	   'stream-malloc-small/stream-$OP.avg' with lines
		">> $LOGDIR_RESULTS/mallocstatic-small-$OP.plot

	print_stream_header $LOGDIR_RESULTS/mallocstatic-large-$OP.plot $LOGDIR_RESULTS/mallocstatic-large-$OP.ps
	echo "plot 'stream-static-largeBDT/stream-$OP.avg' with lines, \
	     	   'stream-malloc-large/stream-$OP.avg' with lines
		">> $LOGDIR_RESULTS/mallocstatic-large-$OP.plot
done

# Compare the operations
for ALLOCTYPE in static malloc; do
	LARGE=large
	if [ "$ALLOCTYPE" = "static" ]; then
		LARGE=largeBDT
	fi
	for SIZE in small $LARGE; do
		print_stream_header $LOGDIR_RESULTS/operations-$ALLOCTYPE-$SIZE.plot $LOGDIR_RESULTS/operations-$ALLOCTYPE-$SIZE.ps
		echo "plot \
			'stream-$ALLOCTYPE-$SIZE/stream-Add.avg' with lines, \
			'stream-$ALLOCTYPE-$SIZE/stream-Copy.avg' with lines, \
			'stream-$ALLOCTYPE-$SIZE/stream-Scale.avg' with lines, \
			'stream-$ALLOCTYPE-$SIZE/stream-Triad.avg' with lines \
		">> $LOGDIR_RESULTS/operations-$ALLOCTYPE-$SIZE.plot
	done
done

# Compare large/small page sizes
for OP in Add Copy Scale Triad; do
	print_stream_header $LOGDIR_RESULTS/pagesizes-$OP.plot $LOGDIR_RESULTS/pagesizes-$OP.ps
	echo "plot 'stream-static-small/stream-$OP.avg' with lines, \
	     	   'stream-static-largeBDT/stream-$OP.avg' with lines, \
		   'stream-malloc-small/stream-$OP.avg' with lines, \
	     	   'stream-malloc-large/stream-$OP.avg' with lines
		">> $LOGDIR_RESULTS/pagesizes-$OP.plot
done

# Generate Summary
if [ "$RET" = "0" ]; then
  echo bench-stream completed successfully
else
  echo bench-stream failed miserably
fi

exit $RET
#### Description Run the VMRegress-based STREAM benchmark
#### Details vmr-stream-bench 6
