aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn B. Brandenburg <bbb@cs.unc.edu>2010-10-09 22:01:02 -0400
committerBjörn B. Brandenburg <bbb@cs.unc.edu>2010-10-09 22:01:02 -0400
commit5c0c56cbb9ee7e983275d016d9d95da6e175760b (patch)
tree2696a0c40c2f80c21482fb02c8e33369ab942215
parent58a0ab886ec6a9647a8ee4f5639d21ef8e7bbed8 (diff)
add utility to aggregate and split weighted schedulability experiments
-rwxr-xr-xwsched.py185
1 files changed, 185 insertions, 0 deletions
diff --git a/wsched.py b/wsched.py
new file mode 100755
index 0000000..8214bf0
--- /dev/null
+++ b/wsched.py
@@ -0,0 +1,185 @@
1#!/usr/bin/env python
2
3import defapp
4from optparse import make_option as o
5from os.path import splitext, basename
6
7import sys
8
9from util import load_csv_file
10
11def split_rows(rows, key_col):
12 by_key_col = {}
13 key_order = []
14
15 # hash each row according by its key
16 for r in rows:
17 key = r[key_col]
18 if not key in by_key_col:
19 key_order.append(key)
20 by_key_col[key] = []
21 by_key_col[key].append(r)
22
23 return (by_key_col, key_order)
24
25
26def group(rows, key_col):
27 (by, order) = split_rows(rows, key_col)
28 for k in order:
29 yield (k, by[k])
30
31def aggregate_column(rows, key_col, aggregate_fun):
32 by_key, order = split_rows(rows, key_col)
33 for key in order:
34 yield aggregate_fun(by_key[key])
35
36
37def weighted_schedulability(data, key_col, ucap_col):
38 def wsched(rows):
39 # Every column except for the key_col and the ucap_col
40 # is presumed to be schedulability values.
41 key = rows[0][key_col]
42 cols = len(rows[0])
43 accum = [0.0 for _ in xrange(cols)]
44 norm = 0.0
45 umax = 0.0
46 for r in rows:
47 ucap = r[ucap_col]
48 umax = max(ucap, umax)
49 norm += ucap
50 for i, val in enumerate(r):
51 if i != key_col and i != ucap_col:
52 accum[i] += ucap * val
53 return [(accum[i] / norm) if i != key_col and i != ucap_col
54 else (key if i == key_col else umax) for i in xrange(cols)]
55
56 return aggregate_column(data, key_col, wsched)
57
58
59def print_row(row, out, fmt):
60 out.write(", ".join(fmt % d for d in row))
61 out.write("\n")
62
63def filter_wsched(fname, key, ucap, out=sys.stdout, fmt="%10.3f"):
64 data = load_csv_file(fname, dtype=float)
65 for row in weighted_schedulability(data, key, ucap):
66 print_row(row, out, fmt)
67 out.flush()
68
69def filter_comments(fname, is_comment=lambda line: line and line[0] == '#',
70 out=sys.stdout):
71 f = open(fname, 'r')
72 for line in f:
73 if is_comment(line):
74 out.write(line)
75 out.flush()
76 f.close()
77
78options = [
79 # output options
80 o('-o', '--output-prefix', action='store', dest='prefix'),
81 o('-k', '--key-column', action='store', type='int', dest='keycol'),
82 o('-u', '--ucap-column', action='store', type='int', dest='ucol'),
83 o(None, '--no-comments', action='store_true', dest='no_comments'),
84 o('-w', '--col-width', action='store', type='int', dest='colwidth'),
85 o(None, '--split', action='store_true', dest='want_split'),
86 ]
87
88defaults = {
89 'prefix' : None,
90 'keycol' : 0,
91 'ucol' : 1,
92 'no_comments' : False,
93 'colwidth' : 10,
94 'precision' : 3,
95 'indent' : 2,
96 'key_fmt' : "_key=%d",
97 'want_split' : False,
98 }
99
100
101class WschedFilter(defapp.App):
102 def __init__(self):
103 defapp.App.__init__(self, options, defaults, no_std_opts=True)
104 self.out = sys.stdout
105
106
107 def filter_wsched(self, fname, out=sys.stdout):
108 data = load_csv_file(fname, dtype=float)
109 for row in weighted_schedulability(
110 data, self.options.keycol, self.options.ucol):
111 out.write(" " * self.options.indent)
112 out.write(", ".join(self.fmt % d for d in row))
113 out.write("\n")
114 out.flush()
115
116 def target_name(self, fname, extra=None):
117 bname = basename(fname)
118 if extra:
119 bname, ext = splitext(bname)
120 bname = "%s%s%s" % (bname, extra, ext)
121 return self.options.prefix + bname
122
123 def filter_file(self, fin, fout=None):
124 out = open(fout, 'w') if fout else sys.stdout
125 if not self.options.no_comments:
126 filter_comments(fin, out=out)
127 self.filter_wsched(fin, out=out)
128 if fout:
129 out.close()
130
131 def write_split(self, fin, fout, rows):
132 out = open(fout, 'w')
133 if not self.options.no_comments:
134 filter_comments(fin, out=out)
135 for r in rows:
136 print_row(r, out, self.fmt)
137 out.close()
138
139 def split_file(self, fname):
140 data = load_csv_file(fname, dtype=float)
141 for (key, rows) in group(data, self.options.keycol):
142 fout = self.target_name(fname, self.options.key_fmt % key)
143 print '\t->', fout
144 self.write_split(fname, fout, rows)
145
146 def wsched(self, _):
147 if self.options.prefix:
148 for i, datafile in enumerate(self.args):
149 fout = self.target_name(datafile)
150 print "[%d/%d] %s -> %s" % \
151 (i + 1, len(self.args), datafile, fout)
152 try:
153 self.filter_file(datafile, fout)
154 except IOError as ioe:
155 sys.stderr.write("[!!] ")
156 sys.stderr.write(str(ioe))
157 sys.stderr.write("\n")
158 else:
159 for fname in self.args:
160 self.filter_file(fname)
161
162 def split(self, _):
163 if self.options.prefix:
164 for i, datafile in enumerate(self.args):
165 print "[%d/%d] Splitting %s..." % \
166 (i + 1, len(self.args), datafile)
167 try:
168 self.split_file(datafile)
169 except IOError as ioe:
170 sys.stderr.write("[!!] ")
171 sys.stderr.write(str(ioe))
172 sys.stderr.write("\n")
173 else:
174 print "split: requires output prefix (-o)."
175
176 def default(self, _):
177 self.fmt = "%%%d.%df" % (self.options.colwidth, self.options.precision)
178 if self.options.want_split:
179 self.split(_)
180 else:
181 self.wsched(_)
182
183if __name__ == '__main__':
184 WschedFilter().launch()
185