diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-03-30 11:28:51 -0400 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-04-02 10:38:21 -0400 |
| commit | 4b75d2b98036195b78d339210ab8d7512d9f2164 (patch) | |
| tree | f7de0e91372f760ab8972c5e280023d57abb6b91 | |
| parent | cb0dda981282df08c544e235f0fefb077268272c (diff) | |
Added option to ignore environment issues and rewrote part of the generation scripts for easier generator creation.
| -rw-r--r-- | common.py | 11 | ||||
| -rw-r--r-- | gen/edf_generators.py | 30 | ||||
| -rw-r--r-- | gen/generator.py | 62 | ||||
| -rwxr-xr-x | gen_exps.py | 4 | ||||
| -rw-r--r-- | run/proc_entry.py | 7 | ||||
| -rwxr-xr-x | run_exps.py | 28 |
6 files changed, 93 insertions, 49 deletions
| @@ -50,6 +50,12 @@ def get_config_option(option): | |||
| 50 | else: | 50 | else: |
| 51 | raise IOError("No config file exists!") | 51 | raise IOError("No config file exists!") |
| 52 | 52 | ||
| 53 | def try_get_config_option(option, default): | ||
| 54 | try: | ||
| 55 | get_config_option(option) | ||
| 56 | except: | ||
| 57 | return default | ||
| 58 | |||
| 53 | def recordtype(typename, field_names, default=0): | 59 | def recordtype(typename, field_names, default=0): |
| 54 | ''' Mutable namedtuple. Recipe from George Sakkis of MIT.''' | 60 | ''' Mutable namedtuple. Recipe from George Sakkis of MIT.''' |
| 55 | field_names = tuple(map(str, field_names)) | 61 | field_names = tuple(map(str, field_names)) |
| @@ -127,10 +133,7 @@ def load_params(fname): | |||
| 127 | with open(fname, 'r') as f: | 133 | with open(fname, 'r') as f: |
| 128 | data = f.read() | 134 | data = f.read() |
| 129 | try: | 135 | try: |
| 130 | parsed = eval(data) | 136 | params = eval(data) |
| 131 | # Convert to defaultdict | ||
| 132 | for k in parsed: | ||
| 133 | params[k] = str(parsed[k]) | ||
| 134 | except Exception as e: | 137 | except Exception as e: |
| 135 | raise IOError("Invalid param file: %s\n%s" % (fname, e)) | 138 | raise IOError("Invalid param file: %s\n%s" % (fname, e)) |
| 136 | 139 | ||
diff --git a/gen/edf_generators.py b/gen/edf_generators.py index c7267f7..9bf6b8f 100644 --- a/gen/edf_generators.py +++ b/gen/edf_generators.py | |||
| @@ -1,15 +1,20 @@ | |||
| 1 | import generator as gen | 1 | import generator as gen |
| 2 | import random | 2 | import random |
| 3 | import schedcat.generator.tasks as tasks | 3 | |
| 4 | TP_TBASE = """#for $t in $task_set | ||
| 5 | {} $t.cost $t.period | ||
| 6 | #end for""" | ||
| 7 | TP_GLOB_TASK = TP_TBASE.format("") | ||
| 8 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu") | ||
| 4 | 9 | ||
| 5 | class EdfGenerator(gen.Generator): | 10 | class EdfGenerator(gen.Generator): |
| 6 | '''Creates sporadic task sets with the most common Litmus options.''' | 11 | '''Creates sporadic task sets with the most common Litmus options.''' |
| 7 | def __init__(self, name, templates, options, params): | 12 | def __init__(self, name, templates, options, params): |
| 8 | super(EdfGenerator, self).__init__(name, templates, | 13 | super(EdfGenerator, self).__init__(name, templates, |
| 9 | self.__make_options(params) + options, | 14 | self.__make_options() + options, |
| 10 | params) | 15 | params) |
| 11 | 16 | ||
| 12 | def __make_options(self, params): | 17 | def __make_options(self): |
| 13 | '''Return generic EDF options.''' | 18 | '''Return generic EDF options.''' |
| 14 | return [gen.Generator._dist_option('utils', ['uni-medium'], | 19 | return [gen.Generator._dist_option('utils', ['uni-medium'], |
| 15 | gen.NAMED_UTILIZATIONS, | 20 | gen.NAMED_UTILIZATIONS, |
| @@ -26,23 +31,12 @@ class EdfGenerator(gen.Generator): | |||
| 26 | udist = self._create_dist('utilization', | 31 | udist = self._create_dist('utilization', |
| 27 | exp_params['utils'], | 32 | exp_params['utils'], |
| 28 | gen.NAMED_UTILIZATIONS) | 33 | gen.NAMED_UTILIZATIONS) |
| 29 | tg = tasks.TaskGenerator(period=pdist, util=udist) | ||
| 30 | 34 | ||
| 31 | ts = [] | 35 | ts = self._create_taskset(exp_params, pdist, udist) |
| 32 | tries = 0 | ||
| 33 | while len(ts) != exp_params['num_tasks'] and tries < 5: | ||
| 34 | ts = tg.make_task_set(max_tasks = exp_params['num_tasks']) | ||
| 35 | tries += 1 | ||
| 36 | if len(ts) != exp_params['num_tasks']: | ||
| 37 | print("Failed to create task set with parameters: %s" % exp_params) | ||
| 38 | 36 | ||
| 39 | self._customize(ts, exp_params) | 37 | self._customize(ts, exp_params) |
| 40 | 38 | ||
| 41 | exp_params['task_set'] = ts | 39 | self._write_schedule(dict(exp_params.items() + ('task_set', ts))) |
| 42 | self._write_schedule(exp_params) | ||
| 43 | |||
| 44 | del exp_params['task_set'] | ||
| 45 | del exp_params['num_tasks'] | ||
| 46 | self._write_params(exp_params) | 40 | self._write_params(exp_params) |
| 47 | 41 | ||
| 48 | def _customize(self, taskset, exp_params): | 42 | def _customize(self, taskset, exp_params): |
| @@ -53,7 +47,7 @@ class EdfGenerator(gen.Generator): | |||
| 53 | class PartitionedGenerator(EdfGenerator): | 47 | class PartitionedGenerator(EdfGenerator): |
| 54 | def __init__(self, name, templates, options, params): | 48 | def __init__(self, name, templates, options, params): |
| 55 | super(PartitionedGenerator, self).__init__(name, | 49 | super(PartitionedGenerator, self).__init__(name, |
| 56 | templates + [gen.TP_PART_TASK], options, params) | 50 | templates + [TP_PART_TASK], options, params) |
| 57 | 51 | ||
| 58 | def _customize(self, taskset, exp_params): | 52 | def _customize(self, taskset, exp_params): |
| 59 | start = 1 if exp_params['release_master'] else 0 | 53 | start = 1 if exp_params['release_master'] else 0 |
| @@ -78,5 +72,5 @@ class CedfGenerator(PartitionedGenerator): | |||
| 78 | 72 | ||
| 79 | class GedfGenerator(EdfGenerator): | 73 | class GedfGenerator(EdfGenerator): |
| 80 | def __init__(self, params={}): | 74 | def __init__(self, params={}): |
| 81 | super(GedfGenerator, self).__init__("GSN-EDF", [gen.TP_GLOB_TASK], | 75 | super(GedfGenerator, self).__init__("GSN-EDF", [TP_GLOB_TASK], |
| 82 | [], params) | 76 | [], params) |
diff --git a/gen/generator.py b/gen/generator.py index 8c3048b..3a6524d 100644 --- a/gen/generator.py +++ b/gen/generator.py | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | import gen.rv as rv | 1 | import gen.rv as rv |
| 2 | import os | 2 | import os |
| 3 | import pprint | ||
| 4 | import schedcat.generator.tasks as tasks | ||
| 3 | import shutil as sh | 5 | import shutil as sh |
| 4 | 6 | ||
| 5 | from Cheetah.Template import Template | 7 | from Cheetah.Template import Template |
| 6 | from collections import namedtuple | 8 | from common import get_config_option,num_cpus,recordtype |
| 7 | from common import get_config_option,num_cpus | ||
| 8 | from config.config import DEFAULTS,PARAMS | 9 | from config.config import DEFAULTS,PARAMS |
| 9 | from gen.dp import DesignPointGenerator | 10 | from gen.dp import DesignPointGenerator |
| 10 | from parse.col_map import ColMapBuilder | 11 | from parse.col_map import ColMapBuilder |
| @@ -21,6 +22,7 @@ NAMED_UTILIZATIONS = { | |||
| 21 | 'uni-light' : rv.uniform(0.001, 0.1), | 22 | 'uni-light' : rv.uniform(0.001, 0.1), |
| 22 | 'uni-medium' : rv.uniform( 0.1, 0.4), | 23 | 'uni-medium' : rv.uniform( 0.1, 0.4), |
| 23 | 'uni-heavy' : rv.uniform( 0.5, 0.9), | 24 | 'uni-heavy' : rv.uniform( 0.5, 0.9), |
| 25 | 'uni-mixed' : rv.uniform(0.001, .4), | ||
| 24 | 26 | ||
| 25 | 'exp-light' : rv.exponential(0, 1, 0.10), | 27 | 'exp-light' : rv.exponential(0, 1, 0.10), |
| 26 | 'exp-medium' : rv.exponential(0, 1, 0.25), | 28 | 'exp-medium' : rv.exponential(0, 1, 0.25), |
| @@ -36,15 +38,12 @@ NAMED_UTILIZATIONS = { | |||
| 36 | 38 | ||
| 37 | '''Components of Cheetah template for schedule file''' | 39 | '''Components of Cheetah template for schedule file''' |
| 38 | TP_RM = """#if $release_master | 40 | TP_RM = """#if $release_master |
| 39 | release_master{1} | 41 | release_master{0} |
| 40 | #end if""" | 42 | #end if""" |
| 41 | TP_TBASE = """#for $t in $task_set | ||
| 42 | {} $t.cost $t.period | ||
| 43 | #end for""" | ||
| 44 | TP_GLOB_TASK = TP_TBASE.format("") | ||
| 45 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu") | ||
| 46 | 43 | ||
| 47 | GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help']) | 44 | GenOptionT = recordtype('GenOption', ['name', 'types', 'default', 'help', 'hidden']) |
| 45 | def GenOption(name, types, default, help, hidden = False): | ||
| 46 | return GenOptionT(name, types, default, help, hidden) | ||
| 48 | 47 | ||
| 49 | class Generator(object): | 48 | class Generator(object): |
| 50 | '''Creates all combinations @options specified by @params. | 49 | '''Creates all combinations @options specified by @params. |
| @@ -92,36 +91,65 @@ class Generator(object): | |||
| 92 | def _create_dist(self, name, value, named_dists): | 91 | def _create_dist(self, name, value, named_dists): |
| 93 | '''Attempt to create a distribution representing the data in @value. | 92 | '''Attempt to create a distribution representing the data in @value. |
| 94 | If @value is a string, use it as a key for @named_dists.''' | 93 | If @value is a string, use it as a key for @named_dists.''' |
| 95 | name = "%s distribution" % name | ||
| 96 | # A list of values | 94 | # A list of values |
| 97 | if type(value) == type([]): | 95 | if type(value) == type([]): |
| 98 | map(lambda x : self.__check_value(name, x, [float, int]), value) | 96 | map(lambda x : self.__check_value(name, x, [float, int]), value) |
| 99 | return rv.uniform_choice(value) | 97 | return rv.uniform_choice(value) |
| 100 | elif type(value) in [float, int]: | 98 | elif type(value) in [float, int]: |
| 101 | return lambda : value | 99 | return lambda : value |
| 102 | elif value in named_dists: | 100 | elif named_dists and value in named_dists: |
| 103 | return named_dists[value] | 101 | return named_dists[value] |
| 104 | else: | 102 | else: |
| 105 | raise ValueError("Invalid %s value: %s" % (name, value)) | 103 | raise ValueError("Invalid %s value: %s" % (name, value)) |
| 106 | 104 | ||
| 105 | def _create_taskset(self, params, periods, utils, max_util = None): | ||
| 106 | tg = tasks.TaskGenerator(period=periods, util=utils) | ||
| 107 | ts = [] | ||
| 108 | tries = 0 | ||
| 109 | while len(ts) != params['num_tasks'] and tries < 100: | ||
| 110 | ts = tg.make_task_set(max_tasks = params['num_tasks'], max_util=max_util) | ||
| 111 | tries += 1 | ||
| 112 | if len(ts) != params['num_tasks']: | ||
| 113 | print(("Only created task set of size %d < %d for params %s. " + | ||
| 114 | "Switching to light utilization.") % | ||
| 115 | (len(ts), params['num_tasks'], params)) | ||
| 116 | print("Switching to light util. This usually means the " + | ||
| 117 | "utilization distribution is too agressive.") | ||
| 118 | return self._create_taskset(params, periods, NAMED_UTILIZATIONS['uni-light'], | ||
| 119 | max_util) | ||
| 120 | return ts | ||
| 121 | |||
| 107 | def _write_schedule(self, params): | ||
