edit
[c11concurrency-benchmarks.git] / silo / scripts / tester.py
1 #!/usr/bin/env python
2
3 import itertools
4 import platform
5 import subprocess
6 import sys
7 import math
8 import pickle
9
10 def normalize(x):
11   denom = sum(x)
12   return [e/denom for e in x]
13
14 def scale(x, a):
15   return [e * a for e in x]
16
17 def argcmp(x, comp, predicate):
18   idx = None
19   val = None
20   for i in xrange(len(x)):
21     if not predicate(x[i]):
22       continue
23     if idx is None or comp(x[i], val):
24       idx = i
25       val = x[i]
26   if idx is None:
27     # couldn't find it
28     raise Exception("no argmin satisfiying predicate")
29   return idx
30
31 def argmin(x, predicate):
32   return argcmp(x, lambda a, b: a < b, predicate)
33
34 def argmax(x, predicate):
35   return argcmp(x, lambda a, b: a > b, predicate)
36
37 def allocate(nworkers, weights):
38   approx = map(int, map(math.ceil, scale(weights, nworkers)))
39   diff = sum(approx) - nworkers
40   if diff > 0:
41     while diff > 0:
42       i = argmin(approx, predicate=lambda x: x > 0)
43       approx[i] -= 1
44       diff -= 1
45   elif diff < 0:
46     i = argmax(approx, lambda x: True)
47     approx[i] += -diff
48   acc = 0
49   ret = []
50   for x in approx:
51     ret.append(range(acc, acc + x))
52     acc += x
53   return ret
54
55 def run(cmd):
56   print >>sys.stderr, '[INFO] running command %s' % str(cmd)
57   p = subprocess.Popen(cmd, stdin=open('/dev/null', 'r'), stdout=subprocess.PIPE)
58   r = p.stdout.read()
59   p.wait()
60   return r
61
62 if __name__ == '__main__':
63   (_, outfile) = sys.argv
64
65   STRATEGIES = ['epoch', 'epoch-compress']
66   NCORES = [1, 2, 4, 8, 16, 24, 32]
67   WSET = [18]
68
69   #STRATEGIES = ['epoch']
70   #NCORES = [1]
71   #WSET = [18]
72
73   node = platform.node()
74
75   if node == 'modis2':
76     LOGGERS = [
77         ('data.log', 1.),
78         ('/data/scidb/001/2/stephentu/data.log', 1.),
79         ('/data/scidb/001/3/stephentu/data.log', 1.),
80     ]
81   elif node == 'istc3':
82     LOGGERS = [
83         ('data.log', 1./3.),
84         ('/f0/stephentu/data.log', 2./3.),
85     ]
86   else:
87     print "unknown node", node
88     assert False, "Unknown node!"
89
90   weights = normalize([x[1] for x in LOGGERS])
91   logfile_cmds = list(itertools.chain.from_iterable([['--logfile', f] for f, _ in LOGGERS]))
92
93   results = []
94   for strat, ncores, ws in itertools.product(STRATEGIES, NCORES, WSET):
95     allocations = allocate(ncores, weights)
96     alloc_cmds = list(
97         itertools.chain.from_iterable([['--assignment', ','.join(map(str, alloc))] for alloc in allocations]))
98     cmd = ['./persist_test'] + \
99         logfile_cmds + \
100         alloc_cmds + \
101         ['--num-threads', str(ncores),
102          '--strategy', strat,
103          '--writeset', str(ws),
104          '--valuesize', '32']
105     output = run(cmd)
106     res = float(output.strip())
107     results.append(((strat, ncores, ws), res))
108
109   with open(outfile, 'w') as fp:
110     pickle.dump(results, fp)