Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • benchmark/plot.py

    re9c5db2 rf34f95c  
    1515import numpy
    1616import re
    17 import statistics
    1817import sys
    1918
     
    2221
    2322class Field:
    24         def __init__(self, unit, _min, _log):
     23        def __init__(self, unit, _min):
    2524                self.unit = unit
    2625                self.min  = _min
    27                 self.log  = _log
    2826
    2927field_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),
     28        "ns per ops"           : Field('ns'    , 0),
     29        "Number of processors" : Field(''      , 1),
     30        "Ops per procs"        : Field('Ops'   , 0),
     31        "Ops per threads"      : Field('Ops'   , 0),
     32        "ns per ops/procs"     : Field('ns'    , 0),
     33        "Number of threads"    : Field('thrd'  , 1),
     34        "Total Operations(ops)": Field('Ops'   , 0),
     35        "Ops/sec/procs"        : Field('Ops'   , 0),
     36        "Total blocks"         : Field('Blocks', 0),
     37        "Ops per second"       : Field('Ops'   , 0),
     38        "Cycle size (# thrds)" : Field('thrd'  , 1),
     39        "Duration (ms)"        : Field('ms'    , 0),
    4840}
    4941
    50 def plot(in_data, x, y, out):
     42def plot(data, x, y, out):
    5143        fig, ax = plt.subplots()
    5244        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] = {}
     45        series = {}
     46        for entry in data:
     47                if not entry[0] in series:
     48                        series[entry[0]] = {'x':[], 'y':[]}
    6549
    6650                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")
     51                        series[entry[0]]['x'].append(entry[2][x])
     52                        series[entry[0]]['y'].append(entry[2][y])
    9353
    9454        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")
     55                plt.scatter(data['x'], data['y'], color=next(colors), label=name, marker='x')
    10256
    10357        mx = max([max(s['x']) for s in series.values()])
    10458        my = max([max(s['y']) for s in series.values()])
    10559
    106         print("Finishing Plots")
    107 
    10860        plt.ylabel(y)
    109         # plt.xticks(range(1, math.ceil(mx) + 1))
     61        plt.xlim(field_names[x].min, mx + 0.25)
     62        plt.xticks(range(1, math.ceil(mx) + 1))
    11063        plt.xlabel(x)
     64        plt.ylim(field_names[y].min, my*1.2)
    11165        plt.grid(b = True)
    11266        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 
    11867        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 
    12468        plt.legend(loc='upper left')
    125 
    126         print("Results Ready")
    12769        if out:
    12870                plt.savefig(out)
     
    13476        # ================================================================================
    13577        # 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")
     78        parser = parser = argparse.ArgumentParser(description='Python Script to draw R.M.I.T. results')
     79        parser.add_argument('-f', '--file', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
     80        parser.add_argument('-o', '--out', nargs='?', type=str, default=None)
     81        parser.add_argument('-y', nargs='?', type=str, default="")
    14182
    142         options =  parser.parse_args()
     83        try:
     84                options =  parser.parse_args()
     85        except:
     86                print('ERROR: invalid arguments', file=sys.stderr)
     87                parser.print_help(sys.stderr)
     88                sys.exit(1)
    14389
    14490        # ================================================================================
     
    164110        if not options.out :
    165111                print(series)
    166                 print("fields: ", ' '.join(fields))
     112                print("fields")
     113                for f in fields:
     114                        print("{}".format(f))
    167115
    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)
     116        if options.y and options.y in field_names.keys():
     117                plot(data, "Number of processors", options.y, options.out)
     118        else:
     119                if options.y:
     120                        print("Could not find key '{}', defaulting to 'ns per ops'".format(options.y))
     121                plot(data, "Number of processors", "ns per ops", options.out)
Note: See TracChangeset for help on using the changeset viewer.