aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/config.py7
-rwxr-xr-xgen_exps.py11
-rwxr-xr-xparse_exps.py34
-rwxr-xr-xplot_exps.py21
-rwxr-xr-xrun_exps.py73
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).'''
45SCHED_EVENTS = range(501, 513) 50SCHED_EVENTS = range(501, 513)
46 51
47'''Overhead events.''' 52'''Overhead events.'''
48OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS'] 53OVH_BASE_EVENTS = ['SCHED', 'RELEASE', 'SCHED2', 'TICK', 'CXS', 'LOCK', 'UNLOCK']
49OVH_ALL_EVENTS = ["%s_%s" % (e, t) for (e,t) in 54OVH_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"])]
51OVH_ALL_EVENTS += ['RELEASE_LATENCY'] 56OVH_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
7import shutil as sh 7import shutil as sh
8import sys 8import sys
9 9
10from config.config import DEFAULTS
10from optparse import OptionParser 11from optparse import OptionParser
11 12
12def parse_args(): 13def 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
97if __name__ == '__main__': 100if __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
2from __future__ import print_function 2from __future__ import print_function
3 3
4import config.config as conf
5import os 4import os
6import parse.ft as ft 5import parse.ft as ft
7import parse.sched as st 6import parse.sched as st
@@ -12,6 +11,7 @@ import traceback
12 11
13from collections import namedtuple 12from collections import namedtuple
14from common import load_params 13from common import load_params
14from config.config import DEFAULTS,PARAMS
15from optparse import OptionParser 15from optparse import OptionParser
16from parse.point import ExpPoint 16from parse.point import ExpPoint
17from parse.tuple_table import TupleTable 17from 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():
41ExpData = namedtuple('ExpData', ['path', 'params', 'work_dir']) 42ExpData = namedtuple('ExpData', ['path', 'params', 'work_dir'])
42 43
43def get_exp_params(data_dir, cm_builder): 44def 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
120def 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
119def main(): 131def 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
6import shutil as sh 6import shutil as sh
7import sys 7import sys
8import traceback 8import traceback
9
9from collections import namedtuple 10from collections import namedtuple
11from config.config import DEFAULTS
10from multiprocessing import Pool, cpu_count 12from multiprocessing import Pool, cpu_count
11from optparse import OptionParser 13from optparse import OptionParser
12from parse.col_map import ColMap,ColMapBuilder 14from 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
145def 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
142def main(): 153def 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
158if __name__ == '__main__': 171if __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 @@
2from __future__ import print_function 2from __future__ import print_function
3 3
4import common as com 4import common as com
5import config.config as conf
6import os 5import os
7import re 6import re
8import shutil 7import shutil
9import sys 8import sys
10import run.tracer as trace 9import run.tracer as trace
11 10
11from config.config import PARAMS,DEFAULTS
12from collections import namedtuple 12from collections import namedtuple
13from optparse import OptionParser 13from optparse import OptionParser
14from run.executable.executable import Executable 14from 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):
184def run_parameter(exp_dir, out_dir, params, param_name): 185def 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
294def 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
293def setup_jabber(target): 311def 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
303def setup_email(target): 322def 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
316def main(): 336def 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()