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