aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common.py26
-rw-r--r--config/config.py16
-rw-r--r--gen/__init__.py0
-rw-r--r--gen/dp.py33
-rw-r--r--gen/generators.py257
-rw-r--r--gen/rv.py86
-rwxr-xr-x[-rw-r--r--]gen_exps.py98
-rw-r--r--parse/ft.py4
-rw-r--r--parse/sched.py2
-rw-r--r--parse/tuple_table.py9
-rwxr-xr-xparse_exps.py13
-rwxr-xr-xrun_exps.py1
12 files changed, 525 insertions, 20 deletions
diff --git a/common.py b/common.py
index 0990cfe..ad3c418 100644
--- a/common.py
+++ b/common.py
@@ -1,9 +1,14 @@
1import os
2import re
3import subprocess
1import sys 4import sys
5
2from collections import defaultdict 6from collections import defaultdict
3from textwrap import dedent 7from textwrap import dedent
4 8
5def get_executable(prog, hint, optional=False): 9def get_executable(prog, hint, optional=False):
6 import os 10 '''Search for @prog in system PATH. Print @hint if no binary is found.'''
11
7 def is_exe(fpath): 12 def is_exe(fpath):
8 return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 13 return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
9 14
@@ -19,12 +24,29 @@ def get_executable(prog, hint, optional=False):
19 24
20 if not optional: 25 if not optional:
21 sys.stderr.write("Cannot find executable '%s' in PATH. This is a part " 26 sys.stderr.write("Cannot find executable '%s' in PATH. This is a part "
22 "of '%s' which should be added to PATH to run." % 27 "of '%s' which should be added to PATH to run.\n" %
23 (prog, hint)) 28 (prog, hint))
24 sys.exit(1) 29 sys.exit(1)
25 else: 30 else:
26 return None 31 return None
27 32
33def get_config_option(option):
34 '''Search for @option in installed kernel config (if present).
35 Raise an IOError if the kernel config isn't found in /boot/.'''
36 uname = subprocess.check_output(["uname", "-r"])[-1]
37 fname = "/boot/config-%s" % uname
38
39 if os.path.exists(fname):
40 config_regex = "^CONFIG_{}=(?P<val>.*)$".format(option)
41 match = re.search(config_regex, open(fname, 'r').read())
42 if not match:
43 return None
44 else:
45 return match.group("val")
46
47 else:
48 raise IOError("No config file exists!")
49
28def recordtype(typename, field_names, default=0): 50def recordtype(typename, field_names, default=0):
29 ''' Mutable namedtuple. Recipe from George Sakkis of MIT.''' 51 ''' Mutable namedtuple. Recipe from George Sakkis of MIT.'''
30 field_names = tuple(map(str, field_names)) 52 field_names = tuple(map(str, field_names))
diff --git a/config/config.py b/config/config.py
index 3282705..d463999 100644
--- a/config/config.py
+++ b/config/config.py
@@ -17,18 +17,20 @@ BINS = {'rtspin' : get_executable('rtspin', 'liblitmus'),
17FILES = {'ft_data' : 'ft.bin', 17FILES = {'ft_data' : 'ft.bin',
18 'linux_data' : 'trace.dat', 18 'linux_data' : 'trace.dat',
19 'sched_data' : 'st-{}.bin', 19 'sched_data' : 'st-{}.bin',
20 'log_data' : 'trace.slog',} 20 'log_data' : 'trace.slog'}
21 21
22'''Default parameter names in params.py.''' 22'''Default parameter names in params.py.'''
23PARAMS = {'sched' : 'scheduler', 23# TODO: add check for config options
24 'dur' : 'duration', 24PARAMS = {'sched' : 'scheduler', # Scheduler used by run_exps
25 'kernel' : 'uname', 25 'dur' : 'duration', # Duration of tests in run_exps
26 'cycles' : 'cpu-frequency'} 26 'kernel' : 'uname', # Regex of required OS name in run_exps
27 'cycles' : 'cpu-frequency', # Frequency run_exps was run with
28 'tasks' : 'tasks' # Number of tasks
29 }
27 30
28'''Default values for program parameters.''' 31'''Default values for program options.'''
29DEFAULTS = {'params_file' : 'params.py', 32DEFAULTS = {'params_file' : 'params.py',
30 'sched_file' : 'sched.py', 33 'sched_file' : 'sched.py',
31 'exps_file' : 'exps.py',
32 'duration' : 10, 34 'duration' : 10,
33 'spin' : 'rtspin', 35 'spin' : 'rtspin',
34 'cycles' : 2000} 36 'cycles' : 2000}
diff --git a/gen/__init__.py b/gen/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gen/__init__.py
diff --git a/gen/dp.py b/gen/dp.py
new file mode 100644
index 0000000..0ac8cce
--- /dev/null
+++ b/gen/dp.py
@@ -0,0 +1,33 @@
1from __future__ import division
2
3class DesignPointGenerator(object):
4 '''Iterates over all combinations of values specified in options.
5 Shamelessly stolen (and simplified) from bcw.'''
6 def __init__(self, options):
7 self.point_idx = 0 # Current point
8 self.options = options
9 self.total = 1
10 for x in options.itervalues():
11 self.total *= len(x)
12
13 def __iter__(self):
14 return self
15
16 def next(self):
17 while True:
18 if self.point_idx == self.total:
19 raise StopIteration
20 else:
21 point = {}
22
23 divisor = 1
24 for key in sorted(self.options.keys()):
25 size = len(self.options[key])
26
27 option_idx = int(self.point_idx / divisor) % size
28 point[key] = self.options[key][option_idx]
29
30 divisor *= size
31 self.point_idx += 1
32
33 return point
diff --git a/gen/generators.py b/gen/generators.py
new file mode 100644
index 0000000..2fc77a7
--- /dev/null
+++ b/gen/generators.py
@@ -0,0 +1,257 @@
1from Cheetah.Template import Template
2from collections import namedtuple
3from common import get_config_option
4from config.config import DEFAULTS
5from gen.dp import DesignPointGenerator
6from parse.tuple_table import ColMap
7
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 = {
16 'harmonic' : rv.uniform_choice([25, 50, 100, 200]),
17 'uni-short' : rv.uniform_int( 3, 33),
18 'uni-moderate' : rv.uniform_int(10, 100),
19 'uni-long' : rv.uniform_int(50, 250),
20}
21
22NAMED_UTILIZATIONS = {
23 'uni-very-light': rv.uniform(0.0001, 0.001),
24 'uni-light' : rv.uniform(0.001, 0.1),
25 'uni-medium' : rv.uniform( 0.1, 0.4),
26 'uni-heavy' : rv.uniform( 0.5, 0.9),
27
28 'exp-light' : rv.exponential(0, 1, 0.10),
29 'exp-medium' : rv.exponential(0, 1, 0.25),
30 'exp-heavy' : rv.exponential(0, 1, 0.50),
31
32 'bimo-light' : rv.multimodal([(rv.uniform(0.001, 0.5), 8),
33 (rv.uniform( 0.5, 0.9), 1)]),
34 'bimo-medium' : rv.multimodal([(rv.uniform(0.001, 0.5), 6),
35 (rv.uniform( 0.5, 0.9), 3)]),
36 'bimo-heavy' : rv.multimodal([(rv.uniform(0.001, 0.5), 4),
37 (rv.uniform( 0.5, 0.9), 5)]),
38}
39
40# Cheetah templates for schedule files
41TP_CLUSTER = "plugins/C-EDF/cluster{$level}"
42TP_RM = """#if $release_master
43release_master{1}
44#end if"""
45TP_TBASE = """#for $t in $task_set
46{}$t.cost $t.period
47#end for"""
48TP_PART_TASK = TP_TBASE.format("-p $t.cpu ")
49TP_GLOB_TASK = TP_TBASE.format("")
50
51GenOption = namedtuple('GenOption', ['name', 'types', 'default', 'help'])
52
53class BaseGenerator(object):
54 '''Creates sporadic task sets with the most common Litmus options.'''
55 def __init__(self, name, templates, options, params):
56 self.options = self.__make_options() + options
57
58 self.__setup_params(params)
59
60 self.params = params
61 self.template = "\n".join([TP_RM] + templates)
62 self.name = name
63
64 def __make_options(self):
65 '''Return generic Litmus options.'''
66
67 # Guess defaults using the properties of this computer
68 cpus = lu.num_cpus()
69 try:
70 config = get_config_option("RELEASE_MASTER") and True
71 except:
72 config = False
73 release_master = list(set([False, config]))
74
75 list_types = [str, float, type([])]
76
77 return [GenOption('cpus', int, [cpus],
78 'Number of processors on target system.'),
79 GenOption('num_tasks', int, range(cpus, 5*cpus, cpus),
80 'Number of tasks per experiment.'),
81 GenOption('utils', list_types + NAMED_UTILIZATIONS.keys(),
82 ['uni-medium'],'Task utilization distributions.'),
83 GenOption('periods', list_types + NAMED_PERIODS.keys(),
84