source: benchmark/plot.py@ 66406f3

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

Updated makefile and data plotting

  • Property mode set to 100755
File size: 6.5 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
[c0458be3]16import os
[0bb691b1]17import re
[57af3f3]18import statistics
[0bb691b1]19import sys
20
21import matplotlib.pyplot as plt
22from matplotlib.ticker import EngFormatter
23
[44706d1]24class Field:
[c0458be3]25 def __init__(self, unit, _min, _log, _name=None, _factor=1.0):
[44706d1]26 self.unit = unit
27 self.min = _min
[e9c5db2]28 self.log = _log
[76f5e9f]29 self.name = _name
[c0458be3]30 self.factor = _factor
[44706d1]31
32field_names = {
[e9c5db2]33 "ns per ops" : Field('ns' , 0, False),
34 "Number of processors" : Field('' , 1, False),
35 "Ops per procs" : Field('Ops' , 0, False),
36 "Ops per threads" : Field('Ops' , 0, False),
[e5e2334]37 "ns per ops/procs" : Field('' , 0, False, _name = "Latency ((ns $/$ Operation) $\\times$ Processor)" ),
[3b5dcfa]38 "Number of threads" : Field('' , 1, False),
[e9c5db2]39 "Total Operations(ops)" : Field('Ops' , 0, False),
40 "Ops/sec/procs" : Field('Ops' , 0, False),
41 "Total blocks" : Field('Blocks', 0, False),
[c0458be3]42 "Ops per second" : Field('' , 0, False),
[e9c5db2]43 "Cycle size (# thrds)" : Field('thrd' , 1, False),
44 "Duration (ms)" : Field('ms' , 0, False),
[3b5dcfa]45 "Target QPS" : Field('' , 0, False),
46 "Actual QPS" : Field('' , 0, False),
[e5e2334]47 "Average Read Latency" : Field('s' , 0, False, _factor = 0.000001),
[c0458be3]48 "Median Read Latency" : Field('s' , 0, True, _factor = 0.000001),
49 "Tail Read Latency" : Field('s' , 0, True, _factor = 0.000001),
50 "Average Update Latency": Field('s' , 0, True, _factor = 0.000001),
51 "Median Update Latency" : Field('s' , 0, True, _factor = 0.000001),
52 "Tail Update Latency" : Field('s' , 0, True, _factor = 0.000001),
[e5e2334]53 "Update Ratio" : Field('%' , 0, False),
[c0458be3]54 "Request Rate" : Field('req/s' , 0, False),
55 "Data Rate" : Field('b/s' , 0, False, _factor = 1000 * 1000, _name = "Response Throughput"),
[e5e2334]56 "Errors" : Field('%' , 0, False),
[44706d1]57}
[0bb691b1]58
[c0458be3]59def plot(in_data, x, y, options, prefix):
[0bb691b1]60 fig, ax = plt.subplots()
[c0458be3]61 colors = itertools.cycle(['#006cb4','#0aa000','#ff6600','#8510a1','#0095e3','#fd8f00','#e30002','#8f00d6','#4b009a','#ffff00','#69df00','#fb0300','#b13f00'])
[57af3f3]62 series = {} # scatter data for each individual data point
63 groups = {} # data points for x value
[e9c5db2]64
65 print("Preparing Data")
66
[57af3f3]67 for entry in in_data:
68 name = entry[0]
69 if not name in series:
70 series[name] = {'x':[], 'y':[]}
71
72 if not name in groups:
73 groups[name] = {}
[0bb691b1]74
75 if x in entry[2] and y in entry[2]:
[57af3f3]76 xval = entry[2][x]
[c0458be3]77 yval = entry[2][y] * field_names[y].factor
[57af3f3]78 series[name]['x'].append(xval)
79 series[name]['y'].append(yval)
80
81 if not xval in groups[name]:
82 groups[name][xval] = []
83
84 groups[name][xval].append(yval)
85
[e9c5db2]86 print("Preparing Lines")
87
[57af3f3]88 lines = {} # lines from groups with min, max, median, etc.
89 for name, data in groups.items():
90 if not name in lines:
91 lines[name] = { 'x': [], 'min':[], 'max':[], 'med':[], 'avg':[] }
92
93 for xkey in sorted(data):
94 ys = data[xkey]
95 lines[name]['x'] .append(xkey)
96 lines[name]['min'].append(min(ys))
97 lines[name]['max'].append(max(ys))
98 lines[name]['med'].append(statistics.median(ys))
99 lines[name]['avg'].append(statistics.mean(ys))
100
[e9c5db2]101 print("Making Plots")
102
[1f4fde5]103 for name, data in sorted(series.items()):
[57af3f3]104 _col = next(colors)
[c0458be3]105 plt.scatter(data['x'], data['y'], color=_col, label=name[len(prefix):], marker='x')
[57af3f3]106 plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
107 plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
108 plt.plot(lines[name]['x'], lines[name]['med'], '-', color=_col)
[0bb691b1]109
[e9c5db2]110 print("Calculating Extremums")
111
[0bb691b1]112 mx = max([max(s['x']) for s in series.values()])
113 my = max([max(s['y']) for s in series.values()])
114
[e9c5db2]115 print("Finishing Plots")
116
[76f5e9f]117 plt.ylabel(field_names[y].name if field_names[y].name else y)
[e9c5db2]118 # plt.xticks(range(1, math.ceil(mx) + 1))
[76f5e9f]119 plt.xlabel(field_names[x].name if field_names[x].name else x)
[0bb691b1]120 plt.grid(b = True)
[44706d1]121 ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
[76f5e9f]122 if options.logx:
123 ax.set_xscale('log')
124 elif field_names[x].log:
[e9c5db2]125 ax.set_xscale('log')
126 else:
127 plt.xlim(field_names[x].min, mx + 0.25)
128
[76f5e9f]129 if options.logy:
130 ax.set_yscale('log')
131 elif field_names[y].log:
[e9c5db2]132 ax.set_yscale('log')
133 else:
[76f5e9f]134 plt.ylim(field_names[y].min, options.MaxY if options.MaxY else my*1.2)
[e9c5db2]135
[c0458be3]136 ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
137
[44706d1]138 plt.legend(loc='upper left')
[e9c5db2]139
140 print("Results Ready")
[76f5e9f]141 if options.out:
142 plt.savefig(options.out, bbox_inches='tight')
[f34f95c]143 else:
144 plt.show()
[0bb691b1]145
146
147if __name__ == "__main__":
148 # ================================================================================
149 # parse command line arguments
[e9c5db2]150 parser = argparse.ArgumentParser(description='Python Script to draw R.M.I.T. results')
151 parser.add_argument('-f', '--file', nargs='?', type=argparse.FileType('r'), default=sys.stdin, help="Input file")
152 parser.add_argument('-o', '--out', nargs='?', type=str, default=None, help="Output file")
153 parser.add_argument('-y', nargs='?', type=str, default="", help="Which field to use as the Y axis")
154 parser.add_argument('-x', nargs='?', type=str, default="", help="Which field to use as the X axis")
[76f5e9f]155 parser.add_argument('--logx', action='store_true', help="if set, makes the x-axis logscale")
156 parser.add_argument('--logy', action='store_true', help="if set, makes the y-axis logscale")
157 parser.add_argument('--MaxY', nargs='?', type=int, help="maximum value of the y-axis")
[e9c5db2]158
159 options = parser.parse_args()
[0bb691b1]160
161 # ================================================================================
162 # load data
163 try :
164 data = json.load(options.file)
165 except :
166 print('ERROR: could not read input', file=sys.stderr)
167 parser.print_help(sys.stderr)
168 sys.exit(1)
169
170 # ================================================================================
171 # identify the keys
172
173 series = set()
174 fields = set()
175
176 for entry in data:
177 series.add(entry[0])
178 for label in entry[2].keys():
179 fields.add(label)
180
[c0458be3]181 # find the common prefix on series for removal
182 prefix = os.path.commonprefix(list(series))
183
[f34f95c]184 if not options.out :
185 print(series)
[e9c5db2]186 print("fields: ", ' '.join(fields))
[f34f95c]187
[e9c5db2]188 wantx = "Number of processors"
189 wanty = "ns per ops"
190
191 if options.x:
192 if options.x in field_names.keys():
193 wantx = options.x
194 else:
195 print("Could not find X key '{}', defaulting to '{}'".format(options.x, wantx))
196
197 if options.y:
198 if options.y in field_names.keys():
199 wanty = options.y
200 else:
201 print("Could not find Y key '{}', defaulting to '{}'".format(options.y, wanty))
202
203
[c0458be3]204 plot(data, wantx, wanty, options, prefix)
Note: See TracBrowser for help on using the repository browser.