source: benchmark/plot.py@ fb63c70

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

Some more tiny fixes to the memcached results handling

  • Property mode set to 100755
File size: 5.4 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('' , 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('' , 0, False),
43 "Actual QPS" : Field('' , 0, False),
44 "Average Read Latency" : Field('us' , 0, True),
45 "Median Read Latency" : Field('us' , 0, True),
46 "Tail Read Latency" : Field('us' , 0, True),
47 "Average Update Latency": Field('us' , 0, True),
48 "Median Update Latency" : Field('us' , 0, True),
49 "Tail Update Latency" : Field('us' , 0, True),
50 "Update Ratio" : Field('\%' , 0, False),
51}
52
53def plot(in_data, x, y, out):
54 fig, ax = plt.subplots()
55 colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
56 series = {} # scatter data for each individual data point
57 groups = {} # data points for x value
58
59 print("Preparing Data")
60
61 for entry in in_data:
62 name = entry[0]
63 if not name in series:
64 series[name] = {'x':[], 'y':[]}
65
66 if not name in groups:
67 groups[name] = {}
68
69 if x in entry[2] and y in entry[2]:
70 xval = entry[2][x]
71 yval = entry[2][y]
72 series[name]['x'].append(xval)
73 series[name]['y'].append(yval)
74
75 if not xval in groups[name]:
76 groups[name][xval] = []
77
78 groups[name][xval].append(yval)
79
80 print("Preparing Lines")
81
82 lines = {} # lines from groups with min, max, median, etc.
83 for name, data in groups.items():
84 if not name in lines:
85 lines[name] = { 'x': [], 'min':[], 'max':[], 'med':[], 'avg':[] }
86
87 for xkey in sorted(data):
88 ys = data[xkey]
89 lines[name]['x'] .append(xkey)
90 lines[name]['min'].append(min(ys))
91 lines[name]['max'].append(max(ys))
92 lines[name]['med'].append(statistics.median(ys))
93 lines[name]['avg'].append(statistics.mean(ys))
94
95 print("Making Plots")
96
97 for name, data in sorted(series.items()):
98 _col = next(colors)
99 plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
100 plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
101 plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
102 plt.plot(lines[name]['x'], lines[name]['med'], '-', color=_col)
103
104 print("Calculating Extremums")
105
106 mx = max([max(s['x']) for s in series.values()])
107 my = max([max(s['y']) for s in series.values()])
108
109 print("Finishing Plots")
110
111 plt.ylabel(y)
112 # plt.xticks(range(1, math.ceil(mx) + 1))
113 plt.xlabel(x)
114 plt.grid(b = True)
115 ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
116 if field_names[x].log:
117 ax.set_xscale('log')
118 else:
119 plt.xlim(field_names[x].min, mx + 0.25)
120
121 ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
122 if field_names[y].log:
123 ax.set_yscale('log')
124 else:
125 plt.ylim(field_names[y].min, my*1.2)
126
127 plt.legend(loc='upper left')
128
129 print("Results Ready")
130 if out:
131 plt.savefig(out)
132 else:
133 plt.show()
134
135
136if __name__ == "__main__":
137 # ================================================================================
138 # parse command line arguments
139 parser = argparse.ArgumentParser(description='Python Script to draw R.M.I.T. results')
140 parser.add_argument('-f', '--file', nargs='?', type=argparse.FileType('r'), default=sys.stdin, help="Input file")
141 parser.add_argument('-o', '--out', nargs='?', type=str, default=None, help="Output file")
142 parser.add_argument('-y', nargs='?', type=str, default="", help="Which field to use as the Y axis")
143 parser.add_argument('-x', nargs='?', type=str, default="", help="Which field to use as the X axis")
144
145 options = parser.parse_args()
146
147 # ================================================================================
148 # load data
149 try :
150 data = json.load(options.file)
151 except :
152 print('ERROR: could not read input', file=sys.stderr)
153 parser.print_help(sys.stderr)
154 sys.exit(1)
155
156 # ================================================================================
157 # identify the keys
158
159 series = set()
160 fields = set()
161
162 for entry in data:
163 series.add(entry[0])
164 for label in entry[2].keys():
165 fields.add(label)
166
167 if not options.out :
168 print(series)
169 print("fields: ", ' '.join(fields))
170
171 wantx = "Number of processors"
172 wanty = "ns per ops"
173
174 if options.x:
175 if options.x in field_names.keys():
176 wantx = options.x
177 else:
178 print("Could not find X key '{}', defaulting to '{}'".format(options.x, wantx))
179
180 if options.y:
181 if options.y in field_names.keys():
182 wanty = options.y
183 else:
184 print("Could not find Y key '{}', defaulting to '{}'".format(options.y, wanty))
185
186
187 plot(data, wantx, wanty, options.out)
Note: See TracBrowser for help on using the repository browser.