diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-08 15:42:16 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-08 15:42:16 -0400 |
commit | d169debf732270c9571be6ea6e7d920345bffc33 (patch) | |
tree | d86c1ff5d0e4a116fcc916717abb29a026862c74 /run | |
parent | 8864a4018c9b9088f330c3ef24ed7b5313ec36a2 (diff) |
Added parameter file options for tracers and pre/post experiment commands.
Diffstat (limited to 'run')
-rw-r--r-- | run/experiment.py | 56 | ||||
-rw-r--r-- | run/tracer.py | 52 |
2 files changed, 71 insertions, 37 deletions
diff --git a/run/experiment.py b/run/experiment.py index 03d6ab6..3dd4866 100644 --- a/run/experiment.py +++ b/run/experiment.py | |||
@@ -3,7 +3,6 @@ import time | |||
3 | import run.litmus_util as lu | 3 | import run.litmus_util as lu |
4 | import shutil as sh | 4 | import shutil as sh |
5 | from operator import methodcaller | 5 | from operator import methodcaller |
6 | from run.tracer import SchedTracer, LogTracer, PerfTracer, LinuxTracer, OverheadTracer | ||
7 | 6 | ||
8 | class ExperimentException(Exception): | 7 | class ExperimentException(Exception): |
9 | '''Used to indicate when there are problems with an experiment.''' | 8 | '''Used to indicate when there are problems with an experiment.''' |
@@ -32,7 +31,8 @@ class Experiment(object): | |||
32 | '''Execute one task-set and save the results. Experiments have unique IDs.''' | 31 | '''Execute one task-set and save the results. Experiments have unique IDs.''' |
33 | INTERRUPTED_DIR = ".interrupted" | 32 | INTERRUPTED_DIR = ".interrupted" |
34 | 33 | ||
35 | def __init__(self, name, scheduler, working_dir, finished_dir, proc_entries, executables): | 34 | def __init__(self, name, scheduler, working_dir, finished_dir, |
35 | proc_entries, executables, tracer_types): | ||
36 | '''Run an experiment, optionally wrapped in tracing.''' | 36 | '''Run an experiment, optionally wrapped in tracing.''' |
37 | 37 | ||
38 | self.name = name | 38 | self.name = name |
@@ -46,27 +46,17 @@ class Experiment(object): | |||
46 | 46 | ||
47 | self.__make_dirs() | 47 | self.__make_dirs() |
48 | self.__assign_executable_cwds() | 48 | self.__assign_executable_cwds() |
49 | self.__setup_tracers(tracer_types) | ||
49 | 50 | ||
50 | self.tracers = [] | 51 | |
51 | if SchedTracer.enabled(): | 52 | def __setup_tracers(self, tracer_types): |
52 | self.log("Enabling sched_trace") | 53 | tracers = [ t(self.working_dir) for t in tracer_types ] |
53 | self.tracers.append( SchedTracer(working_dir) ) | 54 | |
54 | if LinuxTracer.enabled(): | 55 | self.regular_tracers = [t for t in tracers if not t.is_exact()] |
55 | self.log("Enabling trace-cmd") | 56 | self.exact_tracers = [t for t in tracers if t.is_exact()] |
56 | self.tracers.append( LinuxTracer(working_dir) ) | 57 | |
57 | if LogTracer.enabled(): | 58 | for t in tracers: |
58 | self.log("Enabling logging") | 59 | self.log("Enabling %s" % t.get_name()) |
59 | self.tracers.append( LogTracer(working_dir) ) | ||
60 | if PerfTracer.enabled(): | ||
61 | self.log("Tracking CPU performance counters") | ||
62 | self.tracers.append( PerfTracer(working_dir) ) | ||
63 | |||
64 | # Overhead trace must be handled seperately, see __run_tasks | ||
65 | if OverheadTracer.enabled(): | ||
66 | self.log("Enabling overhead tracing") | ||
67 | self.overhead_trace = OverheadTracer(working_dir) | ||
68 | else: | ||
69 | self.overhead_trace = None | ||
70 | 60 | ||
71 | def __make_dirs(self): | 61 | def __make_dirs(self): |
72 | interrupted = None | 62 | interrupted = None |
@@ -111,11 +101,10 @@ class Experiment(object): | |||
111 | raise Exception("Too much time has passed waiting for tasks!") | 101 | raise Exception("Too much time has passed waiting for tasks!") |
112 | time.sleep(1) | 102 | time.sleep(1) |
113 | 103 | ||
114 | # Overhead tracer must be started right after release or overhead | 104 | # Exact tracers (like overheads) must be started right after release or |
115 | # measurements will be full of irrelevant records | 105 | # measurements will be full of irrelevant records |
116 | if self.overhead_trace: | 106 | self.log("Starting %d released tracers" % len(self.exact_tracers)) |
117 | self.log("Starting overhead trace") | 107 | map(methodcaller('start_tracing'), self.exact_tracers) |
118 | self.overhead_trace.start_tracing() | ||
119 | 108 | ||
120 | self.log("Releasing %d tasks" % len(self.executables)) | 109 | self.log("Releasing %d tasks" % len(self.executables)) |
121 | released = lu.release_tasks() | 110 | released = lu.release_tasks() |
@@ -145,10 +134,9 @@ class Experiment(object): | |||
145 | if not e.wait(): | 134 | if not e.wait(): |
146 | ret = False | 135 | ret = False |
147 | 136 | ||
148 | # And it must be stopped here for the same reason | 137 | # And these must be stopped here for the same reason |
149 | if self.overhead_trace: | 138 | self.log("Stopping exact tracers") |
150 | self.log("Stopping overhead trace") | 139 | map(methodcaller('stop_tracing'), self.exact_tracers) |
151 | self.overhead_trace.stop_tracing() | ||
152 | 140 | ||
153 | if not ret: | 141 | if not ret: |
154 | raise ExperimentFailed(self.name) | 142 | raise ExperimentFailed(self.name) |
@@ -186,8 +174,8 @@ class Experiment(object): | |||
186 | self.log("Switching to %s" % self.scheduler) | 174 | self.log("Switching to %s" % self.scheduler) |
187 | lu.switch_scheduler(self.scheduler) | 175 | lu.switch_scheduler(self.scheduler) |
188 | 176 | ||
189 | self.log("Starting %d tracers" % len(self.tracers)) | 177 | self.log("Starting %d regular tracers" % len(self.regular_tracers)) |
190 | map(methodcaller('start_tracing'), self.tracers) | 178 | map(methodcaller('start_tracing'), self.regular_tracers) |
191 | 179 | ||
192 | self.exec_out = open('%s/exec-out.txt' % self.working_dir, 'w') | 180 | self.exec_out = open('%s/exec-out.txt' % self.working_dir, 'w') |
193 | self.exec_err = open('%s/exec-err.txt' % self.working_dir, 'w') | 181 | self.exec_err = open('%s/exec-err.txt' % self.working_dir, 'w') |
@@ -200,6 +188,6 @@ class Experiment(object): | |||
200 | self.exec_out and self.exec_out.close() | 188 | self.exec_out and self.exec_out.close() |
201 | self.exec_err and self.exec_err.close() | 189 | self.exec_err and self.exec_err.close() |
202 | 190 | ||
203 | self.log("Stopping tracers") | 191 | self.log("Stopping regular tracers") |
204 | map(methodcaller('stop_tracing'), self.tracers) | 192 | map(methodcaller('stop_tracing'), self.regular_tracers) |
205 | 193 | ||
diff --git a/run/tracer.py b/run/tracer.py index 065797c..6e1d05c 100644 --- a/run/tracer.py +++ b/run/tracer.py | |||
@@ -6,10 +6,17 @@ from operator import methodcaller | |||
6 | from run.executable.ftcat import FTcat,Executable | 6 | from run.executable.ftcat import FTcat,Executable |
7 | 7 | ||
8 | class Tracer(object): | 8 | class Tracer(object): |
9 | def __init__(self, name, output_dir): | 9 | def __init__(self, name, output_dir, exact=False): |
10 | self.name = name | 10 | self.name = name |
11 | self.output_dir = output_dir | 11 | self.output_dir = output_dir |
12 | self.bins = [] | 12 | self.bins = [] |
13 | self.exact=exact | ||
14 | |||
15 | def get_name(self): | ||
16 | return self.name | ||
17 | |||
18 | def is_exact(self): | ||
19 | return self.exact | ||
13 | 20 | ||
14 | def start_tracing(self): | 21 | def start_tracing(self): |
15 | map(methodcaller("execute"), self.bins) | 22 | map(methodcaller("execute"), self.bins) |
@@ -23,7 +30,7 @@ class LinuxTracer(Tracer): | |||
23 | LITMUS_EVENTS = "%s/events/litmus" % EVENT_ROOT | 30 | LITMUS_EVENTS = "%s/events/litmus" % EVENT_ROOT |
24 | 31 | ||
25 | def __init__(self, output_dir): | 32 | def __init__(self, output_dir): |
26 | super(LinuxTracer, self).__init__("trace-cmd", output_dir) | 33 | super(LinuxTracer, self).__init__("Trace-cmd / Kernelshark", output_dir) |
27 | 34 | ||
28 | extra_args = ["record", # "-e", "sched:sched_switch", | 35 | extra_args = ["record", # "-e", "sched:sched_switch", |
29 | "-e", "litmus:*", | 36 | "-e", "litmus:*", |
@@ -89,7 +96,7 @@ class OverheadTracer(Tracer): | |||
89 | DEVICE_STR = '/dev/litmus/ft_trace0' | 96 | DEVICE_STR = '/dev/litmus/ft_trace0' |
90 | 97 | ||
91 | def __init__(self, output_dir): | 98 | def __init__(self, output_dir): |
92 | super(OverheadTracer, self).__init__("Overhead Trace", output_dir) | 99 | super(OverheadTracer, self).__init__("Overhead Trace", output_dir, True) |
93 | 100 | ||
94 | stdout_f = open('{0}/{1}'.format(self.output_dir, conf.FILES['ft_data']), 'w') | 101 | stdout_f = open('{0}/{1}'.format(self.output_dir, conf.FILES['ft_data']), 'w') |
95 | stderr_f = open('{0}/{1}.stderr.txt'.format(self.output_dir, conf.FILES['ft_data']), 'w') | 102 | stderr_f = open('{0}/{1}.stderr.txt'.format(self.output_dir, conf.FILES['ft_data']), 'w') |
@@ -109,3 +116,42 @@ class PerfTracer(Tracer): | |||
109 | @staticmethod | 116 | @staticmethod |
110 | def enabled(): | 117 | def enabled(): |
111 | return False | 118 | return False |
119 | |||
120 | |||
121 | tracers = {} | ||
122 | |||
123 | def register_tracer(tracer, name): | ||
124 | tracers[name] = tracer | ||
125 | |||
126 | def get_tracer_types(names): | ||
127 | error = True # Error if name is not present | ||
128 | errors = [] | ||
129 | |||
130 | if not names: | ||
131 | # Just return all enabled tracers if none specified | ||
132 | names = tracers.keys() | ||
133 | error = False | ||
134 | |||
135 | ret = [] | ||
136 | |||
137 | for name in names: | ||
138 | if name not in tracers: | ||
139 | raise ValueError("Invalid tracer '%s', valid names are: %s" % | ||
140 | (name, tracers.keys())) | ||
141 | |||
142 | if tracers[name].enabled(): | ||
143 | ret += [ tracers[name] ] | ||
144 | elif error: | ||
145 | errors += ["Tracer '%s' requested, but not enabled." % name] | ||
146 | |||
147 | if errors: | ||
148 | raise ValueError("Check your kernel compile configuration!\n" + | ||
149 | "\n".join(errors)) | ||
150 | |||
151 | return ret | ||
152 | |||
153 | register_tracer(LinuxTracer, "kernelshark") | ||
154 | register_tracer(LogTracer, "log") | ||
155 | register_tracer(SchedTracer, "sched") | ||
156 | register_tracer(OverheadTracer, "overhead") | ||
157 | |||