@@ -1,134 +1,9 @@
1#!/usr/bin/env bash
1#!/usr/bin/env bash
3−#------------------------------------------------------------------------------
5−#------------------------------------------------------------------------------
7−# IMPORTANT NOTE: the names "_grp" and "_cmp" suffixes are special, do
8−# not rename them to something else.
11− Data.Stream.StreamD \
12− Data.Stream.StreamK \
13− Data.Stream.StreamDK"
20−prelude_concurrent_grp="\
34− Data.Array.Storable.Foreign \
37− Data.Array.Prim.Pinned"
39−base_parser_grp="Data.Parser.ParserD Data.Parser.ParserK"
40−parser_grp="Data.Fold Data.Parser"
42−#------------------------------------------------------------------------------
43−# Streaming vs non-streaming
44−#------------------------------------------------------------------------------
45−# The "o-1-space" groups of these benchmarks are run with long stream
46−# sizes when --long option is used.
49− $prelude_serial_grp \
50− $prelude_concurrent_grp \
53−#------------------------------------------------------------------------------
55−#------------------------------------------------------------------------------
56−# *_cmp denotes a comparison benchmarks, the benchmarks provided in *_cmp
57−# variables are compared with each other
58−base_stream_cmp="Data.Stream.StreamD Data.Stream.StreamK"
59−serial_wserial_cmp="Prelude.Serial Prelude.WSerial"
60−serial_async_cmp="Prelude.Serial Prelude.Async"
61−concurrent_cmp="Prelude.Async Prelude.WAsync Prelude.Ahead Prelude.Parallel"
62−array_cmp="Memory.Array Data.Array.Prim Data.Array Data.Array.Prim.Pinned"
63−pinned_array_cmp="Memory.Array Data.Array.Prim.Pinned"
64−base_parser_cmp=$base_parser_grp
74−#------------------------------------------------------------------------------
76−#------------------------------------------------------------------------------
77−# All high level benchmarks
79− $prelude_serial_grp \
80− $prelude_concurrent_grp \
90− prelude_concurrent_grp \
96−#------------------------------------------------------------------------------
98−#------------------------------------------------------------------------------
100−BENCH_SH_DIR=$(cd `dirname $0`; pwd)
3+SCRIPT_DIR=$(cd `dirname $0`; pwd)
103− echo "Individual benchmarks:"
111−list_bench_groups () {
5+RUNNING_BENCHMARKS=y
112− echo "Benchmark groups:"
6+source $SCRIPT_DIR/build-lib.sh
113− for i in $ALL_BENCH_GROUPS
122−list_comparisons () {
123− echo "Comparison groups:"
124− for i in $COMPARISONS
133print_help () {
8print_help () {
134 echo "Usage: $0 "
9 echo "Usage: $0 "
@@ -141,7 +16,9 @@ print_help () {
141 echo " [--slow]"
16 echo " [--slow]"
142 echo " [--quick]"
17 echo " [--quick]"
143 echo " [--raw]"
18 echo " [--raw]"
19+ echo " [--dev-build]"
144 echo " [--cabal-build-flags <flag>]"
20 echo " [--cabal-build-flags <flag>]"
21+ echo " [--rtsopts <opts>]"
145 echo " [--compare] [--base <commit>] [--candidate <commit>]"
22 echo " [--compare] [--base <commit>] [--candidate <commit>]"
146 echo " -- <gauge options or benchmarks>"
23 echo " -- <gauge options or benchmarks>"
@@ -156,6 +33,7 @@ print_help () {
156 echo "--raw: Run the benchmarks but don't report them. This is useful when"
33 echo "--raw: Run the benchmarks but don't report them. This is useful when"
157 echo " you only want to work with the csv files generated."
34 echo " you only want to work with the csv files generated."
158 echo "--cabal-build-flags: Pass any cabal builds flags to be used for build"
35 echo "--cabal-build-flags: Pass any cabal builds flags to be used for build"
36+ echo " e.g. --cabal-build-flags \"--flag fusion-plugin\""
160 echo "When specific space complexity group is chosen then (and only then) "
38 echo "When specific space complexity group is chosen then (and only then) "
161 echo "RTS memory restrictions are used accordingly. For example, "
39 echo "RTS memory restrictions are used accordingly. For example, "
@@ -170,33 +48,37 @@ print_help () {
173−# $1: message
51+#-----------------------------------------------------------------------------
174−die () {
52+# Reporting utility functions
53+#-----------------------------------------------------------------------------
56+ echo "Comparison groups:"
57+ for i in $COMPARISONS
175− >&2 echo -e "Error: $1"
59+ echo -n "$i ["
176− exit 1
60+ eval "echo -n \$$i"
179−set_benchmarks() {
66+# chart is expensive to build and usually not required to be rebuilt,
67+# use master branch as fallback
68+cabal_which_report() {
69+ local path=$(cabal_which streamly-benchmarks $1)
180− if test -z "$BENCHMARKS"
70+ if test -z "$path"
182− echo $DEFAULT_BENCHMARKS
72+ cabal_which_builddir dist-newstyle streamly-benchmarks $1
184− for i in $(echo $BENCHMARKS)
74+ echo $path
187− *_grp) eval "echo -n \$${i}" ;;
188− *_cmp) eval "echo -n \$${i} $i" ;;
196find_report_prog() {
78find_report_prog() {
197 local prog_name="chart"
79 local prog_name="chart"
199− local prog_path=$($WHICH_COMMAND_REPORT $prog_name)
81+ local prog_path=$(cabal_which_report $prog_name)
200 if test -x "$prog_path"
82 if test -x "$prog_path"
202 echo $prog_path
84 echo $prog_path
@@ -207,14 +89,16 @@ find_report_prog() {
208build_report_prog() {
90build_report_prog() {
209 local prog_name="chart"
91 local prog_name="chart"
210− local prog_path=$($WHICH_COMMAND_REPORT $prog_name)
92+ local prog_path=$(cabal_which_report $prog_name)
213 if test ! -x "$prog_path" -a "$BUILD_ONCE" = "0"
95 if test ! -x "$prog_path" -a "$BUILD_ONCE" = "0"
215− echo "Building bench-graph executables"
97+ echo "Building bench-show executables"
216 BUILD_ONCE=1
98 BUILD_ONCE=1
99+ $CABAL_EXECUTABLE v2-build --flags dev chart \
217− $BUILD_CHART_EXE || die "build failed"
100+ || die "bench-show build failed"
218 elif test ! -x "$prog_path"
102 elif test ! -x "$prog_path"
@@ -228,8 +112,8 @@ build_report_progs() {
228 build_report_prog || exit 1
112 build_report_prog || exit 1
229 local prog
113 local prog
230 prog=$(find_report_prog) || \
114 prog=$(find_report_prog) || \
231− die "Cannot find bench-graph executable"
115+ die "Cannot find bench-show executable"
232− echo "Using bench-graph executable [$prog]"
116+ echo "Using bench-show executable [$prog]"
@@ -239,42 +123,12 @@ build_report_progs() {
239# own path currently.
123# own path currently.
241# The path is dependent on the architecture and cabal version.
125# The path is dependent on the architecture and cabal version.
242−# Use this command to find the exe if this script fails with an error:
243−# find .stack-work/ -type f -name "benchmarks"
245−stack_bench_prog () {
247− local bench_prog=`stack path --dist-dir`/build/$bench_name/$bench_name
248− if test -x "$bench_prog"
256−cabal_bench_prog () {
258− local bench_prog=`$WHICH_COMMAND $1`
259− if test -x "$bench_prog"
267bench_output_file() {
127bench_output_file() {
268 local bench_name=$1
128 local bench_name=$1
269 echo "charts/$bench_name/results.csv"
129 echo "charts/$bench_name/results.csv"
273−function run_verbose() {
278# --min-duration 0 means exactly one iteration per sample. We use a million
132# --min-duration 0 means exactly one iteration per sample. We use a million
279# iterations in the benchmarking code explicitly and do not use the iterations
133# iterations in the benchmarking code explicitly and do not use the iterations
280# done by the benchmarking tool.
134# done by the benchmarking tool.
@@ -288,25 +142,21 @@ function run_verbose() {
288# We can pass --min-samples value from the command line as second argument
142# We can pass --min-samples value from the command line as second argument
289# after the benchmark name in case we want to use more than one sample.
143# after the benchmark name in case we want to use more than one sample.
291−run_bench () {
145+# $1: bench name
146+# $2: bench executable
147+target_exe_extra_args () {
292 local bench_name=$1
148 local bench_name=$1
293− local bench_exe=$bench_name
294− local output_file=$(bench_output_file $bench_name)
295− local bench_prog
149+ local bench_prog=$2
296− bench_prog=$($GET_BENCH_PROG $bench_exe) || \
297− die "Cannot find benchmark executable for benchmark $bench_name"
151+ local output_file=$(bench_output_file $bench_name)
299 mkdir -p `dirname $output_file`
152 mkdir -p `dirname $output_file`
301− echo "Running benchmark $bench_name ..."
303 local QUICK_OPTS="--quick --min-duration 0"
154 local QUICK_OPTS="--quick --min-duration 0"
304 local SPEED_OPTIONS
155 local SPEED_OPTIONS
305 if test "$LONG" -eq 0
156 if test "$LONG" -eq 0
307 if test "$SLOW" -eq 0
158 if test "$SLOW" -eq 0
310 if test "$QUICK_MODE" -eq 0
160 if test "$QUICK_MODE" -eq 0
312 # default mode, not super quick, not slow
162 # default mode, not super quick, not slow
@@ -325,20 +175,11 @@ run_bench () {
325 SPEED_OPTIONS="--stream-size 10000000 $QUICK_OPTS --include-first-iter"
175 SPEED_OPTIONS="--stream-size 10000000 $QUICK_OPTS --include-first-iter"
328− export BENCH_EXEC_PATH=$bench_prog
330− run_verbose $bench_prog $SPEED_OPTIONS \
178+ echo "$SPEED_OPTIONS \
331 --csvraw=$output_file \
179 --csvraw=$output_file \
333− --measure-with "$BENCH_SH_DIR/bench-exec-one.sh" \
181+ --measure-with "$SCRIPT_DIR/bench-exec-one.sh" \
334− $GAUGE_ARGS || die "Benchmarking failed"
182+ $GAUGE_ARGS"
344run_benches_comparing() {
185run_benches_comparing() {
@@ -358,14 +199,14 @@ run_benches_comparing() {
358 git checkout "$BASE" || die "Checkout of base commit [$BASE] failed"
199 git checkout "$BASE" || die "Checkout of base commit [$BASE] failed"
360 $BUILD_BENCH || die "build failed"
201 $BUILD_BENCH || die "build failed"
361− run_benches "$bench_list"
202+ run_targets streamly-benchmarks "$bench_list" target_exe_extra_args
363 echo "Checking out candidate commit [$CANDIDATE] for benchmarking"
204 echo "Checking out candidate commit [$CANDIDATE] for benchmarking"
364 git checkout "$CANDIDATE" || \
205 git checkout "$CANDIDATE" || \
365 die "Checkout of candidate [$CANDIDATE] commit failed"
206 die "Checkout of candidate [$CANDIDATE] commit failed"
367 $BUILD_BENCH || die "build failed"
208 $BUILD_BENCH || die "build failed"
368− run_benches "$bench_list"
209+ run_targets streamly-benchmarks "$bench_list" target_exe_extra_args
369 # XXX reset back to the original commit
210 # XXX reset back to the original commit
@@ -389,7 +230,7 @@ run_measurements() {
390 if test "$COMPARE" = "0"
231 if test "$COMPARE" = "0"
392− run_benches "$bench_list"
233+ run_targets streamly-benchmarks "$bench_list" target_exe_extra_args
394 run_benches_comparing "$bench_list"
235 run_benches_comparing "$bench_list"
@@ -413,9 +254,10 @@ run_reports() {
413# Execution starts here
254# Execution starts here
414#-----------------------------------------------------------------------------
255#-----------------------------------------------------------------------------
416−cd $BENCH_SH_DIR/..
257+cd $SCRIPT_DIR/..
418−DEFAULT_BENCHMARKS="$all_grp"
419DEFAULT_FIELDS="allocated bytescopied cputime"
261DEFAULT_FIELDS="allocated bytescopied cputime"
420ALL_FIELDS="$FIELDS time cycles utime stime minflt majflt nvcsw nivcsw"
262ALL_FIELDS="$FIELDS time cycles utime stime minflt majflt nvcsw nivcsw"
421FIELDS=$DEFAULT_FIELDS
263FIELDS=$DEFAULT_FIELDS
@@ -425,53 +267,13 @@ BASE=
425CANDIDATE=
267CANDIDATE=
435GAUGE_ARGS=
275GAUGE_ARGS=
437BUILD_ONCE=0
276BUILD_ONCE=0
441−GHC_VERSION=$(ghc --numeric-version)
443−CABAL_EXECUTABLE=cabal
445−# Use branch specific builds if git-cabal is present in PATH
446−BUILD_DIR=dist-newstyle
447−if which git-cabal 2>/dev/null
449− echo "Using git-cabal for branch specific builds"
450− CABAL_EXECUTABLE=git-cabal
451− BUILD_DIR=$(git-cabal show-builddir)
455−# $2: command to find
456−cabal_which_builddir() {
457− find $1 -type f -path "*${GHC_VERSION}/streamly-benchmarks*/$2" 2>/dev/null
461− cabal_which_builddir $BUILD_DIR $1
464−# chart is expensive to build and usually not required to be rebuilt,
465−# use master branch as fallback
466−cabal_which_report() {
467− local path=$(cabal_which $1)
470− cabal_which_builddir dist-newstyle $1
476#-----------------------------------------------------------------------------
278#-----------------------------------------------------------------------------
477# Read command line
279# Read command line
@@ -482,11 +284,13 @@ do
482 case $1 in
284 case $1 in
483 -h|--help|help) print_help ;;
285 -h|--help|help) print_help ;;
484 # options with arguments
286 # options with arguments
485− --benchmarks) shift; BENCHMARKS=$1; shift ;;
287+ --benchmarks) shift; TARGETS=$1; shift ;;
288+ --targets) shift; TARGETS=$1; shift ;;
486 --fields) shift; FIELDS=$1; shift ;;
289 --fields) shift; FIELDS=$1; shift ;;
487 --base) shift; BASE=$1; shift ;;
290 --base) shift; BASE=$1; shift ;;
488 --candidate) shift; CANDIDATE=$1; shift ;;
291 --candidate) shift; CANDIDATE=$1; shift ;;
489− --cabal-build-flags) shift; CABAL_BUILD_FLAGS=$1; shift ;;
292+ --cabal-build-flags) shift; CABAL_BUILD_OPTIONS=$1; shift ;;
293+ --cabal-build-options) shift; CABAL_BUILD_OPTIONS=$1; shift ;;
490 --rtsopts) shift; RTS_OPTIONS=$1; shift ;;
294 --rtsopts) shift; RTS_OPTIONS=$1; shift ;;
492 --slow) SLOW=1; shift ;;
296 --slow) SLOW=1; shift ;;
@@ -497,6 +301,7 @@ do
497 --long) LONG=1; shift ;;
301 --long) LONG=1; shift ;;
498 --graphs) GRAPH=1; shift ;;
302 --graphs) GRAPH=1; shift ;;
499 --no-measure) MEASURE=0; shift ;;
303 --no-measure) MEASURE=0; shift ;;
304+ --dev-build) RUNNING_DEVBUILD=1; shift ;;
500 --) shift; break ;;
305 --) shift; break ;;
501 -*|--*) echo "Unknown flags: $*"; echo; print_help ;;
306 -*|--*) echo "Unknown flags: $*"; echo; print_help ;;
502 *) break ;;
307 *) break ;;
@@ -504,8 +309,12 @@ do
505GAUGE_ARGS=$*
310GAUGE_ARGS=$*
312+#-----------------------------------------------------------------------------
314+#-----------------------------------------------------------------------------
507only_real_benchmarks () {
316only_real_benchmarks () {
508− for i in $BENCHMARKS
317+ for i in $TARGETS
510 local SKIP=0
319 local SKIP=0
511 for j in $COMPARISONS
320 for j in $COMPARISONS
@@ -522,23 +331,14 @@ only_real_benchmarks () {
525−has_item () {
334+# Requires RUNNING_DEVBUILD var
526− for i in $1
335+source $SCRIPT_DIR/targets.sh
536−BENCHMARKS_ORIG=$BENCHMARKS
537−if test "$(has_item "$BENCHMARKS_ORIG" help)" = "help"
337+if test "$(has_item "$TARGETS" help)" = "help"
539− list_bench_groups
339+ list_target_groups
540 list_comparisons
340 list_comparisons
541− list_benches
341+ list_targets
@@ -551,40 +351,24 @@ fi
552if test "$LONG" -ne 0
352if test "$LONG" -ne 0
554− if test -n "$BENCHMARKS"
354+ if test -n "$TARGETS"
556− echo "Cannot specify benchmarks [$BENCHMARKS] with --long"
356+ echo "Cannot specify benchmarks [$TARGETS] with --long"
559− BENCHMARKS=$infinite_grp
359+ TARGETS=$infinite_grp
562−BENCHMARKS=$(set_benchmarks)
362+DEFAULT_TARGETS="$(all_grp)"
563−BENCHMARKS_ORIG=$BENCHMARKS
363+TARGETS=$(set_targets)
564−BENCHMARKS=$(only_real_benchmarks)
565−EXECUTABLES=$BENCHMARKS
567−echo "Using benchmark suites [$BENCHMARKS]"
365+TARGETS_ORIG=$TARGETS
366+TARGETS=$(only_real_benchmarks)
569−if test "$USE_STACK" = "1"
368+echo "Using benchmark suites [$TARGETS]"
571− WHICH_COMMAND="stack exec which"
572− WHICH_COMMAND_REPORT="stack exec which"
573− BUILD_CHART_EXE="stack build --flag streamly:dev"
574− GET_BENCH_PROG=stack_bench_prog
575− BUILD_BENCH="stack build $STACK_BUILD_FLAGS --bench --no-run-benchmarks"
577− # XXX cabal issue "cabal v2-exec which" cannot find benchmark/test executables
578− #WHICH_COMMAND="cabal v2-exec which"
579− WHICH_COMMAND=cabal_which
580− WHICH_COMMAND_REPORT=cabal_which_report
581− BUILD_CHART_EXE="$CABAL_EXECUTABLE v2-build --flags dev chart"
582− GET_BENCH_PROG=cabal_bench_prog
583− BUILD_BENCH="$CABAL_EXECUTABLE v2-build $CABAL_BUILD_FLAGS --enable-benchmarks"
586#-----------------------------------------------------------------------------
370#-----------------------------------------------------------------------------
587−# Build stuff
371+# Build reporting utility
588#-----------------------------------------------------------------------------
372#-----------------------------------------------------------------------------
590# We need to build the report progs first at the current (latest) commit before
374# We need to build the report progs first at the current (latest) commit before
@@ -592,23 +376,16 @@ fi
592build_report_progs
376build_report_progs
594#-----------------------------------------------------------------------------
378#-----------------------------------------------------------------------------
595−# Run benchmarks
379+# Build and run targets
596#-----------------------------------------------------------------------------
380#-----------------------------------------------------------------------------
382+BUILD_BENCH="$CABAL_EXECUTABLE v2-build $CABAL_BUILD_OPTIONS --enable-benchmarks"
598if test "$MEASURE" = "1"
383if test "$MEASURE" = "1"
601− if test "$USE_STACK" = "1"
603− $BUILD_BENCH || die "build failed"
605− for c in $EXECUTABLES
607− COMPONENTS+="streamly-benchmarks:bench:$c "
385+ run_build "$BUILD_BENCH" streamly-benchmarks bench "$TARGETS"
608− done
386+ export QUICK_MODE
609− $BUILD_BENCH $COMPONENTS || die "build failed"
387+ export RTS_OPTIONS
611− run_measurements "$BENCHMARKS"
388+ run_measurements "$TARGETS"
614#-----------------------------------------------------------------------------
391#-----------------------------------------------------------------------------
@@ -618,7 +395,7 @@ fi
618COMPARISON_REPORTS=""
395COMPARISON_REPORTS=""
619for i in $COMPARISONS
396for i in $COMPARISONS
621− if test "$(has_item "$BENCHMARKS_ORIG" $i)" = $i
398+ if test "$(has_item "$TARGETS_ORIG" $i)" = $i
623 COMPARISON_REPORTS="$COMPARISON_REPORTS $i"
400 COMPARISON_REPORTS="$COMPARISON_REPORTS $i"
624 mkdir -p "charts/$i"
401 mkdir -p "charts/$i"
@@ -634,6 +411,6 @@ done
635if test "$RAW" = "0"
412if test "$RAW" = "0"
637− run_reports "$BENCHMARKS"
414+ run_reports "$TARGETS"
638 run_reports "$COMPARISON_REPORTS"
415 run_reports "$COMPARISON_REPORTS"