diff options
-rw-r--r-- | config/config.py | 7 | ||||
-rwxr-xr-x | gen_exps.py | 11 | ||||
-rwxr-xr-x | parse_exps.py | 34 | ||||
-rwxr-xr-x | plot_exps.py | 21 | ||||
-rwxr-xr-x | run_exps.py | 73 |
5 files changed, 102 insertions, 44 deletions
diff --git a/config/config.py b/config/config.py index cbac6b2..1ac468b 100644 --- a/config/config.py +++ b/config/config.py | |||
@@ -39,13 +39,18 @@ DEFAULTS = {'params_file' : 'params.py', | |||
39 | 'sched_file' : 'sched.py', | 39 | 'sched_file' : 'sched.py', |
40 | 'duration' : 10, | 40 | 'duration' : 10, |
41 | 'prog' : 'rtspin', | 41 | 'prog' : 'rtspin', |
42 | 'out-gen' : 'exps', | ||
43 | 'out-run' : 'run-data', | ||
44 | 'out-parse' : 'parse-data', | ||
45 | 'out-plot' : 'plot-data', | ||
42 | 'cycles' : ft_freq() or 2000} | 46 | 'cycles' : ft_freq() or 2000} |
43 | 47 | ||
48 | |||
44 | '''Default sched_trace events (this is all of them).''' | 49 | '''Default sched_trace events (this is all of them).''' |
45 | SCHED_EVENTS = range(501, 513) | 50 | SCHED_EVENTS = range(501, 513) |
46 | 51 | ||
47 | '''Overhead events.''' | 52 | '''Overhead events.''' |
48 | OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS'] | 53 | OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS', 'LOCK', 'UNLOCK'] |
49 | OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in | 54 | OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in |
50 | itertools.product(OVH_BASE_EVENTS, ["START","END"])] | 55 | itertools.product(OVH_BASE_EVENTS, ["START","END"])] |
51 | OVH_ALL_EVENTS += ['RELEASE_LATENCY'] | 56 | OVH_ALL_EVENTS += ['RELEASE_LATENCY'] |
diff --git a/gen_exps.py b/gen_exps.py index 6488cdc..b847661 100755 --- a/gen_exps.py +++ b/gen_exps.py | |||
@@ -7,6 +7,7 @@ import re | |||
7 | import shutil as sh | 7 | import shutil as sh |
8 | import sys | 8 | import sys |
9 | 9 | ||
10 | from config.config import DEFAULTS | ||
10 | from optparse import OptionParser | 11 | from optparse import OptionParser |
11 | 12 | ||
12 | def parse_args(): | 13 | def parse_args(): |
@@ -15,7 +16,7 @@ def parse_args(): | |||
15 | 16 | ||
16 | parser.add_option('-o', '--out-dir', dest='out_dir', | 17 | parser.add_option('-o', '--out-dir', dest='out_dir', |
17 | help='directory for data output', | 18 | help='directory for data output', |
18 | default=("%s/exps"%os.getcwd())) | 19 | default=("%s/%s"% (os.getcwd(), DEFAULTS['out-gen']))) |
19 | parser.add_option('-f', '--force', action='store_true', default=False, | 20 | parser.add_option('-f', '--force', action='store_true', default=False, |
20 | dest='force', help='overwrite existing data') | 21 | dest='force', help='overwrite existing data') |
21 | parser.add_option('-n', '--num-trials', default=1, type='int', dest='trials', | 22 | parser.add_option('-n', '--num-trials', default=1, type='int', dest='trials', |
@@ -51,9 +52,9 @@ def main(): | |||
51 | if opts.described != None: | 52 | if opts.described != None: |
52 | for generator in opts.described.split(','): | 53 | for generator in opts.described.split(','): |
53 | if generator not in gen.get_generators(): | 54 | if generator not in gen.get_generators(): |
54 | print("No generator '%s'" % generator) | 55 | sys.stderr.write("No generator '%s'\n" % generator) |
55 | else: | 56 | else: |
56 | sys.stdout.write("Generator '%s', " % generator) | 57 | print("Generator '%s', " % generator) |
57 | gen.get_generators()[generator]().print_help() | 58 | gen.get_generators()[generator]().print_help() |
58 | if opts.list_gens or opts.described: | 59 | if opts.list_gens or opts.described: |
59 | return 0 | 60 | return 0 |
@@ -85,7 +86,7 @@ def main(): | |||
85 | if gen_name not in gen.get_generators(): | 86 | if gen_name not in gen.get_generators(): |
86 | raise ValueError("Invalid generator '%s'" % gen_name) | 87 | raise ValueError("Invalid generator '%s'" % gen_name) |
87 | 88 | ||
88 | print("Creating experiments using %s generator..." % gen_name) | 89 | sys.stderr.write("Creating experiments with %s generator...\n" % gen_name) |
89 | 90 | ||
90 | params = dict(gen_params.items() + global_params.items()) | 91 | params = dict(gen_params.items() + global_params.items()) |
91 | clazz = gen.get_generators()[gen_name] | 92 | clazz = gen.get_generators()[gen_name] |
@@ -94,5 +95,7 @@ def main(): | |||
94 | 95 | ||
95 | generator.create_exps(opts.out_dir, opts.force, opts.trials) | 96 | generator.create_exps(opts.out_dir, opts.force, opts.trials) |
96 | 97 | ||
98 | sys.stderr.write("Experiments saved in %s.\n" % opts.out_dir) | ||
99 | |||
97 | if __name__ == '__main__': | 100 | if __name__ == '__main__': |
98 | main() | 101 | main() |
diff --git a/parse_exps.py b/parse_exps.py index c254536..d07378c 100755 --- a/parse_exps.py +++ b/parse_exps.py | |||
@@ -1,7 +1,6 @@ | |||
1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
2 | from __future__ import print_function | 2 | from __future__ import print_function |
3 | 3 | ||
4 | import config.config as conf | ||
5 | import os | 4 | import os |
6 | import parse.ft as ft | 5 | import parse.ft as ft |
7 | import parse.sched as st | 6 | import parse.sched as st |
@@ -12,6 +11,7 @@ import traceback | |||
12 | 11 | ||
13 | from collections import namedtuple | 12 | from collections import namedtuple |
14 | from common import load_params | 13 | from common import load_params |
14 | from config.config import DEFAULTS,PARAMS | ||
15 | from optparse import OptionParser | 15 | from optparse import OptionParser |
16 | from parse.point import ExpPoint | 16 | from parse.point import ExpPoint |
17 | from parse.tuple_table import TupleTable | 17 | from parse.tuple_table import TupleTable |
@@ -22,7 +22,8 @@ def parse_args(): | |||
22 | parser = OptionParser("usage: %prog [options] [data_dir]...") | 22 | parser = OptionParser("usage: %prog [options] [data_dir]...") |
23 | 23 | ||
24 | parser.add_option('-o', '--out', dest='out', | 24 | parser.add_option('-o', '--out', dest='out', |
25 | help='file or directory for data output', default='parse-data') | 25 | help='file or directory for data output', |
26 | default=DEFAULTS['out-parse']) | ||
26 | parser.add_option('-i', '--ignore', metavar='[PARAM...]', default="", | 27 | parser.add_option('-i', '--ignore', metavar='[PARAM...]', default="", |
27 | help='ignore changing parameter values') | 28 | help='ignore changing parameter values') |
28 | parser.add_option('-f', '--force', action='store_true', default=False, | 29 | parser.add_option('-f', '--force', action='store_true', default=False, |
@@ -41,7 +42,7 @@ def parse_args(): | |||
41 | ExpData = namedtuple('ExpData', ['path', 'params', 'work_dir']) | 42 | ExpData = namedtuple('ExpData', ['path', 'params', 'work_dir']) |
42 | 43 | ||
43 | def get_exp_params(data_dir, cm_builder): | 44 | def get_exp_params(data_dir, cm_builder): |
44 | param_file = "%s/%s" % (data_dir, conf.DEFAULTS['params_file']) | 45 | param_file = "%s/%s" % (data_dir, DEFAULTS['params_file']) |
45 | if os.path.isfile(param_file): | 46 | if os.path.isfile(param_file): |
46 | params = load_params(param_file) | 47 | params = load_params(param_file) |
47 | 48 | ||
@@ -53,8 +54,8 @@ def get_exp_params(data_dir, cm_builder): | |||
53 | params = {} | 54 | params = {} |
54 | 55 | ||
55 | # Cycles must be present for feather-trace measurement parsing | 56 | # Cycles must be present for feather-trace measurement parsing |
56 | if conf.PARAMS['cycles'] not in params: | 57 | if PARAMS['cycles'] not in params: |
57 | params[conf.PARAMS['cycles']] = conf.DEFAULTS['cycles'] | 58 | params[PARAMS['cycles']] = DEFAULTS['cycles'] |
58 | 59 | ||
59 | return params | 60 | return params |
60 | 61 | ||
@@ -101,7 +102,7 @@ def parse_exp(exp_force): | |||
101 | if not result: | 102 | if not result: |
102 | try: | 103 | try: |
103 | result = ExpPoint(exp.path) | 104 | result = ExpPoint(exp.path) |
104 | cycles = exp.params[conf.PARAMS['cycles']] | 105 | cycles = exp.params[PARAMS['cycles']] |
105 | 106 | ||
106 | # Write overheads into result | 107 | # Write overheads into result |
107 | ft.extract_ft_data(result, exp.path, exp.work_dir, cycles) | 108 | ft.extract_ft_data(result, exp.path, exp.work_dir, cycles) |
@@ -116,21 +117,31 @@ def parse_exp(exp_force): | |||
116 | 117 | ||
117 | return (exp, result) | 118 | return (exp, result) |
118 | 119 | ||
120 | def get_exps(args): | ||
121 | if args: | ||
122 | return args | ||
123 | elif os.path.exists(DEFAULTS['out-run']): | ||
124 | sys.stderr.write("Reading data from %s/*\n" % DEFAULTS['out-run']) | ||
125 | sched_dirs = os.listdir(DEFAULTS['out-run']) | ||
126 | return ['%s/%s' % (DEFAULTS['out-run'], d) for d in sched_dirs] | ||
127 | else: | ||
128 | sys.stderr.write("Reading data from current directory.\n") | ||
129 | return [os.getcwd()] | ||
130 | |||
119 | def main(): | 131 | def main(): |
120 | opts, args = parse_args() | 132 | opts, args = parse_args() |
121 | 133 | exp_dirs = get_exps(args) | |
122 | args = args or [os.getcwd()] | ||
123 | 134 | ||
124 | # Load exp parameters into a ColMap | 135 | # Load exp parameters into a ColMap |
125 | builder = ColMapBuilder() | 136 | builder = ColMapBuilder() |
126 | exps = load_exps(args, builder, opts.force) | 137 | exps = load_exps(exp_dirs, builder, opts.force) |
127 | 138 | ||
128 | # Don't track changes in ignored parameters | 139 | # Don't track changes in ignored parameters |
129 | if opts.ignore: | 140 | if opts.ignore: |
130 | for param in opts.ignore.split(","): | 141 | for param in opts.ignore.split(","): |
131 | builder.try_remove(param) | 142 | builder.try_remove(param) |
132 | # Always average multiple trials | 143 | # Always average multiple trials |
133 | builder.try_remove(conf.PARAMS['trial']) | 144 | builder.try_remove(PARAMS['trial']) |
134 | 145 | ||
135 | col_map = builder.build() | 146 | col_map = builder.build() |
136 | result_table = TupleTable(col_map) | 147 | result_table = TupleTable(col_map) |
@@ -175,7 +186,8 @@ def main(): | |||
175 | # No csvs to write, assume user meant to print out data | 186 | # No csvs to write, assume user meant to print out data |
176 | if dir_map.is_empty(): | 187 | if dir_map.is_empty(): |
177 | if not opts.verbose: | 188 | if not opts.verbose: |
178 | sys.stderr.write("Too little data to make csv files.\n") | 189 | sys.stderr.write("Too little data to make csv files, " + |
190 | "printing results.\n") | ||
179 | for key, exp in result_table: | 191 | for key, exp in result_table: |
180 | for e in exp: | 192 | for e in exp: |
181 | print(e) | 193 | print(e) |
diff --git a/plot_exps.py b/plot_exps.py index 76e7396..15c54d0 100755 --- a/plot_exps.py +++ b/plot_exps.py | |||
@@ -6,7 +6,9 @@ import os | |||
6 | import shutil as sh | 6 | import shutil as sh |
7 | import sys | 7 | import sys |
8 | import traceback | 8 | import traceback |
9 | |||
9 | from collections import namedtuple | 10 | from collections import namedtuple |
11 | from config.config import DEFAULTS | ||
10 | from multiprocessing import Pool, cpu_count | 12 | from multiprocessing import Pool, cpu_count |
11 | from optparse import OptionParser | 13 | from optparse import OptionParser |
12 | from parse.col_map import ColMap,ColMapBuilder | 14 | from parse.col_map import ColMap,ColMapBuilder |
@@ -17,7 +19,8 @@ def parse_args(): | |||
17 | parser = OptionParser("usage: %prog [options] [csv_dir]...") | 19 | parser = OptionParser("usage: %prog [options] [csv_dir]...") |
18 | 20 | ||
19 | parser.add_option('-o', '--out-dir', dest='out_dir', | 21 | parser.add_option('-o', '--out-dir', dest='out_dir', |
20 | help='directory for plot output', default='plot-data') | 22 | help='directory for plot output', |
23 | default=DEFAULTS['out-plot']) | ||
21 | parser.add_option('-f', '--force', action='store_true', default=False, | 24 | parser.add_option('-f', '--force', action='store_true', default=False, |
22 | dest='force', help='overwrite existing data') | 25 | dest='force', help='overwrite existing data') |
23 | parser.add_option('-p', '--processors', default=max(cpu_count() - 1, 1), | 26 | parser.add_option('-p', '--processors', default=max(cpu_count() - 1, 1), |
@@ -139,21 +142,31 @@ def plot_dir(data_dir, out_dir, max_procs, force): | |||
139 | 142 | ||
140 | sys.stderr.write('\n') | 143 | sys.stderr.write('\n') |
141 | 144 | ||
145 | def get_dirs(args): | ||
146 | if args: | ||
147 | return args | ||
148 | elif os.path.exists(DEFAULTS['out-parse']): | ||
149 | return [DEFAULTS['out-parse']] | ||
150 | else: | ||
151 | return os.getcwd() | ||
152 | |||
142 | def main(): | 153 | def main(): |
143 | opts, args = parse_args() | 154 | opts, args = parse_args() |
144 | args = args or [os.getcwd()] | 155 | dirs = get_dirs(args) |
145 | 156 | ||
146 | if opts.force and os.path.exists(opts.out_dir): | 157 | if opts.force and os.path.exists(opts.out_dir): |
147 | sh.rmtree(opts.out_dir) | 158 | sh.rmtree(opts.out_dir) |
148 | if not os.path.exists(opts.out_dir): | 159 | if not os.path.exists(opts.out_dir): |
149 | os.mkdir(opts.out_dir) | 160 | os.mkdir(opts.out_dir) |
150 | 161 | ||
151 | for dir in args: | 162 | for dir in dirs: |
152 | if len(args) > 1: | 163 | if len(dirs) > 1: |
153 | out_dir = "%s/%s" % (opts.out_dir, os.path.split(dir)[1]) | 164 | out_dir = "%s/%s" % (opts.out_dir, os.path.split(dir)[1]) |
154 | else: | 165 | else: |
155 | out_dir = opts.out_dir | 166 | out_dir = opts.out_dir |
156 | plot_dir(dir, out_dir, opts.processors, opts.force) | 167 | plot_dir(dir, out_dir, opts.processors, opts.force) |
157 | 168 | ||
169 | sys.stderr.write("Plots saved in %s.\n" % opts.out_dir) | ||
170 | |||
158 | if __name__ == '__main__': | 171 | if __name__ == '__main__': |
159 | main() | 172 | main() |
diff --git a/run_exps.py b/run_exps.py index 905d033..d7a06b5 100755 --- a/run_exps.py +++ b/run_exps.py | |||
@@ -2,13 +2,13 @@ | |||
2 | from __future__ import print_function | 2 | from __future__ import print_function |
3 | 3 | ||
4 | import common as com | 4 | import common as com |
5 | import config.config as conf | ||
6 | import os | 5 | import os |
7 | import re | 6 | import re |
8 | import shutil | 7 | import shutil |
9 | import sys | 8 | import sys |
10 | import run.tracer as trace | 9 | import run.tracer as trace |
11 | 10 | ||
11 | from config.config import PARAMS,DEFAULTS | ||
12 | from collections import namedtuple | 12 | from collections import namedtuple |
13 | from optparse import OptionParser | 13 | from optparse import OptionParser |
14 | from run.executable.executable import Executable | 14 | from run.executable.executable import Executable |
@@ -56,12 +56,13 @@ def parse_args(): | |||
56 | parser.add_option('-d', '--duration', dest='duration', type='int', | 56 | parser.add_option('-d', '--duration', dest='duration', type='int', |
57 | help='duration (seconds) of tasks') | 57 | help='duration (seconds) of tasks') |
58 | parser.add_option('-o', '--out-dir', dest='out_dir', | 58 | parser.add_option('-o', '--out-dir', dest='out_dir', |
59 | help='directory for data output', default=("%s/run-data"%os.getcwd())) | 59 | help='directory for data output', |
60 | default=DEFAULTS['out-run']) | ||
60 | parser.add_option('-p', '--params', dest='param_file', | 61 | parser.add_option('-p', '--params', dest='param_file', |
61 | help='file with experiment parameters') | 62 | help='file with experiment parameters') |
62 | parser.add_option('-c', '--schedule-file', dest='sched_file', | 63 | parser.add_option('-c', '--schedule-file', dest='sched_file', |
63 | help='name of schedule files within directories', | 64 | help='name of schedule files within directories', |
64 | default=conf.DEFAULTS['sched_file']) | 65 | default=DEFAULTS['sched_file']) |
65 | parser.add_option('-f', '--force', action='store_true', default=False, | 66 | parser.add_option('-f', '--force', action='store_true', default=False, |
66 | dest='force', help='overwrite existing data') | 67 | dest='force', help='overwrite existing data') |
67 | parser.add_option('-j', '--jabber', metavar='username@domain', | 68 | parser.add_option('-j', '--jabber', metavar='username@domain', |
@@ -96,7 +97,7 @@ def convert_data(data): | |||
96 | proc = (loc, match.group("CONTENT")) | 97 | proc = (loc, match.group("CONTENT")) |
97 | procs.append(proc) | 98 | procs.append(proc) |
98 | else: | 99 | else: |
99 | prog = match.group("PROG") or conf.DEFAULTS['prog'] | 100 | prog = match.group("PROG") or DEFAULTS['prog'] |
100 | spin = (prog, match.group("ARGS")) | 101 | spin = (prog, match.group("ARGS")) |
101 | tasks.append(spin) | 102 | tasks.append(spin) |
102 | 103 | ||
@@ -184,10 +185,10 @@ def verify_environment(exp_params): | |||
184 | def run_parameter(exp_dir, out_dir, params, param_name): | 185 | def run_parameter(exp_dir, out_dir, params, param_name): |
185 | '''Run an executable (arguments optional) specified as a configurable | 186 | '''Run an executable (arguments optional) specified as a configurable |
186 | @param_name in @params.''' | 187 | @param_name in @params.''' |
187 | if conf.PARAMS[param_name] not in params: | 188 | if PARAMS[param_name] not in params: |
188 | return | 189 | return |
189 | 190 | ||
190 | script_params = params[conf.PARAMS[param_name]] | 191 | script_params = params[PARAMS[param_name]] |
191 | 192 | ||
192 | # Split into arguments and program name | 193 | # Split into arguments and program name |
193 | if type(script_params) != type([]): | 194 | if type(script_params) != type([]): |
@@ -210,22 +211,22 @@ def get_exp_params(cmd_scheduler, cmd_duration, file_params): | |||
210 | '''Return ExpParam with configured values of all hardcoded params.''' | 211 | '''Return ExpParam with configured values of all hardcoded params.''' |
211 | kernel = copts = "" | 212 | kernel = copts = "" |
212 | 213 | ||
213 | scheduler = cmd_scheduler or file_params[conf.PARAMS['sched']] | 214 | scheduler = cmd_scheduler or file_params[PARAMS['sched']] |
214 | duration = cmd_duration or file_params[conf.PARAMS['dur']] or\ | 215 | duration = cmd_duration or file_params[PARAMS['dur']] or\ |
215 | conf.DEFAULTS['duration'] | 216 | DEFAULTS['duration'] |
216 | 217 | ||
217 | # Experiments can specify required kernel name | 218 | # Experiments can specify required kernel name |
218 | if conf.PARAMS['kernel'] in file_params: | 219 | if PARAMS['kernel'] in file_params: |
219 | kernel = file_params[conf.PARAMS['kernel']] | 220 | kernel = file_params[PARAMS['kernel']] |
220 | 221 | ||
221 | # Or required config options | 222 | # Or required config options |
222 | if conf.PARAMS['copts'] in file_params: | 223 | if PARAMS['copts'] in file_params: |
223 | copts = file_params[conf.PARAMS['copts']] | 224 | copts = file_params[PARAMS['copts']] |
224 | 225 | ||
225 | # Or required tracers | 226 | # Or required tracers |
226 | requested = [] | 227 | requested = [] |
227 | if conf.PARAMS['trace'] in file_params: | 228 | if PARAMS['trace'] in file_params: |
228 | requested = file_params[conf.PARAMS['trace']] | 229 | requested = file_params[PARAMS['trace']] |
229 | tracers = trace.get_tracer_types(requested) | 230 | tracers = trace.get_tracer_types(requested) |
230 | 231 | ||
231 | # But only these two are mandatory | 232 | # But only these two are mandatory |
@@ -250,7 +251,7 @@ def load_experiment(sched_file, cmd_scheduler, cmd_duration, | |||
250 | 251 | ||
251 | # Load parameter file | 252 | # Load parameter file |
252 | param_file = param_file or \ | 253 | param_file = param_file or \ |
253 | "%s/%s" % (dir_name, conf.DEFAULTS['params_file']) | 254 | "%s/%s" % (dir_name, DEFAULTS['params_file']) |
254 | if os.path.isfile(param_file): | 255 | if os.path.isfile(param_file): |
255 | file_params = com.load_params(param_file) | 256 | file_params = com.load_params(param_file) |
256 | else: | 257 | else: |
@@ -277,19 +278,36 @@ def load_experiment(sched_file, cmd_scheduler, cmd_duration, | |||
277 | 278 | ||
278 | # Save parameters used to run experiment in out_dir | 279 | # Save parameters used to run experiment in out_dir |
279 | out_params = dict(file_params.items() + | 280 | out_params = dict(file_params.items() + |
280 | [(conf.PARAMS['sched'], exp_params.scheduler), | 281 | [(PARAMS['sched'], exp_params.scheduler), |
281 | (conf.PARAMS['tasks'], len(execs)), | 282 | (PARAMS['tasks'], len(execs)), |
282 | (conf.PARAMS['dur'], exp_params.duration)]) | 283 | (PARAMS['dur'], exp_params.duration)]) |
283 | 284 | ||
284 | # Feather-trace clock frequency saved for accurate overhead parsing | 285 | # Feather-trace clock frequency saved for accurate overhead parsing |
285 | ft_freq = com.ft_freq() | 286 | ft_freq = com.ft_freq() |
286 | if ft_freq: | 287 | if ft_freq: |
287 | out_params[conf.PARAMS['cycles']] = ft_freq | 288 | out_params[PARAMS['cycles']] = ft_freq |
288 | 289 | ||
289 | with open("%s/%s" % (out_dir, conf.DEFAULTS['params_file']), 'w') as f: | 290 | with open("%s/%s" % (out_dir, DEFAULTS['params_file']), 'w') as f: |
290 | f.write(str(out_params)) | 291 | f.write(str(out_params)) |
291 | 292 | ||
292 | 293 | ||
294 | def get_exps(opts, args): | ||
295 | if args: | ||
296 | return args | ||
297 | |||
298 | # Default to sched_file > generated dirs | ||
299 | if os.path.exists(opts.sched_file): | ||
300 | sys.stderr.write("Reading schedule from %s.\n" % opts.sched_file) | ||
301 | return [opts.sched_file] | ||
302 | elif os.path.exists(DEFAULTS['out-gen']): | ||
303 | sys.stderr.write("Reading schedules from %s/*.\n" % DEFAULTS['out-gen']) | ||
304 | sched_dirs = os.listdir(DEFAULTS['out-gen']) | ||
305 | return ['%s/%s' % (DEFAULTS['out-gen'], d) for d in sched_dirs] | ||
306 | else: | ||
307 | sys.stderr.write("Run with -h to view options.\n"); | ||
308 | sys.exit(1) | ||
309 | |||
310 | |||
293 | def setup_jabber(target): | 311 | def setup_jabber(target): |
294 | try: | 312 | try: |
295 | from run.jabber import Jabber | 313 | from run.jabber import Jabber |
@@ -300,6 +318,7 @@ def setup_jabber(target): | |||
300 | "Disabling instant messages.\n") | 318 | "Disabling instant messages.\n") |
301 | return None | 319 | return None |
302 | 320 | ||
321 | |||
303 | def setup_email(target): | 322 | def setup_email(target): |
304 | try: | 323 | try: |
305 | from run.emailer import Emailer | 324 | from run.emailer import Emailer |
@@ -313,6 +332,7 @@ def setup_email(target): | |||
313 | sys.stderr.write(message + " Disabling email message.\n") | 332 | sys.stderr.write(message + " Disabling email message.\n") |
314 | return None | 333 | return None |
315 | 334 | ||
335 | |||
316 | def main(): | 336 | def main(): |
317 | opts, args = parse_args() | 337 | opts, args = parse_args() |
318 | 338 | ||
@@ -321,7 +341,7 @@ def main(): | |||
321 | param_file = opts.param_file | 341 | param_file = opts.param_file |
322 | out_base = os.path.abspath(opts.out_dir) | 342 | out_base = os.path.abspath(opts.out_dir) |
323 | 343 | ||
324 | args = args or [opts.sched_file] | 344 | exps = get_exps(opts, args) |
325 | 345 | ||
326 | created = False | 346 | created = False |
327 | if not os.path.exists(out_base): | 347 | if not os.path.exists(out_base): |
@@ -335,9 +355,9 @@ def main(): | |||
335 | invalid = 0 | 355 | invalid = 0 |
336 | 356 | ||
337 | jabber = setup_jabber(opts.jabber) if opts.jabber else None | 357 | jabber = setup_jabber(opts.jabber) if opts.jabber else None |
338 | email = setup_email(opts.email) if opts.email else None | 358 | email = setup_email(opts.email) if opts.email else None |
339 | 359 | ||
340 | for exp in args: | 360 | for exp in exps: |
341 | path = "%s/%s" % (os.getcwd(), exp) | 361 | path = "%s/%s" % (os.getcwd(), exp) |
342 | out_dir = "%s/%s" % (out_base, os.path.split(exp.strip('/'))[1]) | 362 | out_dir = "%s/%s" % (out_base, os.path.split(exp.strip('/'))[1]) |
343 | 363 | ||
@@ -374,6 +394,7 @@ def main(): | |||
374 | 394 | ||
375 | ran += 1 | 395 | ran += 1 |
376 | 396 | ||
397 | # Clean out directory if it failed immediately | ||
377 | if not os.listdir(out_base) and created and not succ: | 398 | if not os.listdir(out_base) and created and not succ: |
378 | os.rmdir(out_base) | 399 | os.rmdir(out_base) |
379 | 400 | ||
@@ -385,6 +406,10 @@ def main(): | |||
385 | 406 | ||
386 | print(message) | 407 | print(message) |
387 | 408 | ||
409 | if succ: | ||
410 | sys.stderr.write("Successful experiment data saved in %s.\n" % | ||
411 | opts.out_dir) | ||
412 | |||
388 | if email: | 413 | if email: |
389 | email.send(message) | 414 | email.send(message) |
390 | email.close() | 415 | email.close() |