diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-09-27 11:50:31 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-09-27 11:50:31 -0400 |
| commit | 5554e053e9f3d5f7987d3f1d889802b211af8eab (patch) | |
| tree | 1353f456be38d88ca9d5165388215edcdfd591f7 | |
| parent | 1cb07c18107395d022cf6e5fc28483156d1abd93 (diff) | |
Added support for interrupted / failed experiments, and included a status summary at the end of run_exps.py
| -rw-r--r-- | experiment/executable/executable.py | 3 | ||||
| -rw-r--r-- | experiment/experiment.py | 5 | ||||
| -rwxr-xr-x | run_exps.py | 60 |
3 files changed, 46 insertions, 22 deletions
diff --git a/experiment/executable/executable.py b/experiment/executable/executable.py index 6697a8d..897c2d9 100644 --- a/experiment/executable/executable.py +++ b/experiment/executable/executable.py | |||
| @@ -43,6 +43,9 @@ class Executable(object): | |||
| 43 | full_command += self.extra_args | 43 | full_command += self.extra_args |
| 44 | return full_command | 44 | return full_command |
| 45 | 45 | ||
| 46 | def __str__(self): | ||
| 47 | return " ".join(self.__get_full_command()) | ||
| 48 | |||
| 46 | def execute(self): | 49 | def execute(self): |
| 47 | """Execute the binary.""" | 50 | """Execute the binary.""" |
| 48 | full_command = self.__get_full_command() | 51 | full_command = self.__get_full_command() |
diff --git a/experiment/experiment.py b/experiment/experiment.py index ce189a1..5ed6480 100644 --- a/experiment/experiment.py +++ b/experiment/experiment.py | |||
| @@ -94,7 +94,10 @@ class Experiment(object): | |||
| 94 | self.log("Starting the program in ({0} seconds)".format( | 94 | self.log("Starting the program in ({0} seconds)".format( |
| 95 | len(self.executables) * exec_pause)) | 95 | len(self.executables) * exec_pause)) |
| 96 | for e in self.executables: | 96 | for e in self.executables: |
| 97 | e.execute() | 97 | try: |
| 98 | e.execute() | ||
| 99 | except: | ||
| 100 | raise Exception("Executable failed: %s" % e) | ||
| 98 | time.sleep(exec_pause) | 101 | time.sleep(exec_pause) |
| 99 | 102 | ||
| 100 | sleep_time = 2 | 103 | sleep_time = 2 |
diff --git a/run_exps.py b/run_exps.py index a2d5077..d2606f8 100755 --- a/run_exps.py +++ b/run_exps.py | |||
| @@ -5,16 +5,17 @@ import config.config as conf | |||
| 5 | import experiment.litmus_util as lu | 5 | import experiment.litmus_util as lu |
| 6 | import os | 6 | import os |
| 7 | import re | 7 | import re |
| 8 | import traceback | ||
| 8 | 9 | ||
| 9 | from collections import defaultdict | 10 | from common import load_params |
| 10 | from optparse import OptionParser | 11 | from optparse import OptionParser |
| 11 | from experiment.executable.executable import Executable | 12 | from experiment.executable.executable import Executable |
| 12 | from experiment.experiment import Experiment | 13 | from experiment.experiment import Experiment,ExperimentDone |
| 13 | from experiment.proc_entry import ProcEntry | 14 | from experiment.proc_entry import ProcEntry |
| 14 | 15 | ||
| 15 | 16 | ||
| 16 | def parse_args(): | 17 | def parse_args(): |
| 17 | parser = OptionParser(); | 18 | parser = OptionParser("usage: %prog [options] [sched_file]... [exp_dir]...]") |
| 18 | 19 | ||
| 19 | parser.add_option('-s', '--scheduler', dest='scheduler', | 20 | parser.add_option('-s', '--scheduler', dest='scheduler', |
| 20 | help='scheduler for all experiments') | 21 | help='scheduler for all experiments') |
| @@ -81,6 +82,8 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_base): | |||
| 81 | 82 | ||
| 82 | dirname = os.path.split(sched_file)[0] | 83 | dirname = os.path.split(sched_file)[0] |
| 83 | 84 | ||
| 85 | params = {} | ||
| 86 | |||
| 84 | if not scheduler or not duration: | 87 | if not scheduler or not duration: |
| 85 | param_file = param_file or \ | 88 | param_file = param_file or \ |
| 86 | "%s/%s" % (dirname, conf.DEFAULTS['params_file']) | 89 | "%s/%s" % (dirname, conf.DEFAULTS['params_file']) |
| @@ -93,27 +96,20 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_base): | |||
| 93 | duration = duration or conf.DEFAULTS['duration'] | 96 | duration = duration or conf.DEFAULTS['duration'] |
| 94 | 97 | ||
| 95 | if not scheduler: | 98 | if not scheduler: |
| 96 | raise IOError("Parameter scheduler not specified") | 99 | raise IOError("Parameter scheduler not specified in %s" % (param_file)) |
| 97 | 100 | ||
| 101 | # Parse schedule file's intentions | ||
| 98 | schedule = load_schedule(sched_file) | 102 | schedule = load_schedule(sched_file) |
| 99 | (work_dir, out_dir) = get_dirs(sched_file, out_base) | 103 | (work_dir, out_dir) = get_dirs(sched_file, out_base) |
| 100 | 104 | ||
| 101 | run_exp(sched_file, schedule, scheduler, duration, work_dir, out_dir) | 105 | run_exp(sched_file, schedule, scheduler, duration, work_dir, out_dir) |
| 102 | 106 | ||
| 103 | 107 | # Save parameters used to run experiment in out_dir | |
| 104 | def load_params(fname): | 108 | out_params = dict(params.items() + |
| 105 | params = defaultdict(int) | 109 | [(conf.PARAMS['sched'], scheduler), |
| 106 | with open(fname, 'r') as f: | 110 | (conf.PARAMS['dur'], duration)]) |
| 107 | data = f.read() | 111 | with open("%s/%s" % (out_dir, conf.DEFAULTS['params_file']), 'w') as f: |
| 108 | try: | 112 | f.write(str(out_params)) |
| 109 | parsed = eval(data) | ||
| 110 | for k in parsed: | ||
| 111 | params[k] = parsed[k] | ||
| 112 | except Exception as e: | ||
| 113 | raise IOError("Invalid param file: %s\n%s" % (fname, e)) | ||
| 114 | |||
| 115 | return params | ||
| 116 | |||
| 117 | 113 | ||
| 118 | def load_schedule(fname): | 114 | def load_schedule(fname): |
| 119 | with open(fname, 'r') as f: | 115 | with open(fname, 'r') as f: |
| @@ -176,6 +172,13 @@ def main(): | |||
| 176 | 172 | ||
| 177 | args = args or [opts.sched_file] | 173 | args = args or [opts.sched_file] |
| 178 | 174 | ||
| 175 | if not os.path.exists(out_base): | ||
| 176 | os.mkdir(out_base) | ||
| 177 | |||
| 178 | done = 0 | ||
| 179 | succ = 0 | ||
| 180 | failed = 0 | ||
| 181 | |||
| 179 | for exp in args: | 182 | for exp in args: |
| 180 | path = "%s/%s" % (os.getcwd(), exp) | 183 | path = "%s/%s" % (os.getcwd(), exp) |
| 181 | 184 | ||
| @@ -183,9 +186,24 @@ def main(): | |||
| 183 | raise IOError("Invalid experiment: %s" % path) | 186 | raise IOError("Invalid experiment: %s" % path) |
| 184 | 187 | ||
| 185 | if os.path.isdir(exp): | 188 | if os.path.isdir(exp): |
| 186 | path = "%s%s" % (path, opts.sched_file) | 189 | path = "%s/%s" % (path, opts.sched_file) |
| 187 | 190 | ||
| 188 | load_experiment(path, scheduler, duration, param_file, out_base) | 191 | try: |
| 192 | load_experiment(path, scheduler, duration, param_file, out_base) | ||
| 193 | succ += 1 | ||
| 194 | except ExperimentDone: | ||
| 195 | done += 1 | ||
| 196 | print("Experiment '%s' already completed at '%s'" % (exp, out_base)) | ||
| 197 | except: | ||
| 198 | print("Failed experiment %s" % exp) | ||
| 199 | traceback.print_exc() | ||
| 200 | failed += 1 | ||
| 201 | |||
| 202 | |||
| 203 | print("Experiments run:\t%d" % len(args)) | ||
| 204 | print(" Successful:\t\t%d" % succ) | ||
| 205 | print(" Failed:\t\t%d" % failed) | ||
| 206 | print(" Skipped:\t\t%d" % done) | ||
| 189 | 207 | ||
| 190 | 208 | ||
| 191 | if __name__ == '__main__': | 209 | if __name__ == '__main__': |
