diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-21 13:28:38 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-21 13:28:38 -0400 |
| commit | fbd1df6f63eb551b99f71330d2370c570ff323f5 (patch) | |
| tree | ca0db4599365bf8f4de7cd247c6363ef0ffba288 | |
| parent | daa0e3a92e03a89baf7ea3750df374df79123245 (diff) | |
Scripts read directories created by other scripts if no arguments.
With no arguments, all scripts first try to load the current directory. If the
current directory has no data, the scripts search for the output of the previous
scripts in the toolchain, e.g. parse_exps.py loads run-data/*, created by
run_exps.py.
This commit also switched messages to stderr where they belong, and adds in
missing lock and unlock overheads.
| -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() |
