diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-10-29 21:48:23 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-10-29 21:48:23 -0400 |
commit | 2e804f8fa7d26755088e47357f8de6feb6dbe292 (patch) | |
tree | 5e96c664fcd2b072d80ad06808371dd0ceb61505 | |
parent | 5b50c58ea4881dd185897dfa93860c60f551d815 (diff) |
Added option to output parsed data as a python-parseable map.
-rw-r--r-- | parse/point.py | 9 | ||||
-rw-r--r-- | parse/sched.py | 5 | ||||
-rw-r--r-- | parse/tuple_table.py | 41 | ||||
-rwxr-xr-x | parse_exps.py | 25 |
4 files changed, 62 insertions, 18 deletions
diff --git a/parse/point.py b/parse/point.py index 8fdd115..d5f4a5e 100644 --- a/parse/point.py +++ b/parse/point.py | |||
@@ -37,12 +37,13 @@ class Measurement(object): | |||
37 | self[Type.Max] = array.max() | 37 | self[Type.Max] = array.max() |
38 | self[Type.Avg] = array.mean() | 38 | self[Type.Avg] = array.mean() |
39 | self[Type.Var] = array.var() | 39 | self[Type.Var] = array.var() |
40 | self[Type.Min] = array.min() | ||
40 | return self | 41 | return self |
41 | 42 | ||
42 | def __check_type(self, type): | 43 | def __check_type(self, type): |
43 | if not type in Type: | 44 | if not type in Type: |
44 | raise AttributeError("Not a valid type '%s'" % type) | 45 | raise AttributeError("Not a valid type '%s'" % type) |
45 | 46 | ||
46 | def __getitem__(self, type): | 47 | def __getitem__(self, type): |
47 | self.__check_type(type) | 48 | self.__check_type(type) |
48 | return self.stats[type] | 49 | return self.stats[type] |
@@ -60,11 +61,11 @@ class Measurement(object): | |||
60 | 61 | ||
61 | def __str__(self): | 62 | def __str__(self): |
62 | return "%s" % dict_str(self.stats, " ") | 63 | return "%s" % dict_str(self.stats, " ") |
63 | 64 | ||
64 | 65 | ||
65 | class Summary(Measurement): | 66 | class Summary(Measurement): |
66 | def __init__(self, id, measures, typemap = default_typemap): | 67 | def __init__(self, id, measures, typemap = default_typemap): |
67 | super(Summary, self).__init__("Summary-%s" % id) | 68 | super(Summary, self).__init__(id) |
68 | 69 | ||
69 | self.__check_types(measures, typemap) | 70 | self.__check_types(measures, typemap) |
70 | self.__summarize(measures, typemap) | 71 | self.__summarize(measures, typemap) |
@@ -108,7 +109,7 @@ class ExpPoint(object): | |||
108 | def __check_val(self, obj): | 109 | def __check_val(self, obj): |
109 | if not isinstance(obj, Measurement): | 110 | if not isinstance(obj, Measurement): |
110 | raise AttributeError("Not a valid measurement '%s'" % obj) | 111 | raise AttributeError("Not a valid measurement '%s'" % obj) |
111 | 112 | ||
112 | def __getitem__(self, type): | 113 | def __getitem__(self, type): |
113 | return self.stats[type] | 114 | return self.stats[type] |
114 | 115 | ||
diff --git a/parse/sched.py b/parse/sched.py index cbb051e..80764b6 100644 --- a/parse/sched.py +++ b/parse/sched.py | |||
@@ -1,6 +1,9 @@ | |||
1 | """ | 1 | """ |
2 | TODO: No longer very pythonic, lot of duplicate code | 2 | TODO: No longer very pythonic, lot of duplicate code |
3 | print out task execution times | 3 | print out task execution times or something |
4 | get miss ratio and tardiness directly from schedule OR | ||
5 | email list about turning on optional summary statistics OR | ||
6 | set up run exps to only get release and completions to get these stats | ||
4 | """ | 7 | """ |
5 | 8 | ||
6 | import config.config as conf | 9 | import config.config as conf |
diff --git a/parse/tuple_table.py b/parse/tuple_table.py index 434eb22..465abb3 100644 --- a/parse/tuple_table.py +++ b/parse/tuple_table.py | |||
@@ -1,7 +1,9 @@ | |||
1 | from collections import defaultdict | 1 | from collections import defaultdict |
2 | from point import SummaryPoint | 2 | from point import SummaryPoint,Type |
3 | from dir_map import DirMap | 3 | from dir_map import DirMap |
4 | 4 | ||
5 | from pprint import pprint | ||
6 | |||
5 | class ColMap(object): | 7 | class ColMap(object): |
6 | def __init__(self): | 8 | def __init__(self): |
7 | self.rev_map = {} | 9 | self.rev_map = {} |
@@ -31,13 +33,16 @@ class ColMap(object): | |||
31 | map[self.col_list[i]] = tuple[i] | 33 | map[self.col_list[i]] = tuple[i] |
32 | return map | 34 | return map |
33 | 35 | ||
36 | def force_add(self, column): | ||
37 | self.rev_map[column] = len(self.col_list) | ||
38 | self.col_list += [column] | ||
39 | |||
34 | def try_add(self, column, value): | 40 | def try_add(self, column, value): |
35 | if column not in self.rev_map: | 41 | if column not in self.rev_map: |
36 | if column not in self.value_map: | 42 | if column not in self.value_map: |
37 | self.value_map[column] = value | 43 | self.value_map[column] = value |
38 | elif value != self.value_map[column]: | 44 | elif value != self.value_map[column]: |
39 | self.rev_map[column] = len(self.col_list) | 45 | self.force_add(column) |
40 | self.col_list += [column] | ||
41 | 46 | ||
42 | def __str__(self): | 47 | def __str__(self): |
43 | return "<ColMap>%s" % (self.rev_map) | 48 | return "<ColMap>%s" % (self.rev_map) |
@@ -53,6 +58,9 @@ class TupleTable(object): | |||
53 | key = self.col_map.get_key(kv) | 58 | key = self.col_map.get_key(kv) |
54 | self.table[key] += [point] | 59 | self.table[key] += [point] |
55 | 60 | ||
61 | def col_map(self): | ||
62 | return self.col_map | ||
63 | |||
56 | def get_exps(self, kv): | 64 | def get_exps(self, kv): |
57 | key = self.col_map.get_key(kv) | 65 | key = self.col_map.get_key(kv) |
58 | return self.table[key] | 66 | return self.table[key] |
@@ -66,9 +74,32 @@ class TupleTable(object): | |||
66 | raise Exception("cannot reduce twice!") | 74 | raise Exception("cannot reduce twice!") |
67 | self.reduced = True | 75 | self.reduced = True |
68 | for key, values in self.table.iteritems(): | 76 | for key, values in self.table.iteritems(): |
69 | self.table[key] = SummaryPoint(str(key), values) | 77 | self.table[key] = SummaryPoint(values[0].id, values) |
70 | 78 | ||
71 | def write_result(self, out_dir): | 79 | def write_map(self, out_map): |
80 | if not self.reduced: | ||
81 | raise Exception("must reduce table to write map!") | ||
82 | |||
83 | rows = {} | ||
84 | |||
85 | for key, point in self.table.iteritems(): | ||
86 | row = {} | ||
87 | for name,measurement in point: | ||
88 | name = name.lower().replace('_','-') | ||
89 | row[name]={} | ||
90 | for base_type in Type: | ||
91 | type_key = str(base_type).lower() | ||
92 | if base_type in measurement[Type.Avg]: | ||
93 | value = measurement[Type.Avg][base_type] | ||
94 | row[name][type_key] = value | ||
95 | rows[key] = row | ||
96 | |||
97 | result = {'columns': self.col_map.columns(), 'rows':rows} | ||
98 | |||
99 | with open(out_map, 'wc') as map_file: | ||
100 | pprint(result,stream=map_file, width=20) | ||
101 | |||
102 | def write_csvs(self, out_dir): | ||
72 | dir_map = DirMap(out_dir) | 103 | dir_map = DirMap(out_dir) |
73 | 104 | ||
74 | for key, point in self.table.iteritems(): | 105 | for key, point in self.table.iteritems(): |
diff --git a/parse_exps.py b/parse_exps.py index aa203d3..2d1c370 100755 --- a/parse_exps.py +++ b/parse_exps.py | |||
@@ -16,10 +16,12 @@ from parse.point import ExpPoint | |||
16 | from parse.tuple_table import ColMap,TupleTable | 16 | from parse.tuple_table import ColMap,TupleTable |
17 | 17 | ||
18 | def parse_args(): | 18 | def parse_args(): |
19 | # TODO: convert data-dir to proper option | ||
19 | parser = OptionParser("usage: %prog [options] [data_dir]...") | 20 | parser = OptionParser("usage: %prog [options] [data_dir]...") |
20 | 21 | ||
21 | parser.add_option('-o', '--out-dir', dest='out_dir', | 22 | parser.add_option('-o', '--out', dest='out', |
22 | help='directory for data output', default='parse-data') | 23 | help='file or directory for data output', default='parse-data') |
24 | |||
23 | # TODO: this means nothing | 25 | # TODO: this means nothing |
24 | parser.add_option('-c', '--clean', action='store_true', default=False, | 26 | parser.add_option('-c', '--clean', action='store_true', default=False, |
25 | dest='clean', help='do not output single-point csvs') | 27 | dest='clean', help='do not output single-point csvs') |
@@ -30,6 +32,9 @@ def parse_args(): | |||
30 | dest='force', help='overwrite existing data') | 32 | dest='force', help='overwrite existing data') |
31 | parser.add_option('-v', '--verbose', action='store_true', default=False, | 33 | parser.add_option('-v', '--verbose', action='store_true', default=False, |
32 | dest='verbose', help='print out data points') | 34 | dest='verbose', help='print out data points') |
35 | parser.add_option('-m', '--write-map', action='store_true', default=False, | ||
36 | dest='write_map', | ||
37 | help='Output map of values instead of csv tree') | ||
33 | 38 | ||
34 | return parser.parse_args() | 39 | return parser.parse_args() |
35 | 40 | ||
@@ -102,8 +107,8 @@ def main(): | |||
102 | raise IOError("Base column '%s' not present in any parameters!" % | 107 | raise IOError("Base column '%s' not present in any parameters!" % |
103 | base_conf.keys()[0]) | 108 | base_conf.keys()[0]) |
104 | 109 | ||
105 | base_table = TupleTable(col_map) | 110 | base_table = TupleTable(col_map) # For tracking 'base' experiments |
106 | result_table = TupleTable(col_map) | 111 | result_table = TupleTable(col_map) # For generating csv directories |
107 | 112 | ||
108 | # Used to find matching scaling_base for each experiment | 113 | # Used to find matching scaling_base for each experiment |
109 | for base in scaling_bases: | 114 | for base in scaling_bases: |
@@ -133,13 +138,17 @@ def main(): | |||
133 | if opts.verbose: | 138 | if opts.verbose: |
134 | print(result) | 139 | print(result) |
135 | 140 | ||
136 | if opts.force and os.path.exists(opts.out_dir): | 141 | if opts.force and os.path.exists(opts.out): |
137 | sh.rmtree(opts.out_dir) | 142 | sh.rmtree(opts.out) |
138 | 143 | ||
139 | # Remove un-plottable values | ||
140 | result_table.reduce() | 144 | result_table.reduce() |
141 | 145 | ||
142 | result_table.write_result(opts.out_dir) | 146 | if opts.write_map: |
147 | # Write summarized results into map | ||
148 | result_table.write_map(opts.out) | ||
149 | else: | ||
150 | # Write out csv directories for all variable params | ||
151 | result_table.write_csvs(opts.out) | ||
143 | 152 | ||
144 | if __name__ == '__main__': | 153 | if __name__ == '__main__': |
145 | main() | 154 | main() |