1#!/bin/bash
2
3
4# DEFAULT VALUES
5TESTS=()
6MIN_TIME=0.0
7MIN_ITER=0
8BATCH_MODE=0
9GRAPH_LINE=0
10GRAPH_ZERO=0
11VARIABLES=
12
13
14# DEFINES
15TEST_NAMES=(
16  LEVELS_VEC3_RELAXED            LEVELS_VEC4_RELAXED           LEVELS_VEC3_FULL              LEVELS_VEC4_FULL       BLUR_RADIUS_25              # 00-04
17  INTRINSIC_BLUR_RADIUS_25       GREYSCALE                     GRAIN                         FISHEYE_FULL           FISHEYE_RELAXED             # 05-09
18  FISHEYE_APPROXIMATE_FULL       FISHEYE_APPROXIMATE_RELAXED   VIGNETTE_FULL                 VIGNETTE_RELAXED       VIGNETTE_APPROXIMATE_FULL   # 10-14
19  VIGNETTE_APPROXIMATE_RELAXED   GROUP_TEST_EMULATED           GROUP_TEST_NATIVE             CONVOLVE_3X3           INTRINSICS_CONVOLVE_3X3     # 15-19
20  COLOR_MATRIX                   INTRINSICS_COLOR_MATRIX       INTRINSICS_COLOR_MATRIX_GREY  COPY                   CROSS_PROCESS_USING_LUT     # 20-24
21  CONVOLVE_5X5                   INTRINSICS_CONVOLVE_5X5       MANDELBROT_FLOAT              INTRINSICS_BLEND       INTRINSICS_BLUR_25G         # 25-29
22  VIBRANCE                       BW_FILTER                     SHADOWS                       CONTRAST               EXPOSURE                    # 30-34
23  WHITE_BALANCE                  COLOR_CUBE                    COLOR_CUBE_3D_INTRINSIC       ARTISTIC1              RESIZE_BI_SCRIPT            # 35-39
24  RESIZE_BI_INTRINSIC            POSTERIZE_INVOKE              POSTERIZE_SET                 HISTOGRAM_INTRINSIC    HISTOGRAM_SCRIPT            # 40-44
25  MANDELBROT_DOUBLE              BLUR_RADIUS_25_HALF                                                                                            # 45-46
26)
27
28FUNCTION_NAMES=(
29  testLevelsVec3Relaxed          testLevelsVec4Relaxed         testLevelsVec3Full            testLevelsVec4Full     testBlurRadius25            # 00-04
30  testIntrinsicBlurRadius25      testGreyscale                 testGrain                     testFisheyeFull        testFishEyeRelaxed          # 05-09
31  testFisheyeApproximateFull     testFisheyeApproximateRelaxed testVignetteFull              testVignetteRelaxed    testVignetteApproximateFull # 10-14
32  testVignetteApproximateRelaxed testGroupTestEmulated         testGroupTestNative           testConvolve3x3        testIntrinsicsConvolve3x3   # 15-19
33  testColorMatrix                testIntrinsicsColorMatrix     testIntrinsicsColorMatrixGrey testCopy               testCrossProcessUsingLUT    # 20-24
34  testConvolve5x5                testIntrinsicsConvolve5x5     testMandelbrot                testIntrinsicsBlend    testIntrinsicsBlur25G       # 25-29
35  testVibrance                   testBWFilter                  testShadows                   testContrast           testExposure                # 30-34
36  testWhiteBalance               testColorCube                 testColorCube3DIntrinsic      testArtistic1          testResizeBiCubicScript     # 35-39
37  testResizeBiCubicIntrinsic     testPosterizeInvoke           testPosterizeSet              testHistogramIntrinsic testHistogramScript         # 40-44
38  testMandelbrotfp64             testBlurRadius25Half                                                                                           # 45-46
39)
40
41RUNNER="com.android.rs.imagejb/android.support.test.runner.AndroidJUnitRunner"
42TEST_ROOT="com.android.rs.imagejb.ImageProcessingTest"
43
44
45# Helper functions
46show_help() {
47  echo "
48    Usage: ${0##*/} [OPTIONS]...
49    Do stuff with FILE and write the result to standard output. With no FILE
50    or when FILE is -, read standard input.
51
52    -h, -?, --?, --help      display this help message
53    -t, --time K             set the minimum time (in seconds) each test should run
54    -i, --iteration[s] K     set the minimum number of iterations each test should run
55    -c, --case[s] T1 [T2]... specify the number corresponding to each test to be run;
56                             the test IDs are below
57    -b, --batch              run all tests together for speed
58    -f, --bestfit            add best fit line to graph
59    -z, --zero               set graph's minimum yrange to 0
60  "
61  echo "Available test cases:"
62  for i in `seq 0 $((${#TEST_NAMES[@]} - 1))`; do
63    echo "  $i: ${TEST_NAMES[$i]}"
64  done
65  echo
66}
67fileexists() {
68  [ `adb shell "[ -f $1 ] && echo found"` ]
69}
70
71
72# display help if blank argument list
73if [ $# -eq 0 ]; then
74  show_help
75  exit
76fi
77
78# command line parsing
79using_cases=0
80while [ $# -gt 0 ]; do
81  case $1 in
82    -h|-\?|--\?|--help)
83      show_help
84      exit
85      ;;
86    -t|--time)
87      using_cases=0
88      if [ -n "$2" ]; then
89        MIN_TIME=$2
90        shift
91        shift
92      else
93        echo 'ERROR: "--time" requires a non-empty option argument.'
94        exit 1
95      fi
96      ;;
97    -i|--iter|--iters|--iteration|--iterations)
98      using_cases=0
99      if [ -n "$2" ]; then
100        MIN_ITER=$2
101        shift
102        shift
103      else
104        echo 'ERROR: "--iteration" requires a non-empty option argument.'
105        exit 1
106      fi
107      ;;
108    -c|--case|--cases)
109      if [ -n "$2" ]; then
110        using_cases=1
111        shift
112      else
113        echo 'ERROR: "--case" requires a non-empty option argument.'
114        exit 1
115      fi
116      ;;
117    -b|--batch)
118      using_cases=0
119      BATCH_MODE=1
120      shift
121      ;;
122    -f|--bestfit)
123      using_cases=0
124      GRAPH_LINE=1
125      shift
126      ;;
127    -z|--zero)
128      using_cases=0
129      GRAPH_ZERO=1
130      shift
131      ;;
132    all)
133      if [ $using_cases -eq 1 ]; then
134        using_cases=0
135        TESTS=(`seq 0 $((${#TEST_NAMES[@]} - 1))`)
136        shift
137      else
138        echo "ERROR: Invalid option: $1"
139      fi
140      ;;
141    [0-9]*)
142      if [ $using_cases -eq 1 ]; then
143        TESTS+=($1)
144        shift
145      else
146        echo "ERROR: Invalid option: $1"
147        exit 1
148      fi
149      ;;
150    *)
151      echo "ERROR: Invalid option: $1"
152      exit 1
153      ;;
154  esac
155done
156
157# error checking
158if [ ${#TESTS[@]} -eq 0 ]; then
159  echo "ERROR: need at least one --case"
160  exit 1
161fi
162
163# configure launch variables
164if [[ ( $MIN_TIME == "0.0" ) && ( $MIN_ITER -eq 0 ) ]]; then
165  MIN_TIME=1.0
166  MIN_ITER=2
167fi
168VARIABLES="$VARIABLES -e minimum_test_runtime $MIN_TIME -e minimum_test_iterations $MIN_ITER"
169TESTS=( `printf "%s\n" "${TESTS[@]}" | sort -n | uniq` )
170
171# print prep
172echo
173[ $BATCH_MODE -eq 0 ] && echo "Running tests:" || echo "Running tests (in batch mode):"
174for i in ${TESTS[@]}; do
175  echo $i: ${TEST_NAMES[$i]}
176done
177echo "with minimum runtime per test of $MIN_TIME seconds and
178minimum number of $MIN_ITER iterations per test"
179echo
180
181# setup
182echo
183if [[ "`adb shell id | tr -d '\r' | awk -F'[()]' '{print $2}'`" != "root" ]]; then
184  adb root
185  adb wait-for-device
186fi
187
188# grant permission
189adb shell pm grant com.android.rs.imagejb android.permission.READ_EXTERNAL_STORAGE
190adb shell pm grant com.android.rs.imagejb android.permission.WRITE_EXTERNAL_STORAGE
191
192# Run each test individually...
193if [[ $BATCH_MODE -eq 0 ]]; then
194
195  # run and plot each test result separately
196  for num in `seq 0 $((${#TESTS[@]} - 1))`; do
197
198    # alias
199    testId=${TESTS[$num]}
200
201    # report progress
202    printf "Running ${TEST_NAMES[$testId]} ($(($num + 1))/${#TESTS[@]})"
203
204    # run individual test
205    adb shell "am instrument -w $VARIABLES -e class $TEST_ROOT#${FUNCTION_NAMES[$testId]} $RUNNER" > /dev/null
206
207    # extract relevant data if present, write to temporary file
208    if fileexists /sdcard/rsTimes/${TEST_NAMES[$testId]}_DATA.txt; then
209      adb shell cat /sdcard/rsTimes/${TEST_NAMES[$testId]}_DATA.txt > timing.tmp
210    else
211      printf "\r                                                                       \r"
212      echo "File ${TEST_NAMES[$testId]} not saved. Is ImageProcessing_jb able to run on this device?"
213      continue
214    fi
215
216    # calculate avg and stdcoef
217    AVG=`cat timing.tmp | awk '{sum+=$2}END{printf "%.2f",sum/NR}'`
218    STDCOEF=`cat timing.tmp | awk '{sum+=$2;sos+=$2*$2}END{printf "%.2f",sqrt((sos-sum*sum/NR)/NR)/(sum/NR)*100}'`
219
220    # create plot file
221    echo "# temporary file" > plot.tmp
222    echo "set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1" >> plot.tmp  # --- blue
223    echo "set style line 2 lc rgb '#ff0000' lt 1 lw 2" >> plot.tmp  # --- green
224    echo "set title \"${TEST_NAMES[$testId]} \(avg=$AVG ms, stdcoef=$STDCOEF%\)\"" >> plot.tmp
225    echo "set xlabel \"Iteration #\"" >> plot.tmp
226    echo "set ylabel \"Elapsed Time (ms)\"" >> plot.tmp
227    if [ $GRAPH_ZERO -eq 1 ]; then
228      echo "set yrange [0.0:*]" >> plot.tmp
229    fi
230    if [ $GRAPH_LINE -eq 1 ]; then
231      echo "set fit quiet" >> plot.tmp
232      echo "set fit logfile '/dev/null'" >> plot.tmp
233      echo "f(x) = a*x + b" >> plot.tmp
234      echo "fit f(x) 'timing.tmp' using 1:2 via a, b" >> plot.tmp
235      echo "string = sprintf('%.3fe-3*x+%.3f', a*1000, b)" >> plot.tmp
236      echo "plot 'timing.tmp' with linespoints ls 1 title 'Data', f(x) ls 2 title string" >> plot.tmp
237    else
238      echo "plot 'timing.tmp' with linespoints ls 1 title 'Data'" >> plot.tmp
239    fi
240
241    # plot data as simple line graph
242    gnuplot -p plot.tmp
243
244    # clear line
245    printf "\r                                                                       \r"
246
247  done
248
249# ...or all at once
250else
251
252  # concatenate all tests together to run in batch
253  TESTS_TEXT="-e class $TEST_ROOT#${FUNCTION_NAMES[${TESTS[0]}]}"
254  for num in `seq 1 $((${#TESTS[@]} - 1))`; do
255    TESTS_TEXT=$TESTS_TEXT,"$TEST_ROOT#${FUNCTION_NAMES[${TESTS[$num]}]}"
256  done
257
258  # run command
259  adb shell "am instrument -w $VARIABLES $TESTS_TEXT $RUNNER"
260
261  # run and plot each test result separately
262  for num in `seq 0 $((${#TESTS[@]} - 1))`; do
263
264    # alias
265    testId=${TESTS[$num]}
266
267    # extract relevant data if present, write to temporary file
268    if fileexists /sdcard/rsTimes/${TEST_NAMES[$testId]}_DATA.txt; then
269      adb shell cat /sdcard/rsTimes/${TEST_NAMES[$testId]}_DATA.txt > timing.tmp
270    else
271      echo "File ${TEST_NAMES[$testId]} not saved. Is ImageProcessing_jb able to run on this device?"
272      continue
273    fi
274
275    # calculate avg and stdcoef
276    AVG=`cat timing.tmp | awk '{sum+=$2}END{printf "%.2f",sum/NR}'`
277    STDCOEF=`cat timing.tmp | awk '{sum+=$2;sos+=$2*$2}END{printf "%.2f",sqrt((sos-sum*sum/NR)/NR)/(sum/NR)*100}'`
278
279    # create plot file
280    echo "# temporary file" > plot.tmp
281    echo "set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1" >> plot.tmp  # --- blue
282    echo "set style line 2 lc rgb '#ff0000' lt 1 lw 2" >> plot.tmp  # --- green
283    echo "set title \"${TEST_NAMES[$testId]} \(avg=$AVG ms, stdcoef=$STDCOEF%\)\"" >> plot.tmp
284    echo "set xlabel \"Iteration #\"" >> plot.tmp
285    echo "set ylabel \"Elapsed Time (ms)\"" >> plot.tmp
286    if [ $GRAPH_ZERO -eq 1 ]; then
287      echo "set yrange [0.0:*]" >> plot.tmp
288    fi
289    if [ $GRAPH_LINE -eq 1 ]; then
290      echo "set fit quiet" >> plot.tmp
291      echo "set fit logfile '/dev/null'" >> plot.tmp
292      echo "f(x) = a*x + b" >> plot.tmp
293      echo "fit f(x) 'timing.tmp' using 1:2 via a, b" >> plot.tmp
294      echo "string = sprintf('%.3fe-3*x+%.3f', a*1000, b)" >> plot.tmp
295      echo "plot 'timing.tmp' with linespoints ls 1 title 'Data', f(x) ls 2 title string" >> plot.tmp
296    else
297      echo "plot 'timing.tmp' with linespoints ls 1 title 'Data'" >> plot.tmp
298    fi
299
300    # plot data as simple line graph
301    gnuplot -p plot.tmp
302
303  done
304
305fi # single or batch mode
306
307# cleanup
308rm -f plot.tmp
309rm -f timing.tmp
310
311
312