aboutsummaryrefslogtreecommitdiffstats
path: root/parse
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-09-27 19:03:22 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2012-09-27 19:03:22 -0400
commit7c09ec981c6e06af2e62d67a609eb53728267954 (patch)
tree76a93db7cadc452ac70eabbd52fdd87ed5fd54c4 /parse
parent5554e053e9f3d5f7987d3f1d889802b211af8eab (diff)
Added script to parse directory data, create CSVs for every chagned value.
This change also makes SchedTrace and OverheadTrace events configurable.
Diffstat (limited to 'parse')
-rw-r--r--parse/__init__.py0
-rw-r--r--parse/dir_map.py104
-rw-r--r--parse/enum.py7
-rw-r--r--parse/ft.py60
-rw-r--r--parse/point.py135
-rw-r--r--parse/sched.py89
-rw-r--r--parse/tuple_table.py76
7 files changed, 471 insertions, 0 deletions
diff --git a/parse/__init__.py b/parse/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/parse/__init__.py
diff --git a/parse/dir_map.py b/parse/dir_map.py
new file mode 100644
index 0000000..6e959f2
--- /dev/null
+++ b/parse/dir_map.py
@@ -0,0 +1,104 @@
1import os
2
3from collections import defaultdict
4from point import Type
5
6class TreeNode(object):
7 def __init__(self, parent = None):
8 self.parent = parent
9 self.children = defaultdict(lambda : TreeNode(self))
10 self.values = []
11
12class DirMap(object):
13 def to_csv(self, vals):
14 val_strs = []
15 for key in sorted(vals.keys()):
16 val_strs += ["%s=%s" % (key, vals[key])]
17 return "%s.csv" % ("_".join(val_strs))
18
19 def __init__(self, out_dir):
20 self.root = TreeNode(None)
21 self.out_dir = out_dir
22 self.values = []
23
24 def debug_update_node(self, path, keys, value):
25 self.__update_node(path, keys, value)
26
27 def __update_node(self, path, keys, value):
28 node = self.root
29
30 path += [ self.to_csv(keys) ]
31 for p in path:
32 node = node.children[p]
33
34 node.values += [value]
35
36 def add_point(self, vary, vary_value, keys, point):
37 for stat in point.get_stats():
38 summary = point[stat]
39
40 for summary_type in Type:
41 measurement = summary[summary_type]
42
43 for base_type in Type:
44 if not base_type in measurement:
45 continue
46 # Ex: wcet/avg/max/vary-type/other-stuff.csv
47 path = [ stat, summary_type, base_type, "vary-%s" % vary ]
48 result = measurement[base_type]
49
50 self.__update_node(path, keys, (vary_value, result))
51
52
53
54 def reduce(self):
55 def reduce2(node):
56 for key in node.children.keys():
57 child = node.children[key]
58 reduce2(child)
59 if not (child.children or child.values):
60 node.children.pop(key)
61
62 if len(node.values) == 1:
63 node.values = []
64
65 reduce2(self.root)
66
67 def write(self):
68 def write2(path, node):
69 out_path = "/".join(path)
70 if node.values:
71 # Leaf
72 with open("/".join(path), "w") as f:
73 arr = [",".join([str(b) for b in n]) for n in node.values]
74 f.write("\n".join(arr) + "\n")
75 elif not os.path.isdir(out_path):
76 os.mkdir(out_path)
77
78 for (key, child) in node.children.iteritems():
79 path.append(key)
80 write2(path, child)
81 path.pop()
82
83
84 write2([self.out_dir], self.root)
85
86
87 def __str__(self):
88 def str2(node, level):
89 header = " " * level
90 ret = ""
91 if not node.children:
92 return "%s%s\n" % (header, str(node.values) if node.values else "")
93 for key,child in node.children.iteritems():
94 ret += "%s/%s\n" % (header, key)
95 ret += str2(child, level + 1)
96 return ret
97
98 return "%s\n%s" % (self.out_dir, str2(self.root, 1))
99
100
101
102
103
104
diff --git a/parse/enum.py b/parse/enum.py
new file mode 100644
index 0000000..bf35d01
--- /dev/null
+++ b/parse/enum.py
@@ -0,0 +1,7 @@
1class Enum(frozenset):
2 def __getattr__(self, name):
3 if name in self:
4 return name
5 raise AttributeError
6
7
diff --git a/parse/ft.py b/parse/ft.py
new file mode 100644
index 0000000..9837898
--- /dev/null
+++ b/parse/ft.py
@@ -0,0 +1,60 @@
1import config.config as conf
2import os
3import re
4import shutil as sh
5import subprocess
6
7from point import Measurement,Type
8
9def get_ft_output(data_dir, out_dir):
10 bin_file = conf.FILES['ft_data'] + "$"
11 bins = [f for f in os.listdir(data_dir) if re.match(bin_file, f)]
12
13 FT_DATA_NAME = "scheduler=x-ft"
14 output_file = "{}/out-ft".format(out_dir)
15
16 if os.path.isfile(output_file):
17 print("ft-output already exists for %s" % data_dir)
18 return output_file
19
20 if len(bins) != 0:
21 err_file = open("%s/err-ft" % out_dir, 'w')
22 # Need to make a copy of the original data file so scripts can change it
23 sh.copyfile("{}/{}".format(data_dir, bins[0]),
24 "{}/{}".format(out_dir, FT_DATA_NAME))
25
26 subprocess.call([conf.BINS['sort'], FT_DATA_NAME],
27 cwd=out_dir, stderr=err_file, stdout=err_file)
28 subprocess.call([conf.BINS['split'], FT_DATA_NAME],
29 cwd=out_dir, stderr=err_file, stdout=err_file)
30
31 # Previous subprocesses just spit out all these intermediate files
32 bins = [f for f in os.listdir(out_dir) if re.match(".*overhead=.*bin", f)]
33 bins = [f for f in bins if os.stat("%s/%s"%(out_dir, f)).st_size]
34
35 # Analyze will summarize those
36 cmd_arr = [conf.BINS['analyze']]
37 cmd_arr.extend(bins)
38 with open(output_file, "w") as f:
39 subprocess.call(cmd_arr, cwd=out_dir, stdout=f, stderr=err_file)
40 else:
41 return None
42 return output_file
43
44def get_ft_data(data_file, result, overheads):
45 rstr = r",(?:\s+[^\s]+){3}.*?([\d\.]+).*?([\d\.]+),(?:\s+[^\s]+){3}.*?([\d\.]+)"
46
47 with open(data_file) as f:
48 data = f.read()
49
50 for ovh in overheads:
51 measure = Measurement("%s-%s" % (data_file, ovh))
52 vals = re.findall(".*{}".format(ovh) + rstr, data);
53 if len(vals) != 0:
54 vals = vals[0]
55 measure[Type.Max] = float(vals[0])
56 measure[Type.Avg] = float(vals[1])
57 measure[Type.Var] = float(vals[2])
58 result[ovh] = measure
59
60 return result
diff --git a/parse/point.py b/parse/point.py
new file mode 100644
index 0000000..4343d03
--- /dev/null
+++ b/parse/point.py
@@ -0,0 +1,135 @@
1"""
2Too much duplicate code in this file
3"""
4
5import copy
6import numpy as np
7from enum import Enum
8from collections import defaultdict
9
10Type = Enum(['Min','Max','Avg','Var'])
11default_typemap = {Type.Max : {Type.Max : 1, Type.Min : 0, Type.Avg : 1, Type.Var : 1},
12 Type.Min : {Type.Max : 1, Type.Min : 0, Type.Avg : 1, Type.Var : 1},
13 Type.Avg : {Type.Max : 1, Type.Min : 0, Type.Avg : 1, Type.Var : 1}}
14
15def make_typemap():
16 return copy.deepcopy(default_typemap)
17
18def dict_str(adict, sep = "\n"):
19 return sep.join(["%s: %s" % (k, str(v)) for (k,v) in adict.iteritems()])
20
21class Measurement(object):
22 def __init__(self, id = None, kv = {}):
23 self.id = id
24 self.stats = {}
25 for k, v in kv.iteritems():
26 self[k] = v
27
28 def from_array(self,array):
29 array = np.array(array)
30 self[Type.Max] = array.max()
31 self[Type.Avg] = array.mean()
32 self[Type.Var] = array.var()
33 return self
34
35 def __check_type(self, type):
36 if not type in Type: