source: benchmark/plot.py @ 8faa6612

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 8faa6612 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.