source: benchmark/plot.py@ 5a076837

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

Forgot to commit change to plot.py

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