source: benchmark/plot.py @ c899175

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since c899175 was c899175, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

  • Property mode set to 100755
File size: 5.3 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        "Update Ratio"          : Field('%'     , 0, False),
49}
50
51def plot(in_data, x, y, out):
52        fig, ax = plt.subplots()
53        colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
54        series = {} # scatter data for each individual data point
55        groups = {} # data points for x value
56
57        print("Preparing Data")
58
59        for entry in in_data:
60                name = entry[0]
61                if not name in series:
62                        series[name] = {'x':[], 'y':[]}
63
64                if not name in groups:
65                        groups[name] = {}
66
67                if x in entry[2] and y in entry[2]:
68                        xval = entry[2][x]
69                        yval = entry[2][y]
70                        series[name]['x'].append(xval)
71                        series[name]['y'].append(yval)
72
73                        if not xval in groups[name]:
74                                groups[name][xval] = []
75
76                        groups[name][xval].append(yval)
77
78        print("Preparing Lines")
79
80        lines = {} # lines from groups with min, max, median, etc.
81        for name, data in groups.items():
82                if not name in lines:
83                        lines[name] = { 'x': [], 'min':[], 'max':[], 'med':[], 'avg':[] }
84
85                for xkey in sorted(data):
86                        ys = data[xkey]
87                        lines[name]['x']  .append(xkey)
88                        lines[name]['min'].append(min(ys))
89                        lines[name]['max'].append(max(ys))
90                        lines[name]['med'].append(statistics.median(ys))
91                        lines[name]['avg'].append(statistics.mean(ys))
92
93        print("Making Plots")
94
95        for name, data in sorted(series.items()):
96                _col = next(colors)
97                plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
98                plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
99                plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
100                plt.plot(lines[name]['x'], lines[name]['med'], '-', color=_col)
101
102        print("Calculating Extremums")
103
104        mx = max([max(s['x']) for s in series.values()])
105        my = max([max(s['y']) for s in series.values()])
106
107        print("Finishing Plots")
108
109        plt.ylabel(y)
110        # plt.xticks(range(1, math.ceil(mx) + 1))
111        plt.xlabel(x)
112        plt.grid(b = True)
113        ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
114        if field_names[x].log:
115                ax.set_xscale('log')
116        else:
117                plt.xlim(field_names[x].min, mx + 0.25)
118
119        ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
120        if field_names[y].log:
121                ax.set_yscale('log')
122        else:
123                plt.ylim(field_names[y].min, my*1.2)
124
125        plt.legend(loc='upper left')
126
127        print("Results Ready")
128        if out:
129                plt.savefig(out)
130        else:
131                plt.show()
132
133
134if __name__ == "__main__":
135        # ================================================================================
136        # parse command line arguments
137        parser = argparse.ArgumentParser(description='Python Script to draw R.M.I.T. results')
138        parser.add_argument('-f', '--file', nargs='?', type=argparse.FileType('r'), default=sys.stdin, help="Input file")
139        parser.add_argument('-o', '--out', nargs='?', type=str, default=None, help="Output file")
140        parser.add_argument('-y', nargs='?', type=str, default="", help="Which field to use as the Y axis")
141        parser.add_argument('-x', nargs='?', type=str, default="", help="Which field to use as the X axis")
142
143        options =  parser.parse_args()
144
145        # ================================================================================
146        # load data
147        try :
148                data = json.load(options.file)
149        except :
150                print('ERROR: could not read input', file=sys.stderr)
151                parser.print_help(sys.stderr)
152                sys.exit(1)
153
154        # ================================================================================
155        # identify the keys
156
157        series = set()
158        fields = set()
159
160        for entry in data:
161                series.add(entry[0])
162                for label in entry[2].keys():
163                        fields.add(label)
164
165        if not options.out :
166                print(series)
167                print("fields: ", ' '.join(fields))
168
169        wantx = "Number of processors"
170        wanty = "ns per ops"
171
172        if options.x:
173                if options.x in field_names.keys():
174                        wantx = options.x
175                else:
176                        print("Could not find X key '{}', defaulting to '{}'".format(options.x, wantx))
177
178        if options.y:
179                if options.y in field_names.keys():
180                        wanty = options.y
181                else:
182                        print("Could not find Y key '{}', defaulting to '{}'".format(options.y, wanty))
183
184
185        plot(data, wantx, wanty, options.out)
Note: See TracBrowser for help on using the repository browser.