aboutsummaryrefslogtreecommitdiffstats
path: root/run_exps.py
diff options
context:
space:
mode:
Diffstat (limited to 'run_exps.py')
-rwxr-xr-x[-rw-r--r--]run_exps.py192
1 files changed, 192 insertions, 0 deletions
diff --git a/run_exps.py b/run_exps.py
index e69de29..c589f51 100644..100755
--- a/run_exps.py
+++ b/run_exps.py
@@ -0,0 +1,192 @@
1#!/usr/bin/env python
2from __future__ import print_function
3
4import config.config as conf
5import experiment.litmus_util as lu
6import os
7import re
8
9from collections import defaultdict
10from optparse import OptionParser
11from experiment.executable.executable import Executable
12from experiment.experiment import Experiment
13from experiment.proc_entry import ProcEntry
14
15
16def parse_args():
17 parser = OptionParser();
18
19 parser.add_option('-s', '--scheduler', dest='scheduler',
20 help='scheduler for all experiments')
21 parser.add_option('-d', '--duration', dest='duration', type='int',
22 help='duration (seconds) of tasks')
23 parser.add_option('-o', '--out-dir', dest='out_dir',
24 help='directory for data output', default=os.getcwd())
25 parser.add_option('-p', '--params', dest='param_file',
26 help='file with experiment parameters')
27 parser.add_option('-f', '--schedule-file', dest='sched_file',
28 help='name of schedule files',
29 default=conf.DEFAULTS['sched_file'])
30
31 return parser.parse_args()
32
33
34def convert_data(data):
35 """Convert a non-python schedule file into the python format"""
36 regex = re.compile(
37
38 r"(?P<PROC>^"
39 r"(?P<HEADER>/proc/\w+?/)?"
40 r"(?P<ENTRY>[\w\/]+)"
41 r"\s*{\s*(?P<CONTENT>.*?)\s*?}$)|"
42 r"(?P<SPIN>^(?P<TYPE>\w+?spin)?\s*?"
43 r"(?P<ARGS>\w[\s\w]*?)?\s*?$)",
44 re.S|re.I|re.M)
45
46 procs = []
47 spins = []
48
49 for match in regex.finditer(data):
50 if match.group("PROC"):
51 header = match.group("HEADER") or "/proc/litmus/"
52 loc = "{}{}".format(header, match.group("ENTRY"))
53 proc = (loc, match.group("CONTENT"))
54 procs.append(proc)
55 else:
56 prog = match.group("TYPE") or "rtspin"
57 spin = (prog, match.group("ARGS"))
58 spins.append(spin)
59
60 return {'proc' : procs, 'spin' : spins}
61
62
63def get_dirs(sched_file, out_base_dir):
64 sched_leaf_dir = re.findall(r".*/([\w_-]+)/.*?$", sched_file)[0]
65 sched_full_dir = os.path.split(sched_file)[0]
66
67 work_dir = "%s/tmp" % sched_full_dir
68
69 if sched_full_dir == out_base_dir:
70 out_dir = "%s/data" % sched_full_dir
71 else:
72 # Put it under the base output dir with the same directory name
73 out_dir = "%s/%s" % (out_base_dir, sched_leaf_dir)
74
75 return (work_dir, out_dir)
76
77
78def load_experiment(sched_file, scheduler, duration, param_file, out_base):
79 if not os.path.isfile(sched_file):
80 raise IOError("Cannot find schedule file: %s" % sched_file)
81
82 dirname = os.path.split(sched_file)[0]
83
84 if not scheduler or not duration:
85 param_file = param_file or \
86 "%s/%s" % (dirname, conf.DEFAULTS['params_file'])
87
88 if os.path.isfile(param_file):
89 params = load_params(param_file)
90 scheduler = scheduler or params[conf.PARAMS['sched']]
91 duration = duration or params[conf.PARAMS['dur']]
92
93 duration = duration or conf.DEFAULTS['duration']
94
95 if not scheduler:
96 raise IOError("Parameter scheduler not specified")
97
98 schedule = load_schedule(sched_file)
99 (work_dir, out_dir) = get_dirs(sched_file, out_base)
100
101 run_exp(sched_file, schedule, scheduler, duration, work_dir, out_dir)
102
103
104def load_params(fname):
105 params = defaultdict(int)
106 with open(fname, 'r') as f:
107 data = f.read()
108 try:
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
118def load_schedule(fname):
119 with open(fname, 'r') as f:
120 data = f.read()
121 try:
122 schedule = eval(data)
123 except:
124 schedule = convert_data(data)
125 return schedule
126
127
128def run_exp(name, schedule, scheduler, duration, work_dir, out_dir):
129 proc_entries = []
130 executables = []
131
132 # Parse values for proc entries
133 for entry_conf in schedule['proc']:
134 path = entry_conf[0]
135 data = entry_conf[1]
136
137 if not os.path.exists(path):
138 raise IOError("Invalid proc path %s: %s" % (path, name))
139
140 proc_entries += [ProcEntry(path, data)]
141
142 # Parse spinners
143 for spin_conf in schedule['spin']:
144 if isinstance(spin_conf, str):
145 # Just a string defaults to default spin
146 (spin, args) = (conf.DEFAULTS['spin'], spin_conf)
147 else:
148 # Otherwise its a pair, the type and the args
149 if len(spin_conf) != 2:
150 raise IOError("Invalid spin conf %s: %s" % (spin_conf, name))
151 (spin, args) = (spin_conf[0], spin_conf[1])
152
153 if not conf.BINS[spin]:
154 raise IndexError("No knowledge of program %s: %s" % (spin, name))
155
156 real_spin = conf.BINS[spin]
157 real_args = ['-w'] + args.split() + [duration]
158
159 if not lu.is_executable(real_spin):
160 raise OSError("Cannot run spin %s: %s" % (real_spin, name))
161
162 executables += [Executable(real_spin, real_args)]
163
164 exp = Experiment(name, scheduler, work_dir, out_dir,
165 proc_entries, executables)
166 exp.run_exp()
167
168
169def main():
170 opts, args = parse_args()
171
172 scheduler = opts.scheduler
173 duration = opts.duration
174 param_file = opts.param_file
175 out_base = os.path.abspath(opts.out_dir)
176
177 args = args or [opts.sched_file]
178
179 for exp in args:
180 path = "%s/%s" % (os.getcwd(), exp)
181
182 if not os.path.exists(path):
183 raise IOError("Invalid experiment: %s" % path)
184
185 if os.path.isdir(exp):
186 path = "%s%s" % (path, opts.sched_file)
187
188 load_experiment(path, scheduler, duration, param_file, out_base)
189
190
191if __name__ == '__main__':
192 main()