on master help sign in
Merge pull request #1549 from composewell/bench-report-ex

Use the haskellified version of bench-report

commit411fd5200432735479033ddf9e8bd5bd83bfeee4 authorHarendra Kumar <harendra@composewell.com> dateFri 29 Apr 2022, 11:27 (5 years ago) parenta849812b7b3aa8
25 files changed+952−1818
.github/workflows/regression-check.yml+13−13 .packcheck.ignore+7−1 benchmark/bench-report/BenchReport.hs−272 benchmark/bench-report/bench-report.cabal−23 benchmark/bench-report/bin/bench-runner.sh−685 benchmark/bench-report/bin/build-lib.sh−218 benchmark/bench-report/default.nix−55 benchmark/bench-runner/Main.hs+130 benchmark/bench-runner/bench-runner.cabal+42 benchmark/bench-runner/cabal.project+1 benchmark/bench-runner/default.nix+164 bin/bench-config.sh−160 bin/bench.sh−15 bin/targets.sh−120 bin/test.sh−247 cabal.project.report+32 streamly.cabal+6−9 targets/Targets.hs+149 benchmark/bench-report/cabal.project → targets/cabal.project targets/default.nix+163 targets/streamly-targets.cabal+12 test/test-runner/Main.hs+34 test/test-runner/cabal.project+1 test/test-runner/default.nix+157 test/test-runner/test-runner.cabal+41
.github/workflows/regression-check.yml+13−13
@@ -60,18 +60,20 @@ jobs:
6060 done
6161 echo "CI_BENCHMARKS=$CI_BENCHMARKS" >> $GITHUB_ENV
6262
63− - name: Setup haskell
64− uses: actions/setup-haskell@v1
65− with:
66− ghc-version: 8.8.4
67− cabal-version: 3.2
63+ - name: Download ghc
64+ run: |
65+ curl -sL -o ./ghcup https://downloads.haskell.org/~ghcup/0.1.17.4/x86_64-linux-ghcup-0.1.17.4
66+ chmod +x ./ghcup
67+ GHCVER=8.10.7
68+ ./ghcup install ghc $GHCVER
69+ ./ghcup set ghc $GHCVER
70+ cabal update
6871
6972 - uses: actions/cache@v2
70− name: Cache ~/.cabal and bench-report
73+ name: Cache ~/.cabal
7174 with:
7275 path: |
7376 ~/.cabal
74− ./benchmark/bench-report/bin/bench-report
7577 # Bump the key version to clear the cache
7678 key: cache-v1
7779
@@ -117,8 +119,7 @@ jobs:
117119
118120 - name: Run benchmarks and append
119121 run: |
120− chmod +x $CI_BENCH_SH
121− $CI_BENCH_SH --benchmarks "$CI_BENCHMARKS" --raw --append
122+ cabal run bench-runner --project-file=cabal.project.report -- --targets "$CI_BENCHMARKS" --raw --append
122123
123124 # -----------------------------------------------------------------
124125 # -- Compare
@@ -126,12 +127,10 @@ jobs:
126127
127128 - name: List all benchmarks
128129 run: |
129− chmod +x $CI_BENCH_SH
130− $CI_BENCH_SH --no-measure
130+ cabal run bench-runner --project-file=cabal.project.report -- --targets "$CI_BENCHMARKS" --no-measure
131131
132132 - name: Compare benchmarks
133133 run: |
134− chmod +x $CI_BENCH_SH
135134
136135 EXIT_STATUS=0
137136
@@ -146,7 +145,8 @@ jobs:
146145
147146 echo
148147 echo "Checking $bname for regressions greater than $cutoff percent"
149− ! $CI_BENCH_SH --benchmarks "$bname" \
148+ ! cabal run bench-runner --project-file=cabal.project.report -- \
149+ --targets "$bname" \
150150 --fields "$CI_FIELDS" \
151151 --no-measure --silent \
152152 --diff-cutoff-percent $cutoff \
.packcheck.ignore+7−1
@@ -7,7 +7,8 @@
77.hlint.yaml
88.packcheck.ignore
99appveyor.yml
10−benchmark/bench-report/default.nix
10+benchmark/bench-runner/default.nix
11+benchmark/bench-runner/cabal.project
1112bin/ghc.sh
1213bin/run-ci.sh
1314bin/run-repl-quick.sh
@@ -17,9 +18,14 @@ cabal.project.doctest
1718cabal.project.ghc-head
1819cabal.project.hpc-coveralls
1920cabal.project.O0
21+cabal.project.report
2022cabal.project.Werror
2123cabal.project.Werror-nocode
2224default.nix
2325examples/README.md
2426hie.yaml
2527stack.yaml
28+targets/default.nix
29+targets/cabal.project
30+test/test-runner/default.nix
31+test/test-runner/cabal.project
benchmark/bench-report/BenchReport.hsdeleted−272
@@ -1,272 +0,0 @@
1−{-# LANGUAGE RecordWildCards #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−module Main where
5−
6−import Control.Exception (catch, ErrorCall(..))
7−import Control.Monad (mzero)
8−import Control.Monad.IO.Class (liftIO)
9−import Control.Monad.Trans.Maybe
10−import Control.Monad.Trans.State
11−import Data.Char (toLower)
12−import Data.List
13−import System.Environment (getArgs)
14−import Text.Read (readMaybe)
15−
16−import BenchShow
17−
18−------------------------------------------------------------------------------
19−-- Command line parsing
20−------------------------------------------------------------------------------
21−
22−data BenchType
23− = Compare String
24− | Standard String
25− deriving Show
26−
27−data Options = Options
28− { genGraphs :: Bool
29− , sortByName :: Bool
30− , useGauge :: Bool
31− , benchType :: Maybe BenchType
32− , fields :: [String]
33− , diffStyle :: GroupStyle
34− , cutOffPercent :: Double
35− } deriving Show
36−
37−defaultOptions :: Options
38−defaultOptions = Options False False False Nothing ["time"] PercentDiff 0
39−
40−setGenGraphs :: Monad m => Bool -> StateT (a, Options) m ()
41−setGenGraphs val = do
42− (args, opts) <- get
43− put (args, opts { genGraphs = val })
44−
45−setSortByName :: Monad m => Bool -> StateT (a, Options) m ()
46−setSortByName val = do
47− (args, opts) <- get
48− put (args, opts { sortByName = val })
49−
50−setUseGauge :: Monad m => Bool -> StateT (a, Options) m ()
51−setUseGauge val = do
52− (args, opts) <- get
53− put (args, opts { useGauge = val })
54−
55−setBenchType :: Monad m => BenchType -> StateT (a, Options) m ()
56−setBenchType val = do
57− (args, opts) <- get
58− put (args, opts { benchType = Just val })
59−
60−setFields :: Monad m => [String] -> StateT (a, Options) m ()
61−setFields val = do
62− (args, opts) <- get
63− put (args, opts { fields = val })
64−
65−setDiff :: Monad m => String -> StateT (a, Options) m ()
66−setDiff val = do
67− (args, opts) <- get
68− let cmpStyle =
69− case val of
70− "absolute" -> Absolute
71− "multiples" -> Multiples
72− "percent" -> PercentDiff
73− x -> error $ "Unknown diff option: " ++ show x
74− in put (args, opts { diffStyle = cmpStyle })
75−
76−setCutOff :: Monad m => String -> StateT (a, Options) m ()
77−setCutOff val = do
78− (args, opts) <- get
79− case readMaybe val of
80− Just x -> put (args, opts { cutOffPercent = x })
81− Nothing -> error $ "Invalid cutoff value: " ++ show val
82−
83−-- Like the shell "shift" to shift the command line arguments
84−shift :: StateT ([String], Options) (MaybeT IO) (Maybe String)
85−shift = do
86− s <- get
87− case s of
88− ([], _) -> return Nothing
89− (x : xs, opts) -> put (xs, opts) >> return (Just x)
90−
91−parseBench :: StateT ([String], Options) (MaybeT IO) ()
92−parseBench = do
93− x <- shift
94− case x of
95− Just str | "_cmp" `isSuffixOf` str -> setBenchType (Compare str)
96− Just str -> setBenchType (Standard str)
97− Nothing -> do
98− liftIO $ putStrLn "please provide a benchmark type "
99− mzero
100−
101−parseFields :: StateT ([String], Options) (MaybeT IO) ()
102−parseFields = do
103− x <- shift
104− case x of
105− Just str -> setFields (words str)
106− Nothing -> do
107− liftIO $ putStrLn
108− "please provide a list of fields after --fields"
109− mzero
110−
111−parseDiff :: StateT ([String], Options) (MaybeT IO) ()
112−parseDiff = do
113− x <- shift
114− case x of
115− Just str -> setDiff str
116− Nothing -> do
117− liftIO $ putStrLn "please provide a diff type"
118− mzero
119−
120−parseCutOff :: StateT ([String], Options) (MaybeT IO) ()
121−parseCutOff = do
122− x <- shift
123− case x of
124− Just str -> setCutOff str
125− Nothing -> do
126− liftIO $ putStrLn "please provide a cutoff percent"
127− mzero
128−
129−-- totally imperative style option parsing
130−parseOptions :: IO (Maybe Options)
131−parseOptions = do
132− args <- getArgs
133− runMaybeT $ flip evalStateT (args, defaultOptions) $ do
134− parseLoop
135− fmap snd get
136−
137− where
138−
139− parseOpt opt =
140− case opt of
141− "--graphs" -> setGenGraphs True
142− "--sort-by-name" -> setSortByName True
143− "--use-gauge" -> setUseGauge True
144− "--benchmark" -> parseBench
145− "--fields" -> parseFields
146− "--diff-style" -> parseDiff
147− "--diff-cutoff-percent" -> parseCutOff
148− str -> do
149− liftIO $ putStrLn $ "Unrecognized option " <> str
150− mzero
151−
152− parseLoop = do
153− next <- shift
154− case next of
155− Just opt -> parseOpt opt >> parseLoop
156− Nothing -> return ()
157−
158−ignoringErr :: IO () -> IO ()
159−ignoringErr a = catch a (\(ErrorCall err :: ErrorCall) ->
160− putStrLn $ "Failed with error:\n" <> err <> "\nSkipping.")
161−
162−------------------------------------------------------------------------------
163−-- Generic
164−------------------------------------------------------------------------------
165−
166−makeGraphs :: String -> Config -> String -> IO ()
167−makeGraphs name cfg inputFile =
168− ignoringErr $ graph inputFile name cfg
169−
170−------------------------------------------------------------------------------
171−-- Arrays
172−------------------------------------------------------------------------------
173−
174−showComparisons :: Options -> Config -> FilePath -> FilePath -> IO ()
175−showComparisons Options{..} cfg inp out =
176− let cfg1 = cfg { classifyBenchmark = classifyComparison }
177− in if genGraphs
178− then ignoringErr $ graph inp "comparison"
179− cfg1 { outputDir = Just out
180− , presentation = Groups Absolute
181− }
182− else ignoringErr $ report inp Nothing cfg1
183−
184− where
185−
186− separator = if useGauge then '/' else '.'
187− dropComponent sep = dropWhile (== sep) . dropWhile (/= sep)
188−
189− -- In case of tasty-bench the names could be like
190− -- All.Data.Array.Prim.Pinned/o-1-space.generation.show
191− -- All.Data.Array.Foreign/o-1-space.generation.show
192− classifyComparison b =
193− let b1 =
194− if useGauge
195− then b
196− else dropComponent separator b --- drop "All." at the beginning
197− in Just
198− ( takeWhile (/= '/') b1
199− , dropComponent '/' b1 -- for tasty-bench drop up to "/"
200− )
201−
202−------------------------------------------------------------------------------
203−-- text reports
204−------------------------------------------------------------------------------
205−
206−selectBench
207− :: Options
208− -> (SortColumn -> Maybe GroupStyle -> Either String [(String, Double)])
209− -> [String]
210−selectBench Options{..} f =
211− -- Apply filterPred only if at least 2 columns exist
212− let colVals =
213− case f (ColumnIndex 1) (Just PercentDiff) of
214− Left _ -> either error id $ f (ColumnIndex 0) (Just PercentDiff)
215− Right xs -> filter (filterPred . snd) xs
216− in reverse
217− $ fmap fst
218− $ sortFunc colVals
219−
220− where
221−
222− sortFunc = if sortByName then sortOn fst else sortOn snd
223−
224− filterPred x
225− | isInfinite x = False
226− | isNaN x = False
227− | cutOffPercent > 0 = x >= cutOffPercent
228− | cutOffPercent < 0 = x <= cutOffPercent
229− | otherwise = True
230−
231−benchShow ::
232− Options
233− -> Config
234− -> (Config -> String -> IO ())
235− -> String
236− -> FilePath
237− -> IO ()
238−benchShow Options{..} cfg func inp out =
239− if genGraphs
240− then func cfg {outputDir = Just out} inp
241− else ignoringErr $ report inp Nothing cfg
242−
243−main :: IO ()
244−main = do
245− res <- parseOptions
246− case res of
247− Nothing -> do
248− putStrLn "cannot parse options"
249− return ()
250− Just opts@Options{fields = fs, benchType = btype} ->
251− let cfg = defaultConfig
252− { presentation = Groups (diffStyle opts)
253− , selectBenchmarks = selectBench opts
254− , selectFields = filter
255− ( flip elem (fmap (fmap toLower) fs)
256− . fmap toLower
257− )
258− }
259− in case btype of
260− Just (Compare str) ->
261− showComparisons opts cfg
262− { title = Just str }
263− ("charts/" ++ str ++ "/results.csv")
264− ("charts/" ++ str)
265− Just (Standard str) ->
266− benchShow opts cfg
267− { title = Just str }
268− (makeGraphs str)
269− ("charts/" ++ str ++ "/results.csv")
270− ("charts/" ++ str)
271− Nothing ->
272− error "Please specify a benchmark using --benchmark."
benchmark/bench-report/bench-report.cabaldeleted−23
@@ -1,23 +0,0 @@
1−cabal-version: 2.2
2−name: bench-report
3−version: 0.0.0
4−synopsis: Benchmark report generation
5−description: Benchmark reporting application is not included in the overall
6− cabal project so that the dependencies of both can remain independent.
7− Benchmark reporting has a lot of dependencies that usually lag behind
8− when new GHC releases arrive.
9−
10−-------------------------------------------------------------------------------
11−-- benchmark comparison and presentation
12−-------------------------------------------------------------------------------
13−
14−executable bench-report
15− default-language: Haskell2010
16− ghc-options: -Wall
17− hs-source-dirs: .
18− main-is: BenchReport.hs
19− buildable: True
20− build-Depends:
21− base >= 4.9 && < 4.17
22− , bench-show >= 0.3.2 && < 0.4
23− , transformers >= 0.4 && < 0.6
benchmark/bench-report/bin/bench-runner.shdeleted−685
@@ -1,685 +0,0 @@
1−#!/usr/bin/env bash
2−
3−# Note that this script is used in the "streamly" package as well as
4−# in "streaming-benchmarks" package. Any changes to the script should be
5−# generic enough so that it works in both the cases.
6−
7−#------------------------------------------------------------------------------
8−
9−set -o pipefail
10−
11−SCRIPT_DIR=$(cd `dirname $0`; pwd)
12−
13−RUNNING_BENCHMARKS=y
14−source $SCRIPT_DIR/build-lib.sh
15−
16−print_help () {
17− echo "Usage: $0 "
18− echo " [--benchmarks <"bench1 bench2 ..." | help>]"
19− echo " [--prefix <benchmark name prefix to match>"
20− echo " [--fields <"field1 field2 ..." | help>]"
21− echo " [--sort-by-name]"
22− echo " [--compare]"
23− echo " [--diff-style <absolute|percent|multiples>]"
24− echo " [--diff-cutoff-percent <percent-value>]"
25− echo " [--graphs]"
26− echo " [--silent]"
27− echo " [--no-measure]"
28− echo " [--append]"
29− echo " [--long]"
30− echo " [--slow]"
31− echo " [--quick]"
32− echo " [--raw]"
33− echo " [--dev-build]"
34− echo " [--use-nix]"
35− echo " [--with-compiler <compiler exe name>]"
36− echo " [--cabal-build-options <options>]"
37− echo " [--rtsopts <opts>]"
38− #echo " [--commit-compare] [--base <commit>] [--candidate <commit>]"
39− #echo " -- <gauge options or benchmarks>"
40− echo
41− echo "--benchmarks: benchmarks to run, use 'help' for list of benchmarks"
42− echo "--compare: compare the specified benchmarks with each other"
43−
44− echo "--diff-cutoff-percent: Diff percentage used for benchmark selection."
45− echo "This applies only to the second column of the report and makes sense"
46− echo "only while comparing benchmarks."
47− echo "A positive cutoff value selects only regressions, whereas, a negative"
48− echo "cutoff value selects only improvements."
49−
50− echo "--fields: measurement fields to report, use 'help' for a list"
51− echo "--graphs: Generate graphical reports"
52− echo "--no-measure: Don't run benchmarks, run reports from previous results"
53− echo "--append: Don't overwrite previous results, append for comparison"
54− echo "--long: Use much longer stream size for infinite stream benchmarks"
55− echo "--slow: Slightly more accurate results at the expense of speed"
56− echo "--quick: Faster results, useful for longer benchmarks"
57− echo "--raw: Run the benchmarks but don't report them. This is useful when"
58− echo " you only want to work with the csv files generated."
59− echo "--cabal-build-options: Pass any cabal build options to be used for build"
60− echo " e.g. --cabal-build-options \"--flag dev\""
61− echo
62− echo "When specific space complexity group is chosen then (and only then) "
63− echo "RTS memory restrictions are used accordingly. For example, "
64− echo "bench.sh --benchmarks Data.Parser -- Data.Parser/o-1-space "
65− echo "restricts Heap/Stack space for O(1) characterstics"
66− echo
67− #echo "When using --commit-compare, by default comparative chart of HEAD^ vs HEAD"
68− #echo "commit is generated, in the 'charts' directory."
69− #echo "Use --base and --candidate to select the commits to compare."
70− #echo
71− #echo "Any arguments after a '--' are passed directly to gauge"
72− exit
73−}
74−
75−#-----------------------------------------------------------------------------
76−# Reporting utility functions
77−#-----------------------------------------------------------------------------
78−
79−list_comparisons () {
80− echo "Comparison groups:"
81− for i in $COMPARISONS
82− do
83− echo -n "$i ["
84− eval "echo -n \$$i"
85− echo "]"
86− done
87− echo
88−}
89−
90−build_report_prog() {
91− local prog_path=$BENCH_REPORT_DIR/bin/bench-report
92−
93− hash -r
94− if test ! -x "$prog_path" -a "$BUILD_ONCE" = "0"
95− then
96− echo "Building bench-report executables"
97− BUILD_ONCE=1
98− pushd $BENCH_REPORT_DIR
99− local cmd
100− cmd="$CABAL_EXECUTABLE install --installdir bin bench-report"
101− if test "$USE_NIX" -eq 0
102− then
103− $cmd || die "bench-report build failed"
104− else
105− nix-shell --run "$cmd" || die "bench-report build failed"
106− fi
107− popd
108− elif test ! -x "$prog_path"
109− then
110− return 1
111− fi
112− return 0
113−}
114−
115−build_report_progs() {
116− if test "$RAW" = "0"
117− then
118− build_report_prog || exit 1
119− local prog
120− prog=$BENCH_REPORT_DIR/bin/bench-report
121− test -x $prog || die "Cannot find bench-report executable"
122− echo "Using bench-report executable [$prog]"
123− fi
124−}
125−
126−# We run the benchmarks in isolation in a separate process so that different
127−# benchmarks do not interfere with other. To enable that we need to pass the
128−# benchmark exe path to gauge as an argument. Unfortunately it cannot find its
129−# own path currently.
130−
131−# The path is dependent on the architecture and cabal version.
132−
133−bench_output_file() {
134− local bench_name=$1
135− echo "charts/$bench_name/results.csv"
136−}
137−
138−#------------------------------------------------------------------------------
139−# Speed options
140−#------------------------------------------------------------------------------
141−
142−# tasty-bench does not like an option set twice
143−set_super_quick_mode () {
144− echo -n super_quick
145−}
146−
147−# For certain long benchmarks if the user has not requested super quick
148−# mode we anyway use a slightly quicker mode.
149−use_quicker_mode () {
150− if test "$QUICK_MODE" -eq 0
151− then
152− echo quicker
153− fi
154−}
155−
156−#------------------------------------------------------------------------------
157−# Determine options from benchmark name
158−#------------------------------------------------------------------------------
159−
160−# Global environment passed:
161−# BENCH_EXEC_PATH: the benchmark executable
162−# RTS_OPTIONS: additional RTS options
163−# QUICK_MODE: whether we are in quick mode
164−# USE_GAUGE: whether to use gauge or tasty-bench
165−# LONG: whether to use a large stream size
166−
167−# $1: bench name
168−bench_exec_one() {
169− local BENCH_NAME_ORIG
170− BENCH_NAME_ORIG="$1"
171− shift
172−
173− local SUPER_QUICK_OPTIONS
174− local QUICKER_OPTIONS
175− if test "$USE_GAUGE" -eq 0
176− then
177− SUPER_QUICK_OPTIONS="--stdev 1000000"
178− QUICKER_OPTIONS="--stdev 100"
179− else
180− # Do not keep time limit as 0 otherwise GC stats may remain 0 in some cases.
181− SUPER_QUICK_OPTIONS="--quick --min-duration 0 --time-limit 0.01 --include-first-iter"
182− QUICKER_OPTIONS="--min-samples 3 --time-limit 1"
183− fi
184−
185− local BENCH_NAME0
186− local BENCH_NAME1
187− local BENCH_NAME2
188− local BENCH_NAME
189− # XXX this is a hack to make the "/" separated names used in the functions
190− # determining options based on benchmark name. For tasty-bench the benchmark
191− # names are separated by "." instead of "/" and are prefixed by "All".
192− #
193− # For example, All.Prelude.Serial/x.y.z => Prelude.Serial/x/y/z
194− if test "$USE_GAUGE" -eq 0
195− then
196− # Remove the prefix "All."
197− BENCH_NAME0=$(echo $BENCH_NAME_ORIG | sed -e s/^All\.//)
198−
199− # Module names could contain dots e.g. "Prelude.Serial". So we insert
200− # an explicit "/" to separate the module name part and the rest of
201− # the benchmark name. For example, Prelude.Serial/elimination.drain
202− BENCH_NAME1=$(echo $BENCH_NAME0 | cut -f1 -d '/')
203−
204− if test "$BENCH_NAME1" = "$BENCH_NAME0"
205− then
206− # There is no "/" separator
207− BENCH_NAME1=$(echo $BENCH_NAME0 | sed -e 's/\./\//g')
208− BENCH_NAME2=""
209− else
210− BENCH_NAME2=/$(echo $BENCH_NAME0 | cut -f2- -d '/' | sed -e 's/\./\//g')
211− fi
212− BENCH_NAME="${BENCH_NAME1}${BENCH_NAME2}"
213− else
214− BENCH_NAME=$BENCH_NAME_ORIG
215− fi
216−
217− local RTS_OPTIONS1
218− RTS_OPTIONS1="\
219−+RTS -T \
220−$(bench_rts_options $(basename $BENCH_EXEC_PATH) $BENCH_NAME) \
221−$RTS_OPTIONS \
222−-RTS"
223−
224− local QUICK_MODE_TYPE
225− QUICK_MODE_TYPE="\
226− $(if test "$QUICK_MODE" -ne 0; then set_super_quick_mode; fi) \
227− $(bench_speed_options $(basename $BENCH_EXEC_PATH) $BENCH_NAME)"
228−
229− local QUICK_BENCH_OPTIONS
230− for i in $QUICK_MODE_TYPE
231− do
232− case "$i" in
233− super_quick) QUICK_BENCH_OPTIONS="$SUPER_QUICK_OPTIONS"; break ;;
234− quicker) QUICK_BENCH_OPTIONS="$QUICKER_OPTIONS"; break ;;
235− esac
236− done
237−
238− local STREAM_SIZE
239− local STREAM_LEN
240− local STREAM_SIZE_OPT
241− if test "$LONG" -ne 0
242− then
243− STREAM_SIZE=10000000
244− STREAM_LEN=$(env LC_ALL=en_US.UTF-8 printf "--stream-size %'.f\n" $STREAM_SIZE)
245− STREAM_SIZE_OPT="--stream-size $STREAM_SIZE"
246− fi
247−
248− echo "$BENCH_NAME_ORIG: \
249− $RTS_OPTIONS1 \
250− $STREAM_LEN \
251− $QUICK_BENCH_OPTIONS" \
252− "$@"
253−
254− #------------------------------------------------------------------------------
255− # Run benchmark with options and collect results
256− #------------------------------------------------------------------------------
257−
258− local output_file
259− output_file=$(bench_output_file $(basename $BENCH_EXEC_PATH))
260− mkdir -p `dirname $output_file`
261− rm -f ${output_file}.tmp
262−
263− local BENCH_NAME_ESC
264− if test $USE_GAUGE -eq 0
265− then
266− # Escape "\" and double quotes in benchmark names
267− BENCH_NAME_ESC=$(echo "$BENCH_NAME_ORIG" | sed -e 's/\\/\\\\/g' | sed -e 's/"/\\"/g')
268− $BENCH_EXEC_PATH \
269− -j 1 \
270− $RTS_OPTIONS1 \
271− $STREAM_SIZE_OPT \
272− $QUICK_BENCH_OPTIONS \
273− "$@" \
274− --csv=${output_file}.tmp \
275− -p '$0 == "'"$BENCH_NAME_ESC"'"' || die "Benchmark execution failed."
276−
277− # Convert cpuTime field from picoseconds to seconds
278− awk --version 2>&1 | grep -q "GNU Awk" \
279− || die "Need GNU awk. [$(which awk)] is not GNU awk."
280− tail -n +2 ${output_file}.tmp | \
281− awk 'BEGIN {FPAT = "([^,]+)|(\"[^\"]+\")";OFS=","} {$2=$2/1000000000000;print}' \
282− >> $output_file
283− else
284− $BENCH_EXEC_PATH \
285− $RTS_OPTIONS1 \
286− $STREAM_SIZE_OPT \
287− $QUICK_BENCH_OPTIONS \
288− "$@" \
289− --csvraw=${output_file}.tmp \
290− -m exact "$BENCH_NAME" || die "Benchmark execution failed."
291− tail -n +2 ${output_file}.tmp \
292− >> $output_file
293− fi
294−}
295−
296−invoke_gauge () {
297− local target_prog="$1"
298− local target_name="$2"
299− local output_file="$3"
300−
301− local MATCH=""
302− if test "$LONG" -ne 0
303− then
304− MATCH="$target_name/o-1-space"
305− else
306− MATCH="$BENCH_PREFIX"
307− fi
308− echo "name,iters,time,cycles,cpuTime,utime,stime,maxrss,minflt,majflt,nvcsw,nivcsw,allocated,numGcs,bytesCopied,mutatorWallSeconds,mutatorCpuSeconds,gcWallSeconds,gcCpuSeconds" >> $output_file
309− # keep only benchmark names with shortest prefix e.g. "a/b/c" and "a/b", we
310− # should only keep "a/b" otherwise benchmarks will run multiple times. why?
311− $target_prog -l \
312− | grep "^$MATCH" \
313− | while read -r name; \
314− do bench_exec_one "$name" "${GAUGE_ARGS[@]}" || exit 1; done \
315− || die "Benchmark execution failed."
316−}
317−
318−invoke_tasty_bench () {
319− local target_prog="$1"
320− local target_name="$2"
321− local output_file="$3"
322−
323− local MATCH=""
324− if test "$LONG" -ne 0
325− then
326− MATCH="-p /$target_name\/o-1-space/"
327− else
328− if test -n "$BENCH_PREFIX"
329− then
330− # escape "/"
331− local escaped_name=$(echo "$BENCH_PREFIX" | sed -e 's/\//\\\//g')
332− MATCH="-p /$escaped_name/"
333− fi
334− fi
335− echo "Name,cpuTime,2*Stdev (ps),Allocated,bytesCopied,maxrss" >> $output_file
336− $target_prog -l $MATCH \
337− | grep "^All" \
338− | while read -r name; \
339− do bench_exec_one "$name" "${GAUGE_ARGS[@]}" || exit 1; done \
340− || die "Benchmark execution failed."
341−}
342−
343−run_bench_target () {
344− local package_name=$1
345− local component=$2
346− local target_name=$3
347−
348− local target_prog
349− if test -z "$BENCHMARK_PACKAGE_VERSION"
350− then
351− echo "Please set BENCHMARK_PACKAGE_VERSION in bench_config"
352− exit 1
353− fi
354− target_prog=$(cabal_target_prog $package_name-$BENCHMARK_PACKAGE_VERSION $component $target_name) || \
355− die "Cannot find executable for target $target_name"
356−
357− echo "Running executable $target_name ..."
358−
359− # Needed by bench_exec_one
360− BENCH_EXEC_PATH=$target_prog
361−
362− local output_file=$(bench_output_file $target_name)
363− mkdir -p `dirname $output_file`
364− if test "$USE_GAUGE" -eq 0
365− then invoke_tasty_bench "$target_prog" "$target_name" "$output_file"
366− else invoke_gauge "$target_prog" "$target_name" "$output_file"
367− fi
368−}
369−
370−# $1: package name
371−# $2: component
372−# $3: targets
373−run_bench_targets() {
374− for i in $3
375− do
376− run_bench_target $1 $2 $i
377− done
378−}
379−
380−run_benches_comparing() {
381− local bench_list=$1
382−
383− if test -z "$CANDIDATE"
384− then
385− CANDIDATE=$(git rev-parse HEAD)
386− fi
387− if test -z "$BASE"
388− then
389− # XXX Should be where the current branch is forked from master
390− BASE="$CANDIDATE^"
391− fi
392− echo "Comparing baseline commit [$BASE] with candidate [$CANDIDATE]"
393− echo "Checking out base commit [$BASE] for benchmarking"
394− # XXX git checkout will overwrite this script itself and the scripts
395− # imported/used by this script.
396− git checkout "$BASE" || die "Checkout of base commit [$BASE] failed"
397−
398− # $BUILD_BENCH || die "build failed"
399− run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS"
400− run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args
401−
402− echo "Checking out candidate commit [$CANDIDATE] for benchmarking"
403− git checkout "$CANDIDATE" || \
404− die "Checkout of candidate [$CANDIDATE] commit failed"
405−
406− # $BUILD_BENCH || die "build failed"
407− run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS"
408− run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args
409− # XXX reset back to the original commit
410−}
411−
412−backup_output_file() {
413− local bench_name=$1
414− local output_file=$(bench_output_file $bench_name)
415−
416− if test -e $output_file -a "$APPEND" != 1
417− then
418− mv -f -v $output_file ${output_file}.prev
419− fi
420−}
421−
422−run_measurements() {
423− local bench_list=$1
424−
425− for i in $bench_list
426− do
427− backup_output_file $i
428− done
429−
430− if test "$COMMIT_COMPARE" = "0"
431− then
432− run_build "$BUILD_BENCH" $BENCHMARK_PACKAGE_NAME bench "$TARGETS"
433− run_bench_targets $BENCHMARK_PACKAGE_NAME b "$bench_list" target_exe_extra_args
434− else
435− run_benches_comparing "$bench_list"
436− fi
437−}
438−
439−run_reports() {
440− local prog
441− prog=$BENCH_REPORT_DIR/bin/bench-report
442− test -x $prog || die "Cannot find bench-report executable"
443− test -z "$SILENT" && echo
444−
445− for i in $1
446− do
447− test -z "$SILENT" && echo "Generating reports for ${i}..."
448− $prog \
449− --benchmark $i \
450− $(test "$USE_GAUGE" = 1 && echo "--use-gauge") \
451− $(test "$GRAPH" = 1 && echo "--graphs") \
452− $(test "$SORT_BY_NAME" = 1 && echo "--sort-by-name") \
453− $(test -n "$BENCH_DIFF_STYLE" && echo "--diff-style $BENCH_DIFF_STYLE") \
454− $(test -n "$BENCH_CUTOFF_PERCENT" && echo "--diff-cutoff-percent $BENCH_CUTOFF_PERCENT") \
455− --fields "$FIELDS"
456− done
457−}
458−
459−#-----------------------------------------------------------------------------
460−# Execution starts here
461−#-----------------------------------------------------------------------------
462−
463−USE_GIT_CABAL=1 # This is used by set_common_vars
464−set_common_vars
465−
466−USE_NIX=0
467−COMPARE=0
468−COMMIT_COMPARE=0
469−BASE=
470−CANDIDATE=
471−
472−APPEND=0
473−LONG=0
474−RAW=0
475−SORT_BY_NAME=0
476−GRAPH=0
477−MEASURE=1
478−
479−GAUGE_ARGS=
480−BUILD_ONCE=0
481−
482−CABAL_BUILD_OPTIONS="--flag fusion-plugin --flag limit-build-mem"
483−
484−#-----------------------------------------------------------------------------
485−# Read command line
486−#-----------------------------------------------------------------------------
487−
488−while test -n "$1"
489−do
490− case $1 in
491− -h|--help|help) print_help ;;
492− # options with arguments
493− --benchmarks) shift; TARGETS=$1; shift ;;
494− --targets) shift; TARGETS=$1; shift ;;
495− --prefix) shift; BENCH_PREFIX="$1"; shift ;;
496− --fields) shift; FIELDS=$1; shift ;;
497− --base) shift; BASE=$1; shift ;;
498− --candidate) shift; CANDIDATE=$1; shift ;;
499− --with-compiler) shift; CABAL_WITH_COMPILER=$1; shift ;;
500− --cabal-build-flags) shift; CABAL_BUILD_OPTIONS+=" $1"; shift ;;
501− --cabal-build-options) shift; CABAL_BUILD_OPTIONS+=" $1"; shift ;;
502− --rtsopts) shift; RTS_OPTIONS=$1; shift ;;
503− --config) shift; BENCH_CONFIG_FILE=$1; shift ;;
504− --diff-style) shift; BENCH_DIFF_STYLE=$1; shift ;;
505− --diff-cutoff-percent) shift; BENCH_CUTOFF_PERCENT=$1; shift ;;
506− # flags
507− --slow) SLOW=1; shift ;;
508− --silent) SILENT=1; shift ;;
509− --quick) QUICK_MODE=1; shift ;;
510− --compare) COMPARE=1; shift ;;
511− --commit-compare) COMMIT_COMPARE=1; shift ;;
512− --raw) RAW=1; shift ;;
513− --append) APPEND=1; shift ;;
514− --long) LONG=1; shift ;;
515− --sort-by-name) SORT_BY_NAME=1; shift ;;
516− --graphs) GRAPH=1; shift ;;
517− --no-measure) MEASURE=0; shift ;;
518− # This is used in build-lib.sh to enable dev_build function which is used
519− # in targets.sh to enable or disable some targets.
520− --dev-build) RUNNING_DEVBUILD=1; shift ;;
521− --use-nix) USE_NIX=1; shift ;;
522− --use-gauge) USE_GAUGE=1; shift ;;
523− --) shift; break ;;
524− *) echo "Unknown flags: $*"; echo; print_help ;;
525− esac
526−done
527−GAUGE_ARGS=("$@")
528−
529−if test -z "$BENCH_CONFIG_FILE"
530−then
531− die "Please use --config to specify config file"
532−fi
533−
534−source "$BENCH_CONFIG_FILE" || \
535− die "Failed to source config file $BENCH_CONFIG_FILE"
536−
537−# Defined in $BENCH_CONFIG_FILE
538−bench_config
539−
540−if test -z "$FIELDS"
541−then
542− FIELDS=$DEFAULT_FIELDS
543−fi
544−
545−set_derived_vars
546−
547−#-----------------------------------------------------------------------------
548−# Determine targets
549−#-----------------------------------------------------------------------------
550−
551−only_real_benchmarks () {
552− for i in $TARGETS
553− do
554− local SKIP=0
555− for j in $COMPARISONS
556− do
557− if test $i == $j
558− then
559− SKIP=1
560− fi
561− done
562− if test "$SKIP" -eq 0
563− then
564− echo -n "$i "
565− fi
566− done
567−}
568−
569−# defined in $BENCH_CONFIG_FILE
570−bench_targets
571−
572−if test "$(has_item "$TARGETS" help)" = "help"
573−then
574− list_target_groups
575− list_comparisons
576− list_targets
577− exit
578−fi
579−
580−COMMON_FIELDS="allocated bytescopied cputime maxrss"
581−if test "$USE_GAUGE" -eq 1
582−then
583− ALL_FIELDS="$COMMON_FIELDS time cycles utime stime minflt majflt nvcsw nivcsw"
584−else
585− ALL_FIELDS="$COMMON_FIELDS"
586−fi
587−if test "$(has_item "$FIELDS" help)" = "help"
588−then
589− echo "Supported fields: $ALL_FIELDS"
590− echo "Default fields: $DEFAULT_FIELDS"
591− exit
592−fi
593−
594−if test "$LONG" -ne 0
595−then
596− if test -n "$TARGETS"
597− then
598− echo "Cannot specify benchmarks [$TARGETS] with --long"
599− exit
600− fi
601− TARGETS=$infinite_grp
602−fi
603−
604−DEFAULT_TARGETS="$(all_grp)"
605−TARGETS=$(set_targets)
606−
607−TARGETS_ORIG=$TARGETS
608−TARGETS=$(only_real_benchmarks)
609−
610−test -z "$SILENT" && echo "Using benchmark suites [$TARGETS]"
611−
612−#-----------------------------------------------------------------------------
613−# Build reporting utility
614−#-----------------------------------------------------------------------------
615−
616−# We need to build the report progs first at the current (latest) commit before
617−# checking out any other commit for benchmarking.
618−if test -z "$SILENT"
619−then build_report_progs
620−else silently build_report_progs
621−fi
622−
623−#-----------------------------------------------------------------------------
624−# Build and run targets
625−#-----------------------------------------------------------------------------
626−
627−if test "$USE_GAUGE" -eq 1
628−then
629− BUILD_FLAGS="--flag use-gauge"
630−fi
631−
632−BUILD_BENCH="$CABAL_EXECUTABLE v2-build $BUILD_FLAGS $CABAL_BUILD_OPTIONS --enable-benchmarks"
633−if test "$MEASURE" = "1"
634−then
635− run_measurements "$TARGETS"
636−fi
637−
638−#-----------------------------------------------------------------------------
639−# Run reports
640−#-----------------------------------------------------------------------------
641−
642−# $1: var name
643−build_comparison_results () {
644− local name
645− local constituents
646−
647− name=$1
648− constituents=$(eval "echo -n \$${name}")
649− mkdir -p "charts/$name"
650− dest_file="charts/$name/results.csv"
651− : > $dest_file
652− for j in $constituents
653− do
654− cat "charts/$j/results.csv" >> $dest_file
655− done
656−}
657−
658−if test "$COMPARE" -eq 1
659−then
660− DYN_CMP_GRP="$(echo "$TARGETS" | sed -e 's/ /_/g')_cmp"
661− eval "$DYN_CMP_GRP=\"$TARGETS\""
662− COMPARISON_REPORTS=$DYN_CMP_GRP
663− build_comparison_results $DYN_CMP_GRP
664−else
665− COMPARISON_REPORTS=""
666−fi
667−
668−for i in $COMPARISONS
669−do
670− if test "$(has_item "$TARGETS_ORIG" $i)" = $i
671− then
672− COMPARISON_REPORTS="$COMPARISON_REPORTS $i"
673− build_comparison_results $i
674− fi
675−done
676−
677−if test "$RAW" = "0"
678−then
679− run_reports "$TARGETS"
680− run_reports "$COMPARISON_REPORTS"
681− if test -n "$DYN_CMP_GRP"
682− then
683− rm -rf "charts/$DYN_CMP_GRP"
684− fi
685−fi
benchmark/bench-report/bin/build-lib.shdeleted−218
@@ -1,218 +0,0 @@
1−# $1: message
2−die () {
3− >&2 echo -e "Error: $1"
4− exit 1
5−}
6−
7−warn () {
8− >&2 echo -e "Warning: $1"
9−}
10−
11−# $1: command
12−function run_verbose() {
13− echo "$*"
14− bash -c "$*"
15−}
16−
17−has_item () {
18− for i in $1
19− do
20− if test "$i" = "$2"
21− then
22− echo "$i"
23− break
24− fi
25− done
26−}
27−
28−# $1: command
29−silently () {
30− eval "$1 &> /dev/null"
31−}
32−
33−#------------------------------------------------------------------------------
34−# target groups
35−#------------------------------------------------------------------------------
36−
37−test_only () {
38− if test -n "$RUNNING_TESTS"
39− then
40− echo $1
41− fi
42−}
43−
44−bench_only () {
45− if test -n "$RUNNING_BENCHMARKS"
46− then
47− echo $1
48− fi
49−}
50−
51−dev_build () {
52− if test -n "$RUNNING_DEVBUILD"
53− then
54− echo $1
55− fi
56−}
57−
58−# A group consisting of all known individual targets
59−all_grp () {
60− { for i in $GROUP_TARGETS
61− do
62− for j in $(eval "echo \$$i")
63− do
64− echo $j
65− done
66− done
67− for i in $INDIVIDUAL_TARGETS
68− do
69− echo $i
70− done
71− } | sort | uniq
72−}
73−
74−# All groups
75−all_target_groups () {
76− echo $GROUP_TARGETS
77−}
78−
79−# XXX pass as arg
80−list_targets () {
81− echo "Individual targets:"
82− for i in $(all_grp)
83− do
84− echo "$i"
85− done
86− echo
87−}
88−
89−# XXX pass as arg
90−list_target_groups () {
91− echo "All Targets: all_grp"
92− echo "Target groups:"
93− for i in $(all_target_groups)
94− do
95− echo -n "$i ["
96− eval "echo -n \$$i"
97− echo "]"
98− done
99− echo
100−}
101−
102−# XXX pass as arg
103−set_targets() {
104− if test -z "$TARGETS"
105− then
106− echo $DEFAULT_TARGETS
107− else
108− for i in $(echo $TARGETS)
109− do
110− case $i in
111− *_grp) eval "echo -n \$${i}" ;;
112− *_cmp) eval "echo -n \$${i} $i" ;;
113− *) echo -n $i ;;
114− esac
115− echo -n " "
116− done
117− fi
118−}
119−
120−# XXX cabal issue "cabal v2-exec which" cannot find benchmark/test executables
121−
122−# $1: builddir
123−# $2: package name with version
124−# $3: component ("" (lib), t (test), b (benchmark), x (executable))
125−# $4: command to find
126−cabal_which_builddir() {
127− local noopt=""
128− if test "$TEST_QUICK_MODE" = "1"
129− then
130− noopt="/noopt"
131− fi
132−
133− local path=$(echo $1/build/*/ghc-${GHC_VERSION}/${2}/$3/$4$noopt/build/$4/$4)
134− echo "[cabal_which $path]" 1>&2
135− test -f "$path" && echo $path
136−}
137−
138−# $1: package name with version
139−# $2: component
140−# $3: command to find
141−cabal_which() {
142− cabal_which_builddir $BUILD_DIR $1 $2 $3
143−}
144−
145−# We run the benchmarks in isolation in a separate process so that different
146−# benchmarks do not interfere with other. To enable that we need to pass the
147−# benchmark exe path to gauge as an argument. Unfortunately it cannot find its
148−# own path currently.
149−
150−# The path is dependent on the architecture and cabal version.
151−
152−# $1: package name with version
153−# $2: component
154−# $3: target
155−cabal_target_prog () {
156− local target_prog=`cabal_which $1 $2 $3`
157− if test -x "$target_prog"
158− then
159− echo $target_prog
160− else
161− return 1
162− fi
163−}
164−
165−set_common_vars () {
166− SLOW=0
167− QUICK_MODE=0
168−
169− RUNNING_DEVBUILD=
170−
171− TARGET_EXE_ARGS=
172− RTS_OPTIONS=
173−
174− CABAL_BUILD_OPTIONS=""
175− CABAL_EXECUTABLE=cabal
176−
177− # Use branch specific builds if git-cabal is present in PATH
178− BUILD_DIR=dist-newstyle
179− if test "$USE_GIT_CABAL" -eq 1
180− then
181− if which git-cabal 2>/dev/null
182− then
183− echo "Using git-cabal for branch specific builds"
184− CABAL_EXECUTABLE=git-cabal
185− BUILD_DIR=$(git-cabal show-builddir)
186− fi
187− fi
188−}
189−
190−# To be called after parsing CLI arguments
191−set_derived_vars () {
192− if test -n "$CABAL_WITH_COMPILER"
193− then
194− CABAL_BUILD_OPTIONS+=" --with-compiler $CABAL_WITH_COMPILER"
195− else
196− CABAL_WITH_COMPILER=ghc
197− fi
198−
199− GHC_VERSION=$($CABAL_WITH_COMPILER --numeric-version)
200−}
201−
202−# $1: build program
203−# $2: package name
204−# $3: component prefix
205−# $4: targets
206−run_build () {
207− local build_prog=$1
208− local package=$2
209− local component_prefix=$3
210− local COMPONENTS
211− local c
212−
213− for c in $4
214− do
215− COMPONENTS+="$package:$component_prefix:$c "
216− done
217− run_verbose $build_prog $COMPONENTS || die "build failed"
218−}
benchmark/bench-report/default.nixdeleted−55
@@ -1,55 +0,0 @@
1−let
2− nixpkgsPath_21_11 =
3− "https://github.com/NixOS/nixpkgs/archive/refs/tags/21.11.tar.gz";
4− nixpkgsDefault = import (builtins.fetchTarball nixpkgsPath_21_11) { };
5−in
6−{
7− nixpkgs ? nixpkgsDefault
8−, compiler ? "default"
9−}:
10−let haskellPackages =
11− if compiler == "default"
12− then nixpkgs.haskellPackages
13− else nixpkgs.haskell.packages.${compiler};
14−
15− mkPackage = super: pkg: path: opts: inShell:
16− let orig = super.callCabal2nixWithOptions pkg path opts {};
17− in if inShell
18− # Avoid copying the source directory to nix store by using
19− # src = null.
20− then orig.overrideAttrs (oldAttrs: { src = null; })
21− else orig;
22−
23− mkHaskellPackages = inShell:
24− haskellPackages.override {
25− overrides = self: super:
26− with nixpkgs.haskell.lib;
27− {
28− bench-show = super.callHackageDirect {
29− pkg = "bench-show";
30− ver = "0.3.2";
31− sha256 = "16b8vyzdp9b5bh34kqmbfwjsyv8wgnxxwl8kjcpgxjsh52xzyaa0";
32− } { };
33−
34− bench-report = mkPackage super "bench-report" ./. "" inShell;
35− };
36− };
37−
38− drv = mkHaskellPackages true;
39−
40− shell = drv.shellFor {
41− packages = p:
42− [ p.bench-report
43− ];
44− # Use a better prompt
45− shellHook = ''
46− export CABAL_DIR="$(pwd)/.cabal.nix"
47− if test -n "$PS_SHELL"
48− then
49− export PS1="$PS_SHELL\[$bldred\](nix)\[$txtrst\] "
50− fi
51− '';
52− };
53−in if nixpkgs.lib.inNixShell
54− then shell
55− else (mkHaskellPackages false).bench-report
benchmark/bench-runner/Main.hsnew file+130
@@ -0,0 +1,130 @@
1+module Main (main) where
2+
3+import BenchRunner (mainWith)
4+import BuildLib (Quickness(..))
5+import Control.Applicative ((<|>))
6+import Data.List (isInfixOf, isPrefixOf, isSuffixOf)
7+
8+import Targets (targets)
9+
10+rtsOpts :: String -> String -> String
11+rtsOpts exeName benchName0 = unwords [general, exeSpecific, benchSpecific]
12+
13+ where
14+
15+ -- Drop All.
16+ benchName = drop 4 benchName0
17+ general
18+ | "o-1-sp" `isInfixOf` benchName = "-K36K -M16M"
19+ | "o-n-h" `isInfixOf` benchName = "-K36K -M32M"
20+ | "o-n-st" `isInfixOf` benchName = "-K1M -M16M"
21+ | "o-n-sp" `isInfixOf` benchName = "-K1M -M32M"
22+ | otherwise = ""
23+ exeSpecific
24+ | "Prelude.Concurrent" `isSuffixOf` exeName = "-K512K -M384M"
25+ | otherwise = ""
26+ benchSpecific
27+ | "Data.Stream.StreamD/o-n-space.elimination.toList" == benchName =
28+ "-K2M"
29+ | "Data.Stream.StreamK/o-n-space.elimination.toList" == benchName =
30+ "-K2M"
31+ | "Prelude.Parallel/o-n-heap.mapping.mapM" == benchName = "-M256M"
32+ | "Prelude.Parallel/o-n-heap.monad-outer-product."
33+ `isPrefixOf` benchName = "-M256M"
34+ | "Prelude.Parallel/o-n-space.monad-outer-product."
35+ `isPrefixOf` benchName = "-K2M -M256M"
36+ | "Prelude.Rate/o-1-space." `isPrefixOf` benchName = "-K128K"
37+ | "Prelude.Rate/o-1-space.asyncly." `isPrefixOf` benchName = "-K128K"
38+ | "Prelude.Serial/o-1-space.mixed.sum-product-fold" == benchName =
39+ "-K64M"
40+ | "Prelude.Serial/o-n-heap.grouping.classifySessionsOf"
41+ `isPrefixOf` benchName = "-K1M -M32M"
42+ | "Prelude.Serial/o-n-heap.Functor." `isPrefixOf` benchName =
43+ "-K4M -M32M"
44+ | "Prelude.Serial/o-n-heap.transformer." `isPrefixOf` benchName =
45+ "-K8M -M64M"
46+ | "Prelude.Serial/o-n-space.Functor." `isPrefixOf` benchName =
47+ "-K4M -M64M"
48+ | "Prelude.Serial/o-n-space.Applicative." `isPrefixOf` benchName =
49+ "-K8M -M128M"
50+ | "Prelude.Serial/o-n-space.Monad." `isPrefixOf` benchName =
51+ "-K8M -M64M"
52+ | "Prelude.Serial/o-n-space.grouping." `isPrefixOf` benchName = ""
53+ | "Prelude.Serial/o-n-space." `isPrefixOf` benchName = "-K4M"
54+ | "Prelude.WSerial/o-n-space." `isPrefixOf` benchName = "-K4M"
55+ | "Prelude.Async/o-n-space.monad-outer-product." `isPrefixOf` benchName =
56+ "-K4M"
57+ | "Prelude.Ahead/o-n-space.monad-outer-product." `isPrefixOf` benchName =
58+ "-K4M"
59+ | "Prelude.Ahead/o-1-space." `isPrefixOf` benchName = "-K128K"
60+ | "Prelude.WAsync/o-n-heap.monad-outer-product.toNull3" == benchName =
61+ "-M64M"
62+ | "Prelude.WAsync/o-n-space.monad-outer-product." `isPrefixOf` benchName =
63+ "-K4M"
64+ | "Data.Parser.ParserD/o-1-space.some" == benchName = "-K8M"
65+ | "Data.Parser/o-1-space.some" == benchName = "-K8M"
66+ | "Data.Parser.ParserD/o-1-space.manyTill" == benchName = "-K4M"
67+ | "Data.Parser/o-1-space.manyTill" == benchName = "-K4M"
68+ | "Data.Parser/o-n-heap.manyAlt" == benchName = "-K4M -M128M"
69+ | "Data.Parser/o-n-heap.someAlt" == benchName = "-K4M -M128M"
70+ | "Data.Parser/o-n-heap.choice" == benchName = "-K16M -M32M"
71+ | "Data.Parser.ParserK/o-n-heap.manyAlt" == benchName = "-K4M -M128M"
72+ | "Data.Parser.ParserK/o-n-heap.someAlt" == benchName = "-K4M -M128M"
73+ | "Data.Parser.ParserK/o-n-heap.sequence" == benchName = "-M64M"
74+ | "Data.Parser.ParserK/o-n-heap.sequenceA" == benchName = "-M64M"
75+ | "Data.SmallArray.o-1-sp" `isPrefixOf` benchName = "-K128K"
76+ | "Data.Array" `isPrefixOf` benchName
77+ && "/o-1-space.generation.show" `isSuffixOf` benchName = "-M32M"
78+ | "Data.Array/o-1-space.transformationX4.map" == benchName = "-M32M"
79+ | "Data.Array.Foreign/o-1-space.elimination.foldable.foldl"
80+ `isPrefixOf` benchName = "-K8M"
81+ | "Data.Array.Foreign/o-1-space.elimination.foldable.sum" == benchName =
82+ "-K8M"
83+ | otherwise = ""
84+
85+speedOpts :: String -> String -> Maybe Quickness
86+speedOpts exeName benchName0 = exeSpecific <|> benchSpecific
87+
88+ where
89+
90+ -- slowestOf Quicker _ = Quicker
91+ -- slowestOf _ Quicker = Quicker
92+ -- slowestOf _ _ = SuperQuick
93+
94+ -- Drop All.
95+ benchName = drop 4 benchName0
96+ exeSpecific
97+ | "Prelude.Concurrent" == exeName = Just SuperQuick
98+ | "Prelude.Rate" == exeName = Just SuperQuick
99+ | "Prelude.Adaptive" == exeName = Just SuperQuick
100+ | otherwise = Nothing
101+ benchSpecific
102+ | "Prelude.Parallel/o-n-heap.mapping.mapM" == benchName =
103+ Just SuperQuick
104+ | "Prelude.Parallel/o-n-heap.monad-outer-product."
105+ `isPrefixOf` benchName = Just SuperQuick
106+ | "Prelude.Parallel.o-n-space.monad-outer-product."
107+ `isPrefixOf` benchName = Just SuperQuick
108+ | "Prelude.Parallel/o-n-heap.generation." `isPrefixOf` benchName =
109+ Just Quicker
110+ | "Prelude.Parallel/o-n-heap.mapping." `isPrefixOf` benchName =
111+ Just Quicker
112+ | "Prelude.Parallel/o-n-heap.concat-foldable." `isPrefixOf` benchName =
113+ Just Quicker
114+ | "Prelude.Async/o-1-space.monad-outer-product." `isPrefixOf` benchName =
115+ Just Quicker
116+ | "Prelude.Async/o-n-space.monad-outer-product." `isPrefixOf` benchName =
117+ Just Quicker
118+ | "Prelude.Ahead/o-1-space.monad-outer-product." `isPrefixOf` benchName =
119+ Just Quicker
120+ | "Prelude.Ahead/o-n-space.monad-outer-product." `isPrefixOf` benchName =
121+ Just Quicker
122+ | "Prelude.WAsync/o-n-heap.monad-outer-product." `isPrefixOf` benchName =
123+ Just Quicker
124+ | "Prelude.WAsync/o-n-space.monad-outer-product." `isPrefixOf` benchName =
125+ Just Quicker
126+ | "FileSystem.Handle." `isPrefixOf` benchName = Just Quicker
127+ | otherwise = Nothing
128+
129+main :: IO ()
130+main = mainWith targets speedOpts rtsOpts
benchmark/bench-runner/bench-runner.cabalnew file+42
@@ -0,0 +1,42 @@
1+cabal-version: 2.4
2+name: bench-runner
3+version: 0.1.0.0
4+
5+-- A short (one-line) description of the package.
6+-- synopsis:
7+
8+-- A longer description of the package.
9+-- description:
10+
11+-- A URL where users can report bugs.
12+-- bug-reports:
13+
14+-- The license under which the package is released.
15+-- license:
16+
17+-- The package author(s).
18+-- author:
19+
20+-- An email address to which users can send suggestions, bug reports, and patches.
21+-- maintainer:
22+
23+-- A copyright notice.
24+-- copyright:
25+-- category:
26+-- extra-source-files: CHANGELOG.md
27+
28+executable bench-runner
29+ ghc-options: -Wall
30+ main-is: Main.hs
31+
32+ -- Modules included in this executable, other than Main.
33+ -- other-modules:
34+
35+ -- LANGUAGE extensions used by modules in this package.
36+ -- other-extensions:
37+ build-depends: base
38+ , bench-report
39+ , containers
40+ , streamly-targets
41+ hs-source-dirs: .
42+ default-language: Haskell2010
benchmark/bench-runner/cabal.projectnew file+1
@@ -0,0 +1 @@
1+packages: ., ../../targets
benchmark/bench-runner/default.nixnew file+164
@@ -0,0 +1,164 @@
1+let
2+ nixpkgsPath_21_11 =
3+ "https://github.com/NixOS/nixpkgs/archive/refs/tags/21.11.tar.gz";
4+ nixpkgsDefault = import (builtins.fetchTarball nixpkgsPath_21_11) { };
5+in
6+{
7+ nixpkgs ? nixpkgsDefault
8+, compiler ? "default"
9+}:
10+let haskellPackages =
11+ if compiler == "default"
12+ then nixpkgs.haskellPackages
13+ else nixpkgs.haskell.packages.${compiler};
14+
15+ mkPackage = super: pkg: path: opts: inShell:
16+ let orig = super.callCabal2nixWithOptions pkg path opts {};
17+ in if inShell
18+ # Avoid copying the source directory to nix store by using
19+ # src = null.
20+ then orig.overrideAttrs (oldAttrs: { src = null; })
21+ else orig;
22+
23+ mkPkgGit = super: gitSrc: rev: name:
24+ let
25+ src = builtins.fetchGit {
26+ url = gitSrc;
27+ rev = rev;
28+ };
29+ in super.callCabal2nix name src { };
30+
31+ mkPkgGitRef = super: gitSrc: rev: ref: name:
32+ let
33+ src = builtins.fetchGit {
34+ url = gitSrc;
35+ rev = rev;
36+ ref = ref;
37+ };
38+ in super.callCabal2nix name src { };
39+
40+ mkHaskellPackages = inShell:
41+ haskellPackages.override {
42+ overrides = self: super:
43+ with nixpkgs.haskell.lib;
44+ {
45+ report = mkPackage super "report" ./. "" inShell;
46+ streamly-targets = mkPackage super "streamly-targets" ../../targets "" false;
47+
48+ bench-report =
49+ nixpkgs.haskell.lib.overrideCabal
50+ (let src = fetchGit {
51+ url = "git@github.com:composewell/bench-report.git";
52+ rev = "57d0ad221c74cdb2ce81646ab18300e8bb8e716b";
53+ }; in super.callCabal2nix "bench-report" src {})
54+ (old:
55+ { enableLibraryProfiling = false;
56+ doHaddock = false;
57+ });
58+
59+ bench-show = super.callHackageDirect {
60+ pkg = "bench-show";
61+ ver = "0.3.2";
62+ sha256 = "16b8vyzdp9b5bh34kqmbfwjsyv8wgnxxwl8kjcpgxjsh52xzyaa0";
63+ } { };
64+
65+# streamly-coreutils = let
66+# src = "git@github.com:composewell/streamly-coreutils.git";
67+# rev = "a12756efe24bbf303f2f6d66a95426c7657d297b";
68+# in mkPkgGit super src rev "streamly-coreutils";
69+
70+ streamly-coreutils =
71+ nixpkgs.haskell.lib.overrideCabal
72+ (let src = fetchGit {
73+ url = "git@github.com:composewell/streamly-coreutils.git";
74+ rev = "8fa4a3ebedb3f970f64b7d78d8ab340b0f771abe";
75+ }; in super.callCabal2nix "streamly-coreutils" src {})
76+ (old:
77+ { librarySystemDepends =
78+ if builtins.currentSystem == "x86_64-darwin"
79+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
80+ else [];
81+ #enableLibraryProfiling = false;
82+ doHaddock = false;
83+ doCheck = false;
84+ });
85+
86+ streamly-shell = let
87+ src = "https://github.com/composewell/streamly-shell.git";
88+ rev = "7d77ddc0c06aec21fbbfd1b920ec4f58da654a1b";
89+ in mkPkgGit super src rev "streamly-shell";
90+
91+ streamly-process = let
92+ src = "https://github.com/composewell/streamly-process.git";
93+ rev = "a56ef61c1208c2d564a526eba315d903c0b4af2c";
94+ in nixpkgs.haskell.lib.dontCheck
95+ (mkPkgGit super src rev "streamly-process");
96+
97+ #streamly-process = nixpkgs.haskell.lib.dontCheck
98+ # (super.callHackageDirect {
99+ # pkg = "streamly-process";
100+ # ver = "0.1.0";
101+ # sha256 = "01nxisqfmn29fbirdsx71sfjp2rdqwrf469qyjcql2d11i1bxn94";
102+ # } { });
103+
104+ # streamly = super.callHackageDirect {
105+ # pkg = "streamly";
106+ # ver = "0.8.0";
107+ # sha256 = "0vy2lkljizlhpbpbybmg9jcmj2g4s1aaqd2dzy5c0y0n4rgwxask";
108+ # } { };
109+ streamly =
110+ nixpkgs.haskell.lib.overrideCabal
111+ #(super.callHackageDirect
112+ # { pkg = "streamly";
113+ # ver = "0.8.2";
114+ # sha256 = "sha256-CjFq9SCdbgLZa7NqOE4OtC8OaFg4vK8VmIDjGU5rGko=";
115+ # } {})
116+ (let src = fetchGit {
117+ url = "git@github.com:composewell/streamly.git";
118+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
119+ }; in super.callCabal2nix "streamly" src {})
120+ (old:
121+ { librarySystemDepends =
122+ if builtins.currentSystem == "x86_64-darwin"
123+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
124+ else [];
125+ #enableLibraryProfiling = false;
126+ doHaddock = false;
127+ });
128+
129+ streamly-core =
130+ nixpkgs.haskell.lib.overrideCabal
131+ (let src = fetchGit {
132+ url = "git@github.com:composewell/streamly.git";
133+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
134+ }; in super.callCabal2nix "streamly-core" "${src}/core" {})
135+ (old:
136+ { librarySystemDepends =
137+ if builtins.currentSystem == "x86_64-darwin"
138+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
139+ else [];
140+ #enableLibraryProfiling = false;
141+ doHaddock = false;
142+ });
143+
144+ };
145+ };
146+
147+ drv = mkHaskellPackages true;
148+
149+ shell = drv.shellFor {
150+ packages = p:
151+ [ p.report
152+ ];
153+ # Use a better prompt
154+ shellHook = ''
155+ export CABAL_DIR="$(pwd)/.cabal.nix"
156+ if test -n "$PS_SHELL"
157+ then
158+ export PS1="$PS_SHELL\[$bldred\](nix)\[$txtrst\] "
159+ fi
160+ '';
161+ };
162+in if nixpkgs.lib.inNixShell
163+ then shell
164+ else (mkHaskellPackages false).report
bin/bench-config.shdeleted−160
@@ -1,160 +0,0 @@
1−#!/usr/bin/env bash
2−
3−BENCH_CONFIG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
4−source $BENCH_CONFIG_DIR/targets.sh \
5− || { echo "Cannot source $BENCH_CONFIG_DIR/targets.sh"; exit 1; }
6−
7−# Customization options
8−bench_config () {
9− BENCH_REPORT_DIR=benchmark/bench-report
10− BENCHMARK_PACKAGE_NAME=streamly-benchmarks
11− BENCHMARK_PACKAGE_VERSION=0.0.0
12−
13− USE_GAUGE=0
14− DEFAULT_FIELDS="allocated cputime bytescopied"
15−}
16−
17−#------------------------------------------------------------------------------
18−# benchmark groups
19−#------------------------------------------------------------------------------
20−
21−bench_targets () {
22− targets
23−}
24−
25−#------------------------------------------------------------------------------
26−# RTS options based on the benchmark executable name and benchmark name
27−#------------------------------------------------------------------------------
28−
29−bench_rts_options () {
30− local exe_name
31− local bench_name
32−
33− exe_name="$1"
34− bench_name="$2"
35−
36− # Based on benchmark class
37− case "$bench_name" in
38− */o-1-sp*) echo -n "-K36K -M16M" ;;
39− */o-n-h*) echo -n "-K36K -M32M" ;;
40− */o-n-st*) echo -n "-K1M -M16M" ;;
41− */o-n-sp*) echo -n "-K1M -M32M" ;;
42− *) echo -n "" ;;
43− esac
44−
45− echo -n " "
46− case "$exe_name" in
47− Prelude.Concurrent*) echo -n "-K256K -M384M" ;;
48− *) echo -n "" ;;
49− esac
50−
51− echo -n " "
52− # Based on specific benchmark
53− # XXX Note: for tasty-bench we replace the "." separator in the benchmark names
54− # with "/" for matching with this. It may not work reliably if the benchmark
55− # name already contains ".".
56− case "$bench_name" in
57− Data.Stream.StreamD/o-n-space/elimination/toList) echo -n "-K2M" ;;
58− Data.Stream.StreamK/o-n-space/elimination/toList) echo -n "-K2M" ;;
59−
60− Prelude.Parallel/o-n-heap/mapping/mapM) echo -n "-M256M" ;;
61− Prelude.Parallel/o-n-heap/monad-outer-product/*) echo -n "-M256M" ;;
62− Prelude.Parallel/o-n-space/monad-outer-product/*) echo -n "-K4M -M256M" ;;
63−
64− Prelude.Rate/o-1-space/*) echo -n "-K128K" ;;
65− Prelude.Rate/o-1-space/asyncly/*) echo -n "-K128K" ;;
66−
67− # XXX For GHC-9.0
68− Prelude.Serial/o-1-space/mixed/sum-product-fold) echo -n "-K64M" ;;
69−
70− # XXX These should be moved to o-n-space?
71− Prelude.Serial/o-n-heap/grouping/classifySessionsOf*) echo -n "-K4M -M32M" ;;
72− Prelude.Serial/o-n-heap/Functor/*) echo -n "-K4M -M32M" ;;
73− Prelude.Serial/o-n-heap/transformer/*) echo -n "-K8M -M64M" ;;
74−
75− Prelude.Serial/o-n-space/Functor/*) echo -n "-K4M -M64M" ;;
76− Prelude.Serial/o-n-space/Applicative/*) echo -n "-K8M -M128M" ;;
77− Prelude.Serial/o-n-space/Monad/*) echo -n "-K8M -M64M" ;;
78−
79− # Use -K4M for o-n-space except for grouping
80− Prelude.Serial/o-n-space/grouping/*) echo -n "" ;;
81− Prelude.Serial/o-n-space/*) echo -n "-K4M" ;;
82−
83− Prelude.WSerial/o-n-space/*) echo -n "-K4M" ;;
84−
85− Prelude.Async/o-n-space/monad-outer-product/*) echo -n "-K4M" ;;
86− Prelude.Ahead/o-n-space/monad-outer-product/*) echo -n "-K4M" ;;
87− Prelude.Ahead/o-1-space/*) echo -n "-K128K" ;;
88−
89− Prelude.WAsync/o-n-heap/monad-outer-product/toNull3) echo -n "-M64M" ;;
90− Prelude.WAsync/o-n-space/monad-outer-product/*) echo -n "-K4M" ;;
91−
92− # XXX need to investigate these, taking too much stack
93− Data.Parser.ParserD/o-1-space/some) echo -n "-K8M" ;;
94− Data.Parser/o-1-space/some) echo -n "-K8M" ;;
95− Data.Parser.ParserD/o-1-space/manyTill) echo -n "-K4M" ;;
96− Data.Parser/o-1-space/manyTill) echo -n "-K4M" ;;
97− Data.Parser/o-n-heap/manyAlt) echo -n "-K4M -M128M" ;;
98− Data.Parser/o-n-heap/someAlt) echo -n "-K4M -M128M" ;;
99− Data.Parser/o-n-heap/choice) echo -n "-K16M -M32M" ;;
100− Data.Parser.ParserK/o-n-heap/manyAlt) echo -n "-K4M -M128M" ;;
101− Data.Parser.ParserK/o-n-heap/someAlt) echo -n "-K4M -M128M" ;;
102− Data.Parser.ParserK/o-n-heap/sequence) echo -n "-M64M";;
103− Data.Parser.ParserK/o-n-heap/sequenceA) echo -n "-M64M";;
104−
105− Data.SmallArray/o-1-sp*) echo -n "-K128K" ;;
106− # For tasty-bench
107− Data.Array*/o-1-space/generation/show) echo -n "-M32M" ;;
108− # XXX For GHC-8.10
109− Data.Array/o-1-space/transformationX4/map) echo -n "-M32M" ;;
110− # DEVBUILD only benchmarks - array foldable instance
111− Data.Array.Foreign/o-1-space/elimination/foldable/foldl*) echo -n "-K8M" ;;
112− Data.Array.Foreign/o-1-space/elimination/foldable/sum) echo -n "-K8M" ;;
113− *) echo -n "" ;;
114− esac
115−}
116−
117−#------------------------------------------------------------------------------
118−# Speed options
119−#------------------------------------------------------------------------------
120−
121−bench_speed_options () {
122− local exe_name
123− local bench_name
124−
125− exe_name="$1"
126− bench_name="$2"
127−
128− case "$exe_name" in
129− Prelude.Concurrent) set_super_quick_mode ;;
130− Prelude.Rate) set_super_quick_mode ;;
131− Prelude.Adaptive) set_super_quick_mode;;
132− *) echo -n "" ;;
133− esac
134−
135− # XXX Note: for tasty-bench we replace the "." separator in the benchmark names
136− # with "/" for matching with this. It may not work reliably if the benchmark
137− # name already contains ".".
138−
139− # Use quick options for benchmarks that take too long
140− case "$bench_name" in
141− Prelude.Parallel/o-n-heap/mapping/mapM) set_super_quick_mode ;;
142− Prelude.Parallel/o-n-heap/monad-outer-product/*) set_super_quick_mode ;;
143− Prelude.Parallel/o-n-space/monad-outer-product/*) set_super_quick_mode ;;
144− Prelude.Parallel/o-n-heap/generation/*) use_quicker_mode ;;
145− Prelude.Parallel/o-n-heap/mapping/*) use_quicker_mode ;;
146− Prelude.Parallel/o-n-heap/concat-foldable/*) use_quicker_mode ;;
147−
148− Prelude.Async/o-1-space/monad-outer-product/*) use_quicker_mode ;;
149− Prelude.Async/o-n-space/monad-outer-product/*) use_quicker_mode ;;
150−
151− Prelude.Ahead/o-1-space/monad-outer-product/*) use_quicker_mode ;;
152− Prelude.Ahead/o-n-space/monad-outer-product/*) use_quicker_mode ;;
153−
154− Prelude.WAsync/o-n-heap/monad-outer-product/*) use_quicker_mode ;;
155− Prelude.WAsync/o-n-space/monad-outer-product/*) use_quicker_mode ;;
156−
157− FileSystem.Handle/*) use_quicker_mode ;;
158− *) echo -n "" ;;
159− esac
160−}
bin/bench.shdeleted−15
@@ -1,15 +0,0 @@
1−#!/usr/bin/env bash
2−
3−SCRIPT_DIR=$(cd `dirname $0`; pwd)
4−source $SCRIPT_DIR/bench-config.sh \
5− || { echo "Cannot source $SCRIPT_DIR/bench-config.sh"; exit 1; }
6−
7−bench_config
8−if test -z "$BENCH_REPORT_DIR"
9−then
10− echo "BENCH_REPORT_DIR variable not defined by bench-config() in $SCRIPT_DIR/bench-config.sh"
11− exit 1
12−fi
13−
14−cd $SCRIPT_DIR/..
15−$BENCH_REPORT_DIR/bin/bench-runner.sh --config $SCRIPT_DIR/bench-config.sh "$@"
bin/targets.shdeleted−120
@@ -1,120 +0,0 @@
1−#------------------------------------------------------------------------------
2−# test and benchmark groups
3−#------------------------------------------------------------------------------
4−
5−# Depends on RUNNING_TESTS, RUNNING_BENCHMARKS, RUNNING_DEVBUILD variables
6−# being set for dev_build, test_only, bench_only functions to work. So the
7−# "targets" fucntion should be called only after these are set.
8−
9−# IMPORTANT NOTE: the names "_grp" and "_cmp" suffixes are special, do
10−# not rename them to something else.
11−
12−targets () {
13− base_stream_grp="\
14− `bench_only Data.Stream.StreamD` \
15− `bench_only Data.Stream.StreamK` \
16− `bench_only Data.Stream.StreamDK`"
17−
18− prelude_serial_grp="\
19− Prelude.Serial \
20− Prelude.WSerial \
21− Prelude.ZipSerial"
22−
23− prelude_concurrent_grp="\
24− Prelude.Async \
25− Prelude.WAsync \
26− Prelude.Ahead \
27− Prelude.Parallel \
28− Prelude.ZipAsync"
29−
30− prelude_other_grp="\
31− `test_only Prelude` \
32− $(test_only $(dev_build Prelude.Rate)) \
33− `bench_only Prelude.Rate` \
34− `test_only Prelude.Fold` \
35− `test_only Prelude.Concurrent` \
36− $(bench_only $(dev_build Prelude.Concurrent)) \
37− `bench_only Prelude.Adaptive`"
38−
39− array_grp="\
40− Data.Array \
41− Data.Array.Foreign \
42− Data.Array.Prim \
43− Data.SmallArray \
44− Data.Array.Prim.Pinned"
45−
46− base_parser_grp="\
47− Data.Parser.ParserD \
48− `bench_only Data.Parser.ParserK`"
49−
50− parser_grp="\
51− Data.Fold \
52− Data.Parser"
53−
54− list_grp="\
55− `test_only Data.List.Base` \
56− `test_only Data.List`"
57−
58− #------------------------------------------------------------------------------
59− # Streaming vs non-streaming
60− #------------------------------------------------------------------------------
61− # The "o-1-space" groups of these benchmarks are run with long stream
62− # sizes when --long option is used.
63−
64− infinite_grp="\
65− $prelude_serial_grp \
66− $prelude_concurrent_grp \
67− `bench_only Prelude.Rate`"
68−
69− #------------------------------------------------------------------------------
70− # Benchmark comparison groups
71− #------------------------------------------------------------------------------
72−
73− # *_cmp denotes a comparison benchmark, the benchmarks provided in *_cmp
74− # variables are compared with each other
75− base_stream_cmp="Data.Stream.StreamD Data.Stream.StreamK"
76− serial_wserial_cmp="Prelude.Serial Prelude.WSerial"
77− serial_async_cmp="Prelude.Serial Prelude.Async"
78− concurrent_cmp="Prelude.Async Prelude.WAsync Prelude.Ahead Prelude.Parallel"
79− array_cmp="Data.Array.Foreign Data.Array.Prim Data.Array Data.Array.Prim.Pinned"
80− pinned_array_cmp="Data.Array.Foreign Data.Array.Prim.Pinned"
81− base_parser_cmp=$base_parser_grp
82−
83− COMPARISONS="\
84− base_stream_cmp \
85− serial_wserial_cmp \
86− serial_async_cmp \
87− concurrent_cmp \
88− array_cmp \
89− pinned_array_cmp \
90− base_parser_cmp"
91−
92− #------------------------------------------------------------------------------
93− # All test/benchmark modules must be in at least one of these
94− #------------------------------------------------------------------------------
95−
96− # All groups
97− GROUP_TARGETS="\
98− base_stream_grp \
99− prelude_serial_grp \
100− prelude_concurrent_grp \
101− prelude_other_grp \
102− array_grp \
103− base_parser_grp \
104− parser_grp \
105− list_grp \
106− infinite_grp"
107−
108− # Not in any groups
109− INDIVIDUAL_TARGETS="\
110− Data.Unfold \
111− Unicode.Stream \
112− $(test_only $(dev_build Unicode.Char)) \
113− `bench_only Unicode.Char` \
114− `bench_only Unicode.Utf8` \
115− FileSystem.Handle \
116− `test_only FileSystem.Event` \
117− `test_only Network.Socket` \
118− `test_only Network.Inet.TCP` \
119− `test_only version-bounds`"
120−}
bin/test.shdeleted−247
@@ -1,247 +0,0 @@
1−#!/usr/bin/env bash
2−
3−SCRIPT_DIR=$(dirname $0)
4−
5−STREAMLY_VERSION=0.8.2
6−BENCH_REPORT_DIR=benchmark/bench-report
7−source $SCRIPT_DIR/targets.sh
8−
9−#------------------------------------------------------------------------------
10−# Script
11−#------------------------------------------------------------------------------
12−
13−print_help () {
14− echo "Usage: $0 "
15− echo " [--targets <"target1 target2 ..." | help>]"
16− echo
17− echo " [--quick]"
18− echo " [--with-compiler <compiler exe name>]"
19− echo " [--cabal-build-options <option>]"
20− echo " [--dev-build]"
21− echo
22− echo " [--coverage]"
23− echo " [--hpc-report-options <option>]"
24− echo " [--no-measure]"
25− echo " [--raw]"
26− echo
27− echo " [--rtsopts <option>]"
28− echo " -- <hspec options or test names>"
29− echo
30− echo "--targets: targets to run, use 'help' for list of targets"
31− echo
32− echo "--quick: disable optimizations to build quickly"
33− echo "--cabal-build-options: Pass any cabal build options to be used for build"
34− echo "--dev-build: runs some additional tests"
35− echo
36− echo "--coverage: enable coverage and report coverage info"
37− echo "--hpc-report-options: option for 'hpc report'"
38− echo "--no-measure: with --coverage, do not run tests, only show coverage info"
39− echo "--raw: with --coverage, do not run hpc"
40− echo
41− echo "--rtsopts: pass GHC RTS options to the test executable"
42− echo "Any arguments after a '--' are passed directly to hspec"
43− exit
44−}
45−
46−#-----------------------------------------------------------------------------
47−# Read command line
48−#-----------------------------------------------------------------------------
49−
50−RUNNING_TESTS=y
51−source $BENCH_REPORT_DIR/bin/build-lib.sh
52−
53−USE_GIT_CABAL=1
54−set_common_vars
55−COVERAGE=0
56−MEASURE=1
57−HPC_REPORT_OPTIONS=
58−RAW=0
59−CABAL_BUILD_OPTIONS="--flag limit-build-mem"
60−TEST_QUICK_MODE=0
61−
62−# XXX add a bisect option
63−while test -n "$1"
64−do
65− case $1 in
66− -h|--help|help) print_help ;;
67− # options with arguments
68− --targets) shift; TARGETS=$1; shift ;;
69− --with-compiler) shift; CABAL_WITH_COMPILER=$1; shift ;;
70− --cabal-build-options) shift; CABAL_BUILD_OPTIONS+=" $1"; shift ;;
71− --hpc-report-options) shift; HPC_REPORT_OPTIONS="$1"; shift ;;
72− --rtsopts) shift; RTS_OPTIONS="$1"; shift ;;
73− # flags
74− --raw) RAW=1; shift ;;
75− #--slow) SLOW=1; shift ;; # not implemented
76− --quick) TEST_QUICK_MODE=1; shift ;;
77− --dev-build) RUNNING_DEVBUILD=1 CABAL_BUILD_OPTIONS+=" --flag dev"; shift ;;
78− --coverage) COVERAGE=1; shift ;;
79− --no-measure) MEASURE=0; shift ;;
80− --) shift; break ;;
81− -*|--*) echo "Unknown flags: $*"; echo; print_help ;;
82− *) break ;;
83− esac
84−done
85−TARGET_EXE_ARGS=$*
86−
87−set_derived_vars
88−
89−if test $TEST_QUICK_MODE -eq 1
90−then
91− CABAL_BUILD_OPTIONS+=" --disable-optimization --flags -opt"
92−fi
93−
94−#-----------------------------------------------------------------------------
95−# Determine targets
96−#-----------------------------------------------------------------------------
97−
98−# Defined in targets.sh
99−targets
100−
101−if test "$(has_item "$TARGETS" help)" = "help"
102−then
103− list_target_groups
104− list_targets
105− exit
106−fi
107−
108−DEFAULT_TARGETS="$(all_grp)"
109−TARGETS=$(set_targets)
110−
111−echo "Using targets [$TARGETS]"
112−
113−#-----------------------------------------------------------------------------
114−# Build targets
115−#-----------------------------------------------------------------------------
116−
117−test_exe_rts_opts () {
118− case "$1" in
119− # XXX Data.Array.* heap requirement increased for GHC-8.10
120− Data.Array.Foreign) echo -n "-M128M" ;;
121− Data.Array.Prim) echo -n "-M128M" ;;
122− Data.Array.Prim.Pinned) echo -n "-M128M" ;;
123− Prelude.Rate) echo -n "-M512M" ;;
124− # For -O0 case writeChunks test fails, maybe we should have a separate flag
125− # for O0 case?
126− FileSystem.Handle) echo -n "-K16M" ;;
127− *) if test "$COVERAGE" -eq "1"
128− then
129− echo -n "-K8M -M1024M"
130− else
131− echo -n "-K8M -M64M"
132− fi ;;
133− esac
134−}
135−
136−# $1: bench name
137−# $2: bench executable
138−target_exe_extra_args () {
139− local bench_name=$1
140− local bench_prog=$2
141−
142− echo "+RTS \
143− $(test_exe_rts_opts $(basename $bench_prog)) \
144− $RTS_OPTIONS \
145− -RTS"
146−}
147−
148−if test "$COVERAGE" -eq "1"
149−then
150− # Used to determine the hpc tix dir
151− PACKAGE_FULL_NAME=streamly-$STREAMLY_VERSION
152− case `uname` in
153− Linux) SYSTEM=x86_64-linux ;;
154− *) echo "Unsupported system"; exit 1 ;;
155− esac
156−
157− # With the --enable-coverage option the tests as well as the library get
158− # compiled with -fhpc, and we get coverage for tests as well. But we want to
159− # exclude that, so a project file is needed.
160− CABAL_BUILD_OPTIONS+=" --project-file cabal.project.coverage"
161− mkdir -p $BUILD_DIR/hpc
162−fi
163−BUILD_TEST="$CABAL_EXECUTABLE v2-build $CABAL_BUILD_OPTIONS --enable-tests"
164−
165−if test "$MEASURE" -eq "1"
166−then
167−run_build "$BUILD_TEST" streamly-tests test "$TARGETS"
168−fi
169−
170−#-----------------------------------------------------------------------------
171−# Run targets
172−#-----------------------------------------------------------------------------
173−
174−# $1: target name
175−get_tix_file () {
176− echo $BUILD_DIR/build/$SYSTEM/ghc-${GHC_VERSION}/$PACKAGE_FULL_NAME/hpc/vanilla/tix/$1/$1.tix
177−}
178−
179−# $1: package name
180−# $2: component
181−# $3: target
182−# $4: args generator func
183−run_target () {
184− local package_name=$1
185− local component=$2
186− local target_name=$3
187− local extra_args=$4
188−
189− local target_prog
190−
191− target_prog=$(cabal_target_prog $package_name $component $target_name) || \
192− die "Cannot find executable for target $target_name"
193−
194− echo "Running executable $target_name ..."
195−
196− mkdir -p $(dirname $(get_tix_file $target_name))
197− export HPCTIXFILE=$(get_tix_file $target_name)
198−
199− run_verbose $target_prog $($extra_args $target_name $target_prog) \
200− || die "Target exe failed"
201−
202− # hpc-coveralls fails if there is an empty dir and no .tix file generated
203− rmdir $(dirname $(get_tix_file $target_name)) 2>/dev/null || true
204−}
205−
206−# $1: package name with version
207−# $2: component
208−# $3: targets
209−# $4: args generator func
210−run_targets() {
211− for i in $3
212− do
213− run_target $1 $2 $i $4
214− done
215−}
216−
217−if test "$MEASURE" -eq "1"
218−then
219−run_targets "streamly-tests-0.0.0" t "$TARGETS" target_exe_extra_args
220−fi
221−
222−#-----------------------------------------------------------------------------
223−# Run coverage reports
224−#-----------------------------------------------------------------------------
225−
226−PACKAGE_NAME=streamly-$STREAMLY_VERSION
227−MIX_DIR=$BUILD_DIR/build/$SYSTEM/ghc-${GHC_VERSION}/$PACKAGE_NAME/hpc/vanilla/mix/$PACKAGE_NAME/
228−ALLTIX=$BUILD_DIR/hpc/all.tix
229−
230−if test "$COVERAGE" -eq "1" -a "$RAW" -eq 0
231−then
232− TIXFILES=
233− for i in $TARGETS
234− do
235− tixfile="$(get_tix_file ${i})"
236− if test -f "$tixfile"
237− then
238− TIXFILES+="$tixfile "
239− fi
240− done
241−
242− #echo "Combining tix files:"
243− #echo $TIXFILES | tr ' ' '\n'
244− hpc sum --union --output=$ALLTIX $TIXFILES
245− run_verbose hpc markup $ALLTIX --hpcdir $MIX_DIR
246− run_verbose hpc report $ALLTIX $HPC_REPORT_OPTIONS --hpcdir $MIX_DIR
247−fi
cabal.project.reportnew file+32
@@ -0,0 +1,32 @@
1+packages:
2+ targets/streamly-targets.cabal
3+ benchmark/bench-runner/bench-runner.cabal
4+ test/test-runner/test-runner.cabal
5+ streamly.cabal
6+ core/streamly-core.cabal
7+
8+package bench-report
9+ flags: +no-charts
10+
11+package bench-show
12+ flags: +no-charts
13+
14+source-repository-package
15+ type: git
16+ location: https://github.com/composewell/bench-report.git
17+ tag: master
18+
19+source-repository-package
20+ type: git
21+ location: https://github.com/composewell/streamly-coreutils.git
22+ tag: 8fa4a3ebedb3f970f64b7d78d8ab340b0f771abe
23+
24+source-repository-package
25+ type: git
26+ location: https://github.com/composewell/streamly-shell.git
27+ tag: 7d77ddc0c06aec21fbbfd1b920ec4f58da654a1b
28+
29+source-repository-package
30+ type: git
31+ location: https://github.com/composewell/streamly-process.git
32+ tag: 6a70b0a304cb47a725ff697eae01eaa5ea6fe833
streamly.cabal+6−9
@@ -49,11 +49,8 @@ build-type: Configure
4949
5050extra-source-files:
5151 benchmark/*.hs
52− benchmark/bench-report/BenchReport.hs
53− benchmark/bench-report/bench-report.cabal
54− benchmark/bench-report/bin/bench-runner.sh
55− benchmark/bench-report/bin/build-lib.sh
56− benchmark/bench-report/cabal.project
52+ benchmark/bench-runner/Main.hs
53+ benchmark/bench-runner/bench-runner.cabal
5754 benchmark/Streamly/Benchmark/Data/*.hs
5855 benchmark/Streamly/Benchmark/Data/Array/Common.hs
5956 benchmark/Streamly/Benchmark/Data/Array/CommonImports.hs
@@ -74,16 +71,16 @@ extra-source-files:
7471 benchmark/lib/Streamly/Benchmark/*.hs
7572 benchmark/lib/Streamly/Benchmark/Common/*.hs
7673 benchmark/streamly-benchmarks.cabal
77− bin/bench.sh
78− bin/bench-config.sh
7974 bin/mk-hscope.sh
8075 bin/mk-tags.sh
81− bin/targets.sh
82− bin/test.sh
8376 configure
8477 configure.ac
8578 docs/*.hs
8679 docs/streamly-docs.cabal
80+ targets/streamly-targets.cabal
81+ targets/Targets.hs
82+ test/test-runner/Main.hs
83+ test/test-runner/test-runner.cabal
8784
8885 -- This is duplicated
8986 src/Streamly/Internal/Data/Stream/Instances.hs
targets/Targets.hsnew file+149
@@ -0,0 +1,149 @@
1+module Targets
2+ ( targets
3+ )
4+where
5+
6+targets :: [(String, [String])]
7+targets =
8+ [ -- Base streams
9+ ("Data.Stream.StreamD",
10+ [ "base_stream_grp"
11+ , "base_stream_cmp"
12+ , "noTest"
13+ ]
14+ )
15+ , ("Data.Stream.StreamK",
16+ [ "base_stream_grp"
17+ , "base_stream_cmp"
18+ , "noTest"
19+ ]
20+ )
21+ , ("Data.Stream.StreamDK",
22+ [ "base_stream_grp"
23+ , "noTest"
24+ ]
25+ )
26+
27+ -- Streams
28+ , ("Prelude.Serial", ["serial_wserial_cmp"])
29+ , ("Prelude.WSerial", ["serial_wserial_cmp"])
30+ , ("Prelude.Serial",
31+ [ "prelude_serial_grp"
32+ , "infinite_grp"
33+ , "serial_wserial_cmp"
34+ , "serial_async_cmp"
35+ ]
36+ )
37+ , ("Prelude.WSerial",
38+ [ "prelude_serial_grp"
39+ , "infinite_grp"
40+ , "serial_wserial_cmp"
41+ ]
42+ )
43+ , ("Prelude.ZipSerial",
44+ [ "prelude_serial_grp"
45+ , "infinite_grp"
46+ ]
47+ )
48+ , ("Prelude.Async",
49+ [ "prelude_concurrent_grp"
50+ , "infinite_grp"
51+ , "concurrent_cmp"
52+ , "serial_async_cmp"
53+ ]
54+ )
55+ , ("Prelude.WAsync",
56+ [ "prelude_concurrent_grp"
57+ , "infinite_grp"
58+ , "concurrent_cmp"
59+ ]
60+ )
61+ , ("Prelude.Ahead",
62+ [ "prelude_concurrent_grp"
63+ , "infinite_grp"
64+ , "concurrent_cmp"
65+ ]
66+ )
67+ , ("Prelude.Parallel",
68+ [ "prelude_concurrent_grp"
69+ , "infinite_grp"
70+ , "concurrent_cmp"
71+ ]
72+ )
73+ , ("Prelude.ZipAsync",
74+ [ "prelude_concurrent_grp"
75+ , "infinite_grp"
76+ ]
77+ )
78+ , ("Prelude.Concurrent", [ "prelude_other_grp" ])
79+ , ("Prelude.Rate",
80+ [ "prelude_other_grp"
81+ , "infinite_grp"
82+ , "testDevOnly"
83+ ]
84+ )
85+ , ("Prelude.Adaptive",
86+ [ "prelude_other_grp"
87+ , "noTest"
88+ ]
89+ )
90+
91+ -- Arrays
92+ , ("Data.Array",
93+ [ "array_grp"
94+ , "array_cmp"
95+ ]
96+ )
97+ , ("Data.Array.Foreign",
98+ [ "array_grp"
99+ , "array_cmp"
100+ , "pinned_array_cmp"
101+ ]
102+ )
103+ , ("Data.Array.Prim",
104+ [ "array_grp"
105+ , "array_cmp"
106+ ]
107+ )
108+ , ("Data.Array.Prim.Pinned",
109+ [ "array_grp"
110+ , "array_cmp"
111+ , "pinned_array_cmp"
112+ ]
113+ )
114+ , ("Data.SmallArray",
115+ [ "array_grp" ]
116+ )
117+
118+ -- Parsers
119+ , ("Data.Parser.ParserD",
120+ [ "base_parser_grp"
121+ , "base_parser_cmp"
122+ ]
123+ )
124+ , ("Data.Parser.ParserK",
125+ [ "base_parser_grp"
126+ , "base_parser_cmp"
127+ , "noTest"
128+ ]
129+ )
130+ , ("Data.Fold", [ "parser_grp" ])
131+ , ("Data.Parser", [ "parser_grp" ])
132+
133+ , ("Data.Unfold", [])
134+ , ("FileSystem.Handle", [])
135+ , ("Unicode.Stream", [])
136+ , ("Unicode.Utf8", ["noTest"])
137+ , ("Unicode.Char", ["testDevOnly"])
138+
139+ -- test only, no benchmarks
140+ , ("Prelude", ["prelude_other_grp", "noBench"])
141+ , ("Prelude.Fold", ["prelude_other_grp", "noBench"])
142+ , ("FileSystem.Event", ["noBench"])
143+ , ("Network.Socket", ["noBench"])
144+ , ("Network.Inet.TCP", ["noBench"])
145+ , ("version-bounds", ["noBench"])
146+
147+ , ("Data.List", ["list_grp", "noBench"])
148+ , ("Data.List.Base", ["list_grp", "noBench"])
149+ ]
benchmark/bench-report/cabal.project → targets/cabal.projectrenamed

The content is the same.

targets/default.nixnew file+163
@@ -0,0 +1,163 @@
1+let
2+ nixpkgsPath_21_11 =
3+ "https://github.com/NixOS/nixpkgs/archive/refs/tags/21.11.tar.gz";
4+ nixpkgsDefault = import (builtins.fetchTarball nixpkgsPath_21_11) { };
5+in
6+{
7+ nixpkgs ? nixpkgsDefault
8+, compiler ? "default"
9+}:
10+let haskellPackages =
11+ if compiler == "default"
12+ then nixpkgs.haskellPackages
13+ else nixpkgs.haskell.packages.${compiler};
14+
15+ mkPackage = super: pkg: path: opts: inShell:
16+ let orig = super.callCabal2nixWithOptions pkg path opts {};
17+ in if inShell
18+ # Avoid copying the source directory to nix store by using
19+ # src = null.
20+ then orig.overrideAttrs (oldAttrs: { src = null; })
21+ else orig;
22+
23+ mkPkgGit = super: gitSrc: rev: name:
24+ let
25+ src = builtins.fetchGit {
26+ url = gitSrc;
27+ rev = rev;
28+ };
29+ in super.callCabal2nix name src { };
30+
31+ mkPkgGitRef = super: gitSrc: rev: ref: name:
32+ let
33+ src = builtins.fetchGit {
34+ url = gitSrc;
35+ rev = rev;
36+ ref = ref;
37+ };
38+ in super.callCabal2nix name src { };
39+
40+ mkHaskellPackages = inShell:
41+ haskellPackages.override {
42+ overrides = self: super:
43+ with nixpkgs.haskell.lib;
44+ {
45+ report = mkPackage super "streamly-targets" ./. "" inShell;
46+
47+ bench-report =
48+ nixpkgs.haskell.lib.overrideCabal
49+ (let src = fetchGit {
50+ url = "git@github.com:composewell/bench-report.git";
51+ rev = "57d0ad221c74cdb2ce81646ab18300e8bb8e716b";
52+ }; in super.callCabal2nix "bench-report" src {})
53+ (old:
54+ { enableLibraryProfiling = false;
55+ doHaddock = false;
56+ });
57+
58+ bench-show = super.callHackageDirect {
59+ pkg = "bench-show";
60+ ver = "0.3.2";
61+ sha256 = "16b8vyzdp9b5bh34kqmbfwjsyv8wgnxxwl8kjcpgxjsh52xzyaa0";
62+ } { };
63+
64+# streamly-coreutils = let
65+# src = "git@github.com:composewell/streamly-coreutils.git";
66+# rev = "a12756efe24bbf303f2f6d66a95426c7657d297b";
67+# in mkPkgGit super src rev "streamly-coreutils";
68+
69+ streamly-coreutils =
70+ nixpkgs.haskell.lib.overrideCabal
71+ (let src = fetchGit {
72+ url = "git@github.com:composewell/streamly-coreutils.git";
73+ rev = "8fa4a3ebedb3f970f64b7d78d8ab340b0f771abe";
74+ }; in super.callCabal2nix "streamly-coreutils" src {})
75+ (old:
76+ { librarySystemDepends =
77+ if builtins.currentSystem == "x86_64-darwin"
78+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
79+ else [];
80+ #enableLibraryProfiling = false;
81+ doHaddock = false;
82+ doCheck = false;
83+ });
84+
85+ streamly-shell = let
86+ src = "https://github.com/composewell/streamly-shell.git";
87+ rev = "7d77ddc0c06aec21fbbfd1b920ec4f58da654a1b";
88+ in mkPkgGit super src rev "streamly-shell";
89+
90+ streamly-process = let
91+ src = "https://github.com/composewell/streamly-process.git";
92+ rev = "a56ef61c1208c2d564a526eba315d903c0b4af2c";
93+ in nixpkgs.haskell.lib.dontCheck
94+ (mkPkgGit super src rev "streamly-process");
95+
96+ #streamly-process = nixpkgs.haskell.lib.dontCheck
97+ # (super.callHackageDirect {
98+ # pkg = "streamly-process";
99+ # ver = "0.1.0";
100+ # sha256 = "01nxisqfmn29fbirdsx71sfjp2rdqwrf469qyjcql2d11i1bxn94";
101+ # } { });
102+
103+ # streamly = super.callHackageDirect {
104+ # pkg = "streamly";
105+ # ver = "0.8.0";
106+ # sha256 = "0vy2lkljizlhpbpbybmg9jcmj2g4s1aaqd2dzy5c0y0n4rgwxask";
107+ # } { };
108+ streamly =
109+ nixpkgs.haskell.lib.overrideCabal
110+ #(super.callHackageDirect
111+ # { pkg = "streamly";
112+ # ver = "0.8.2";
113+ # sha256 = "sha256-CjFq9SCdbgLZa7NqOE4OtC8OaFg4vK8VmIDjGU5rGko=";
114+ # } {})
115+ (let src = fetchGit {
116+ url = "git@github.com:composewell/streamly.git";
117+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
118+ }; in super.callCabal2nix "streamly" src {})
119+ (old:
120+ { librarySystemDepends =
121+ if builtins.currentSystem == "x86_64-darwin"
122+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
123+ else [];
124+ #enableLibraryProfiling = false;
125+ doHaddock = false;
126+ });
127+
128+ streamly-core =
129+ nixpkgs.haskell.lib.overrideCabal
130+ (let src = fetchGit {
131+ url = "git@github.com:composewell/streamly.git";
132+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
133+ }; in super.callCabal2nix "streamly-core" "${src}/core" {})
134+ (old:
135+ { librarySystemDepends =
136+ if builtins.currentSystem == "x86_64-darwin"
137+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
138+ else [];
139+ #enableLibraryProfiling = false;
140+ doHaddock = false;
141+ });
142+
143+ };
144+ };
145+
146+ drv = mkHaskellPackages true;
147+
148+ shell = drv.shellFor {
149+ packages = p:
150+ [ p.report
151+ ];
152+ # Use a better prompt
153+ shellHook = ''
154+ export CABAL_DIR="$(pwd)/.cabal.nix"
155+ if test -n "$PS_SHELL"
156+ then
157+ export PS1="$PS_SHELL\[$bldred\](nix)\[$txtrst\] "
158+ fi
159+ '';
160+ };
161+in if nixpkgs.lib.inNixShell
162+ then shell
163+ else (mkHaskellPackages false).streamly-targets
targets/streamly-targets.cabalnew file+12
@@ -0,0 +1,12 @@
1+cabal-version: 2.4
2+name: streamly-targets
3+version: 0.1.0.0
4+
5+library
6+ hs-source-dirs: .
7+ exposed-modules: Targets
8+ ghc-options: -Wall
9+ build-depends: base
10+ , bench-report
11+ , containers
12+ default-language: Haskell2010
test/test-runner/Main.hsnew file+34
@@ -0,0 +1,34 @@
1+module Main where
2+
3+import TestRunner (mainWith)
4+import BuildLib (Quickness(..))
5+import Control.Applicative ((<|>))
6+import Data.List (isInfixOf, isPrefixOf, isSuffixOf)
7+import Data.Map (Map)
8+
9+import qualified Data.Map as Map
10+import Targets (targets)
11+
12+rtsOpts :: Bool -> String -> String -> String
13+rtsOpts relaxMem exeName target =
14+
15+ if relaxMem
16+ then "-K16M -M1024M"
17+ else "-K8M -M64M " <> targetSpecific
18+
19+ where
20+
21+ targetSpecific =
22+ case target of
23+ -- XXX Data.Array.* heap requirement increased for GHC-8.10
24+ "Data.Array.Foreign" -> "-M128M"
25+ "Data.Array.Prim" -> "-M128M"
26+ "Data.Array.Prim.Pinned" -> "-M128M"
27+ "Prelude.Rate" -> "-M512M"
28+ -- For -O0 case writeChunks test fails, maybe we should have a
29+ -- separate flag for O0 case?
30+ "FileSystem.Handle" -> "-K16M"
31+ _ -> ""
32+
33+main :: IO ()
34+main = mainWith targets rtsOpts
test/test-runner/cabal.projectnew file+1
@@ -0,0 +1 @@
1+packages: ., ../../targets
test/test-runner/default.nixnew file+157
@@ -0,0 +1,157 @@
1+let
2+ nixpkgsPath_21_11 =
3+ "https://github.com/NixOS/nixpkgs/archive/refs/tags/21.11.tar.gz";
4+ nixpkgsDefault = import (builtins.fetchTarball nixpkgsPath_21_11) { };
5+in
6+{
7+ nixpkgs ? nixpkgsDefault
8+, compiler ? "default"
9+}:
10+let haskellPackages =
11+ if compiler == "default"
12+ then nixpkgs.haskellPackages
13+ else nixpkgs.haskell.packages.${compiler};
14+
15+ mkPackage = super: pkg: path: opts: inShell:
16+ let orig = super.callCabal2nixWithOptions pkg path opts {};
17+ in if inShell
18+ # Avoid copying the source directory to nix store by using
19+ # src = null.
20+ then orig.overrideAttrs (oldAttrs: { src = null; })
21+ else orig;
22+
23+ mkPkgGit = super: gitSrc: rev: name:
24+ let
25+ src = builtins.fetchGit {
26+ url = gitSrc;
27+ rev = rev;
28+ };
29+ in super.callCabal2nix name src { };
30+
31+ mkPkgGitRef = super: gitSrc: rev: ref: name:
32+ let
33+ src = builtins.fetchGit {
34+ url = gitSrc;
35+ rev = rev;
36+ ref = ref;
37+ };
38+ in super.callCabal2nix name src { };
39+
40+ mkHaskellPackages = inShell:
41+ haskellPackages.override {
42+ overrides = self: super:
43+ with nixpkgs.haskell.lib;
44+ {
45+ report = mkPackage super "streamly-test-report" ./. "" inShell;
46+
47+ bench-report =
48+ nixpkgs.haskell.lib.overrideCabal
49+ (let src = fetchGit {
50+ url = "git@github.com:composewell/bench-report.git";
51+ rev = "c11f79b202d812efe4d1785e0537f1ad4d947bfe";
52+ }; in super.callCabal2nix "bench-report" src {})
53+ (old:
54+ { enableLibraryProfiling = false;
55+ doHaddock = false;
56+ });
57+
58+# streamly-coreutils = let
59+# src = "git@github.com:composewell/streamly-coreutils.git";
60+# rev = "a12756efe24bbf303f2f6d66a95426c7657d297b";
61+# in mkPkgGit super src rev "streamly-coreutils";
62+
63+ streamly-coreutils =
64+ nixpkgs.haskell.lib.overrideCabal
65+ (let src = fetchGit {
66+ url = "git@github.com:composewell/streamly-coreutils.git";
67+ rev = "8fa4a3ebedb3f970f64b7d78d8ab340b0f771abe";
68+ }; in super.callCabal2nix "streamly-coreutils" src {})
69+ (old:
70+ { librarySystemDepends =
71+ if builtins.currentSystem == "x86_64-darwin"
72+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
73+ else [];
74+ #enableLibraryProfiling = false;
75+ doHaddock = false;
76+ doCheck = false;
77+ });
78+
79+ streamly-shell = let
80+ src = "https://github.com/composewell/streamly-shell.git";
81+ rev = "7d77ddc0c06aec21fbbfd1b920ec4f58da654a1b";
82+ in mkPkgGit super src rev "streamly-shell";
83+
84+ streamly-process = let
85+ src = "https://github.com/composewell/streamly-process.git";
86+ rev = "a56ef61c1208c2d564a526eba315d903c0b4af2c";
87+ in nixpkgs.haskell.lib.dontCheck
88+ (mkPkgGit super src rev "streamly-process");
89+
90+ #streamly-process = nixpkgs.haskell.lib.dontCheck
91+ # (super.callHackageDirect {
92+ # pkg = "streamly-process";
93+ # ver = "0.1.0";
94+ # sha256 = "01nxisqfmn29fbirdsx71sfjp2rdqwrf469qyjcql2d11i1bxn94";
95+ # } { });
96+
97+ # streamly = super.callHackageDirect {
98+ # pkg = "streamly";
99+ # ver = "0.8.0";
100+ # sha256 = "0vy2lkljizlhpbpbybmg9jcmj2g4s1aaqd2dzy5c0y0n4rgwxask";
101+ # } { };
102+ streamly =
103+ nixpkgs.haskell.lib.overrideCabal
104+ #(super.callHackageDirect
105+ # { pkg = "streamly";
106+ # ver = "0.8.2";
107+ # sha256 = "sha256-CjFq9SCdbgLZa7NqOE4OtC8OaFg4vK8VmIDjGU5rGko=";
108+ # } {})
109+ (let src = fetchGit {
110+ url = "git@github.com:composewell/streamly.git";
111+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
112+ }; in super.callCabal2nix "streamly" src {})
113+ (old:
114+ { librarySystemDepends =
115+ if builtins.currentSystem == "x86_64-darwin"
116+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
117+ else [];
118+ #enableLibraryProfiling = false;
119+ doHaddock = false;
120+ });
121+
122+ streamly-core =
123+ nixpkgs.haskell.lib.overrideCabal
124+ (let src = fetchGit {
125+ url = "git@github.com:composewell/streamly.git";
126+ rev = "a849812d9960d5b7868e770156ab774ee8f70157";
127+ }; in super.callCabal2nix "streamly-core" "${src}/core" {})
128+ (old:
129+ { librarySystemDepends =
130+ if builtins.currentSystem == "x86_64-darwin"
131+ then [nixpkgs.darwin.apple_sdk.frameworks.Cocoa]
132+ else [];
133+ #enableLibraryProfiling = false;
134+ doHaddock = false;
135+ });
136+
137+ };
138+ };
139+
140+ drv = mkHaskellPackages true;
141+
142+ shell = drv.shellFor {
143+ packages = p:
144+ [ p.report
145+ ];
146+ # Use a better prompt
147+ shellHook = ''
148+ export CABAL_DIR="$(pwd)/.cabal.nix"
149+ if test -n "$PS_SHELL"
150+ then
151+ export PS1="$PS_SHELL\[$bldred\](nix)\[$txtrst\] "
152+ fi
153+ '';
154+ };
155+in if nixpkgs.lib.inNixShell
156+ then shell
157+ else (mkHaskellPackages false).streamly-test-report
test/test-runner/test-runner.cabalnew file+41
@@ -0,0 +1,41 @@
1+cabal-version: 2.4
2+name: test-runner
3+version: 0.1.0.0
4+
5+-- A short (one-line) description of the package.
6+-- synopsis:
7+
8+-- A longer description of the package.
9+-- description:
10+
11+-- A URL where users can report bugs.
12+-- bug-reports:
13+
14+-- The license under which the package is released.
15+-- license:
16+
17+-- The package author(s).
18+-- author:
19+
20+-- An email address to which users can send suggestions, bug reports, and patches.
21+-- maintainer:
22+
23+-- A copyright notice.
24+-- copyright:
25+-- category:
26+-- extra-source-files: CHANGELOG.md
27+
28+executable test-runner
29+ main-is: Main.hs
30+
31+ -- Modules included in this executable, other than Main.
32+ -- other-modules:
33+
34+ -- LANGUAGE extensions used by modules in this package.
35+ -- other-extensions:
36+ build-depends: base
37+ , bench-report
38+ , containers
39+ , streamly-targets
40+ hs-source-dirs: .
41+ default-language: Haskell2010