source: benchmark/plot.py @ f835806

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