aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-04-29 16:50:23 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2013-04-29 16:50:23 -0400
commit7e32c3915e7ea27d2533d99a22fa53ef923198f5 (patch)
tree5bd8d8a3ed6861e039a683f47a953d2f7a22d8b1
parent7545402506aa76261e18d85af585ff0ac1cf05c1 (diff)
Added run_exps.py option to --retry failed experiments.
If the retry flag is specified, failed experiments will be re-run after all other experiments have run. They can be re-run at most 5 times. This commit required a refactoring of run_exps.py to clean up the main experiment running loop.
-rw-r--r--gen/edf_generators.py1
-rwxr-xr-xgen_exps.py15
-rw-r--r--run/experiment.py50
-rwxr-xr-xrun_exps.py246
4 files changed, 194 insertions, 118 deletions
diff --git a/gen/edf_generators.py b/gen/edf_generators.py
index a722c21..8e4b8df 100644
--- a/gen/edf_generators.py
+++ b/gen/edf_generators.py
@@ -28,6 +28,7 @@ class EdfGenerator(gen.Generator):
28 pdist = self._create_dist('period', 28 pdist = self._create_dist('period',
29 exp_params['periods'], 29 exp_params['periods'],
30 gen.NAMED_PERIODS) 30 gen.NAMED_PERIODS)
31
31 udist = self._create_dist('utilization', 32 udist = self._create_dist('utilization',
32 exp_params['utils'], 33 exp_params['utils'],
33 gen.NAMED_UTILIZATIONS) 34 gen.NAMED_UTILIZATIONS)
diff --git a/gen_exps.py b/gen_exps.py
index b847661..00ce27b 100755
--- a/gen_exps.py
+++ b/gen_exps.py
@@ -43,6 +43,14 @@ def load_file(fname):
43 except: 43 except:
44 raise IOError("Invalid generation file: %s" % fname) 44 raise IOError("Invalid generation file: %s" % fname)
45 45
46def print_descriptions(described):
47 for generator in described.split(','):
48 if generator not in gen.get_generators():
49 sys.stderr.write("No generator '%s'\n" % generator)
50 else:
51 print("Generator '%s', " % generator)
52 gen.get_generators()[generator]().print_help()
53
46def main(): 54def main():
47 opts, args = parse_args() 55 opts, args = parse_args()
48 56
@@ -50,12 +58,7 @@ def main():
50 if opts.list_gens: 58 if opts.list_gens:
51 print(", ".join(gen.get_generators())) 59 print(", ".join(gen.get_generators()))
52 if opts.described != None: 60 if opts.described != None:
53 for generator in opts.described.split(','): 61 print_descriptions(opts.described)
54 if generator not in gen.get_generators():
55 sys.stderr.write("No generator '%s'\n" % generator)
56 else:
57 print("Generator '%s', " % generator)
58 gen.get_generators()[generator]().print_help()
59 if opts.list_gens or opts.described: 62 if opts.list_gens or opts.described:
60 return 0 63 return 0
61 64
diff --git a/run/experiment.py b/run/experiment.py
index b0e46b6..9a70414 100644
--- a/run/experiment.py
+++ b/run/experiment.py
@@ -2,6 +2,7 @@ import os
2import time 2import time
3import run.litmus_util as lu 3import run.litmus_util as lu
4import shutil as sh 4import shutil as sh
5
5from operator import methodcaller 6from operator import methodcaller
6 7
7class ExperimentException(Exception): 8class ExperimentException(Exception):
@@ -69,21 +70,24 @@ class Experiment(object):
69 executable.cwd = self.working_dir 70 executable.cwd = self.working_dir
70 map(assign_cwd, self.executables) 71 map(assign_cwd, self.executables)
71 72
72 def __kill_all(self): 73 def __try_kill_all(self):
73 if lu.waiting_tasks(): 74 try:
74 released = lu.release_tasks() 75 if lu.waiting_tasks():
75 self.log("Re-released %d tasks" % released) 76 released = lu.release_tasks()
77 self.log("Re-released %d tasks" % released)
76 78
77 time.sleep(1) 79 time.sleep(1)
78 80
79 self.log("Killing all tasks") 81 self.log("Killing all tasks")
80 for e in self.executables: 82 for e in self.executables:
81 try: 83 try:
82 e.kill() 84 e.kill()
83 except: 85 except:
84 pass 86 pass
85 87
86 time.sleep(1) 88 time.sleep(1)
89 except:
90 self.log("Failed to kill all tasks.")
87 91
88 def __strip_path(self, path): 92 def __strip_path(self, path):
89 '''Shorten path to something more readable.''' 93 '''Shorten path to something more readable.'''
@@ -138,7 +142,7 @@ class Experiment(object):
138 now_ready = lu.waiting_tasks() 142 now_ready = lu.waiting_tasks()
139 if now_ready != num_ready: 143 if now_ready != num_ready:
140 wait_start = time.time() 144 wait_start = time.time()
141 num_ready = lu.now_ready 145 num_ready = now_ready
142 146
143 def __run_tasks(self): 147 def __run_tasks(self):
144 self.log("Starting %d tasks" % len(self.executables)) 148 self.log("Starting %d tasks" % len(self.executables))
@@ -185,6 +189,7 @@ class Experiment(object):
185 189
186 sched = lu.scheduler() 190 sched = lu.scheduler()
187 if sched != "Linux": 191 if sched != "Linux":
192 self.log("Switching back to Linux scheduler")
188 try: 193 try:
189 lu.switch_scheduler("Linux") 194 lu.switch_scheduler("Linux")
190 except: 195 except:
@@ -229,6 +234,8 @@ class Experiment(object):
229 self.log("Stopping regular tracers") 234 self.log("Stopping regular tracers")
230 map(methodcaller('stop_tracing'), self.regular_tracers) 235 map(methodcaller('stop_tracing'), self.regular_tracers)
231 236
237 os.system('sync')
238
232 def log(self, msg): 239 def log(self, msg):
233 print("[Exp %s]: %s" % (self.name, msg)) 240 print("[Exp %s]: %s" % (self.name, msg))
234 241
@@ -236,6 +243,7 @@ class Experiment(object):
236 self.__to_linux() 243 self.__to_linux()
237 244
238 succ = False 245 succ = False
246 exception = None
239 try: 247 try:
240 self.__setup() 248 self.__setup()
241 249
@@ -244,16 +252,20 @@ class Experiment(object):
244 self.log("Saving results in %s" % self.finished_dir) 252 self.log("Saving results in %s" % self.finished_dir)
245 succ = True 253 succ = True
246 except Exception as e: 254 except Exception as e:
255 exception = e
256
247 # Give time for whatever failed to finish failing 257 # Give time for whatever failed to finish failing
248 time.sleep(2) 258 time.sleep(2)
249 self.__kill_all()
250 259
251 raise e 260 self.__try_kill_all()
252 finally:
253 self.__teardown()
254 finally: 261 finally:
255 self.log("Switching back to Linux scheduler") 262 try:
256 self.__to_linux() 263 self.__teardown()
264 self.__to_linux()
265 except Exception as e:
266 exception = exception or e
267 finally:
268 if exception: raise exception
257 269
258 if succ: 270 if succ:
259 self.__save_results() 271 self.__save_results()
diff --git a/run_exps.py b/run_exps.py
index a15018d..1d46b45 100755
--- a/run_exps.py
+++ b/run_exps.py
@@ -3,6 +3,7 @@ from __future__ import print_function
3 3
4import common as com 4import common as com
5import os 5import os
6import pprint
6import re 7import re
7import shutil 8import shutil
8import sys 9import sys
@@ -11,17 +12,26 @@ import run.tracer as trace
11from config.config import PARAMS,DEFAULTS 12from config.config import PARAMS,DEFAULTS
12from collections import namedtuple 13from collections import namedtuple
13from optparse import OptionParser 14from optparse import OptionParser
15from parse.enum import Enum
14from run.executable.executable import Executable 16from run.executable.executable import Executable
15from run.experiment import Experiment,ExperimentDone,SystemCorrupted 17from run.experiment import Experiment,ExperimentDone,SystemCorrupted
16from run.proc_entry import ProcEntry 18from run.proc_entry import ProcEntry
17 19
20'''Maximum times an experiment will be retried'''
21MAX_RETRY = 5
22
18'''Customizable experiment parameters''' 23'''Customizable experiment parameters'''
19ExpParams = namedtuple('ExpParams', ['scheduler', 'duration', 'tracers', 24ExpParams = namedtuple('ExpParams', ['scheduler', 'duration', 'tracers',
20 'kernel', 'config_options', 'file_params', 25 'kernel', 'config_options', 'file_params',
21 'pre_script', 'post_script']) 26 'pre_script', 'post_script'])
27'''Tracked with each experiment'''
28ExpState = Enum(['Failed', 'Succeeded', 'Invalid', 'Done', 'None'])
29ExpData = com.recordtype('ExpData', ['name', 'params', 'sched_file', 'out_dir',
30 'retries', 'state'])
22'''Comparison of requested versus actual kernel compile parameter value''' 31'''Comparison of requested versus actual kernel compile parameter value'''
23ConfigResult = namedtuple('ConfigResult', ['param', 'wanted', 'actual']) 32ConfigResult = namedtuple('ConfigResult', ['param', 'wanted', 'actual'])
24 33