From de8f92b176252b52827f29621aabb91743c17c63 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 30 Oct 2019 12:46:15 +0100 Subject: add and use write_tex_table function --- src/benchmark.py | 101 +++++++++++++++++++++++++++++++++++++++++ src/benchmarks/dj_trace.py | 14 ++++++ src/benchmarks/falsesharing.py | 9 +++- src/benchmarks/lld.py | 5 ++ src/benchmarks/loop.py | 5 ++ src/benchmarks/mysql.py | 8 ++++ src/benchmarks/t_test1.py | 8 +++- 7 files changed, 147 insertions(+), 3 deletions(-) diff --git a/src/benchmark.py b/src/benchmark.py index 0df2bc3..a774ac9 100644 --- a/src/benchmark.py +++ b/src/benchmark.py @@ -809,3 +809,104 @@ class Benchmark: print(row[-1], "\\\\", file=f) print("\\end{tabular}", file=f) print("\\end{document}", file=f) + + def write_tex_table(self, entries, sort=">", + filepostfix="", sumdir="", std=False): + """generate a latex standalone table from an list of entries dictionaries + + Entries must have at least the two keys: "label" and "expression". + The optional "sort" key specifies the direction of the order: + ">" : bigger is better. + "<" : smaller is better. + + Table layout: + + | alloc1 | alloc2 | .... + --------------------------------------- + | name1 name2 | ... + --------------------------------------- + perm1 | eavl1 eval2 | ... + perm2 | eval1 eval2 | ... + """ + args = self.results["args"] + allocators = self.results["allocators"] + nallocators = len(allocators) + nentries = len(entries) + perm_fields = self.Perm._fields + nperm_fields = len(perm_fields) + + alloc_header_line = f"\\multicolumn{{{nperm_fields}}}{{c|}}{{}} &" + for alloc in allocators: + alloc_header_line += f"\\multicolumn{{{nentries}}}{{c|}}{{{alloc}}} &" + alloc_header_line = alloc_header_line[:-1] + "\\\\" + + perm_fields_header = "" + for field in self.Perm._fields: + perm_fields_header += f'{field} &' + entry_header_line = "" + for entry in entries: + entry_header_line += f'{entry["label"]} &' + entry_header_line = perm_fields_header + entry_header_line * nallocators + entry_header_line = entry_header_line[:-1] + "\\\\" + + fname = os.path.join(sumdir, ".".join([self.name, filepostfix, "tex"])) + with open(fname, "w") as f: + print("\\documentclass{standalone}", file=f) + print("\\usepackage{xcolor}", file=f) + print("\\begin{document}", file=f) + print("\\begin{tabular}{|", f"{'c|'*nperm_fields}", f"{'c'*nentries}|"*nallocators, "}", file=f) + + print(alloc_header_line, file=f) + print("\\hline", file=f) + print(entry_header_line, file=f) + print("\\hline", file=f) + + for perm in self.iterate_args(args=args): + values = [[] for _ in entries] + maxs = [None for _ in entries] + mins = [None for _ in entries] + for allocator in allocators: + for i, entry in enumerate(entries): + expr = entry["expression"] + values[i].append(eval(expr.format(**self.results["stats"][allocator][perm]["mean"]))) + + # get max and min for each entry + for i, entry in enumerate(entries): + if not "sort" in entry: + continue + # bigger is better + elif entry["sort"] == ">": + maxs[i] = max(values[i]) + mins[i] = min(values[i]) + # smaller is better + elif entry["sort"] == "<": + mins[i] = max(values[i]) + maxs[i] = min(values[i]) + + # build row + row = "" + perm_dict = perm._asdict() + for field in perm_fields: + row += str(perm_dict[field]) + "&" + + for i, _ in enumerate(allocators): + for y, entry_vals in enumerate(values): + val = entry_vals[i] + + # format + val_str = str(val) + if type(val) == float: + val_str = f"{val:.2f}" + + # colorize + if val == maxs[y]: + val_str = f"\\textcolor{{green}}{{{val_str}}}" + elif val == mins[y]: + val_str = f"\\textcolor{{red}}{{{val_str}}}" + row += f"{val_str} &" + #escape _ for latex + row = row.replace("_", "\_") + print(row[:-1], "\\\\", file=f) + + print("\\end{tabular}", file=f) + print("\\end{document}", file=f) diff --git a/src/benchmarks/dj_trace.py b/src/benchmarks/dj_trace.py index 3f87e86..bca0d17 100644 --- a/src/benchmarks/dj_trace.py +++ b/src/benchmarks/dj_trace.py @@ -209,6 +209,11 @@ class BenchmarkDJTrace(Benchmark): title='"Highwatermark of Vm (VmHWM)"', filepostfix="newrss") + # self.barplot_fixed_arg("{Max_RSS}/1000", + # ylabel='"Max RSS in MB"', + # title='"Highwatermark of Vm (VmHWM)"', + # filepostfix="newrss") + del allocators["Ideal_RSS"] del self.results["stats"]["Ideal_RSS"] @@ -238,6 +243,15 @@ class BenchmarkDJTrace(Benchmark): self.export_stats_to_dataref("Max_RSS") self.export_stats_to_dataref("cputime") + # Big table + self.write_tex_table([{"label": "Runtime [ms]", + "expression": "{cputime}/1000", + "sort": "<"}, + {"label": "Max RSS [MB]", + "expression": "{Max_RSS}/1000", + "sort":"<"}], + filepostfix="table") + # Tables for perm in self.iterate_args(args=args): # collect data diff --git a/src/benchmarks/falsesharing.py b/src/benchmarks/falsesharing.py index b7222f6..93c2fe9 100644 --- a/src/benchmarks/falsesharing.py +++ b/src/benchmarks/falsesharing.py @@ -70,7 +70,9 @@ class BenchmarkFalsesharing(Benchmark): data = [float(m["time"]) for m in self.results[allocator][perm]] - y_vals.append(single_threaded / np.mean(data)) + speedup = single_threaded / np.mean(data) + self.results["stats"][allocator][perm]["mean"]["speedup"] = speedup + y_vals.append(speedup) plt.plot(nthreads, y_vals, marker='.', linestyle='-', label=allocator, color=allocators[allocator]["color"]) @@ -96,5 +98,10 @@ class BenchmarkFalsesharing(Benchmark): autoticks=False, fixed=["bench"]) + self.write_tex_table([{"label": "Speedup", + "expression": "{speedup}", + "sort":">"}], + filepostfix="speedup.table") + falsesharing = BenchmarkFalsesharing() diff --git a/src/benchmarks/lld.py b/src/benchmarks/lld.py index 1c30ce0..d9796bc 100644 --- a/src/benchmarks/lld.py +++ b/src/benchmarks/lld.py @@ -274,5 +274,10 @@ class BenchmarkLld(Benchmark): # self.export_stats_to_dataref("VmHWM") self.export_stats_to_dataref("task-clock") + self.write_tex_table([{"label": "Runtime [ms]", + "expression": "{task-clock}", + "sort": "<"}], + filepostfix="table") + lld = BenchmarkLld() diff --git a/src/benchmarks/loop.py b/src/benchmarks/loop.py index 1f6a831..407aac1 100644 --- a/src/benchmarks/loop.py +++ b/src/benchmarks/loop.py @@ -74,6 +74,11 @@ class BenchmarkLoop(Benchmark): self.write_best_doublearg_tex_table("perm.nthreads / ({task-clock}/1000)", filepostfix="time.matrix") + self.write_tex_table([{"label": "MOPS/s", + "expression": "perm.nthreads / ({task-clock}/1000)", + "sort":">"}], + filepostfix="mops.table") + self.export_stats_to_csv("task-clock") self.export_stats_to_dataref("task-clock") diff --git a/src/benchmarks/mysql.py b/src/benchmarks/mysql.py index 74d49cb..c7519c5 100644 --- a/src/benchmarks/mysql.py +++ b/src/benchmarks/mysql.py @@ -225,6 +225,14 @@ class BenchmarkMYSQL(Benchmark): title='"Memusage sysbench oltp read only"', filepostfix="mem") + self.write_tex_table([{"label": "Transactions", + "expression": "{transactions}", + "sort": ">"}, + {"label": "Memusage [KB]", + "expression": "{rssmax}", + "sort": "<"}], + filepostfix="table") + # Colored latex table showing transactions count d = {allocator: {} for allocator in allocators} for perm in self.iterate_args(args=args): diff --git a/src/benchmarks/t_test1.py b/src/benchmarks/t_test1.py index d892a15..cbb9051 100644 --- a/src/benchmarks/t_test1.py +++ b/src/benchmarks/t_test1.py @@ -55,8 +55,12 @@ class BenchmarkTTest1(Benchmark): autoticks=False) # Speed Matrix - self.write_best_doublearg_tex_table(yval, - filepostfix="memusage.matrix") + self.write_best_doublearg_tex_table(yval, filepostfix="mops.matrix") + + self.write_tex_table([{"label": "MOPS/s", + "expression": yval, + "sort": ">"}], + filepostfix="mops.table") self.export_stats_to_csv("task-clock") -- cgit v1.2.3