From a68cead60f099a76034567eb1991d56b678c8bd3 Mon Sep 17 00:00:00 2001 From: Joe Bond Date: Fri, 20 Oct 2023 14:57:12 +0100 Subject: [PATCH 1/5] Modified benchmark script to have more options. Need to be able to store plots, that's next --- Benchmarks/benchmarks(1).csv | 67 ++++++++++++++++++ Benchmarks/benchmarks(2).csv | 67 ++++++++++++++++++ Benchmarks/benchmarks.csv | 131 +++++++++++++++++------------------ bwd_perf.py | 28 ++++++++ plot_bench.py | 33 +++++++-- 5 files changed, 256 insertions(+), 70 deletions(-) create mode 100644 Benchmarks/benchmarks(1).csv create mode 100644 Benchmarks/benchmarks(2).csv create mode 100644 bwd_perf.py diff --git a/Benchmarks/benchmarks(1).csv b/Benchmarks/benchmarks(1).csv new file mode 100644 index 000000000..20cc0dc9d --- /dev/null +++ b/Benchmarks/benchmarks(1).csv @@ -0,0 +1,67 @@ +Test-Name,Graph-Bwd,Graph-BwdAll,Graph-BwdDual,Graph-Eval,Graph-Fwd,Graph-FwdAsDeMorgan,Graph-FwdDual,Trace-Bwd,Trace-Eval,Trace-Fwd +arithmetic,1.0,1.0,0.0,14.0,0.0,5.0,0.0,12.0,13.0,2.0 +array,2.0,1.0,0.0,8.0,0.0,4.0,0.0,11.0,14.0,6.0 +compose,0.0,1.0,0.0,7.0,0.0,2.0,0.0,9.0,7.0,1.0 +dicts,1.0,2.0,1.0,9.0,2.0,3.0,0.0,12.0,7.0,2.0 +div-mod-quot-rem,0.0,4.0,0.0,17.0,1.0,5.0,0.0,8.0,13.0,1.0 +factorial,1.0,35.0,0.0,19.0,0.0,146.0,0.0,14.0,18.0,5.0 +filter,1.0,1.0,0.0,9.0,0.0,2.0,0.0,8.0,13.0,4.0 +first-class-constr,0.0,1.0,1.0,13.0,0.0,3.0,0.0,8.0,12.0,3.0 +flatten,2.0,2.0,0.0,17.0,0.0,3.0,0.0,10.0,16.0,7.0 +foldr_sumSquares,1.0,1.0,0.0,10.0,0.0,3.0,0.0,8.0,12.0,4.0 +lexicalScoping,1.0,1.0,0.0,2.0,0.0,3.0,0.0,23.0,17.0,1.0 +length,3.0,0.0,0.0,3.0,0.0,3.0,0.0,7.0,6.0,1.0 +lookup,2.0,1.0,0.0,26.0,0.0,4.0,0.0,20.0,40.0,6.0 +map,1.0,3.0,1.0,27.0,1.0,5.0,1.0,8.0,12.0,2.0 +mergeSort,1.0,1.0,0.0,43.0,0.0,6.0,0.0,23.0,32.0,22.0 +normalise,1.0,1.0,0.0,5.0,0.0,3.0,0.0,6.0,6.0,4.0 +pattern-match,1.0,2.0,0.0,17.0,0.0,5.0,0.0,8.0,13.0,5.0 +range,2.0,2.0,0.0,53.0,0.0,12.0,0.0,24.0,32.0,11.0 +records,1.0,1.0,0.0,22.0,0.0,4.0,0.0,11.0,14.0,10.0 +reverse,2.0,1.0,0.0,6.0,0.0,3.0,0.0,8.0,20.0,3.0 +dtw/next-indices,2.0,143.0,0.0,206.0,6.0,741.0,1.0,50.0,130.0,51.0 +dtw/cost-matrix,2.0,7.0,1.0,196.0,2.0,118.0,1.0,46.0,119.0,33.0 +dtw/matrix-update,0.0,1.0,0.0,7.0,1.0,3.0,0.0,9.0,8.0,2.0 +desugar/list-comp-1,1.0,2.0,0.0,51.0,0.0,7.0,0.0,23.0,37.0,15.0 +desugar/list-comp-2,1.0,10.0,0.0,208.0,1.0,28.0,0.0,38.0,111.0,44.0 +desugar/list-comp-3,1.0,2.0,0.0,47.0,0.0,7.0,0.0,14.0,32.0,10.0 +desugar/list-comp-4,1.0,1.0,0.0,20.0,0.0,3.0,0.0,9.0,16.0,3.0 +desugar/list-comp-5,0.0,1.0,0.0,15.0,0.0,3.0,0.0,8.0,17.0,3.0 +desugar/list-comp-6,1.0,0.0,0.0,1.0,0.0,9.0,0.0,11.0,11.0,1.0 +desugar/list-comp-7,1.0,1.0,0.0,16.0,0.0,3.0,0.0,11.0,19.0,3.0 +desugar/list-enum,1.0,6.0,0.0,13.0,0.0,7.0,0.0,8.0,15.0,2.0 +add,0.0,1.0,0.0,2.0,1.0,1.0,0.0,6.0,6.0,0.0 +array/lookup,0.0,1.0,0.0,69.0,0.0,16.0,0.0,15.0,44.0,18.0 +array/dims,0.0,1.0,0.0,7.0,0.0,3.0,0.0,9.0,10.0,3.0 +convolution/edgeDetect,31.0,44.0,1.0,6144.0,9.0,4437.0,341.0,1144.0,3552.0,1402.0 +convolution/emboss,24.0,35.0,0.0,5347.0,2.0,4085.0,334.0,890.0,3084.0,1182.0 +convolution/gaussian,26.0,36.0,1.0,4913.0,1.0,3813.0,360.0,828.0,2827.0,1306.0 +dict/create,2.0,5.0,0.0,5.0,1.0,6.0,0.0,11.0,30.0,0.0 +dict/difference,1.0,1.0,0.0,3.0,0.0,7.0,0.0,6.0,7.0,1.0 +dict/disjointUnion,1.0,1.0,0.0,2.0,0.0,3.0,0.0,10.0,6.0,0.0 +dict/foldl,2.0,2.0,0.0,46.0,0.0,13.0,0.0,15.0,18.0,5.0 +dict/intersectionWith,2.0,1.0,2.0,28.0,1.0,4.0,0.0,26.0,17.0,18.0 +dict/fromRecord,0.0,1.0,0.0,1.0,1.0,2.0,0.0,9.0,7.0,0.0 +dict/get,0.0,2.0,0.0,3.0,0.0,2.0,0.0,8.0,7.0,1.0 +dict/map,1.0,1.0,0.0,11.0,0.0,4.0,0.0,10.0,10.0,3.0 +divide,0.0,0.0,0.0,2.0,0.0,4.0,0.0,5.0,13.0,0.0 +filter,1.0,1.0,0.0,15.0,0.0,3.0,0.0,13.0,16.0,2.0 +intersperse,1.0,1.0,0.0,10.0,1.0,3.0,0.0,8.0,7.0,2.0 +intersperse,1.0,2.0,0.0,7.0,0.0,2.0,1.0,7.0,10.0,4.0 +length,1.0,1.0,0.0,8.0,0.0,2.0,0.0,6.0,15.0,1.0 +list-comp,1.0,2.0,1.0,94.0,2.0,13.0,3.0,28.0,67.0,29.0 +list-comp,1.0,1.0,0.0,77.0,1.0,7.0,2.0,24.0,65.0,24.0 +lookup,0.0,0.0,1.0,14.0,0.0,3.0,1.0,10.0,14.0,4.0 +map,0.0,0.0,0.0,8.0,0.0,3.0,0.0,10.0,8.0,1.0 +multiply,1.0,2.0,0.0,1.0,0.0,1.0,0.0,8.0,15.0,0.0 +nth,0.0,0.0,0.0,4.0,1.0,3.0,0.0,7.0,18.0,1.0 +section-5-example,1.0,3.0,1.0,87.0,1.0,7.0,4.0,25.0,71.0,30.0 +section-5-example,1.0,2.0,0.0,83.0,1.0,10.0,2.0,23.0,58.0,25.0 +section-5-example,2.0,2.0,0.0,111.0,1.0,9.0,3.0,21.0,62.0,28.0 +zeros,1.0,1.0,0.0,4.0,1.0,2.0,0.0,10.0,7.0,2.0 +zeros,0.0,0.0,0.0,3.0,0.0,2.0,0.0,5.0,8.0,5.0 +zipWith,1.0,2.0,0.0,13.0,0.0,2.0,1.0,9.0,14.0,6.0 +graphics/background,2.0,4.0,0.0,12.0,2.0,20.0,0.0,9.0,12.0,3.0 +graphics/grouped-bar-chart,6.0,853.0,1.0,526.0,250.0,2585.0,0.0,107.0,294.0,134.0 +graphics/line-chart,9.0,1953.0,1.0,799.0,856.0,3744.0,0.0,139.0,443.0,191.0 +graphics/stacked-bar-chart,4.0,228.0,0.0,288.0,143.0,189.0,0.0,64.0,173.0,70.0 \ No newline at end of file diff --git a/Benchmarks/benchmarks(2).csv b/Benchmarks/benchmarks(2).csv new file mode 100644 index 000000000..20cc0dc9d --- /dev/null +++ b/Benchmarks/benchmarks(2).csv @@ -0,0 +1,67 @@ +Test-Name,Graph-Bwd,Graph-BwdAll,Graph-BwdDual,Graph-Eval,Graph-Fwd,Graph-FwdAsDeMorgan,Graph-FwdDual,Trace-Bwd,Trace-Eval,Trace-Fwd +arithmetic,1.0,1.0,0.0,14.0,0.0,5.0,0.0,12.0,13.0,2.0 +array,2.0,1.0,0.0,8.0,0.0,4.0,0.0,11.0,14.0,6.0 +compose,0.0,1.0,0.0,7.0,0.0,2.0,0.0,9.0,7.0,1.0 +dicts,1.0,2.0,1.0,9.0,2.0,3.0,0.0,12.0,7.0,2.0 +div-mod-quot-rem,0.0,4.0,0.0,17.0,1.0,5.0,0.0,8.0,13.0,1.0 +factorial,1.0,35.0,0.0,19.0,0.0,146.0,0.0,14.0,18.0,5.0 +filter,1.0,1.0,0.0,9.0,0.0,2.0,0.0,8.0,13.0,4.0 +first-class-constr,0.0,1.0,1.0,13.0,0.0,3.0,0.0,8.0,12.0,3.0 +flatten,2.0,2.0,0.0,17.0,0.0,3.0,0.0,10.0,16.0,7.0 +foldr_sumSquares,1.0,1.0,0.0,10.0,0.0,3.0,0.0,8.0,12.0,4.0 +lexicalScoping,1.0,1.0,0.0,2.0,0.0,3.0,0.0,23.0,17.0,1.0 +length,3.0,0.0,0.0,3.0,0.0,3.0,0.0,7.0,6.0,1.0 +lookup,2.0,1.0,0.0,26.0,0.0,4.0,0.0,20.0,40.0,6.0 +map,1.0,3.0,1.0,27.0,1.0,5.0,1.0,8.0,12.0,2.0 +mergeSort,1.0,1.0,0.0,43.0,0.0,6.0,0.0,23.0,32.0,22.0 +normalise,1.0,1.0,0.0,5.0,0.0,3.0,0.0,6.0,6.0,4.0 +pattern-match,1.0,2.0,0.0,17.0,0.0,5.0,0.0,8.0,13.0,5.0 +range,2.0,2.0,0.0,53.0,0.0,12.0,0.0,24.0,32.0,11.0 +records,1.0,1.0,0.0,22.0,0.0,4.0,0.0,11.0,14.0,10.0 +reverse,2.0,1.0,0.0,6.0,0.0,3.0,0.0,8.0,20.0,3.0 +dtw/next-indices,2.0,143.0,0.0,206.0,6.0,741.0,1.0,50.0,130.0,51.0 +dtw/cost-matrix,2.0,7.0,1.0,196.0,2.0,118.0,1.0,46.0,119.0,33.0 +dtw/matrix-update,0.0,1.0,0.0,7.0,1.0,3.0,0.0,9.0,8.0,2.0 +desugar/list-comp-1,1.0,2.0,0.0,51.0,0.0,7.0,0.0,23.0,37.0,15.0 +desugar/list-comp-2,1.0,10.0,0.0,208.0,1.0,28.0,0.0,38.0,111.0,44.0 +desugar/list-comp-3,1.0,2.0,0.0,47.0,0.0,7.0,0.0,14.0,32.0,10.0 +desugar/list-comp-4,1.0,1.0,0.0,20.0,0.0,3.0,0.0,9.0,16.0,3.0 +desugar/list-comp-5,0.0,1.0,0.0,15.0,0.0,3.0,0.0,8.0,17.0,3.0 +desugar/list-comp-6,1.0,0.0,0.0,1.0,0.0,9.0,0.0,11.0,11.0,1.0 +desugar/list-comp-7,1.0,1.0,0.0,16.0,0.0,3.0,0.0,11.0,19.0,3.0 +desugar/list-enum,1.0,6.0,0.0,13.0,0.0,7.0,0.0,8.0,15.0,2.0 +add,0.0,1.0,0.0,2.0,1.0,1.0,0.0,6.0,6.0,0.0 +array/lookup,0.0,1.0,0.0,69.0,0.0,16.0,0.0,15.0,44.0,18.0 +array/dims,0.0,1.0,0.0,7.0,0.0,3.0,0.0,9.0,10.0,3.0 +convolution/edgeDetect,31.0,44.0,1.0,6144.0,9.0,4437.0,341.0,1144.0,3552.0,1402.0 +convolution/emboss,24.0,35.0,0.0,5347.0,2.0,4085.0,334.0,890.0,3084.0,1182.0 +convolution/gaussian,26.0,36.0,1.0,4913.0,1.0,3813.0,360.0,828.0,2827.0,1306.0 +dict/create,2.0,5.0,0.0,5.0,1.0,6.0,0.0,11.0,30.0,0.0 +dict/difference,1.0,1.0,0.0,3.0,0.0,7.0,0.0,6.0,7.0,1.0 +dict/disjointUnion,1.0,1.0,0.0,2.0,0.0,3.0,0.0,10.0,6.0,0.0 +dict/foldl,2.0,2.0,0.0,46.0,0.0,13.0,0.0,15.0,18.0,5.0 +dict/intersectionWith,2.0,1.0,2.0,28.0,1.0,4.0,0.0,26.0,17.0,18.0 +dict/fromRecord,0.0,1.0,0.0,1.0,1.0,2.0,0.0,9.0,7.0,0.0 +dict/get,0.0,2.0,0.0,3.0,0.0,2.0,0.0,8.0,7.0,1.0 +dict/map,1.0,1.0,0.0,11.0,0.0,4.0,0.0,10.0,10.0,3.0 +divide,0.0,0.0,0.0,2.0,0.0,4.0,0.0,5.0,13.0,0.0 +filter,1.0,1.0,0.0,15.0,0.0,3.0,0.0,13.0,16.0,2.0 +intersperse,1.0,1.0,0.0,10.0,1.0,3.0,0.0,8.0,7.0,2.0 +intersperse,1.0,2.0,0.0,7.0,0.0,2.0,1.0,7.0,10.0,4.0 +length,1.0,1.0,0.0,8.0,0.0,2.0,0.0,6.0,15.0,1.0 +list-comp,1.0,2.0,1.0,94.0,2.0,13.0,3.0,28.0,67.0,29.0 +list-comp,1.0,1.0,0.0,77.0,1.0,7.0,2.0,24.0,65.0,24.0 +lookup,0.0,0.0,1.0,14.0,0.0,3.0,1.0,10.0,14.0,4.0 +map,0.0,0.0,0.0,8.0,0.0,3.0,0.0,10.0,8.0,1.0 +multiply,1.0,2.0,0.0,1.0,0.0,1.0,0.0,8.0,15.0,0.0 +nth,0.0,0.0,0.0,4.0,1.0,3.0,0.0,7.0,18.0,1.0 +section-5-example,1.0,3.0,1.0,87.0,1.0,7.0,4.0,25.0,71.0,30.0 +section-5-example,1.0,2.0,0.0,83.0,1.0,10.0,2.0,23.0,58.0,25.0 +section-5-example,2.0,2.0,0.0,111.0,1.0,9.0,3.0,21.0,62.0,28.0 +zeros,1.0,1.0,0.0,4.0,1.0,2.0,0.0,10.0,7.0,2.0 +zeros,0.0,0.0,0.0,3.0,0.0,2.0,0.0,5.0,8.0,5.0 +zipWith,1.0,2.0,0.0,13.0,0.0,2.0,1.0,9.0,14.0,6.0 +graphics/background,2.0,4.0,0.0,12.0,2.0,20.0,0.0,9.0,12.0,3.0 +graphics/grouped-bar-chart,6.0,853.0,1.0,526.0,250.0,2585.0,0.0,107.0,294.0,134.0 +graphics/line-chart,9.0,1953.0,1.0,799.0,856.0,3744.0,0.0,139.0,443.0,191.0 +graphics/stacked-bar-chart,4.0,228.0,0.0,288.0,143.0,189.0,0.0,64.0,173.0,70.0 \ No newline at end of file diff --git a/Benchmarks/benchmarks.csv b/Benchmarks/benchmarks.csv index 20cc0dc9d..b04d43411 100644 --- a/Benchmarks/benchmarks.csv +++ b/Benchmarks/benchmarks.csv @@ -1,67 +1,66 @@ Test-Name,Graph-Bwd,Graph-BwdAll,Graph-BwdDual,Graph-Eval,Graph-Fwd,Graph-FwdAsDeMorgan,Graph-FwdDual,Trace-Bwd,Trace-Eval,Trace-Fwd -arithmetic,1.0,1.0,0.0,14.0,0.0,5.0,0.0,12.0,13.0,2.0 -array,2.0,1.0,0.0,8.0,0.0,4.0,0.0,11.0,14.0,6.0 -compose,0.0,1.0,0.0,7.0,0.0,2.0,0.0,9.0,7.0,1.0 -dicts,1.0,2.0,1.0,9.0,2.0,3.0,0.0,12.0,7.0,2.0 -div-mod-quot-rem,0.0,4.0,0.0,17.0,1.0,5.0,0.0,8.0,13.0,1.0 -factorial,1.0,35.0,0.0,19.0,0.0,146.0,0.0,14.0,18.0,5.0 -filter,1.0,1.0,0.0,9.0,0.0,2.0,0.0,8.0,13.0,4.0 -first-class-constr,0.0,1.0,1.0,13.0,0.0,3.0,0.0,8.0,12.0,3.0 -flatten,2.0,2.0,0.0,17.0,0.0,3.0,0.0,10.0,16.0,7.0 -foldr_sumSquares,1.0,1.0,0.0,10.0,0.0,3.0,0.0,8.0,12.0,4.0 -lexicalScoping,1.0,1.0,0.0,2.0,0.0,3.0,0.0,23.0,17.0,1.0 -length,3.0,0.0,0.0,3.0,0.0,3.0,0.0,7.0,6.0,1.0 -lookup,2.0,1.0,0.0,26.0,0.0,4.0,0.0,20.0,40.0,6.0 -map,1.0,3.0,1.0,27.0,1.0,5.0,1.0,8.0,12.0,2.0 -mergeSort,1.0,1.0,0.0,43.0,0.0,6.0,0.0,23.0,32.0,22.0 -normalise,1.0,1.0,0.0,5.0,0.0,3.0,0.0,6.0,6.0,4.0 -pattern-match,1.0,2.0,0.0,17.0,0.0,5.0,0.0,8.0,13.0,5.0 -range,2.0,2.0,0.0,53.0,0.0,12.0,0.0,24.0,32.0,11.0 -records,1.0,1.0,0.0,22.0,0.0,4.0,0.0,11.0,14.0,10.0 -reverse,2.0,1.0,0.0,6.0,0.0,3.0,0.0,8.0,20.0,3.0 -dtw/next-indices,2.0,143.0,0.0,206.0,6.0,741.0,1.0,50.0,130.0,51.0 -dtw/cost-matrix,2.0,7.0,1.0,196.0,2.0,118.0,1.0,46.0,119.0,33.0 -dtw/matrix-update,0.0,1.0,0.0,7.0,1.0,3.0,0.0,9.0,8.0,2.0 -desugar/list-comp-1,1.0,2.0,0.0,51.0,0.0,7.0,0.0,23.0,37.0,15.0 -desugar/list-comp-2,1.0,10.0,0.0,208.0,1.0,28.0,0.0,38.0,111.0,44.0 -desugar/list-comp-3,1.0,2.0,0.0,47.0,0.0,7.0,0.0,14.0,32.0,10.0 -desugar/list-comp-4,1.0,1.0,0.0,20.0,0.0,3.0,0.0,9.0,16.0,3.0 -desugar/list-comp-5,0.0,1.0,0.0,15.0,0.0,3.0,0.0,8.0,17.0,3.0 -desugar/list-comp-6,1.0,0.0,0.0,1.0,0.0,9.0,0.0,11.0,11.0,1.0 -desugar/list-comp-7,1.0,1.0,0.0,16.0,0.0,3.0,0.0,11.0,19.0,3.0 -desugar/list-enum,1.0,6.0,0.0,13.0,0.0,7.0,0.0,8.0,15.0,2.0 -add,0.0,1.0,0.0,2.0,1.0,1.0,0.0,6.0,6.0,0.0 -array/lookup,0.0,1.0,0.0,69.0,0.0,16.0,0.0,15.0,44.0,18.0 -array/dims,0.0,1.0,0.0,7.0,0.0,3.0,0.0,9.0,10.0,3.0 -convolution/edgeDetect,31.0,44.0,1.0,6144.0,9.0,4437.0,341.0,1144.0,3552.0,1402.0 -convolution/emboss,24.0,35.0,0.0,5347.0,2.0,4085.0,334.0,890.0,3084.0,1182.0 -convolution/gaussian,26.0,36.0,1.0,4913.0,1.0,3813.0,360.0,828.0,2827.0,1306.0 -dict/create,2.0,5.0,0.0,5.0,1.0,6.0,0.0,11.0,30.0,0.0 -dict/difference,1.0,1.0,0.0,3.0,0.0,7.0,0.0,6.0,7.0,1.0 -dict/disjointUnion,1.0,1.0,0.0,2.0,0.0,3.0,0.0,10.0,6.0,0.0 -dict/foldl,2.0,2.0,0.0,46.0,0.0,13.0,0.0,15.0,18.0,5.0 -dict/intersectionWith,2.0,1.0,2.0,28.0,1.0,4.0,0.0,26.0,17.0,18.0 -dict/fromRecord,0.0,1.0,0.0,1.0,1.0,2.0,0.0,9.0,7.0,0.0 -dict/get,0.0,2.0,0.0,3.0,0.0,2.0,0.0,8.0,7.0,1.0 -dict/map,1.0,1.0,0.0,11.0,0.0,4.0,0.0,10.0,10.0,3.0 -divide,0.0,0.0,0.0,2.0,0.0,4.0,0.0,5.0,13.0,0.0 -filter,1.0,1.0,0.0,15.0,0.0,3.0,0.0,13.0,16.0,2.0 -intersperse,1.0,1.0,0.0,10.0,1.0,3.0,0.0,8.0,7.0,2.0 -intersperse,1.0,2.0,0.0,7.0,0.0,2.0,1.0,7.0,10.0,4.0 -length,1.0,1.0,0.0,8.0,0.0,2.0,0.0,6.0,15.0,1.0 -list-comp,1.0,2.0,1.0,94.0,2.0,13.0,3.0,28.0,67.0,29.0 -list-comp,1.0,1.0,0.0,77.0,1.0,7.0,2.0,24.0,65.0,24.0 -lookup,0.0,0.0,1.0,14.0,0.0,3.0,1.0,10.0,14.0,4.0 -map,0.0,0.0,0.0,8.0,0.0,3.0,0.0,10.0,8.0,1.0 -multiply,1.0,2.0,0.0,1.0,0.0,1.0,0.0,8.0,15.0,0.0 -nth,0.0,0.0,0.0,4.0,1.0,3.0,0.0,7.0,18.0,1.0 -section-5-example,1.0,3.0,1.0,87.0,1.0,7.0,4.0,25.0,71.0,30.0 -section-5-example,1.0,2.0,0.0,83.0,1.0,10.0,2.0,23.0,58.0,25.0 -section-5-example,2.0,2.0,0.0,111.0,1.0,9.0,3.0,21.0,62.0,28.0 -zeros,1.0,1.0,0.0,4.0,1.0,2.0,0.0,10.0,7.0,2.0 -zeros,0.0,0.0,0.0,3.0,0.0,2.0,0.0,5.0,8.0,5.0 -zipWith,1.0,2.0,0.0,13.0,0.0,2.0,1.0,9.0,14.0,6.0 -graphics/background,2.0,4.0,0.0,12.0,2.0,20.0,0.0,9.0,12.0,3.0 -graphics/grouped-bar-chart,6.0,853.0,1.0,526.0,250.0,2585.0,0.0,107.0,294.0,134.0 -graphics/line-chart,9.0,1953.0,1.0,799.0,856.0,3744.0,0.0,139.0,443.0,191.0 -graphics/stacked-bar-chart,4.0,228.0,0.0,288.0,143.0,189.0,0.0,64.0,173.0,70.0 \ No newline at end of file +arithmetic,0.8999999985098839,0.5999999977648258,0.0,2.2999999970197678,0.19999999925494194,2.600000001490116,0.0,7.299999997019768,8.100000001490116,0.8000000007450581 +array,0.30000000074505806,0.30000000074505806,0.0,3.7999999970197678,0.0,2.800000000745058,0.0,4.399999998509884,5.5,1.0 +compose,0.30000000074505806,0.19999999925494194,0.10000000149011612,0.5,0.0,5.099999997764826,0.10000000149011612,2.0,2.899999998509884,0.19999999925494194 +dicts,0.5,1.0,0.19999999925494194,1.800000000745058,1.3999999985098839,2.100000001490116,0.0,4.099999997764826,2.900000002235174,0.5999999977648258 +div-mod-quot-rem,0.5,1.7000000029802322,0.09999999776482582,2.100000001490116,0.8000000007450581,3.099999997764826,0.0,2.800000000745058,3.600000001490116,0.8000000007450581 +factorial,0.30000000074505806,31.800000000745058,0.0,6.600000001490116,0.0,89.29999999701977,0.10000000149011612,4.300000000745058,6.600000001490116,4.699999999254942 +filter,1.1000000014901161,0.5999999977648258,0.0,2.399999998509884,0.10000000149011612,2.600000001490116,0.10000000149011612,4.400000002235174,8.799999997019768,1.3999999985098839 +first-class-constr,0.30000000074505806,0.6000000014901161,0.0,3.300000000745058,0.09999999776482582,1.9000000022351742,0.09999999776482582,4.899999998509884,4.600000001490116,1.300000000745058 +flatten,0.30000000074505806,1.3999999985098839,0.10000000149011612,4.899999998509884,0.10000000149011612,2.599999997764826,0.0,4.199999999254942,4.199999999254942,2.699999999254942 +foldr_sumSquares,0.30000000074505806,0.30000000074505806,0.0,4.600000001490116,0.0,1.800000000745058,0.0,5.600000001490116,2.899999998509884,2.0 +lexicalScoping,0.19999999925494194,0.19999999925494194,0.0,1.300000000745058,0.0,1.6000000014901161,0.0,4.300000000745058,2.800000000745058,0.6000000014901161 +length,0.19999999925494194,0.30000000074505806,0.0,0.6000000014901161,0.0,1.699999999254942,0.0,2.600000001490116,2.0,0.30000000074505806 +lookup,0.30000000074505806,0.5,0.0,5.300000000745058,0.09999999776482582,3.199999999254942,0.0,6.099999997764826,4.300000000745058,1.699999999254942 +map,0.19999999925494194,1.6000000014901161,0.0,2.5,0.0,1.7000000029802322,0.09999999776482582,3.0,2.899999998509884,2.100000001490116 +mergeSort,0.5,0.7999999970197678,0.10000000149011612,10.600000001490116,0.0,3.800000000745058,0.0,5.800000000745058,9.5,6.899999998509884 +normalise,0.19999999925494194,0.3999999985098839,0.0,0.6999999992549419,0.0,2.100000001490116,0.0,2.300000000745058,2.5,0.19999999925494194 +pattern-match,0.30000000074505806,1.800000000745058,0.0,5.5,0.0,5.199999999254942,0.10000000149011612,5.300000000745058,6.0,2.5 +range,0.19999999925494194,1.5,0.10000000149011612,12.100000001490116,0.09999999776482582,10.699999999254942,0.0,8.800000000745058,9.099999997764826,9.099999997764826 +records,0.3999999985098839,0.5999999977648258,0.0,5.100000001490116,0.0,3.0,0.0,5.5,4.5,2.199999999254942 +reverse,1.199999999254942,0.5,0.0,1.4000000022351742,0.10000000149011612,1.800000000745058,0.0,2.5,3.300000000745058,0.5999999977648258 +slicing/dtw/compute-dtw,1.300000000745058,598.0,0.19999999925494194,256.3999999985099,6.0,26677.70000000298,0.19999999925494194,149.30000000074506,148.19999999925494,131.39999999850988 +slicing/dtw/average-series,1.199999999254942,70.69999999925494,0.10000000149011612,300.0,0.10000000149011612,60939.800000000745,0.09999999776482582,178.10000000149012,207.40000000223517,174.19999999925494 +desugar/list-comp-1,0.30000000074505806,2.600000001490116,0.09999999776482582,20.799999997019768,0.19999999925494194,5.599999997764826,0.0,15.199999999254942,14.699999999254942,11.5 +desugar/list-comp-2,1.6000000014901161,5.600000001490116,0.09999999776482582,56.399999998509884,0.8999999985098839,19.100000001490116,0.0,32.70000000298023,41.5,34.0 +desugar/list-comp-3,0.30000000074505806,1.8999999985098839,0.10000000149011612,14.900000002235174,0.0,5.300000000745058,0.0,9.5,10.0,10.899999998509884 +desugar/list-comp-4,0.30000000074505806,0.5,0.0,7.0,0.09999999776482582,2.0,0.0,6.100000001490116,5.5,4.300000000745058 +desugar/list-comp-5,2.300000000745058,0.8000000007450581,0.0,3.0,0.10000000149011612,2.599999997764826,0.0,3.100000001490116,5.300000000745058,4.0 +desugar/list-comp-6,0.19999999925494194,2.0,0.10000000149011612,0.30000000074505806,0.09999999776482582,1.2999999970197678,0.0,2.099999997764826,1.699999999254942,0.10000000149011612 +desugar/list-comp-7,0.30000000074505806,0.5999999977648258,0.0,7.699999999254942,0.09999999776482582,3.5,0.10000000149011612,3.699999999254942,8.400000002235174,1.9000000022351742 +desugar/list-enum,0.19999999925494194,4.300000000745058,0.10000000149011612,2.100000001490116,0.0,8.399999998509884,0.0,3.300000000745058,4.600000001490116,3.199999999254942 +add,0.19999999925494194,0.19999999925494194,0.0,0.3999999985098839,0.19999999925494194,1.199999999254942,0.0,4.199999999254942,2.300000000745058,0.0 +array/lookup,0.3999999985098839,0.30000000074505806,0.0,22.700000002980232,0.09999999776482582,11.599999997764826,0.10000000149011612,10.699999999254942,14.200000002980232,12.5 +array/dims,0.3999999985098839,0.30000000074505806,0.10000000149011612,1.1000000014901161,0.10000000149011612,4.0,0.09999999776482582,2.600000001490116,4.0,2.5 +convolution/edgeDetect,4.5,14.199999999254942,0.20000000298023224,1634.2999999970198,5.0,2813.900000002235,217.70000000298023,651.0,890.3999999985099,849.4000000022352 +convolution/emboss,5.199999999254942,11.199999999254942,0.19999999925494194,1379.7000000029802,1.300000000745058,2718.099999997765,241.10000000149012,497.8999999985099,728.1999999992549,736.7999999970198 +convolution/gaussian,3.699999999254942,12.099999997764826,0.19999999925494194,1422.8999999985099,1.300000000745058,2771.699999999255,266.5,514.1000000014901,763.3999999985099,762.1999999992549 +dict/create,0.30000000074505806,0.30000000074505806,0.0,0.3999999985098839,0.10000000149011612,3.5,0.10000000149011612,2.399999998509884,4.5,0.0 +dict/difference,0.9000000022351742,0.8999999985098839,0.19999999925494194,1.2999999970197678,0.20000000298023224,5.699999999254942,0.10000000149011612,4.0,5.800000000745058,0.5 +dict/disjointUnion,0.5,0.4000000022351742,0.09999999776482582,0.5999999977648258,0.0,2.7000000029802322,0.0,4.0,2.199999999254942,0.19999999925494194 +dict/foldl,0.30000000074505806,0.30000000074505806,0.19999999925494194,6.399999998509884,0.19999999925494194,3.199999999254942,0.10000000149011612,7.400000002235174,10.099999997764826,4.5 +dict/intersectionWith,0.30000000074505806,0.3999999985098839,0.30000000074505806,1.300000000745058,0.19999999925494194,1.7999999970197678,0.20000000298023224,3.0,2.7999999970197678,0.3999999985098839 +dict/fromRecord,0.6000000014901161,0.3999999985098839,0.0,0.6999999992549419,0.19999999925494194,2.399999998509884,0.0,4.900000002235174,3.5,0.0 +dict/get,0.5999999977648258,0.3999999985098839,0.0,1.0,0.10000000149011612,2.699999999254942,0.0,3.300000000745058,1.800000000745058,0.20000000298023224 +dict/map,0.29999999701976776,0.4000000022351742,0.30000000074505806,2.100000001490116,0.20000000298023224,2.2000000029802322,0.7999999970197678,3.900000002235174,4.799999997019768,0.8000000007450581 +divide,0.6999999992549419,0.6000000014901161,0.19999999925494194,0.4000000022351742,0.19999999925494194,3.300000000745058,0.09999999776482582,3.599999997764826,3.199999999254942,0.0 +filter,0.4000000022351742,0.8000000007450581,0.09999999776482582,3.699999999254942,0.3999999985098839,2.800000000745058,0.6000000014901161,2.800000000745058,3.699999999254942,1.5999999977648258 +intersperse,1.0999999977648258,1.0,0.09999999776482582,1.800000000745058,0.19999999925494194,2.899999998509884,0.6000000014901161,2.300000000745058,2.899999998509884,0.5999999977648258 +intersperse,0.8000000007450581,1.5,0.09999999776482582,2.600000001490116,0.5,2.300000000745058,1.699999999254942,3.300000000745058,4.5,1.199999999254942 +length,0.8000000007450581,0.8000000007450581,0.29999999701976776,1.800000000745058,0.5,3.099999997764826,1.1000000014901161,2.400000002235174,2.5,1.5 +list-comp,0.5,1.300000000745058,0.10000000149011612,22.300000000745058,1.2999999970197678,4.699999999254942,2.5,14.0,16.699999999254942,13.5 +list-comp,0.6999999992549419,1.1000000014901161,0.19999999925494194,24.699999999254942,1.5,5.099999997764826,3.0,14.799999997019768,21.5,14.399999998509884 +lookup,0.8999999985098839,0.5,0.30000000074505806,2.900000002235174,1.1000000014901161,2.100000001490116,0.7999999970197678,3.699999999254942,4.200000002980232,1.5 +map,0.30000000074505806,0.5,0.10000000149011612,0.8999999985098839,0.30000000074505806,2.900000002235174,0.09999999776482582,2.5,2.0,0.5 +multiply,0.29999999701976776,0.19999999925494194,0.09999999776482582,0.30000000074505806,0.0,2.300000000745058,0.0,2.100000001490116,1.7999999970197678,0.10000000149011612 +nth,0.5,0.4000000022351742,0.09999999776482582,1.4000000022351742,0.09999999776482582,3.100000001490116,0.09999999776482582,3.800000000745058,3.399999998509884,1.0 +section-5-example,0.6999999992549419,1.300000000745058,0.30000000074505806,23.200000002980232,1.6000000014901161,5.199999999254942,3.300000000745058,14.800000000745058,17.599999997764826,14.199999999254942 +section-5-example,0.5,1.199999999254942,0.10000000149011612,21.400000002235174,0.5,6.199999999254942,1.300000000745058,12.399999998509884,14.699999999254942,12.800000000745058 +section-5-example,0.6000000014901161,1.800000000745058,0.09999999776482582,24.600000001490116,0.8000000007450581,6.5,2.400000002235174,13.600000001490116,18.300000000745058,13.600000001490116 +zeros,0.30000000074505806,0.3999999985098839,0.10000000149011612,0.9000000022351742,0.19999999925494194,2.100000001490116,0.20000000298023224,3.5,1.8999999985098839,0.3999999985098839 +zeros,1.0,0.3999999985098839,0.10000000149011612,0.9000000022351742,0.19999999925494194,1.699999999254942,0.20000000298023224,2.099999997764826,2.0,0.3999999985098839 +zipWith,1.199999999254942,1.2000000029802322,0.19999999925494194,3.399999998509884,0.5,2.599999997764826,0.6999999992549419,3.800000000745058,5.199999999254942,2.5 +graphics/background,0.9000000022351742,2.5,0.10000000149011612,3.199999999254942,0.5999999977648258,9.599999997764826,0.0,2.800000000745058,2.600000001490116,0.6000000014901161 +graphics/grouped-bar-chart,2.0,478.5,0.8000000007450581,147.5,124.59999999776483,1463.300000000745,0.10000000149011612,70.09999999776483,84.90000000223517,72.69999999925494 +graphics/line-chart,2.199999999254942,1020.0999999977648,1.0,191.10000000149012,416.4000000022352,2151.0,0.30000000074505806,97.10000000149012,125.89999999850988,104.5 +graphics/stacked-bar-chart,1.8999999985098839,121.0,0.5,70.60000000149012,73.0,105.5,0.09999999776482582,41.400000002235174,57.899999998509884,42.19999999925494 \ No newline at end of file diff --git a/bwd_perf.py b/bwd_perf.py new file mode 100644 index 000000000..e8b1260e6 --- /dev/null +++ b/bwd_perf.py @@ -0,0 +1,28 @@ +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt + +def parse(): + # Read benchmark csv + benchmarks = pd.read_csv('Benchmarks/benchmarks.csv', skipinitialspace=True, delimiter=',', index_col='Test-Name') + + # Extract test names of interest + test_names = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart', 'slicing/dtw/compute-dtw'] + df = pd.DataFrame(benchmarks.loc[test_names]) + print(df[['Trace-Eval', 'Trace-Bwd', 'Graph-Eval', 'Graph-Bwd']]) + + # Reorder benchmark columns + column_order = ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'] + # column_colors = ['#0d6b12', '#93dbb5', '#3e3875', '#b8bef5', '#910303', '#e84d4d', '#e8bceb', '#5073a1'] + + # Plot as bar chart + df[column_order].plot( kind="bar" + # , color=column_colors + , ylabel="Milliseconds", rot=0) + + # Inserting a coloured horizontal line just to make clearer which columns have zero values + plt.ylim(bottom=-10) + plt.gca().axhline(0, lw=0.3, color='blue', label="Zero accuracy") + + plt.show() +parse() \ No newline at end of file diff --git a/plot_bench.py b/plot_bench.py index 4fa3af8ab..ee9466e03 100644 --- a/plot_bench.py +++ b/plot_bench.py @@ -30,10 +30,32 @@ def decompose_list(input_str): inner = input_str.split(", ") return inner +def test_names(test_str): + if test_str == "expensive": + return ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart', 'slicing/dtw/compute-dtw'] + elif test_str == "graphics": + return ['graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] + elif test_str == "convolution": + return ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian'] + else: + return decompose_list(test_str) + +def bench_names(bench_str): + if bench_str == "all": + return ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'] + elif bench_str == "bwd": + return ['Trace-Eval','Trace-Bwd', 'Graph-Eval', 'Graph-Bwd'] + elif bench_str == "fwd": + return ['Trace-Eval', 'Trace-Fwd', 'Graph-Eval', 'Graph-Fwd', 'Graph-FwdAsDeMorgan'] + elif bench_str == "standard": + return ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'] + else: + return decompose_list(bench_str) + parser = argparse.ArgumentParser() parser.add_argument("-s", "--Suite", help = "Premade testsuite") -parser.add_argument("-t", "--Tests", type=decompose_list, help = "Specify list of tests") -parser.add_argument("-b", "--Benches",type=decompose_list, help = "Specify list of benchmarks to show") +parser.add_argument("-t", "--Tests", help = "Specify list of tests") +parser.add_argument("-b", "--Benches", help = "Specify list of benchmarks to show") args = parser.parse_args() @@ -54,6 +76,9 @@ def decompose_list(input_str): test_cases = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] bench_names = ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'] - parse(test_cases, bench_names) + parse(test_cases, bench_names) elif args.Tests and args.Benches: - parse(args.Tests, args.Benches) \ No newline at end of file + tests = test_names(args.Tests) + benches = bench_names(args.Benches) + + parse(tests, benches) \ No newline at end of file From 3f169da409ceee19b282c53d75883e5640f30516 Mon Sep 17 00:00:00 2001 From: Joe Bond Date: Mon, 23 Oct 2023 10:04:57 +0100 Subject: [PATCH 2/5] Refactorings for benchmarking script --- Benchmarks/recent.png | Bin 0 -> 45206 bytes plot_bench.py | 68 +++++++++++++++++------------------------- zoomroom.png | Bin 0 -> 28492 bytes zoomroom2.png | Bin 0 -> 34580 bytes 4 files changed, 27 insertions(+), 41 deletions(-) create mode 100644 Benchmarks/recent.png create mode 100644 zoomroom.png create mode 100644 zoomroom2.png diff --git a/Benchmarks/recent.png b/Benchmarks/recent.png new file mode 100644 index 0000000000000000000000000000000000000000..0876421b4a0c56343962dd7a8b2b2085dd3f3ba3 GIT binary patch literal 45206 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

poaDYhr$|cHNp> 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 literal 0 HcmV?d00001 diff --git a/plot_bench.py b/plot_bench.py index ee9466e03..e23a0ccc4 100644 --- a/plot_bench.py +++ b/plot_bench.py @@ -4,7 +4,20 @@ import argparse -def parse(test_names, column_order): +test_sets = { + 'expensive': ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart', 'slicing/dtw/compute-dtw'], + 'graphics': ['graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'], + 'convolution': ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian'], +} + +bench_sets = { + 'all': ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'], + 'bwd': ['Trace-Eval','Trace-Bwd', 'Graph-Eval', 'Graph-Bwd'], + 'fwd': ['Trace-Eval', 'Trace-Fwd', 'Graph-Eval', 'Graph-Fwd', 'Graph-FwdAsDeMorgan'], + 'standard': ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'], +} + +def parse(test_names, column_order, dest='Benchmarks/recent.png'): # Read benchmark csv benchmarks = pd.read_csv('Benchmarks/benchmarks.csv', skipinitialspace=True, delimiter=',', index_col='Test-Name') @@ -14,16 +27,16 @@ def parse(test_names, column_order): # Reorder benchmark columns # column_colors = ['#0d6b12', '#93dbb5', '#3e3875', '#b8bef5', '#910303', '#e84d4d', '#e8bceb', '#5073a1'] - # Plot as bar chart df[column_order].plot( kind="bar" # , color=column_colors - , ylabel="Milliseconds", rot=0) + , ylabel="Milliseconds", rot=0 + , figsize=(16,6)) # Inserting a coloured horizontal line just to make clearer which columns have zero values plt.ylim(bottom=-10) plt.gca().axhline(0, lw=0.3, color='blue', label="Zero accuracy") - + plt.savefig(dest) plt.show() def decompose_list(input_str): @@ -31,54 +44,27 @@ def decompose_list(input_str): return inner def test_names(test_str): - if test_str == "expensive": - return ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart', 'slicing/dtw/compute-dtw'] - elif test_str == "graphics": - return ['graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] - elif test_str == "convolution": - return ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian'] + if test_str in test_sets: + return test_sets[test_str] else: return decompose_list(test_str) def bench_names(bench_str): - if bench_str == "all": - return ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'] - elif bench_str == "bwd": - return ['Trace-Eval','Trace-Bwd', 'Graph-Eval', 'Graph-Bwd'] - elif bench_str == "fwd": - return ['Trace-Eval', 'Trace-Fwd', 'Graph-Eval', 'Graph-Fwd', 'Graph-FwdAsDeMorgan'] - elif bench_str == "standard": - return ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'] + if bench_str in bench_sets: + return bench_sets[bench_str] else: return decompose_list(bench_str) parser = argparse.ArgumentParser() -parser.add_argument("-s", "--Suite", help = "Premade testsuite") parser.add_argument("-t", "--Tests", help = "Specify list of tests") parser.add_argument("-b", "--Benches", help = "Specify list of benchmarks to show") - +parser.add_argument("-d", "--Dest", help = "Specify where to save plot") args = parser.parse_args() -if args.Suite: - test_cases = [] - bench_names = [] - - if args.Suite == "all": - test_cases = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] - bench_names = ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'] - elif args.Suite == "bwd": - test_cases = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] - bench_names = ['Trace-Eval','Trace-Bwd', 'Graph-Eval', 'Graph-Bwd'] - elif args.Suite == "fwd": - test_cases = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] - bench_names = ['Trace-Eval', 'Trace-Fwd', 'Graph-Eval', 'Graph-Fwd', 'Graph-FwdAsDeMorgan'] - else: - test_cases = ['convolution/edgeDetect', 'convolution/emboss', 'convolution/gaussian', 'graphics/grouped-bar-chart', 'graphics/line-chart', 'graphics/stacked-bar-chart'] - bench_names = ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'] - - parse(test_cases, bench_names) -elif args.Tests and args.Benches: +if args.Tests and args.Benches: tests = test_names(args.Tests) benches = bench_names(args.Benches) - - parse(tests, benches) \ No newline at end of file + if args.Dest: + parse(tests, benches, args.Dest) + else: + parse(tests, benches) \ No newline at end of file diff --git a/zoomroom.png b/zoomroom.png new file mode 100644 index 0000000000000000000000000000000000000000..0132f0c139f719b6445b829e2606ea9a66501cb9 GIT binary patch literal 28492 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 literal 0 HcmV?d00001 diff --git a/zoomroom2.png b/zoomroom2.png new file mode 100644 index 0000000000000000000000000000000000000000..7d11aeef4a324612c06de1272de63bf0c5031d1f GIT binary patch literal 34580 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 W!B@@Yr8wS3QKp-=8RZ)~NBjpRZc@Sk literal 0 HcmV?d00001 From 6783c4d2317d4c74b46cd11681cd3af755a1db8d Mon Sep 17 00:00:00 2001 From: Joe Bond Date: Mon, 23 Oct 2023 10:07:55 +0100 Subject: [PATCH 3/5] Added plots directory --- plot_bench.py | 5 +++-- plots/.gitignore | 2 ++ zoomroom.png | Bin 28492 -> 0 bytes zoomroom2.png | Bin 34580 -> 0 bytes 4 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 plots/.gitignore delete mode 100644 zoomroom.png delete mode 100644 zoomroom2.png diff --git a/plot_bench.py b/plot_bench.py index e23a0ccc4..d67df307c 100644 --- a/plot_bench.py +++ b/plot_bench.py @@ -17,7 +17,7 @@ 'standard': ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'], } -def parse(test_names, column_order, dest='Benchmarks/recent.png'): +def parse(test_names, column_order, dest='recent.png'): # Read benchmark csv benchmarks = pd.read_csv('Benchmarks/benchmarks.csv', skipinitialspace=True, delimiter=',', index_col='Test-Name') @@ -36,7 +36,8 @@ def parse(test_names, column_order, dest='Benchmarks/recent.png'): # Inserting a coloured horizontal line just to make clearer which columns have zero values plt.ylim(bottom=-10) plt.gca().axhline(0, lw=0.3, color='blue', label="Zero accuracy") - plt.savefig(dest) + real_dest = "plots/" + dest + plt.savefig(real_dest) plt.show() def decompose_list(input_str): diff --git a/plots/.gitignore b/plots/.gitignore new file mode 100644 index 000000000..c96a04f00 --- /dev/null +++ b/plots/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/zoomroom.png b/zoomroom.png deleted file mode 100644 index 0132f0c139f719b6445b829e2606ea9a66501cb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28492 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 diff --git a/zoomroom2.png b/zoomroom2.png deleted file mode 100644 index 7d11aeef4a324612c06de1272de63bf0c5031d1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34580 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 W!B@@Yr8wS3QKp-=8RZ)~NBjpRZc@Sk From a4bf6419f20d02e72cdb98c0f576c43c2c5c214b Mon Sep 17 00:00:00 2001 From: Joe Bond Date: Mon, 23 Oct 2023 13:21:10 +0100 Subject: [PATCH 4/5] Added caption and labelling options to plotting script --- plot_bench.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/plot_bench.py b/plot_bench.py index d67df307c..6c4e462f4 100644 --- a/plot_bench.py +++ b/plot_bench.py @@ -17,14 +17,15 @@ 'standard': ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'], } -def parse(test_names, column_order, dest='recent.png'): +def parse(test_names, column_order, cap, lab, dest='recent.png'): # Read benchmark csv benchmarks = pd.read_csv('Benchmarks/benchmarks.csv', skipinitialspace=True, delimiter=',', index_col='Test-Name') # Extract test names of interest - df = pd.DataFrame(benchmarks.loc[test_names]) + df = pd.DataFrame(benchmarks.loc[test_names]).round(1) + tex = df[column_order].to_latex(float_format="%.2f", caption = cap, label = lab) print(df[column_order]) - + print(tex) # Reorder benchmark columns # column_colors = ['#0d6b12', '#93dbb5', '#3e3875', '#b8bef5', '#910303', '#e84d4d', '#e8bceb', '#5073a1'] # Plot as bar chart @@ -32,13 +33,17 @@ def parse(test_names, column_order, dest='recent.png'): # , color=column_colors , ylabel="Milliseconds", rot=0 , figsize=(16,6)) - + # Inserting a coloured horizontal line just to make clearer which columns have zero values plt.ylim(bottom=-10) plt.gca().axhline(0, lw=0.3, color='blue', label="Zero accuracy") - real_dest = "plots/" + dest - plt.savefig(real_dest) - plt.show() + dest_png = dest + '.png' + dest_tex = dest + '.tex' + tex_f = open(dest_tex, "w") + tex_f.write(tex) + tex_f.close() + plt.savefig(dest_png) + # plt.show() def decompose_list(input_str): inner = input_str.split(", ") @@ -56,7 +61,7 @@ def bench_names(bench_str): else: return decompose_list(bench_str) -parser = argparse.ArgumentParser() +parser = argparse.ArgumentParser() parser.add_argument("-t", "--Tests", help = "Specify list of tests") parser.add_argument("-b", "--Benches", help = "Specify list of benchmarks to show") parser.add_argument("-d", "--Dest", help = "Specify where to save plot") @@ -65,7 +70,9 @@ def bench_names(bench_str): if args.Tests and args.Benches: tests = test_names(args.Tests) benches = bench_names(args.Benches) + capt = "Tests: " + args.Tests + ", Benches: " + args.Benches + lab = args.Tests + '-' + args.Benches if args.Dest: - parse(tests, benches, args.Dest) + parse(tests, benches, capt, lab, args.Dest) else: - parse(tests, benches) \ No newline at end of file + parse(tests, benches, capt, lab) \ No newline at end of file From c095dea7271409586e1322ad2dce707fc0262903 Mon Sep 17 00:00:00 2001 From: Joe Bond Date: Tue, 24 Oct 2023 13:42:38 +0100 Subject: [PATCH 5/5] Fixing up python script --- plot_bench.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plot_bench.py b/plot_bench.py index 6c4e462f4..dbbe94917 100644 --- a/plot_bench.py +++ b/plot_bench.py @@ -12,7 +12,7 @@ bench_sets = { 'all': ['Trace-Eval', 'Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-BwdDual', 'Graph-BwdAll', 'Graph-Fwd', 'Graph-FwdDual', 'Graph-FwdAsDeMorgan'], - 'bwd': ['Trace-Eval','Trace-Bwd', 'Graph-Eval', 'Graph-Bwd'], + 'bwd': ['Trace-Eval','Trace-Bwd','Graph-Eval', 'Graph-Bwd'], 'fwd': ['Trace-Eval', 'Trace-Fwd', 'Graph-Eval', 'Graph-Fwd', 'Graph-FwdAsDeMorgan'], 'standard': ['Trace-Eval','Trace-Bwd', 'Trace-Fwd', 'Graph-Eval', 'Graph-Bwd', 'Graph-Fwd'], } @@ -73,6 +73,6 @@ def bench_names(bench_str): capt = "Tests: " + args.Tests + ", Benches: " + args.Benches lab = args.Tests + '-' + args.Benches if args.Dest: - parse(tests, benches, capt, lab, args.Dest) + parse(tests, benches, capt, lab, dest=args.Dest) else: parse(tests, benches, capt, lab) \ No newline at end of file