aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-03-07 14:51:32 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-03-07 14:51:32 -0500
commite3b7c78aa5b96af6bdbad20a13e0f540d1658b7f (patch)
treedc9590fb22e5d6484088d2c730b8eeea8db6a7b0
parente5d531eabf3091af18ca1a331e52b184a67750f7 (diff)
Seperated BaseGenerator into EdfGenerator and its superclass Generator.
-rw-r--r--gen/generator.py (renamed from gen/generators.py)117
-rwxr-xr-xgen_exps.py2
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 @@
1import gen.rv as rv
2import os
3import run.litmus_util as lu
4import shutil as sh
5
1from Cheetah.Template import Template 6from Cheetah.Template import Template
2from collections import namedtuple 7from collections import namedtuple
3from common import get_config_option 8from common import get_config_option
@@ -5,13 +10,6 @@ from config.config import DEFAULTS
5from gen.dp import DesignPointGenerator 10from gen.dp import DesignPointGenerator
6from parse.col_map import ColMapBuilder 11from parse.col_map import ColMapBuilder
7 12
8import gen.rv as rv
9import os
10import random
11import run.litmus_util as lu
12import schedcat.generator.tasks as tasks
13import shutil as sh
14
15NAMED_PERIODS = { 13NAMED_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'''
41TP_CLUSTER = "plugins/C-EDF/cluster{$level}"
42TP_RM = """#if $release_master 39TP_RM = """#if $release_master
43release_master{1} 40release_master{1}
44#end if""" 41#end if"""
45TP_TBASE = """#for $t in $task_set 42TP_TBASE = """#for $t in $task_set
46{}$t.cost $t.period 43{} $t.cost $t.period
47#end for""" 44#end for"""
48TP_PART_TASK = TP_TBASE.format("-p $t.cpu ")
49TP_GLOB_TASK = TP_TBASE.format("") 45TP_GLOB_TASK = TP_TBASE.format("")
46TP_PART_TASK = TP_TBASE.format("-p $t.cpu")
50 47
51GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help']) 48GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help'])
52 49
53class BaseGenerator(object): 50class 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
242class 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
253class PedfGenerator(PartitionedGenerator):
254 def __init__(self, params={}):
255 super(PedfGenerator, self).__init__("PSN-EDF", [], [], params)
256
257class 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
265class 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
5import re 5import re
6import shutil as sh 6import shutil as sh
7 7
8from gen.generators import GedfGenerator,PedfGenerator,CedfGenerator 8from gen.edf_generators import GedfGenerator,PedfGenerator,CedfGenerator
9from optparse import OptionParser 9from 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...