benchmark silo added
[c11concurrency-benchmarks.git] / silo / benchmarks / results / make_graphs-3.py
diff --git a/silo/benchmarks/results/make_graphs-3.py b/silo/benchmarks/results/make_graphs-3.py
new file mode 100755 (executable)
index 0000000..b482606
--- /dev/null
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+
+import matplotlib
+import pylab as plt
+import numpy as np
+
+import os
+import sys
+import math
+
+if __name__ == '__main__':
+  files = sys.argv[1:]
+  for f in files:
+    execfile(f)
+
+    #names = ['scale', 'multipart:pct', 'multipart:cpu']
+
+    def deal_with_posK_res(k, x):
+      if type(x) == list:
+        return [e[k] for e in x]
+      return x[k]
+
+    def deal_with_pos0_res(x):
+      return deal_with_posK_res(0, x)
+
+    def deal_with_pos1_res(x):
+      return deal_with_posK_res(1, x)
+
+    import re
+    RGX = re.compile(r'--new-order-remote-item-pct (\d+)')
+    def extract_pct(x):
+      m = RGX.search(x)
+      assert m
+      p = int(m.group(1))
+      assert p >= 0 and p <= 100
+      def pn(n, p):
+        return 1.0 - (1.0 - p)**n
+      def ex(p):
+        import math
+        return math.fsum([(1.0/11.0)*pn(float(n), p) for n in range(5, 16)])
+      return ex(p/100.0) * 100.0
+
+    def extract_p(x):
+      m = RGX.search(x)
+      assert m
+      p = int(m.group(1))
+      assert p >= 0 and p <= 100
+      return p
+
+    def multipart_cpu_process(config):
+      assert config['db'] == 'ndb-proto2' or \
+             config['db'] == 'kvdb'
+      if config['db'] == 'ndb-proto2':
+        return config['threads']
+      else:
+        return 8
+
+    def readonly_lines_func(config):
+      if 'disable-read-only-snapshots' in config['bench_opts']:
+        return 'No-Snapshots'
+      else:
+        return 'Snapshots'
+
+    def MFormatter(x, p):
+      if x == 0:
+        return '0'
+      v = float(x)/float(10**6)
+      if math.ceil(v) == v:
+        return '%dM' % v
+      return '%.1fM' % v
+
+    def KFormatter(x, p):
+      if x == 0:
+        return '0'
+      v = float(x)/float(10**3)
+      if math.ceil(v) == v:
+        return '%dK' % v
+      return '%.1fK' % v
+
+    descs = [
+      {
+        'name' : 'scale',
+        'x-axis' : 'threads',
+        'x-axis-func' : lambda x: x,
+        'y-axis' : deal_with_pos0_res,
+        'lines' : ['db'], # each line holds this constant
+        'x-label' : 'threads',
+        'y-label' : 'throughput (txns/sec)',
+        'y-axis-major-formatter' : matplotlib.ticker.FuncFormatter(MFormatter),
+        'x-axis-set-major-locator' : True,
+        #'title' : 'ycsb throughput graph',
+      },
+      {
+        'name' : 'scale_tpcc',
+        'x-axis' : 'threads',
+        'x-axis-func' : lambda x: x,
+        'y-axis' : deal_with_pos0_res,
+        'lines' : ['db'], # each line holds this constant
+        'x-label' : 'threads',
+        'y-label' : 'throughput (txns/sec)',
+        'y-axis-major-formatter' : matplotlib.ticker.FuncFormatter(MFormatter),
+        'x-axis-set-major-locator' : True,
+        #'title' : 'tpcc throughput graph',
+      },
+      {
+        'name' : 'multipart:pct',
+        'x-axis' : 'bench_opts',
+        'x-axis-func' : extract_pct,
+        'y-axis' : deal_with_pos0_res,
+        'lines' : ['db'], # each line holds this constant
+        'x-label' : '% cross-partition',
+        'y-label' : 'throughput (txns/sec)',
+        'y-axis-major-formatter' : matplotlib.ticker.FuncFormatter(MFormatter),
+        'x-axis-set-major-locator' : False,
+        #'title' : 'tpcc new-order throughput graph',
+        'legend' : 'upper right',
+      },
+      #{
+      #  'name' : 'multipart:cpu',
+      #  'x-axis-process' : multipart_cpu_process,
+      #  'y-axis' : deal_with_pos0_res,
+      #  'lines' : ['db'], # each line holds this constant
+      #  'x-label' : 'num threads',
+      #  'y-label' : 'txns/sec',
+      #  'title' : 'tpcc full workload throughput graph',
+      #},
+      {
+        'name' : 'readonly',
+        'x-axis' : 'bench_opts',
+        'x-axis-func' : extract_p,
+        'y-axis' : deal_with_pos0_res,
+        'lines-func' : readonly_lines_func,
+        'x-label' : '% remote warehouse stock',
+        'y-label' : 'throughput (txns/sec)',
+        'y-axis-major-formatter' : matplotlib.ticker.FuncFormatter(KFormatter),
+        'x-axis-set-major-locator' : True,
+        #'title' : 'tpcc read only throughput graph',
+        'legend' : 'right',
+      },
+    ]
+
+    def label_transform(x):
+      if x == 'kvdb':
+        return 'Key-Value'
+      if x == 'ndb-proto1':
+        return 'Malflingo-Star'
+      if x == 'ndb-proto2':
+        return 'Malflingo'
+      if x == 'kvdb-st':
+        return 'Partitioned-Store'
+      return x
+
+    for desc in descs:
+      bench = desc['name']
+      bench_results = [d for d in RESULTS if d[0]['name'] == bench]
+      if not bench_results:
+        print >>sys.stderr, 'skipping bench %s' % bench
+        continue
+      lines = {}
+      for (config, result) in bench_results:
+        if 'lines-func' in desc:
+          key = desc['lines-func'](config)
+        else:
+          key = tuple(config[x] for x in desc['lines'])
+        pts = lines.get(key, {})
+        if 'x-axis-process' in desc:
+          xpt = desc['x-axis-process'](config)
+        else:
+          xpt = desc['x-axis-func'](config[desc['x-axis']])
+        assert xpt not in pts
+        pts[xpt] = desc['y-axis'](result)
+        lines[key] = pts
+
+      def mean(x): return sum(x)/len(x)
+      def median(x): return sorted(x)[len(x)/2]
+
+      # find min/max of xpts
+      xmin = min([e for l in lines.values() for e in l])
+      xmax = max([e for l in lines.values() for e in l])
+      #print xmin, xmax
+
+      labels = []
+      for (name, pts) in lines.iteritems():
+        spts = sorted(pts.iteritems(), key=lambda x: x[0])
+        ypts = [sorted(x[1]) for x in spts]
+        ymins = np.array([min(x) for x in ypts])
+        ymaxs = np.array([max(x) for x in ypts])
+        ymid = np.array([median(x) for x in ypts])
+        yerr=np.array([ymid - ymins, ymaxs - ymid])
+        xpts = [x[0] for x in spts]
+        assert len(xpts)
+        if len(xpts) == 1:
+          xpts = range(xmin, xmax + 1)
+          assert len(ymins) == 1
+          assert len(ymaxs) == 1
+          assert len(ymid) == 1
+          ymins = np.array([ymins[0] for _ in xpts])
+          ymaxs = np.array([ymaxs[0] for _ in xpts])
+          ymid = np.array([ymid[0] for _ in xpts])
+          yerr=np.array([ymid - ymins, ymaxs - ymid])
+
+        plt.errorbar(xpts, ymid, yerr=yerr)
+        if type(name) == str:
+          labels.append(label_transform(name))
+        else:
+          labels.append(label_transform('-'.join(name)))
+
+      ax = plt.gca()
+      if desc['x-axis-set-major-locator']:
+        ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(sorted(lines.values()[0].keys())))
+      if 'y-axis-major-formatter' in desc:
+        ax.yaxis.set_major_formatter(desc['y-axis-major-formatter'])
+
+      plt.xlabel(desc['x-label'])
+      plt.ylabel(desc['y-label'])
+      if 'title' in desc:
+        plt.title(desc['title'])
+
+      plt.xlim(xmin = xmin, xmax = xmax)
+      plt.ylim(ymin = 0)
+
+      placement = 'upper left' if not 'legend' in desc else desc['legend']
+      plt.legend(labels, loc=placement)
+      bname = '.'.join(os.path.basename(f).split('.')[:-1])
+      plt.savefig('.'.join([bname + '-' + bench, 'pdf']))
+      plt.close()