aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-04-12 11:30:27 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2013-04-12 11:30:27 -0400
commit09bc409657606a37346d82ab1e4c44a165bd3541 (patch)
tree72c569f69f37acafdc89fde4724bde7b373ef8f9
parent384e322f974534c1c734db144633e3c3e002b1f8 (diff)
Improved error handling in run_exps.py.
-rw-r--r--common.py6
-rw-r--r--parse/sched.py1
-rw-r--r--run/executable/executable.py6
-rw-r--r--run/experiment.py128
-rw-r--r--run/litmus_util.py23
-rwxr-xr-xrun_exps.py18
6 files changed, 114 insertions, 68 deletions
diff --git a/common.py b/common.py
index 4920ec8..a2c6224 100644
--- a/common.py
+++ b/common.py
@@ -26,15 +26,17 @@ def get_executable_hint(prog, hint, optional=False):
26 '''Search for @prog in system PATH. Print @hint if no binary is found. 26 '''Search for @prog in system PATH. Print @hint if no binary is found.
27 Die if not @optional.''' 27 Die if not @optional.'''
28 try: 28 try:
29 prog = get_executable(prog) 29 full_path = get_executable(prog)
30 except IOError: 30 except IOError:
31 if not optional: 31 if not optional:
32 sys.stderr.write(("Cannot find executable '%s' in PATH. This is " +\ 32 sys.stderr.write(("Cannot find executable '%s' in PATH. This is " +\
33 "a part of '%s' which should be added to PATH.\n")\ 33 "a part of '%s' which should be added to PATH.\n")\
34 % (prog, hint)) 34 % (prog, hint))
35 sys.exit(1) 35 sys.exit(1)
36 else:
37 full_path = None
36 38
37 return prog 39 return full_path
38 40
39def get_config_option(option): 41def get_config_option(option):
40 '''Search for @option in installed kernel config (if present). 42 '''Search for @option in installed kernel config (if present).
diff --git a/parse/sched.py b/parse/sched.py
index 2da0149..147a2e5 100644
--- a/parse/sched.py
+++ b/parse/sched.py
@@ -161,6 +161,7 @@ def extract_sched_data(result, data_dir, work_dir):
161 cmd_arr = [conf.BINS['st_show']] 161 cmd_arr = [conf.BINS['st_show']]
162 cmd_arr.extend(bins) 162 cmd_arr.extend(bins)
163 with open(output_file, "w") as f: 163 with open(output_file, "w") as f:
164 print("calling %s" % cmd_arr)
164 subprocess.call(cmd_arr, cwd=data_dir, stdout=f) 165 subprocess.call(cmd_arr, cwd=data_dir, stdout=f)
165 166
166 task_dict = defaultdict(lambda : 167 task_dict = defaultdict(lambda :
diff --git a/run/executable/executable.py b/run/executable/executable.py
index 02e35ae..263e305 100644
--- a/run/executable/executable.py
+++ b/run/executable/executable.py
@@ -1,13 +1,13 @@
1import sys 1import sys
2import subprocess 2import subprocess
3import signal 3import signal
4from common import is_executable 4from common import get_executable
5 5
6class Executable(object): 6class Executable(object):
7 '''Parent object that represents an executable for use in task-sets.''' 7 '''Parent object that represents an executable for use in task-sets.'''
8 8
9 def __init__(self, exec_file, extra_args=None, stdout_file = None, stderr_file = None): 9 def __init__(self, exec_file, extra_args=None, stdout_file = None, stderr_file = None):
10 self.exec_file = exec_file 10 self.exec_file = get_executable(exec_file)
11 self.cwd = None 11 self.cwd = None
12 self.stdout_file = stdout_file 12 self.stdout_file = stdout_file
13 self.stderr_file = stderr_file 13 self.stderr_file = stderr_file
@@ -18,7 +18,7 @@ class Executable(object):
18 else: 18 else:
19 self.extra_args = [str(a) for a in list(extra_args)] # make a duplicate 19 self.extra_args = [str(a) for a in list(extra_args)] # make a duplicate
20 20
21 if not is_executable(self.exec_file): 21 if not self.exec_file:
22 raise Exception("Not executable ? : %s" % self.exec_file) 22 raise Exception("Not executable ? : %s" % self.exec_file)
23 23
24 def __del__(self): 24 def __del__(self):
diff --git a/run/experiment.py b/run/experiment.py
index e5811f8..ff0e9f3 100644
--- a/run/experiment.py
+++ b/run/experiment.py
@@ -1,7 +1,9 @@
1import common as com
1import os 2import os
2import time 3import time
3import run.litmus_util as lu 4import run.litmus_util as lu
4import shutil as sh 5import shutil as sh
6import traceback
5from operator import methodcaller 7from operator import methodcaller
6 8
7class ExperimentException(Exception): 9class ExperimentException(Exception):
@@ -15,17 +17,12 @@ class ExperimentDone(ExperimentException):
15 def __str__(self): 17 def __str__(self):
16 return "Experiment finished already: %d" % self.name 18 return "Experiment finished already: %d" % self.name
17 19
18
19class ExperimentInterrupted(ExperimentException):
20 '''Raised when an experiment appears to be interrupted (partial results).'''
21 def __str__(self):
22 return "Experiment was interrupted in progress: %d" % self.name
23
24
25class ExperimentFailed(ExperimentException): 20class ExperimentFailed(ExperimentException):
26 def __str__(self): 21 def __str__(self):
27 return "Experiment failed during execution: %d" % self.name 22 return "Experiment failed during execution: %d" % self.name
28 23
24class SystemCorrupted(Exception):
25 pass
29 26
30class Experiment(object): 27class Experiment(object):
31 '''Execute one task-set and save the results. Experiments have unique IDs.''' 28 '''Execute one task-set and save the results. Experiments have unique IDs.'''
@@ -44,6 +41,8 @@ class Experiment(object):
44 self.exec_out = None 41 self.exec_out = None
45 self.exec_err = None 42 self.exec_err = None
46 43
44 self.task_batch = com.num_cpus()
45
47 self.__make_dirs() 46 self.__make_dirs()
48 self.__assign_executable_cwds() 47 self.__assign_executable_cwds()
49 self.__setup_tracers(tracer_types) 48 self.__setup_tracers(tracer_types)
@@ -84,65 +83,67 @@ class Experiment(object):
84 executable.cwd = self.working_dir 83 executable.cwd = self.working_dir
85 map(assign_cwd, self.executables) 84 map(assign_cwd, self.executables)
86 85
87 def __run_tasks(self): 86 def __kill_all(self):
88 already_waiting = lu.waiting_tasks() 87 # Give time for whatever failed to finish failing
88 time.sleep(2)
89
90 released = lu.release_tasks()
91 self.log("Re-released %d tasks" % released)
89 92
90 if already_waiting: 93 time.sleep(5)
91 self.log("Already %d tasks waiting for release!")
92 self.log("Experiment will fail if any of these tasks are released.")
93 94
94 self.log("Starting the programs") 95 self.log("Killing all tasks")
95 for e in self.executables: 96 for e in self.executables:
96 try: 97 try:
98 e.kill()
99 except:
100 pass
101
102 time.sleep(2)
103
104 def __run_tasks(self):
105 self.log("Starting %d tasks" % len(self.executables))
106
107 for i,e in enumerate(self.executables):
108 try:
97 e.execute() 109 e.execute()
98 except: 110 except:
99 raise Exception("Executable failed: %s" % e) 111 raise Exception("Executable failed: %s" % e)
100 112
101 self.log("Sleeping until tasks are ready for release...") 113 self.log("Sleeping until tasks are ready for release...")
102 start = time.clock() 114 start = time.time()
103 while (lu.waiting_tasks() - already_waiting) < len(self.executables): 115 while lu.waiting_tasks() < len(self.executables):
104 if time.clock() - start > 30.0: 116 if time.time() - start > 30.0:
105 raise Exception("Too much time has passed waiting for tasks!") 117 s = "waiting: %d, submitted: %d" %\
118 (lu.waiting_tasks(), len(self.executables))
119 raise Exception("Too much time spent waiting for tasks! %s" % s)
106 time.sleep(1) 120 time.sleep(1)
107 121
108 # Exact tracers (like overheads) must be started right after release or 122 # Exact tracers (like overheads) must be started right after release or
109 # measurements will be full of irrelevant records 123 # measurements will be full of irrelevant records
110 self.log("Starting %d released tracers" % len(self.exact_tracers)) 124 self.log("Starting %d released tracers" % len(self.exact_tracers))
111 map(methodcaller('start_tracing'), self.exact_tracers) 125 map(methodcaller('start_tracing'), self.exact_tracers)
126 time.sleep(1)
112 127
113 self.log("Releasing %d tasks" % len(self.executables)) 128 try:
114 released = lu.release_tasks() 129 self.log("Releasing %d tasks" % len(self.executables))
115
116 ret = True
117 if released != len(self.executables):
118 # Some tasks failed to release, kill all tasks and fail
119 # Need to re-release non-released tasks before we can kill them though
120 self.log("Failed to release {} tasks! Re-releasing and killing".format(
121 len(self.executables) - released, len(self.executables)))
122 time.sleep(5)
123
124 released = lu.release_tasks() 130 released = lu.release_tasks()
125 131
126 self.log("Re-released %d tasks" % released) 132 if released != len(self.executables):
127 133 # Some tasks failed to release, kill all tasks and fail
128 time.sleep(5) 134 # Need to release non-released tasks before they can be killed