diff options
Diffstat (limited to 'parse/ft.py')
-rw-r--r-- | parse/ft.py | 132 |
1 files changed, 99 insertions, 33 deletions
diff --git a/parse/ft.py b/parse/ft.py index 4e310b0..cbf75f2 100644 --- a/parse/ft.py +++ b/parse/ft.py | |||
@@ -1,4 +1,5 @@ | |||
1 | import config.config as conf | 1 | import config.config as conf |
2 | import numpy as np | ||
2 | import os | 3 | import os |
3 | import re | 4 | import re |
4 | import shutil as sh | 5 | import shutil as sh |
@@ -6,14 +7,17 @@ import subprocess | |||
6 | 7 | ||
7 | from point import Measurement,Type | 8 | from point import Measurement,Type |
8 | 9 | ||
9 | def get_ft_output(data_dir, out_dir, force=False): | 10 | SPLIT_DATA_NAME = "overhead={}.bin" |
11 | FT_DATA_NAME = "sorted-ft.bin" | ||
12 | FIELDS = ["Overhead", "samples", "max", "avg", "min", "med", "std", "var"] | ||
13 | |||
14 | def get_ft_output(data_dir, cycles, out_dir, force=False): | ||
10 | """ | 15 | """ |
11 | Create and return files containing sorted and analyzed overhead data | 16 | Create and return file containing analyzed overhead data |
12 | """ | 17 | """ |
13 | bin_file = conf.FILES['ft_data'] + "$" | 18 | freg = conf.FILES['ft_data'] + "$" |
14 | bins = [f for f in os.listdir(data_dir) if re.match(bin_file, f)] | 19 | bins = [f for f in os.listdir(data_dir) if re.match(freg, f)] |
15 | 20 | ||
16 | FT_DATA_NAME = "scheduler=x-ft" | ||
17 | output_file = "{}/out-ft".format(out_dir) | 21 | output_file = "{}/out-ft".format(out_dir) |
18 | 22 | ||
19 | if os.path.isfile(output_file): | 23 | if os.path.isfile(output_file): |
@@ -23,44 +27,106 @@ def get_ft_output(data_dir, out_dir, force=False): | |||
23 | return output_file | 27 | return output_file |
24 | 28 | ||
25 | if len(bins) != 0: | 29 | if len(bins) != 0: |
30 | bin_file = "{}/{}".format(data_dir, bins[0]) | ||
26 | err_file = open("%s/err-ft" % out_dir, 'w') | 31 | err_file = open("%s/err-ft" % out_dir, 'w') |
27 | # Need to make a copy of the original data file so scripts can change it | 32 | |
28 | sh.copyfile("{}/{}".format(data_dir, bins[0]), | 33 | sorted_bin = sort_ft(bin_file, err_file, out_dir) |
29 | "{}/{}".format(out_dir, FT_DATA_NAME)) | 34 | make_data_file(sorted_bin, cycles, output_file, err_file, out_dir) |
30 | 35 | ||
31 | subprocess.call([conf.BINS['sort'], FT_DATA_NAME], | 36 | os.remove(sorted_bin) |
32 | cwd=out_dir, stderr=err_file, stdout=err_file) | 37 | |
33 | subprocess.call([conf.BINS['split'], FT_DATA_NAME], | 38 | return output_file |
34 | cwd=out_dir, stderr=err_file, stdout=err_file) | ||
35 | |||
36 | # Previous subprocesses just spit out all these intermediate files | ||
37 | bins = [f for f in os.listdir(out_dir) if re.match(".*overhead=.*bin", f)] | ||
38 | bins = [f for f in bins if os.stat("%s/%s"%(out_dir, f)).st_size] | ||
39 | |||
40 | # Analyze will summarize those | ||
41 | # todo pass in f | ||
42 | cmd_arr = [conf.BINS['analyze']] | ||
43 | cmd_arr.extend(bins) | ||
44 | with open(output_file, "w") as f: | ||
45 | subprocess.call(cmd_arr, cwd=out_dir, stdout=f, stderr=err_file) | ||
46 | else: | 39 | else: |
47 | return None | 40 | return None |
48 | return output_file | 41 | return output_file |
49 | 42 | ||
50 | def extract_ft_data(data_file, result, overheads): | 43 | def fmt_cell(x): |
51 | rstr = r",(?:\s+[^\s]+){3}.*?([\d\.]+).*?([\d\.]+),(?:\s+[^\s]+){3}.*?([\d\.]+)" | 44 | if type(x) == str: |
45 | return "%15s" % x | ||
46 | if type(x) == int: | ||
47 | return "%15d" % x | ||
48 | else: | ||
49 | return "%15.3f" % x | ||
50 | |||
51 | def make_data_file(sorted_bin, cycles, out_fname, err_file, out_dir): | ||
52 | """ | ||
53 | Create file containing all overhead information. | ||
54 | """ | ||
55 | base_name = "{}/{}".format(out_dir, SPLIT_DATA_NAME) | ||
56 | |||
57 | with open(out_fname, "w") as f: | ||
58 | f.write("#%s" % ", ".join(fmt_cell(x) for x in FIELDS)) | ||
59 | f.write("\n") | ||
60 | |||
61 | for event in conf.BASE_EVENTS: | ||
62 | ovh_fname = base_name.format(event.replace("_", "-")) | ||
63 | |||
64 | if os.path.exists(ovh_fname): | ||
65 | os.remove(ovh_fname) | ||
66 | ovh_file = open(ovh_fname, 'w') | ||
67 | |||
68 | # Extract matching overhead events into a seperate file | ||
69 | cmd = [conf.BINS["split"], "-r", "-b", event, sorted_bin] | ||
70 | ret = subprocess.call(cmd, cwd=out_dir, | ||
71 | stderr=err_file, stdout=ovh_file) | ||
72 | size = os.stat(ovh_fname).st_size | ||
73 | |||
74 | if ret: | ||
75 | err_file.write("Failed with command: %s" % " ".join(cmd)) | ||
76 | if not size: | ||
77 | os.remove(ovh_fname) | ||
78 | if not size or ret: | ||
79 | continue | ||
80 | |||
81 | # Map and sort file for stats | ||
82 | data = np.memmap(ovh_fname, dtype="float32", mode='c') | ||
83 | data /= float(cycles) # Scale for processor speed | ||
84 | data.sort() | ||
52 | 85 | ||
86 | stats = [event, len(data), data[-1], np.mean(data), data[0], | ||
87 | np.median(data), np.std(data, ddof=1), np.var(data)] | ||
88 | f.write(", ".join([fmt_cell(x) for x in stats])) | ||
89 | f.write("\n") | ||
90 | |||
91 | os.remove(ovh_fname) | ||
92 | |||
93 | def sort_ft(ft_file, err_file, out_dir): | ||
94 | """ | ||
95 | Create and return file with sorted overheads from @ft_file. | ||
96 | """ | ||
97 | out_fname = "{}/{}".format(out_dir, FT_DATA_NAME) | ||
98 | |||
99 | # Sort happens in-place | ||
100 | sh.copyfile(ft_file, out_fname) | ||
101 | cmd = [conf.BINS['ftsort'], out_fname] | ||
102 | ret = subprocess.call(cmd, cwd=out_dir, stderr=err_file, stdout=err_file) | ||
103 | |||
104 | if ret: | ||
105 | raise Exception("Sort failed with command: %s" % " ".join(cmd)) | ||
106 | |||
107 | return out_fname | ||
108 | |||
109 | def extract_ft_data(data_file, result, overheads): | ||
110 | """ | ||
111 | Return exp point with overhead measurements from data_file | ||
112 | """ | ||
53 | with open(data_file) as f: | 113 | with open(data_file) as f: |
54 | data = f.read() | 114 | data = f.read() |
55 | 115 | ||
56 | for ovh in overheads: | 116 | for ovh in overheads: |
117 | regex = r"({}[^\n]*)".format(ovh) | ||
118 | line = re.search(regex, data) | ||
119 | |||
120 | if not line: | ||
121 | continue | ||
122 | |||
123 | vals = re.split(r"[,\s]+", line.groups(1)[0]) | ||
124 | |||
57 | measure = Measurement("%s-%s" % (data_file, ovh)) | 125 | measure = Measurement("%s-%s" % (data_file, ovh)) |
58 | vals = re.findall(r"\s+{}".format(ovh.replace('_','-')) + rstr, data); | 126 | measure[Type.Max] = float(vals[FIELDS.index("max")]) |
59 | if len(vals) != 0: | 127 | measure[Type.Avg] = float(vals[FIELDS.index("avg")]) |
60 | vals = vals[0] | 128 | measure[Type.Var] = float(vals[FIELDS.index("var")]) |
61 | measure[Type.Max] = float(vals[0]) | 129 | |
62 | measure[Type.Avg] = float(vals[1]) | 130 | result[ovh] = measure |
63 | measure[Type.Var] = float(vals[2]) | ||
64 | result[ovh] = measure | ||
65 | 131 | ||
66 | return result | 132 | return result |