aboutsummaryrefslogtreecommitdiffstats
path: root/gen/generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'gen/generator.py')
-rw-r--r--gen/generator.py62
1 files changed, 46 insertions, 16 deletions
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 @@
1import gen.rv as rv 1import gen.rv as rv
2import os 2import os
3import pprint
4import schedcat.generator.tasks as tasks
3import shutil as sh 5import shutil as sh
4 6
5from Cheetah.Template import Template 7from Cheetah.Template import Template
6from collections import namedtuple 8from common import get_config_option,num_cpus,recordtype
7from common import get_config_option,num_cpus
8from config.config import DEFAULTS,PARAMS 9from config.config import DEFAULTS,PARAMS
9from gen.dp import DesignPointGenerator 10from gen.dp import DesignPointGenerator
10from parse.col_map import ColMapBuilder 11from 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'''
38TP_RM = """#if $release_master 40TP_RM = """#if $release_master
39release_master{1} 41release_master{0}
40#end if""" 42#end if"""
41TP_TBASE = """#for $t in $task_set
42{} $t.cost $t.period
43#end for"""
44TP_GLOB_TASK = TP_TBASE.format("")
45TP_PART_TASK = TP_TBASE.format("-p $t.cpu")
46 43
47GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help']) 44GenOptionT = recordtype('GenOption', ['name', 'types', 'default', 'help', 'hidden'])
45def GenOption(name, types, default, help, hidden = False):
46 return GenOptionT(name, types, default, help, hidden)
48 47
49class Generator(object): 48class 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): 122 def _write_schedule(self, params):
108 '''Write schedule file using current template for @params.''' 123 '''Write schedule file using current template for @params.'''
109 sched_file = self.out_dir + "/" + DEFAULTS['sched_file'] 124 sched_file = self.out_dir + "/" + DEFAULTS['sched_file']
110 with open(sched_file, 'wa') as f: 125 with open(sched_file, 'wa') as f:
111 f.write(str(Template(self.template, searchList=[params]))) 126 f.write(str(Template(self.template, searchList=[params])))
112 127
128
113 def _write_params(self, params): 129 def _write_params(self, params):
114 '''Write out file with relevant parameters.''' 130 '''Write out file with relevant parameters.'''
131 # Don't include this in the parameters. It will be automatically added
132 # in run_exps.py
133 if 'num_tasks' in params:
134 num_tasks = params.pop('num_tasks')
135 else:
136 num_tasks = 0
137
115 exp_params_file = self.out_dir + "/" + DEFAULTS['params_file'] 138 exp_params_file = self.out_dir + "/" + DEFAULTS['params_file']
116 with open(exp_params_file, 'wa') as f: 139 with open(exp_params_file, 'wa') as f:
117 params['scheduler'] = self.name 140 params['scheduler'] = self.name
118 f.write(str(params)) 141 pprint.pprint(params, f)
142
143 if num_tasks:
144 params['num_tasks'] = num_tasks
119 145
120 def __setup_params(self, params): 146 def __setup_params(self, params):
121 '''Set default parameter values and check that values are valid.''' 147 '''Set default parameter values and check that values are valid.'''
122 for option in self.options: 148 for option in self.options:
123 if option.name not in params: 149 if option.name not in params:
124 params[option.name] = option.default 150 params[option.name] = option.default
151 else:
152 option.hidden = True
125 params[option.name] = self._check_value(option.name, 153 params[option.name] = self._check_value(option.name,
126 option.types, 154 option.types,
127 params[option.name]) 155 params[option.name])
@@ -207,14 +235,16 @@ class Generator(object):
207 if PARAMS['trial'] in dp: 235 if PARAMS['trial'] in dp:
208 del dp[PARAMS['trial']] 236 del dp[PARAMS['trial']]
209 237
238 HELP_INDENT = 17
210 239
211 def print_help(self): 240 def print_help(self):
241 display_options = [o for o in self.options if not o.hidden]
212 s = str(Template("""Generator $name: 242 s = str(Template("""Generator $name:
213 #for $o in $options 243 #for $o in $options
214 $o.name -- $o.help 244 $o.name -- $o.help
215 \tDefault: $o.default 245 \tDefault: $o.default
216 \tAllowed: $o.types 246 \tAllowed: $o.types
217 #end for""", searchList=vars(self))) 247 #end for""", searchList={'name':self.name, 'options':display_options}))
218 248
219 # Has to be an easier way to print this out... 249 # Has to be an easier way to print this out...
220 for line in s.split("\n"): 250 for line in s.split("\n"):
@@ -223,8 +253,8 @@ class Generator(object):
223 for word in line.split(", "): 253 for word in line.split(", "):
224 i += len(word) 254 i += len(word)
225 res += [word] 255 res += [word]
226 if i > 80: 256 if i > 80 and len(word) < 80:
227 print(", ".join(res[:-1])) 257 print(", ".join(res[:-1]))
228 res = ["\t\t "+res[-1]] 258 res = [" "*Generator.HELP_INDENT +res[-1]]
229 i = line.index("'") 259 i = Generator.HELP_INDENT + len(word)
230 print(", ".join(res)) 260 print(", ".join(res))