source: benchmark/plot.py @ c8f5f7d

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

Forgot to commit change to plot.py

  • Property mode set to 100755
File size: 6.0 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, _name=None):
25                self.unit = unit
26                self.min  = _min
27                self.log  = _log
28                self.name = _name
29
30field_names = {
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),
35        "ns per ops/procs"      : Field(''    , 0, False, _name = "Latency (ns $/$ (Processor $\\times$ Operation))" ),
36        "Number of threads"     : Field(''      , 1, False),
37        "Total Operations(ops)" : Field('Ops'   , 0, False),
38        "Ops/sec/procs"         : Field('Ops'   , 0, False),
39        "Total blocks"          : Field('Blocks', 0, False),
40        "Ops per second"        : Field(''   , 0, False),
41        "Cycle size (# thrds)"  : Field('thrd'  , 1, False),
42        "Duration (ms)"         : Field('ms'    , 0, False),
43        "Target QPS"            : Field(''      , 0, False),
44        "Actual QPS"            : Field(''      , 0, False),
45        "Average Read Latency"  : Field('us'    , 0, True),
46        "Median Read Latency"   : Field('us'    , 0, True),
47        "Tail Read Latency"     : Field('us'    , 0, True),
48        "Average Update Latency": Field('us'    , 0, True),
49        "Median Update Latency" : Field('us'    , 0, True),
50        "Tail Update Latency"   : Field('us'    , 0, True),
51        "Update Ratio"          : Field('\%'    , 0, False),
52}
53
54def plot(in_data, x, y, options):
55        fig, ax = plt.subplots()
56        colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
57        series = {} # scatter data for each individual data point
58        groups = {} # data points for x value
59
60        print("Preparing Data")
61
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] = {}
69
70                if x in entry[2] and y in entry[2]:
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
81        print("Preparing Lines")
82
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
96        print("Making Plots")
97
98        for name, data in sorted(series.items()):
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)
104
105        print("Calculating Extremums")
106
107        mx = max([max(s['x']) for s in series.values()])
108        my = max([max(s['y']) for s in series.values()])
109
110        print("Finishing Plots")
111
112        plt.ylabel(field_names[y].name if field_names[y].name else y)
113        # plt.xticks(range(1, math.ceil(mx) + 1))
114        plt.xlabel(field_names[x].name if field_names[x].name else x)
115        plt.grid(b = True)
116        ax.xaxis.set_major_formatter( EngFormatter(unit=field_names[x].unit) )
117        if options.logx:
118                ax.set_xscale('log')
119        elif field_names[x].log:
120                ax.set_xscale('log')
121        else:
122                plt.xlim(field_names[x].min, mx + 0.25)
123
124        ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
125        if options.logy:
126                ax.set_yscale('log')
127        elif field_names[y].log:
128                ax.set_yscale('log')
129        else:
130                plt.ylim(field_names[y].min, options.MaxY if options.MaxY else my*1.2)
131
132        plt.legend(loc='upper left')
133
134        print("Results Ready")
135        if options.out:
136                plt.savefig(options.out, bbox_inches='tight')
137        else:
138                plt.show()
139
140
141if __name__ == "__main__":
142        # ================================================================================
143        # parse command line arguments
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")
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")
152
153        options =  parser.parse_args()
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
175        if not options.out :
176                print(series)
177                print("fields: ", ' '.join(fields))
178
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
195        plot(data, wantx, wanty, options)
Note: See TracBrowser for help on using the repository browser.