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() |
