1# print summary of output generated by pwrtest.sh
2#
3# default results directories are <device>-<date>[-experiment]. By default
4# match any device and the year 201*.
5#
6# Examples:
7#
8# - show output for all bullhead tests in july 2015:
9#    ./pwrsummary.sh -r "bh-201507*"
10#
11# - generate CSV file for import into spreadsheet:
12#    ./pwrsummary.sh -o csv
13#
14
15CMDDIR=$(dirname $0 2>/dev/null)
16CMDDIR=${CMDDIR:=.}
17cd $CMDDIR
18CMDDIR=$(pwd)
19cd -
20POWERAVE="python $CMDDIR/powerave.py"
21
22defaultPattern="*-201*"
23defaultVoltage=4.3
24defaultFrequency=5
25
26function Usage {
27	echo "$0 [-o format] [-v voltage] [-h freq] [-f resultsDirectories]"
28}
29
30while [ $# -gt 0 ]
31do
32	case "$1" in
33	(-o) format=$2; shift;;
34	(-v) voltage=$2; shift;;
35	(-h) hz=$2; shift;;
36	(-r) testResults="$2"; shift;;
37	(--help) Usage; exit 0;;
38	(--) shift; break;;
39	(*)
40		echo Unknown option: $1
41		Usage
42		exit 1;;
43	esac
44	shift
45done
46
47testResults=${testResults:=$defaultPattern}
48voltage=${voltage:=$defaultVoltage}
49hz=${hz:=$defaultFrequency}
50
51function printHeader {
52	workload=$1
53	units="unknown"
54	case $workload in
55	(suntemple|shadowgrid2)
56		units="FPS";;
57	(recentfling|youtube|chrome)
58		units="FPS from app point of view: 1/(90th percentile render time)";;
59	(sysapps)
60		units="App start/switch per second";;
61	esac
62
63	echo "Performance unit for $workload is: $units"
64	if [ "$format" = csv ]; then
65		printf "%s,%s,%s,%s,%s,%s,%s,%s,%s\n" " " build min ave max net-mA@${voltage}v base-mW net-mW perf/W
66	else
67		printf "%-30s %-8s %12.12s %12.12s %12.12s %12.12s %12.12s %12.12s %12.12s\n" " " build min ave max net-mA@${voltage}v base-mW net-mW perf/W
68	fi
69}
70
71function average {
72	awk 'BEGIN { count=0; sum=0; max=-1000000000; min=1000000000; }
73	{
74		cur = $1;
75		sum = sum + cur;
76		if (cur > max) max = cur;
77		if (cur < min) min = cur;
78		count++;
79	}
80
81	END {
82		if (count > 0) {
83			ave = sum / count;
84			printf "%.2f %.2f %.2f\n", min, ave, max;
85		}
86	}'
87}
88
89function hwuiOutputParser {
90	# Stats since: 60659316905953ns
91	# Total frames rendered: 150
92	# Janky frames: 89 (59.33%)
93	# 90th percentile: 23ms
94	# 95th percentile: 27ms
95	# 99th percentile: 32ms
96	# Number Missed Vsync: 0
97	# Number High input latency: 0
98	# Number Slow UI thread: 0
99	# Number Slow bitmap uploads: 12
100	# Number Slow draw: 89
101	# use with "stdbuf -o0 " to disable pipe buffering
102	# stdbuf -o0 adb shell /data/local/tmp/hwuimacro shadowgrid2 400 | stdbuf -o0 ./hwuitestfilter.sh  | tee t.csv
103	sed -e 's/ns//' -e 's/[\(\)%]/ /g' | awk '
104	BEGIN { startTime=0; lastTime=0; }
105	/^Stats since:/ {
106		curTime = $3;
107		if (startTime == 0) {
108			startTime = curTime;
109		}
110		if (lastTime) {
111			interval = curTime - lastTime;
112			fps = totalFrames*1000000000 / interval;
113			diffTime = curTime - startTime;
114			printf "%.2f, %.2f, ",diffTime/1000000, fps;
115		}
116	}
117	/^Total frames/ { totalFrames=$4; }
118	/^Janky frames:/ {
119		if (lastTime) {
120			printf "%.2f\n",$4; lastTime=curTime;
121		}
122		lastTime = curTime;
123	}'
124}
125
126function sysappOutputParser {
127	awk '
128	BEGIN { fmt=0; count=0; sum=0; }
129	/^App/ {
130		if (count != 0) {
131			if (fmt > 2) printf "Ave: %0.2fms\n", sum/count;
132			else printf " %0.2f\n", sum/count;
133			count = 0;
134			sum = 0;
135		}
136	}
137	/^[a-z]/ { val=$2; if (val != 0) { count++; sum+=val; } }
138	/^Iteration/ { if (fmt > 2) printf "%s : ", $0; else if (fmt) printf "%d ", $2; }
139	'
140}
141
142function calcPerfData {
143	testdir=$1
144	workload=$2
145	baselineCurrent=$3
146	baselinePower=$4
147
148	file=${workload}.out
149	powerfile=${workload}-power.out
150	build="$(cat build 2>/dev/null)"
151	build=${build:="Unknown"}
152
153	lines=$(wc -l $file 2>/dev/null | cut -f1 -d\ )
154
155	if [ ${lines:=0} -eq -0 ]; then
156		# No performance data captured
157		if [ "$format" = csv ]; then
158			printf "%s,%s,%s\n" $testdir "$build" "no data"
159		else
160			printf "%-30s %-8s %12.12s\n" $testdir "$build" "no data"
161		fi
162		return 1
163	fi
164
165	set -- $($POWERAVE $hz $voltage $powerfile)
166	current=$(echo $1 $baselineCurrent | awk '{ printf "%.2f", $1-$2; }')
167	power=$(echo $2 $baselinePower | awk '{ printf "%.2f", $1-$2; }')
168
169	case $workload in
170	(idle)
171		set -- 0 0 0
172		;;
173	(suntemple)
174		# units are fps
175		set -- $(grep "FPS average" $file  | sed 's/^.*seconds for a //' | awk '{ print $1; }' | average)
176		;;
177	(recentfling|youtube|chrome)
178		# units are ms, so need to convert to app/ms
179		set -- $(grep ^Frames:  $file | tr "/" " " | awk '{ print $4; }' | average | awk '{ printf "%.3f %.3f %.3f\n", 1000/$3, 1000/$2, 1000/$1;}'  )
180		;;
181	(sysapps)
182		# units are ms, so need to convert to app/ms
183		set -- $(cat $file | sysappOutputParser | average | awk '{ printf "%.3f %.3f %.3f\n", 1000/$3, 1000/$2, 1000/$1;}'  )
184		;;
185	(shadowgrid2)
186		# units are fps
187		set -- $(cat $file | hwuiOutputParser | tr ',' ' ' | awk '{print $2;}' | average)
188		;;
189	esac
190
191	minperf=$1
192	aveperf=$2
193	maxperf=$3
194	perfPerWatt=$(echo $aveperf $power | awk '{ if ($2) { val=$1*1000/$2; printf "%.3f\n", val; } else print "unknown"; }')
195	if [ "$format" = csv ]; then
196		printf "%s,%s,%f,%f,%f,%f,%f,%f," $testdir "$build" $minperf $aveperf $maxperf $current $baselinePower $power
197		printf "%s\n" $perfPerWatt
198	else
199		printf "%-30s %-8s %12.2f %12.2f %12.2f %12.2f %12.2f %12.2f " $testdir "$build" $minperf $aveperf $maxperf $current $baselinePower $power
200		printf "%12s\n" $perfPerWatt
201	fi
202}
203
204function calcBaselinePower {
205	workload=$1
206	defaultPowerFile="idle-display-power.out"
207	powerFile=$defaultPowerFile
208	case $workload in
209	(shadowgrid2|suntemple|recentfling)
210		powerFile="idle-airplane-display-power.out"
211		if [ ! -f  $powerFile ]; then
212			powerFile=$defaultPowerFile
213		fi;;
214	esac
215	if [ -f  $powerFile ]; then
216		$POWERAVE 5 4.3 $powerFile
217	fi
218}
219
220for t in $(cat tests)
221do
222	echo .======================= $t ================================
223	printHeader $t
224	for i in $testResults
225	do
226		cd $i
227		baseline="$(calcBaselinePower $t)"
228		if [ "$baseline" != "" ]; then
229	       		calcPerfData $i $t $baseline
230		else
231			echo "$i : no baseline current"
232		fi
233		cd - > /dev/null
234	done
235done
236