diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-03-18 14:24:35 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-03-18 14:24:35 -0400 |
| commit | 57f52d18ca984a6328a04edbc1854407005e89cf (patch) | |
| tree | c9f15a12db30f270c95136e6a89b138ec400a531 | |
| parent | 0b49f91cd3f0e35acc6e3eeebf11f8d69aac834f (diff) | |
Allow users to specify required kernel configuration options.
| -rw-r--r-- | config/config.py | 1 | ||||
| -rwxr-xr-x | run_exps.py | 53 |
2 files changed, 44 insertions, 10 deletions
diff --git a/config/config.py b/config/config.py index a6edece..75130fd 100644 --- a/config/config.py +++ b/config/config.py | |||
| @@ -25,6 +25,7 @@ FILES = {'ft_data' : 'ft.bin', | |||
| 25 | PARAMS = {'sched' : 'scheduler', # Scheduler used by run_exps | 25 | PARAMS = {'sched' : 'scheduler', # Scheduler used by run_exps |
| 26 | 'dur' : 'duration', # Duration of tests in run_exps | 26 | 'dur' : 'duration', # Duration of tests in run_exps |
| 27 | 'kernel' : 'uname', # Regex of required OS name in run_exps | 27 | 'kernel' : 'uname', # Regex of required OS name in run_exps |
| 28 | 'copts' : 'config-options', # Required kernel configuration options | ||
| 28 | 'cycles' : 'clock-frequency', # Frequency run_exps was run with | 29 | 'cycles' : 'clock-frequency', # Frequency run_exps was run with |
| 29 | 'tasks' : 'tasks', # Number of tasks | 30 | 'tasks' : 'tasks', # Number of tasks |
| 30 | 'trial' : 'trial' # For multiple exps with same config | 31 | 'trial' : 'trial' # For multiple exps with same config |
diff --git a/run_exps.py b/run_exps.py index a05ff93..dc15701 100755 --- a/run_exps.py +++ b/run_exps.py | |||
| @@ -1,13 +1,14 @@ | |||
| 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
| 2 | from __future__ import print_function | 2 | from __future__ import print_function |
| 3 | 3 | ||
| 4 | import common as com | ||
| 4 | import config.config as conf | 5 | import config.config as conf |
| 5 | import os | 6 | import os |
| 6 | import re | 7 | import re |
| 7 | import shutil | 8 | import shutil |
| 8 | import traceback | 9 | import traceback |
| 9 | 10 | ||
| 10 | from common import load_params,get_executable,uname_matches,ft_freq | 11 | from collections import namedtuple |
| 11 | from optparse import OptionParser | 12 | from optparse import OptionParser |
| 12 | from run.executable.executable import Executable | 13 | from run.executable.executable import Executable |
| 13 | from run.experiment import Experiment,ExperimentDone | 14 | from run.experiment import Experiment,ExperimentDone |
| @@ -21,6 +22,16 @@ class InvalidKernel(Exception): | |||
| 21 | def __str__(self): | 22 | def __str__(self): |
| 22 | return "Kernel '%s' does not match '%s'." % (self.kernel, self.wanted) | 23 | return "Kernel '%s' does not match '%s'." % (self.kernel, self.wanted) |
| 23 | 24 | ||
| 25 | ConfigResult = namedtuple('ConfigResult', ['param', 'wanted', 'actual']) | ||
| 26 | class InvalidConfig(Exception): | ||
| 27 | def __init__(self, results): | ||
| 28 | self.results = results | ||
| 29 | |||
| 30 | def __str__(self): | ||
| 31 | rstr = "'%s' - wanted: '%s', found: %s" | ||
| 32 | result = [rstr % (r.actual, r.param, r.wanted) for r in self.results] | ||
| 33 | return "Invalid kernel configuration\n" + result.join("\n") | ||
| 34 | |||
| 24 | def parse_args(): | 35 | def parse_args(): |
| 25 | parser = OptionParser("usage: %prog [options] [sched_file]... [exp_dir]...") | 36 | parser = OptionParser("usage: %prog [options] [sched_file]... [exp_dir]...") |
| 26 | 37 | ||
| @@ -83,6 +94,23 @@ def fix_paths(schedule, exp_dir, sched_file): | |||
| 83 | 94 | ||
| 84 | schedule['spin'][idx] = (spin, args) | 95 | schedule['spin'][idx] = (spin, args) |
| 85 | 96 | ||
| 97 | def verify_environment(kernel, copts): | ||
| 98 | if kernel and not com.uname_matches(kernel): | ||
| 99 | raise InvalidKernel(kernel) | ||
| 100 | |||
| 101 | if copts: | ||
| 102 | results = [] | ||
| 103 | for param, wanted in copts.iteritems(): | ||
| 104 | try: | ||
| 105 | actual = com.get_config_option(param) | ||
| 106 | except IOError: | ||
| 107 | actual = None | ||
| 108 | if not str(wanted) == str(actual): | ||
| 109 | results += [ConfigResult(param, wanted, actual)] | ||
| 110 | |||
| 111 | if results: | ||
| 112 | raise InvalidKernel(results) | ||
| 113 | |||
| 86 | def load_experiment(sched_file, scheduler, duration, param_file, out_dir): | 114 | def load_experiment(sched_file, scheduler, duration, param_file, out_dir): |
| 87 | if not os.path.isfile(sched_file): | 115 | if not os.path.isfile(sched_file): |
| 88 | raise IOError("Cannot find schedule file: %s" % sched_file) | 116 | raise IOError("Cannot find schedule file: %s" % sched_file) |
| @@ -97,13 +125,16 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_dir): | |||
| 97 | "%s/%s" % (dir_name, conf.DEFAULTS['params_file']) | 125 | "%s/%s" % (dir_name, conf.DEFAULTS['params_file']) |
| 98 | 126 | ||
| 99 | if os.path.isfile(param_file): | 127 | if os.path.isfile(param_file): |
| 100 | params = load_params(param_file) | 128 | params = com.load_params(param_file) |
| 101 | scheduler = scheduler or params[conf.PARAMS['sched']] | 129 | scheduler = scheduler or params[conf.PARAMS['sched']] |
| 102 | duration = duration or params[conf.PARAMS['dur']] | 130 | duration = duration or params[conf.PARAMS['dur']] |
| 103 | 131 | ||
| 104 | # Experiments can specify required kernel name | 132 | # Experiments can specify required kernel name |
| 105 | if conf.PARAMS['kernel'] in params: | 133 | if conf.PARAMS['kernel'] in params: |
| 106 | kernel = params[conf.PARAMS['kernel']] | 134 | kernel = params[conf.PARAMS['kernel']] |
| 135 | # Or required config options | ||
| 136 | if conf.PARAMS['copts'] in params: | ||
| 137 | copts = params[conf.PARAMS['copts']] | ||
| 107 | 138 | ||
| 108 | duration = duration or conf.DEFAULTS['duration'] | 139 | duration = duration or conf.DEFAULTS['duration'] |
| 109 | 140 | ||
| @@ -113,8 +144,11 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_dir): | |||
| 113 | # Parse schedule file's intentions | 144 | # Parse schedule file's intentions |
| 114 | schedule = load_schedule(sched_file) | 145 | schedule = load_schedule(sched_file) |
| 115 | work_dir = "%s/tmp" % dir_name | 146 | work_dir = "%s/tmp" % dir_name |
| 147 | |||
| 116 | fix_paths(schedule, os.path.split(sched_file)[0], sched_file) | 148 | fix_paths(schedule, os.path.split(sched_file)[0], sched_file) |
| 117 | 149 | ||
| 150 | verify_environment(kernel, copts) | ||
| 151 | |||
| 118 | run_exp(exp_name, schedule, scheduler, kernel, duration, work_dir, out_dir) | 152 | run_exp(exp_name, schedule, scheduler, kernel, duration, work_dir, out_dir) |
| 119 | 153 | ||
| 120 | # Save parameters used to run experiment in out_dir | 154 | # Save parameters used to run experiment in out_dir |
| @@ -124,7 +158,7 @@ def load_experiment(sched_file, scheduler, duration, param_file, out_dir): | |||
| 124 | (conf.PARAMS['dur'], duration)]) | 158 | (conf.PARAMS['dur'], duration)]) |
| 125 | 159 | ||
| 126 | # Feather-trace clock frequency saved for accurate overhead parsing | 160 | # Feather-trace clock frequency saved for accurate overhead parsing |
| 127 | ft_freq = ft_freq() | 161 | ft_freq = com.ft_freq() |
| 128 | if ft_freq: | 162 | if ft_freq: |
| 129 | out_params[conf.PARAMS['cycles']] = ft_freq | 163 | out_params[conf.PARAMS['cycles']] = ft_freq |
| 130 | 164 | ||
| @@ -145,9 +179,6 @@ def run_exp(name, schedule, scheduler, kernel, duration, work_dir, out_dir): | |||
| 145 | proc_entries = [] | 179 | proc_entries = [] |
| 146 | executables = [] | 180 | executables = [] |
| 147 | 181 | ||
| 148 | if kernel and not uname_matches(kernel): | ||
| 149 | raise InvalidKernel(kernel) | ||
| 150 | |||
| 151 | # Parse values for proc entries | 182 | # Parse values for proc entries |
| 152 | for entry_conf in schedule['proc']: | 183 | for entry_conf in schedule['proc']: |
| 153 | path = entry_conf[0] | 184 | path = entry_conf[0] |
| @@ -172,12 +203,12 @@ def run_exp(name, schedule, scheduler, kernel, duration, work_dir, out_dir): | |||
| 172 | # if not conf.BINS[spin]: | 203 | # if not conf.BINS[spin]: |
| 173 | # raise IndexError("No knowledge of program %s: %s" % (spin, name)) | 204 | # raise IndexError("No knowledge of program %s: %s" % (spin, name)) |
| 174 | 205 | ||
| 175 | real_spin = get_executable(spin, "") | 206 | real_spin = com.get_executable(spin, "") |
| 176 | real_args = args.split() | 207 | real_args = args.split() |
| 177 | if re.match(".*spin", real_spin): | 208 | if re.match(".*spin", real_spin): |
| 178 | real_args = ['-w'] + real_args + [duration] | 209 | real_args = ['-w'] + real_args + [duration] |
| 179 | 210 | ||
| 180 | if not is_executable(real_spin): | 211 | if not com.is_executable(real_spin): |
| 181 | raise OSError("Cannot run spin %s: %s" % (real_spin, name)) | 212 | raise OSError("Cannot run spin %s: %s" % (real_spin, name)) |
| 182 | 213 | ||
| 183 | executables += [Executable(real_spin, real_args)] | 214 | executables += [Executable(real_spin, real_args)] |
| @@ -226,8 +257,10 @@ def main(): | |||
| 226 | except ExperimentDone: | 257 | except ExperimentDone: |
| 227 | done += 1 | 258 | done += 1 |
| 228 | print("Experiment '%s' already completed at '%s'" % (exp, out_base)) | 259 | print("Experiment '%s' already completed at '%s'" % (exp, out_base)) |
| 229 | except InvalidKernel: | 260 | except (InvalidKernel, InvalidConfig) as e: |
| 230 | invalid += 1 | 261 | invalid += 1 |
| 262 | print("Invalid environment for experiment '%s'") | ||
| 263 | print(e) | ||
| 231 | except: | 264 | except: |
| 232 | print("Failed experiment %s" % exp) | 265 | print("Failed experiment %s" % exp) |
| 233 | traceback.print_exc() | 266 | traceback.print_exc() |
| @@ -240,7 +273,7 @@ def main(): | |||
| 240 | print(" Successful:\t\t%d" % succ) | 273 | print(" Successful:\t\t%d" % succ) |
| 241 | print(" Failed:\t\t%d" % failed) | 274 | print(" Failed:\t\t%d" % failed) |
| 242 | print(" Already Done:\t\t%d" % done) | 275 | print(" Already Done:\t\t%d" % done) |
| 243 | print(" Wrong Kernel:\t\t%d" % invalid) | 276 | print(" Invalid environment:\t\t%d" % invalid) |
| 244 | 277 | ||
| 245 | 278 | ||
| 246 | if __name__ == '__main__': | 279 | if __name__ == '__main__': |
