diff options
-rw-r--r-- | gen/generator.py (renamed from gen/generators.py) | 117 | ||||
-rwxr-xr-x | gen_exps.py | 2 |
2 files changed, 37 insertions, 82 deletions
diff --git a/gen/generators.py b/gen/generator.py index fccc747..28a6387 100644 --- a/gen/generators.py +++ b/gen/generator.py | |||
@@ -1,3 +1,8 @@ | |||
1 | import gen.rv as rv | ||
2 | import os | ||
3 | import run.litmus_util as lu | ||
4 | import shutil as sh | ||
5 | |||
1 | from Cheetah.Template import Template | 6 | from Cheetah.Template import Template |
2 | from collections import namedtuple | 7 | from collections import namedtuple |
3 | from common import get_config_option | 8 | from common import get_config_option |
@@ -5,13 +10,6 @@ from config.config import DEFAULTS | |||
5 | from gen.dp import DesignPointGenerator | 10 | from gen.dp import DesignPointGenerator |
6 | from parse.col_map import ColMapBuilder | 11 | from parse.col_map import ColMapBuilder |
7 | 12 | ||
8 | import gen.rv as rv | ||
9 | import os | ||
10 | import random | ||
11 | import run.litmus_util as lu | ||
12 | import schedcat.generator.tasks as tasks | ||
13 | import shutil as sh | ||
14 | |||
15 | NAMED_PERIODS = { | 13 | NAMED_PERIODS = { |
16 | 'harmonic' : rv.uniform_choice([25, 50, 100, 200]), | 14 | 'harmonic' : rv.uniform_choice([25, 50, 100, 200]), |
17 | 'uni-short' : rv.uniform_int( 3, 33), | 15 | 'uni-short' : rv.uniform_int( 3, 33), |
@@ -37,21 +35,24 @@ NAMED_UTILIZATIONS = { | |||
37 | (rv.uniform( 0.5, 0.9), 5)]), | 35 | (rv.uniform( 0.5, 0.9), 5)]), |
38 | } | 36 | } |
39 | 37 | ||
40 | # Cheetah templates for schedule files | 38 | '''Components of Cheetah template for schedule file''' |
41 | TP_CLUSTER = "plugins/C-EDF/cluster{$level}" | ||
42 | TP_RM = """#if $release_master | 39 | TP_RM = """#if $release_master |
43 | release_master{1} | 40 | release_master{1} |
44 | #end if""" | 41 | #end if""" |
45 | TP_TBASE = """#for $t in $task_set | 42 | TP_TBASE = """#for $t in $task_set |
46 | {}$t.cost $t.period | 43 | {} $t.cost $t.period |
47 | #end for""" | 44 | #end for""" |
48 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu ") | ||
49 | TP_GLOB_TASK = TP_TBASE.format("") | 45 | TP_GLOB_TASK = TP_TBASE.format("") |
46 | TP_PART_TASK = TP_TBASE.format("-p $t.cpu") | ||
50 | 47 | ||
51 | GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help']) | 48 | GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help']) |
52 | 49 | ||
53 | class BaseGenerator(object): | 50 | class Generator(object): |
54 | '''Creates sporadic task sets with the most common Litmus options.''' | 51 | '''Creates all combinations @options specified by @params. |
52 | |||
53 | This class also performs checks of parameter values and prints out help. | ||
54 | All subclasses must implement _create_exp. | ||
55 | ''' | ||
55 | def __init__(self, name, templates, options, params): | 56 | def __init__(self, name, templates, options, params): |
56 | self.options = self.__make_options(params) + options | 57 | self.options = self.__make_options(params) + options |
57 | 58 | ||
@@ -75,21 +76,19 @@ class BaseGenerator(object): | |||
75 | config = False | 76 | config = False |
76 | release_master = list(set([False, config])) | 77 | release_master = list(set([False, config])) |
77 | 78 | ||
78 | list_types = [str, float, type([])] | ||
79 | 79 | ||
80 | return [GenOption('cpus', int, [cpus], | 80 | return [GenOption('cpus', int, [cpus], |
81 | 'Number of processors on target system.'), | 81 | 'Number of processors on target system.'), |
82 | GenOption('num_tasks', int, range(cpus, 5*cpus, cpus), | ||
83 | 'Number of tasks per experiment.'), | ||
84 | GenOption('utils', list_types + NAMED_UTILIZATIONS.keys(), | ||
85 | ['uni-medium'],'Task utilization distributions.'), | ||
86 | GenOption('periods', list_types + NAMED_PERIODS.keys(), | ||
87 | ['harmonic'], 'Task period distributions.'), | ||
88 | GenOption('release_master', [True,False], release_master, | 82 | GenOption('release_master', [True,False], release_master, |
89 | 'Redirect release interrupts to a single CPU.'), | 83 | 'Redirect release interrupts to a single CPU.'), |
90 | GenOption('duration', float, [30], 'Experiment duration.')] | 84 | GenOption('duration', float, [30], 'Experiment duration.')] |
91 | 85 | ||
92 | def __create_dist(self, name, value, named_dists): | 86 | @staticmethod |
87 | def _dist_option(name, default, distribution, help): | ||
88 | return GenOption(name, [str, float, type([])] + distribution.keys(), | ||
89 | default, help) | ||
90 | |||
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 | 94 | name = "%s distribution" % name |
@@ -104,37 +103,18 @@ class BaseGenerator(object): | |||
104 | else: | 103 | else: |
105 | raise ValueError("Invalid %s value: %s" % (name, value)) | 104 | raise ValueError("Invalid %s value: %s" % (name, value)) |
106 | 105 | ||
107 | def __create_exp(self, exp_params, out_dir): | 106 | def _write_schedule(self, params): |
108 | '''Create a single experiment with @exp_params in @out_dir.''' | 107 | '''Write schedule file using current template for @params.''' |
109 | pdist = self.__create_dist('period', | 108 | sched_file = self.out_dir + "/" + DEFAULTS['sched_file'] |
110 | exp_params['periods'], | ||
111 | NAMED_PERIODS) | ||
112 | udist = self.__create_dist('utilization', | ||
113 | exp_params['utils'], | ||
114 | NAMED_UTILIZATIONS) | ||
115 | tg = tasks.TaskGenerator(period=pdist, util=udist) | ||
116 | |||
117 | ts = [] | ||
118 | tries = 0 | ||
119 | while len(ts) != exp_params['num_tasks'] and tries < 5: | ||
120 | ts = tg.make_task_set(max_tasks = exp_params['num_tasks']) | ||
121 | tries += 1 | ||
122 | if len(ts) != exp_params['num_tasks']: | ||
123 | print("Failed to create task set with parameters: %s" % exp_params) | ||
124 | |||
125 | self._customize(ts, exp_params) | ||
126 | |||
127 | sched_file = out_dir + "/" + DEFAULTS['sched_file'] | ||
128 | with open(sched_file, 'wa') as f: | 109 | with open(sched_file, 'wa') as f: |
129 | exp_params['task_set'] = ts | 110 | f.write(str(Template(self.template, searchList=[params]))) |
130 | f.write(str(Template(self.template, searchList=[exp_params]))) | ||
131 | 111 | ||
132 | del exp_params['task_set'] | 112 | def _write_params(self, params): |
133 | del exp_params['num_tasks'] | 113 | '''Write out file with relevant parameters.''' |
134 | exp_params_file = out_dir + "/" + DEFAULTS['params_file'] | 114 | exp_params_file = self.out_dir + "/" + DEFAULTS['params_file'] |
135 | with open(exp_params_file, 'wa') as f: | 115 | with open(exp_params_file, 'wa') as f: |
136 | exp_params['scheduler'] = self.name | 116 | params['scheduler'] = self.name |
137 | f.write(str(exp_params)) | 117 | f.write(str(params)) |
138 | 118 | ||
139 | def __setup_params(self, params): | 119 | def __setup_params(self, params): |
140 | '''Set default parameter values and check that values are valid.''' | 120 | '''Set default parameter values and check that values are valid.''' |
@@ -182,9 +162,9 @@ class BaseGenerator(object): | |||
182 | retval += [v] | 162 | retval += [v] |
183 | return retval | 163 | return retval |
184 | 164 | ||
185 | def _customize(self, taskset, exp_params): | 165 | def _create_exp(self, exp_params, out_dir): |
186 | '''Configure a generated taskset with extra parameters.''' | 166 | '''Overridden by subclasses.''' |
187 | pass | 167 | raise NotImplementedError |
188 | 168 | ||
189 | def create_exps(self, out_dir, force, trials): | 169 | def create_exps(self, out_dir, force, trials): |
190 | '''Create experiments for all possible combinations of params in | 170 | '''Create experiments for all possible combinations of params in |
@@ -216,7 +196,9 @@ class BaseGenerator(object): | |||
216 | 196 | ||
217 | os.mkdir(dir_path) | 197 | os.mkdir(dir_path) |
218 | 198 | ||
219 | self.__create_exp(dict(dp), dir_path) | 199 | self.out_dir = dir_path |
200 | self._create_exp(dict(dp)) | ||
201 | del(self.out_dir) | ||
220 | 202 | ||
221 | def print_help(self): | 203 | def print_help(self): |
222 | s = str(Template("""Generator $name: | 204 | s = str(Template("""Generator $name: |
@@ -231,37 +213,10 @@ class BaseGenerator(object): | |||
231 | res = [] | 213 | res = [] |
232 | i = 0 | 214 | i = 0 |
233 | for word in line.split(", "): | 215 | for word in line.split(", "): |
234 | i+= len(word) | 216 | i += len(word) |
235 | res += [word] | 217 | res += [word] |
236 | if i > 80: | 218 | if i > 80: |
237 | print(", ".join(res[:-1])) | 219 | print(", ".join(res[:-1])) |
238 | res = ["\t\t "+res[-1]] | 220 | res = ["\t\t "+res[-1]] |
239 | i = line.index("'") | 221 | i = line.index("'") |
240 | print(", ".join(res)) | 222 | print(", ".join(res)) |
241 | |||
242 | class PartitionedGenerator(BaseGenerator): | ||
243 | def __init__(self, name, templates, options, params): | ||
244 | super(PartitionedGenerator, self).__init__(name, | ||
245 | templates + [TP_PART_TASK], options, params) | ||
246 | |||
247 | def _customize(self, taskset, exp_params): | ||
248 | start = 1 if exp_params['release_master'] else 0 | ||
249 | # Random partition for now: could do a smart partitioning | ||
250 | for t in taskset: | ||
251 | t.cpu = random.randint(start, exp_params['cpus'] - 1) | ||
252 | |||
253 | class PedfGenerator(PartitionedGenerator): | ||
254 | def __init__(self, params={}): | ||
255 | super(PedfGenerator, self).__init__("PSN-EDF", [], [], params) | ||
256 | |||
257 | class CedfGenerator(PartitionedGenerator): | ||
258 | LEVEL_OPTION = GenOption('level', ['L2', 'L3', 'All'], ['L2'], | ||
259 | 'Cache clustering level.',) | ||
260 | |||
261 | def __init__(self, params={}): | ||
262 | super(CedfGenerator, self).__init__("C-EDF", [TP_CLUSTER], | ||
263 | [CedfGenerator.LEVEL_OPTION], params) | ||
264 | |||
265 | class GedfGenerator(BaseGenerator): | ||
266 | def __init__(self, params={}): | ||
267 | super(GedfGenerator, self).__init__("GSN-EDF", [TP_GLOB_TASK], [], params) | ||
diff --git a/gen_exps.py b/gen_exps.py index 80ae777..20a6c6f 100755 --- a/gen_exps.py +++ b/gen_exps.py | |||
@@ -5,7 +5,7 @@ import os | |||
5 | import re | 5 | import re |
6 | import shutil as sh | 6 | import shutil as sh |
7 | 7 | ||
8 | from gen.generators import GedfGenerator,PedfGenerator,CedfGenerator | 8 | from gen.edf_generators import GedfGenerator,PedfGenerator,CedfGenerator |
9 | from optparse import OptionParser | 9 | from optparse import OptionParser |
10 | 10 | ||
11 | # There has to be a better way to do this... | 11 | # There has to be a better way to do this... |