source: benchmark/plot.py@ f6737ae1

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since f6737ae1 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
RevLine 
[0bb691b1]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
[57af3f3]17import statistics
[0bb691b1]18import sys
19
20import matplotlib.pyplot as plt
21from matplotlib.ticker import EngFormatter
22
[44706d1]23class Field:
[e9c5db2]24 def __init__(self, unit, _min, _log):
[44706d1]25 self.unit = unit
26 self.min = _min
[e9c5db2]27 self.log = _log
[44706d1]28
29field_names = {
[e9c5db2]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),
[3b5dcfa]35 "Number of threads" : Field('' , 1, False),
[e9c5db2]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),
[3b5dcfa]42 "Target QPS" : Field('' , 0, False),
43 "Actual QPS" : Field('' , 0, False),
44 "Average Read Latency" : Field('us' , 0, True),
[e9c5db2]45 "Median Read Latency" : Field('us' , 0, True),
46 "Tail Read Latency" : Field('us' , 0, True),
[3b5dcfa]47 "Average Update Latency": Field('us' , 0, True),
[e9c5db2]48 "Median Update Latency" : Field('us' , 0, True),
49 "Tail Update Latency" : Field('us' , 0, True),
[3b5dcfa]50 "Update Ratio" : Field('\%' , 0, False),
[44706d1]51}
[0bb691b1]52
[57af3f3]53def plot(in_data, x, y, out):
[0bb691b1]54 fig, ax = plt.subplots()
[44706d1]55 colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
[57af3f3]56 series = {} # scatter data for each individual data point
57 groups = {} # data points for x value
[e9c5db2]58
59 print("Preparing Data")
60
[57af3f3]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] = {}
[0bb691b1]68
69 if x in entry[2] and y in entry[2]:
[57af3f3]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
[e9c5db2]80 print("Preparing Lines")
81
[57af3f3]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
[e9c5db2]95 print("Making Plots")
96
[1f4fde5]97 for name, data in sorted(series.items()):
[57af3f3]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)
[0bb691b1]103
[e9c5db2]104 print("Calculating Extremums")
105
[0bb691b1]106 mx = max([max(s['x']) for s in series.values()])
107 my = max([max(s['y']) for s in series.values()])
108
[e9c5db2]109 print("Finishing Plots")
110
[0bb691b1]111 plt.ylabel(y)
[e9c5db2]112 # plt.xticks(range(1, math.ceil(mx) + 1))
[0bb691b1]113 plt.xlabel(x)
114 plt.grid(b = True)
[44706d1]115 ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
[e9c5db2]116 if field_names[x].log:
117 ax.set_xscale('log')
118 else:
119 plt.xlim(field_names[x].min, mx + 0.25)
120
[44706d1]121 ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
[e9c5db2]122 if field_names[y].log:
123 ax.set_yscale('log')
124 else:
125 plt.ylim(field_names[y].min, my*1.2)
126
[44706d1]127 plt.legend(loc='upper left')
[e9c5db2]128
129 print("Results Ready")
[f34f95c]130 if out:
131 plt.savefig(out)
132 else:
133 plt.show()
[0bb691b1]134
135
136if __name__ == "__main__":
137 # ================================================================================
138 # parse command line arguments
[e9c5db2]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()
[0bb691b1]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
[f34f95c]167 if not options.out :
168 print(series)
[e9c5db2]169 print("fields: ", ' '.join(fields))
[f34f95c]170
[e9c5db2]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.