diff options
-rw-r--r-- | experiment/experiment.py | 2 | ||||
-rw-r--r-- | parse/ft.py | 12 | ||||
-rw-r--r-- | parse/sched.py | 8 | ||||
-rw-r--r-- | parse/tuple_table.py | 5 | ||||
-rwxr-xr-x | parse_exps.py | 26 | ||||
-rw-r--r-- | plot_exps.py | 21 | ||||
-rwxr-xr-x | run_exps.py | 49 |
7 files changed, 79 insertions, 44 deletions
diff --git a/experiment/experiment.py b/experiment/experiment.py index e6dc92d..f0c201d 100644 --- a/experiment/experiment.py +++ b/experiment/experiment.py | |||
@@ -197,7 +197,7 @@ class Experiment(object): | |||
197 | self.exec_out and self.exec_out.close() | 197 | self.exec_out and self.exec_out.close() |
198 | self.exec_err and self.exec_err.close() | 198 | self.exec_err and self.exec_err.close() |
199 | 199 | ||
200 | sleep_time = 5 | 200 | sleep_time = 10 |
201 | self.log("Sleeping %d seconds to allow buffer flushing" % sleep_time) | 201 | self.log("Sleeping %d seconds to allow buffer flushing" % sleep_time) |
202 | time.sleep(sleep_time) | 202 | time.sleep(sleep_time) |
203 | 203 | ||
diff --git a/parse/ft.py b/parse/ft.py index 127e49f..c915978 100644 --- a/parse/ft.py +++ b/parse/ft.py | |||
@@ -6,7 +6,10 @@ import subprocess | |||
6 | 6 | ||
7 | from point import Measurement,Type | 7 | from point import Measurement,Type |
8 | 8 | ||
9 | def get_ft_output(data_dir, out_dir): | 9 | def get_ft_output(data_dir, out_dir, force=False): |
10 | """ | ||
11 | Create and return files containing sorted and analyzed overhead data | ||
12 | """ | ||
10 | bin_file = conf.FILES['ft_data'] + "$" | 13 | bin_file = conf.FILES['ft_data'] + "$" |
11 | bins = [f for f in os.listdir(data_dir) if re.match(bin_file, f)] | 14 | bins = [f for f in os.listdir(data_dir) if re.match(bin_file, f)] |
12 | 15 | ||
@@ -14,8 +17,11 @@ def get_ft_output(data_dir, out_dir): | |||
14 | output_file = "{}/out-ft".format(out_dir) | 17 | output_file = "{}/out-ft".format(out_dir) |
15 | 18 | ||
16 | if os.path.isfile(output_file): | 19 | if os.path.isfile(output_file): |
17 | print("ft-output already exists for %s" % data_dir) | 20 | if force: |
18 | return output_file | 21 | os.remove(output_file) |
22 | else: | ||
23 | print("ft-output already exists for %s" % data_dir) | ||
24 | return output_file | ||
19 | 25 | ||
20 | if len(bins) != 0: | 26 | if len(bins) != 0: |
21 | err_file = open("%s/err-ft" % out_dir, 'w') | 27 | err_file = open("%s/err-ft" % out_dir, 'w') |
diff --git a/parse/sched.py b/parse/sched.py index 300c569..a65f001 100644 --- a/parse/sched.py +++ b/parse/sched.py | |||
@@ -50,7 +50,7 @@ class LeveledArray(object): | |||
50 | name = "%s%s" % ("%s-" % level if level else "", self.name) | 50 | name = "%s%s" % ("%s-" % level if level else "", self.name) |
51 | result[name] = Measurement(name).from_array(arr) | 51 | result[name] = Measurement(name).from_array(arr) |
52 | 52 | ||
53 | def get_st_output(data_dir, out_dir): | 53 | def get_st_output(data_dir, out_dir, force=False): |
54 | """ | 54 | """ |
55 | Create and return files containing unpacked sched data | 55 | Create and return files containing unpacked sched data |
56 | """ | 56 | """ |
@@ -60,7 +60,11 @@ def get_st_output(data_dir, out_dir): | |||
60 | output_file = "%s/out-st" % out_dir | 60 | output_file = "%s/out-st" % out_dir |
61 | 61 | ||
62 | if os.path.isfile(output_file): | 62 | if os.path.isfile(output_file): |
63 | return output_file | 63 | if force: |
64 | os.remove(output_file) | ||
65 | else: | ||
66 | print("st-output already exists for %s" % data_dir) | ||
67 | return output_file | ||
64 | 68 | ||
65 | if len(bins) != 0: | 69 | if len(bins) != 0: |
66 | cmd_arr = [conf.BINS['st_show']] | 70 | cmd_arr = [conf.BINS['st_show']] |
diff --git a/parse/tuple_table.py b/parse/tuple_table.py index e6f0cc5..5e98d87 100644 --- a/parse/tuple_table.py +++ b/parse/tuple_table.py | |||
@@ -24,7 +24,7 @@ class ColMap(object): | |||
24 | if added < len(kv): | 24 | if added < len(kv): |
25 | raise Exception("column map '%s' missed field in map '%s'" % | 25 | raise Exception("column map '%s' missed field in map '%s'" % |
26 | (self.col_list, kv)) | 26 | (self.col_list, kv)) |
27 | 27 | ||
28 | return key | 28 | return key |
29 | 29 | ||
30 | def __contains__(self, col): | 30 | def __contains__(self, col): |
@@ -58,7 +58,7 @@ class TupleTable(object): | |||
58 | key = self.col_map.get_key(kv) | 58 | key = self.col_map.get_key(kv) |
59 | return self.table[key] | 59 | return self.table[key] |
60 | 60 | ||
61 | def __reduce(self): | 61 | def reduce(self): |
62 | if self.reduced: | 62 | if self.reduced: |
63 | raise Exception("cannot reduce twice!") | 63 | raise Exception("cannot reduce twice!") |
64 | self.reduced = True | 64 | self.reduced = True |
@@ -67,7 +67,6 @@ class TupleTable(object): | |||
67 | 67 | ||
68 | def write_result(self, out_dir): | 68 | def write_result(self, out_dir): |
69 | dir_map = DirMap(out_dir) | 69 | dir_map = DirMap(out_dir) |
70 | self.__reduce() | ||
71 | for key, point in self.table.iteritems(): | 70 | for key, point in self.table.iteritems(): |
72 | kv = self.col_map.get_map(key) | 71 | kv = self.col_map.get_map(key) |
73 | 72 | ||
diff --git a/parse_exps.py b/parse_exps.py index 8f98309..1f36bab 100755 --- a/parse_exps.py +++ b/parse_exps.py | |||
@@ -7,6 +7,7 @@ import os | |||
7 | import parse.ft as ft | 7 | import parse.ft as ft |
8 | import parse.sched as st | 8 | import parse.sched as st |
9 | import re | 9 | import re |
10 | import shutil as sh | ||
10 | 11 | ||
11 | from collections import namedtuple | 12 | from collections import namedtuple |
12 | from common import load_params | 13 | from common import load_params |
@@ -18,10 +19,16 @@ def parse_args(): | |||
18 | parser = OptionParser("usage: %prog [options] [data_dir]...") | 19 | parser = OptionParser("usage: %prog [options] [data_dir]...") |
19 | 20 | ||
20 | parser.add_option('-o', '--out-dir', dest='out_dir', | 21 | parser.add_option('-o', '--out-dir', dest='out_dir', |
21 | help='directory for data output', default=os.getcwd()) | 22 | help='directory for data output', default='parse-data') |
23 | parser.add_option('-c', '--clean', action='store_true', default=False, | ||
24 | dest='clean', help='do not output single-point csvs') | ||
22 | parser.add_option('-s', '--scale-against', dest='scale_against', | 25 | parser.add_option('-s', '--scale-against', dest='scale_against', |
23 | metavar='PARAM=VALUE', default="", | 26 | metavar='PARAM=VALUE', default="", |
24 | help='calculate task scaling factors against these configs') | 27 | help='calculate task scaling factors against these configs') |
28 | parser.add_option('-f', '--force', action='store_true', default=False, | ||
29 | dest='force', help='overwrite existing data') | ||
30 | parser.add_option('-v', '--verbose', action='store_true', default=False, | ||
31 | dest='verbose', help='print out data points') | ||
25 | 32 | ||
26 | return parser.parse_args() | 33 | return parser.parse_args() |
27 | 34 | ||
@@ -46,7 +53,7 @@ def get_exp_params(data_dir, col_map): | |||
46 | return params | 53 | return params |
47 | 54 | ||
48 | 55 | ||
49 | def gen_exp_data(exp_dirs, base_conf, col_map): | 56 | def gen_exp_data(exp_dirs, base_conf, col_map, force): |
50 | plain_exps = [] | 57 | plain_exps = [] |
51 | scaling_bases = [] | 58 | scaling_bases = [] |
52 | 59 | ||
@@ -60,8 +67,8 @@ def gen_exp_data(exp_dirs, base_conf, col_map): | |||
60 | 67 | ||
61 | # Read and translate exp output files | 68 | # Read and translate exp output files |
62 | params = get_exp_params(data_dir, col_map) | 69 | params = get_exp_params(data_dir, col_map) |
63 | st_output = st.get_st_output(data_dir, tmp_dir) | 70 | st_output = st.get_st_output(data_dir, tmp_dir, force) |
64 | ft_output = ft.get_ft_output(data_dir, tmp_dir) | 71 | ft_output = ft.get_ft_output(data_dir, tmp_dir, force) |
65 | 72 | ||
66 | # Create experiment named after the data dir | 73 | # Create experiment named after the data dir |
67 | exp_data = ExpData(data_dir, params, DataFiles(ft_output, st_output)) | 74 | exp_data = ExpData(data_dir, params, DataFiles(ft_output, st_output)) |
@@ -88,7 +95,7 @@ def main(): | |||
88 | 95 | ||
89 | col_map = ColMap() | 96 | col_map = ColMap() |
90 | 97 | ||
91 | (plain_exps, scaling_bases) = gen_exp_data(args, base_conf, col_map) | 98 | (plain_exps, scaling_bases) = gen_exp_data(args, base_conf, col_map, opts.force) |
92 | 99 | ||
93 | if base_conf and base_conf.keys()[0] not in col_map: | 100 | if base_conf and base_conf.keys()[0] not in col_map: |
94 | raise IOError("Base column '%s' not present in any parameters!" % | 101 | raise IOError("Base column '%s' not present in any parameters!" % |
@@ -121,8 +128,15 @@ def main(): | |||
121 | 128 | ||
122 | result_table.add_exp(exp.params, result) | 129 | result_table.add_exp(exp.params, result) |
123 | 130 | ||
124 | print(result) | 131 | if opts.verbose: |
132 | print(result) | ||
125 | 133 | ||
134 | if opts.force and os.path.exists(opts.out_dir): | ||
135 | sh.rmtree(opts.out_dir) | ||
136 | |||
137 | # Remove un-plottable values | ||
138 | if opts.clean: | ||
139 | result_table.reduce() | ||
126 | 140 | ||
127 | result_table.write_result(opts.out_dir) | 141 | result_table.write_result(opts.out_dir) |
128 | 142 | ||
diff --git a/plot_exps.py b/plot_exps.py index e69de29..06f43b0 100644 --- a/plot_exps.py +++ b/plot_exps.py | |||
@@ -0,0 +1,21 @@ | |||
1 | #!/usr/bin/env python | ||
2 | from __future__ import print_function | ||
3 | |||
4 | from optparse import OptionParser | ||
5 | |||
6 | def parse_args(): | ||
7 | parser = OptionParser("usage: %prog [options] [csv_dir]...") | ||
8 | |||
9 | parser.add_option('-o', '--out-dir', dest='out_dir', | ||
10 | help='directory for plot output', default='plot-data') | ||
11 | parser.add_option('-f', '--force', action='store_true', default=False, | ||
12 | dest='force', help='overwrite existing data') | ||
13 | |||
14 | return parser.parse_args() | ||
15 | |||
16 | def main(): | ||
17 | opts, args = parse_args() | ||
18 | args = args or [os.getcwd()] | ||
19 | |||
20 | if __name__ == '__main__': | ||
21 | main() | ||
diff --git a/run_exps.py b/run_exps.py index 8f72adb..19dbad1 100755 --- a/run_exps.py +++ b/run_exps.py | |||
@@ -1,14 +1,11 @@ | |||
1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
2 | from __future__ import print_function | 2 | from __future__ import print_function |
3 | """ | ||
4 | TODO: no -f flag, instead allow individual schedules to be passed in. | ||
5 | -f flag now forced, which removes old data directories | ||
6 | """ | ||
7 | 3 | ||
8 | import config.config as conf | 4 | import config.config as conf |
9 | import experiment.litmus_util as lu | 5 | import experiment.litmus_util as lu |
10 | import os | 6 | import os |
11 | import re | 7 | import re |
8 | import shutil | ||
12 | import traceback | 9 | import traceback |
13 | 10 | ||
14 | from common import load_params | 11 | from common import load_params |
@@ -22,19 +19,21 @@ def InvalidKernel(Exception): | |||
22 | self.kernel = kernel | 19 | self.kernel = kernel |
23 | 20 | ||
24 | def parse_args(): | 21 | def parse_args(): |
25 | parser = OptionParser("usage: %prog [options] [sched_file]... [exp_dir]...]") | 22 | parser = OptionParser("usage: %prog [options] [sched_file]... [exp_dir]...") |
26 | 23 | ||
27 | parser.add_option('-s', '--scheduler', dest='scheduler', | 24 | parser.add_option('-s', '--scheduler', dest='scheduler', |
28 | help='scheduler for all experiments') | 25 | help='scheduler for all experiments') |
29 | parser.add_option('-d', '--duration', dest='duration', type='int', | 26 | parser.add_option('-d', '--duration', dest='duration', type='int', |
30 | help='duration (seconds) of tasks') | 27 | help='duration (seconds) of tasks') |
31 | parser.add_option('-o', '--out-dir', dest='out_dir', | 28 | parser.add_option('-o', '--out-dir', dest='out_dir', |
32 | help='directory for data output', default=os.getcwd()) | 29 | help='directory for data output', default="run-data") |
33 | parser.add_option('-p', '--params', dest='param_file', | 30 | parser.add_option('-p', '--params', dest='param_file', |
34 | help='file with experiment parameters') | 31 | help='file with experiment parameters') |
35 | parser.add_option('-f', '--schedule-file', dest='sched_file', | 32 | parser.add_option('-c', '--schedule-file', dest='sched_file', |
36 | help='name of schedule files', | 33 | help='name of schedule files within directories', |
37 | default=conf.DEFAULTS['sched_file']) | 34 | default=conf.DEFAULTS['sched_file']) |
35 | parser.add_option('-f', '--force', action='store_true', default=False, | ||
36 | dest='force', help='overwrite existing data') | ||
38 | 37 | ||
39 | return parser.parse_args() | 38 | return parser.parse_args() |
40 | 39 | ||
@@ -67,33 +66,21 @@ def convert_data(data): | |||
67 | 66 | ||
68 | return {'proc' : procs, 'spin' : spins} | 67 | return {'proc' : procs, 'spin' : spins} |
69 | 68 | ||
70 | def fix_paths(schedule, exp_dir): | 69 | def fix_paths(schedule, exp_dir, sched_file): |
71 | for (idx, (spin, args)) in enumerate(schedule['spin']): | 70 | for (idx, (spin, args)) in enumerate(schedule['spin']): |
72 | # Replace relative paths (if present) with absolute ones | 71 | # Replace relative paths (if present) with absolute ones |
73 | for arg in args.split(" "): | 72 | for arg in re.split(" +", args): |
74 | abspath = "%s/%s" % (exp_dir, arg) | 73 | abspath = "%s/%s" % (exp_dir, arg) |
75 | if os.path.exists(abspath): | 74 | if os.path.exists(abspath): |
76 | args = args.replace(arg, abspath) | 75 | args = args.replace(arg, abspath) |
77 | break | 76 | break |
77 | elif re.match(r'.*\w+\.\w+', arg): | ||
78 | print("WARNING: non-existent file '%s' may be referenced:\n\t%s" | ||
79 | % (arg, sched_file)) | ||
78 | 80 | ||
79 | schedule['spin'][idx] = (spin, args) | 81 | schedule['spin'][idx] = (spin, args) |
80 | 82 | ||
81 | def get_dirs(sched_file, out_base_dir): | 83 | def load_experiment(sched_file, scheduler, duration, param_file, out_dir): |
82 | sched_leaf_dir = re.findall(r".*/([\w_-]+)/.*?$", sched_file)[0] | ||
83 | sched_full_dir = os.path.split(sched_file)[0] | ||
84 | |||
85 | work_dir = "%s/tmp" % sched_full_dir | ||
86 | |||
87 | if sched_full_dir == out_base_dir: | ||
88 | out_dir = "%s/data" % sched_full_dir | ||
89 | else: | ||
90 | # Put it under the base output dir with the same directory name | ||
91 | out_dir = "%s/%s" % (out_base_dir, sched_leaf_dir) | ||
92 | |||
93 | return (work_dir, out_dir) | ||
94 | |||
95 | |||
96 | def load_experiment(sched_file, scheduler, duration, param_file, out_base): | ||
97 | if not os.path.isfile(sched_file): | 84 | if not os.path.isfile(sched_file): |
98 | raise IOError("Cannot find schedule file: %s" % sched_file) | 85 | raise IOError("Cannot find schedule file: %s" % sched_file) |
99 | 86 | ||
@@ -121,8 +108,8 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_base): | |||
121 | 108 | ||
122 | # Parse schedule file's intentions | 109 | # Parse schedule file's intentions |
123 | schedule = load_schedule(sched_file) | 110 | schedule = load_schedule(sched_file) |
124 | (work_dir, out_dir) = get_dirs(sched_file, out_base) | 111 | work_dir = "%s/tmp" % dirname |
125 | fix_paths(schedule, os.path.split(sched_file)[0]) | 112 | fix_paths(schedule, os.path.split(sched_file)[0], sched_file) |
126 | 113 | ||
127 | run_exp(sched_file, schedule, scheduler, kernel, duration, work_dir, out_dir) | 114 | run_exp(sched_file, schedule, scheduler, kernel, duration, work_dir, out_dir) |
128 | 115 | ||
@@ -209,15 +196,19 @@ def main(): | |||
209 | 196 | ||
210 | for exp in args: | 197 | for exp in args: |
211 | path = "%s/%s" % (os.getcwd(), exp) | 198 | path = "%s/%s" % (os.getcwd(), exp) |
199 | out_dir = "%s/%s" % (out_base, exp) | ||
212 | 200 | ||
213 | if not os.path.exists(path): | 201 | if not os.path.exists(path): |
214 | raise IOError("Invalid experiment: %s" % path) | 202 | raise IOError("Invalid experiment: %s" % path) |
215 | 203 | ||
204 | if opts.force and os.path.exists(out_dir): | ||
205 | shutil.rmtree(out_dir) | ||
206 | |||
216 | if os.path.isdir(exp): | 207 | if os.path.isdir(exp): |
217 | path = "%s/%s" % (path, opts.sched_file) | 208 | path = "%s/%s" % (path, opts.sched_file) |
218 | 209 | ||
219 | try: | 210 | try: |
220 | load_experiment(path, scheduler, duration, param_file, out_base) | 211 | load_experiment(path, scheduler, duration, param_file, out_dir) |
221 | succ += 1 | 212 | succ += 1 |
222 | except ExperimentDone: | 213 | except ExperimentDone: |
223 | done += 1 | 214 | done += 1 |