source: benchmark/plot.py@ ffc1689

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since ffc1689 was e9c5db2, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Minor fixes to benchmark processing scripts

  • Property mode set to 100755
File size: 5.2 KB
Line 
1#!/usr/bin/python3
2"""
3Python Script to plot values obtained by the rmit.py script
4Runs a R.I.P.L.
5
6./plot.py
7-t trials
8-o option:values
9"""
10
11import argparse
12import itertools
13import json
14import math
15import numpy
16import re
17import statistics
18import sys
19
20import matplotlib.pyplot as plt
21from matplotlib.ticker import EngFormatter
22
23class Field:
24 def __init__(self, unit, _min, _log):
25 self.unit = unit
26 self.min = _min
27 self.log = _log
28
29field_names = {
30 "ns per ops" : Field('ns' , 0, False),
31 "Number of processors" : Field('' , 1, False),
32 "Ops per procs" : Field('Ops' , 0, False),
33 "Ops per threads" : Field('Ops' , 0, False),
34 "ns per ops/procs" : Field('ns' , 0, False),
35 "Number of threads" : Field('thrd' , 1, False),
36 "Total Operations(ops)" : Field('Ops' , 0, False),
37 "Ops/sec/procs" : Field('Ops' , 0, False),
38 "Total blocks" : Field('Blocks', 0, False),
39 "Ops per second" : Field('Ops' , 0, False),
40 "Cycle size (# thrds)" : Field('thrd' , 1, False),
41 "Duration (ms)" : Field('ms' , 0, False),
42 "Target QPS" : Field('QPS' , 0, False),
43 "Actual QPS" : Field('QPS' , 0, False),
44 "Median Read Latency" : Field('us' , 0, True),
45 "Tail Read Latency" : Field('us' , 0, True),
46 "Median Update Latency" : Field('us' , 0, True),
47 "Tail Update Latency" : Field('us' , 0, True),
48}
49
50def plot(in_data, x, y, out):
51 fig, ax = plt.subplots()
52 colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
53 series = {} # scatter data for each individual data point
54 groups = {} # data points for x value
55
56 print("Preparing Data")
57
58 for entry in in_data:
59 name = entry[0]
60 if not name in series:
61 series[name] = {'x':[], 'y':[]}
62
63 if not name in groups:
64 groups[name] = {}
65
66 if x in entry[2] and y in entry[2]:
67 xval = entry[2][x]
68 yval = entry[2][y]
69 series[name]['x'].append(xval)
70 series[name]['y'].append(yval)
71
72 if not xval in groups[name]:
73 groups[name][xval] = []
74
75 groups[name][xval].append(yval)
76
77 print("Preparing Lines")
78
79 lines = {} # lines from groups with min, max, median, etc.
80 for name, data in groups.items():
81 if not name in lines:
82 lines[name] = { 'x': [], 'min':[], 'max':[], 'med':[], 'avg':[] }
83
84 for xkey in sorted(data):
85 ys = data[xkey]
86 lines[name]['x'] .append(xkey)
87 lines[name]['min'].append(min(ys))
88 lines[name]['max'].append(max(ys))
89 lines[name]['med'].append(statistics.median(ys))
90 lines[name]['avg'].append(statistics.mean(ys))
91
92 print("Making Plots")
93
94 for name, data in series.items():
95 _col = next(colors)
96 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
97 plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
98 plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
99 plt.plot(lines[name]['x'], lines[name]['med'], '-', color=_col)
100
101 print("Calculating Extremums")
102
103 mx = max([max(s['x']) for s in series.values()])
104 my = max([max(s['y']) for s in series.values()])
105
106 print("Finishing Plots")
107
108 plt.ylabel(y)
109 # plt.xticks(range(1, math.ceil(mx) + 1))
110 plt.xlabel(x)
111 plt.grid(b = True)
112 ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
113 if field_names[x].log:
114 ax.set_xscale('log')
115 else:
116 plt.xlim(field_names[x].min, mx + 0.25)
117
118 ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
119 if field_names[y].log:
120 ax.set_yscale('log')
121 else:
122 plt.ylim(field_names[y].min, my*1.2)
123
124 plt.legend(loc='upper left')
125
126 print("Results Ready")
127 if out:
128 plt.savefig(out)
129 else:
130 plt.show()
131
132
133if __name__ == "__main__":
134 # ================================================================================
135 # parse command line arguments
136 parser = argparse.ArgumentParser(description='Python Script to draw R.M.I.T. results')
137 parser.add_argument('-f', '--file', nargs='?', type=argparse.FileType('r'), default=sys.stdin, help="Input file")
138 parser.add_argument('-o', '--out', nargs='?', type=str, default=None, help="Output file")
139 parser.add_argument('-y', nargs='?', type=str, default="", help="Which field to use as the Y axis")
140 parser.add_argument('-x', nargs='?', type=str, default="", help="Which field to use as the X axis")
141
142 options = parser.parse_args()
143
144 # ================================================================================
145 # load data
146 try :
147 data = json.load(options.file)
148 except :
149 print('ERROR: could not read input', file=sys.stderr)
150 parser.print_help(sys.stderr)
151 sys.exit(1)
152
153 # ================================================================================
154 # identify the keys
155
156 series = set()
157 fields = set()
158
159 for entry in data:
160 series.add(entry[0])
161 for label in entry[2].keys():
162 fields.add(label)
163
164 if not options.out :
165 print(series)
166 print("fields: ", ' '.join(fields))
167
168 wantx = "Number of processors"
169 wanty = "ns per ops"
170
171 if options.x:
172 if options.x in field_names.keys():
173 wantx = options.x
174 else:
175 print("Could not find X key '{}', defaulting to '{}'".format(options.x, wantx))
176
177 if options.y:
178 if options.y in field_names.keys():
179 wanty = options.y
180 else:
181 print("Could not find Y key '{}', defaulting to '{}'".format(options.y, wanty))
182
183
184 plot(data, wantx, wanty, options.out)
Note: See TracBrowser for help on using the repository browser.