source: benchmark/plot.py @ e9c5db2

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since e9c5db2 was e9c5db2, checked in by Thierry Delisle <tdelisle@…>, 2 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.