diff options
| -rw-r--r-- | common.py | 51 | ||||
| -rw-r--r-- | config/config.py | 5 | ||||
| -rw-r--r-- | gen/generator.py | 5 | ||||
| -rw-r--r-- | parse/dir_map.py | 3 | ||||
| -rw-r--r-- | parse/ft.py | 2 | ||||
| -rw-r--r-- | parse/point.py | 3 | ||||
| -rwxr-xr-x | parse_exps.py | 35 | ||||
| -rw-r--r-- | run/executable/executable.py | 2 | ||||
| -rw-r--r-- | run/litmus_util.py | 50 | ||||
| -rw-r--r-- | run/tracer.py | 10 | ||||
| -rwxr-xr-x | run_exps.py | 9 |
11 files changed, 92 insertions, 83 deletions
| @@ -1,5 +1,6 @@ | |||
| 1 | import os | 1 | import os |
| 2 | import re | 2 | import re |
| 3 | import stat | ||
| 3 | import subprocess | 4 | import subprocess |
| 4 | import sys | 5 | import sys |
| 5 | 6 | ||
| @@ -134,3 +135,53 @@ def load_params(fname): | |||
| 134 | raise IOError("Invalid param file: %s\n%s" % (fname, e)) | 135 | raise IOError("Invalid param file: %s\n%s" % (fname, e)) |
| 135 | 136 | ||
| 136 | return params | 137 | return params |
| 138 | |||
| 139 | |||
| 140 | def num_cpus(): | ||
| 141 | '''Return the number of CPUs in the system.''' | ||
| 142 | |||
| 143 | lnx_re = re.compile(r'^(processor|online)') | ||
| 144 | cpus = 0 | ||
| 145 | |||
| 146 | with open('/proc/cpuinfo', 'r') as f: | ||
| 147 | for line in f: | ||
| 148 | if lnx_re.match(line): | ||
| 149 | cpus += 1 | ||
| 150 | return cpus | ||
| 151 | |||
| 152 | def ft_freq(): | ||
| 153 | umachine = subprocess.check_output(["uname", "-m"]) | ||
| 154 | |||
| 155 | if re.match("armv7", umachine): | ||
| 156 | # Arm V7s use a millisecond timer | ||
| 157 | freq = 1000.0 | ||
| 158 | elif re.match("x86", umachine): | ||
| 159 | # X86 timer is equal to processor clock | ||
| 160 | reg = re.compile(r'^cpu MHz\s*:\s*(?P<FREQ>\d+)', re.M) | ||
| 161 | with open('/proc/cpuinfo', 'r') as f: | ||
| 162 | data = f.read() | ||
| 163 | |||
| 164 | match = re.search(reg, data) | ||
| 165 | if not match: | ||
| 166 | raise Exception("Cannot parse CPU frequency from x86 CPU!") | ||
| 167 | freq = int(match.group('FREQ')) | ||
| 168 | else: | ||
| 169 | # You're on your own | ||
| 170 | freq = 0 | ||
| 171 | return freq | ||
| 172 | |||
| 173 | |||
| 174 | def uname_matches(reg): | ||
| 175 | data = subprocess.check_output(["uname", "-r"]) | ||
| 176 | return bool( re.match(reg, data) ) | ||
| 177 | |||
| 178 | def is_executable(fname): | ||
| 179 | '''Return whether the file passed in is executable''' | ||
| 180 | mode = os.stat(fname)[stat.ST_MODE] | ||
| 181 | return mode & stat.S_IXUSR and mode & stat.S_IRUSR | ||
| 182 | |||
| 183 | def is_device(dev): | ||
| 184 | if not os.path.exists(dev): | ||
| 185 | return False | ||
| 186 | mode = os.stat(dev)[stat.ST_MODE] | ||
| 187 | return not (not mode & stat.S_IFCHR) | ||
diff --git a/config/config.py b/config/config.py index 1199278..a6edece 100644 --- a/config/config.py +++ b/config/config.py | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | from __future__ import print_function | 1 | from __future__ import print_function |
| 2 | import itertools | 2 | import itertools |
| 3 | from common import get_executable | 3 | from common import get_executable,ft_freq |
| 4 | 4 | ||
| 5 | '''Paths to binaries.''' | 5 | '''Paths to binaries.''' |
| 6 | BINS = {'rtspin' : get_executable('rtspin', 'liblitmus'), | 6 | BINS = {'rtspin' : get_executable('rtspin', 'liblitmus'), |
| @@ -16,6 +16,7 @@ BINS = {'rtspin' : get_executable('rtspin', 'liblitmus'), | |||
| 16 | 16 | ||
| 17 | '''Names of output files.''' | 17 | '''Names of output files.''' |
| 18 | FILES = {'ft_data' : 'ft.bin', | 18 | FILES = {'ft_data' : 'ft.bin', |
| 19 | 'ft_matches' : r'(ft.*\.bin)|(.*\.ft)', | ||
| 19 | 'linux_data' : 'trace.dat', | 20 | 'linux_data' : 'trace.dat', |
| 20 | 'sched_data' : 'st-{}.bin', | 21 | 'sched_data' : 'st-{}.bin', |
| 21 | 'log_data' : 'trace.slog'} | 22 | 'log_data' : 'trace.slog'} |
| @@ -34,7 +35,7 @@ DEFAULTS = {'params_file' : 'params.py', | |||
| 34 | 'sched_file' : 'sched.py', | 35 | 'sched_file' : 'sched.py', |
| 35 | 'duration' : 10, | 36 | 'duration' : 10, |
| 36 | 'spin' : 'rtspin', | 37 | 'spin' : 'rtspin', |
| 37 | 'cycles' : 2000} | 38 | 'cycles' : ft_freq() or 2000} |
| 38 | 39 | ||
| 39 | '''Default sched_trace events (this is all of them).''' | 40 | '''Default sched_trace events (this is all of them).''' |
| 40 | SCHED_EVENTS = range(501, 513) | 41 | SCHED_EVENTS = range(501, 513) |
diff --git a/gen/generator.py b/gen/generator.py index dbf2a7b..8c3048b 100644 --- a/gen/generator.py +++ b/gen/generator.py | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | import gen.rv as rv | 1 | import gen.rv as rv |
| 2 | import os | 2 | import os |
| 3 | import run.litmus_util as lu | ||
| 4 | import shutil as sh | 3 | import shutil as sh |
| 5 | 4 | ||
| 6 | from Cheetah.Template import Template | 5 | from Cheetah.Template import Template |
| 7 | from collections import namedtuple | 6 | from collections import namedtuple |
| 8 | from common import get_config_option | 7 | from common import get_config_option,num_cpus |
| 9 | from config.config import DEFAULTS,PARAMS | 8 | from config.config import DEFAULTS,PARAMS |
| 10 | from gen.dp import DesignPointGenerator | 9 | from gen.dp import DesignPointGenerator |
| 11 | from parse.col_map import ColMapBuilder | 10 | from parse.col_map import ColMapBuilder |
| @@ -69,7 +68,7 @@ class Generator(object): | |||
| 69 | if 'cpus' in params: | 68 | if 'cpus' in params: |
| 70 | cpus = min(map(int, params['cpus'])) | 69 | cpus = min(map(int, params['cpus'])) |
| 71 | else: | 70 | else: |
| 72 | cpus = lu.num_cpus() | 71 | cpus = num_cpus() |
| 73 | try: | 72 | try: |
| 74 | config = get_config_option("RELEASE_MASTER") and True | 73 | config = get_config_option("RELEASE_MASTER") and True |
| 75 | except: | 74 | except: |
diff --git a/parse/dir_map.py b/parse/dir_map.py index 601dd3b..a8d2a83 100644 --- a/parse/dir_map.py +++ b/parse/dir_map.py | |||
| @@ -56,6 +56,9 @@ class DirMap(object): | |||
| 56 | 56 | ||
| 57 | remove_childless2(self.root) | 57 | remove_childless2(self.root) |
| 58 | 58 | ||
| 59 | def is_empty(self): | ||
| 60 | return not len(self.root.children) | ||
| 61 | |||
| 59 | def write(self, out_dir): | 62 | def write(self, out_dir): |
| 60 | def write2(path, node): | 63 | def write2(path, node): |
| 61 | out_path = "/".join(path) | 64 | out_path = "/".join(path) |
diff --git a/parse/ft.py b/parse/ft.py index 19453d1..98405f4 100644 --- a/parse/ft.py +++ b/parse/ft.py | |||
| @@ -63,7 +63,7 @@ def extract_ft_data(result, data_dir, work_dir, cycles): | |||
| 63 | data_dir = os.path.abspath(data_dir) | 63 | data_dir = os.path.abspath(data_dir) |
| 64 | work_dir = os.path.abspath(work_dir) | 64 | work_dir = os.path.abspath(work_dir) |
| 65 | 65 | ||
| 66 | freg = conf.FILES['ft_data'] + "$" | 66 | freg = conf.FILES['ft_matches'] + "$" |
| 67 | bins = [f for f in os.listdir(data_dir) if re.match(freg, f)] | 67 | bins = [f for f in os.listdir(data_dir) if re.match(freg, f)] |
| 68 | 68 | ||
| 69 | if not len(bins): | 69 | if not len(bins): |
diff --git a/parse/point.py b/parse/point.py index d577306..f2b266a 100644 --- a/parse/point.py +++ b/parse/point.py | |||
| @@ -128,8 +128,7 @@ class ExpPoint(object): | |||
| 128 | self.stats[type] = value | 128 | self.stats[type] = value |
| 129 | 129 | ||
| 130 | def __str__(self): | 130 | def __str__(self): |
| 131 | # return "<ExpPoint-%s>\n%s" % (self.id, dict_str(self.stats)) | 131 | return "<ExpPoint-%s>\n%s" % (self.id, dict_str(self.stats)) |
| 132 | return "<ExpPoint-%s>" % (self.id) | ||
| 133 | 132 | ||
| 134 | def get_stats(self): | 133 | def get_stats(self): |
| 135 | return self.stats.keys() | 134 | return self.stats.keys() |
diff --git a/parse_exps.py b/parse_exps.py index 7dfc9cd..8fcf5c3 100755 --- a/parse_exps.py +++ b/parse_exps.py | |||
| @@ -22,8 +22,6 @@ def parse_args(): | |||
| 22 | # TODO: convert data-dir to proper option, clean 'dest' options | 22 | # TODO: convert data-dir to proper option, clean 'dest' options |
| 23 | parser = OptionParser("usage: %prog [options] [data_dir]...") | 23 | parser = OptionParser("usage: %prog [options] [data_dir]...") |
| 24 | 24 | ||
| 25 | print("default to no params.py") | ||
| 26 | |||
| 27 | parser.add_option('-o', '--out', dest='out', | 25 | parser.add_option('-o', '--out', dest='out', |
| 28 | help='file or directory for data output', default='parse-data') | 26 | help='file or directory for data output', default='parse-data') |
| 29 | parser.add_option('-c', '--clean', action='store_true', default=False, | 27 | parser.add_option('-c', '--clean', action='store_true', default=False, |
| @@ -44,15 +42,15 @@ ExpData = namedtuple('ExpData', ['path', 'params', 'work_dir']) | |||
| 44 | 42 | ||
| 45 | def get_exp_params(data_dir, cm_builder): | 43 | def get_exp_params(data_dir, cm_builder): |
| 46 | param_file = "%s/%s" % (data_dir, conf.DEFAULTS['params_file']) | 44 | param_file = "%s/%s" % (data_dir, conf.DEFAULTS['params_file']) |
| 47 | if not os.path.isfile: | 45 | if os.path.isfile(param_file): |
| 48 | raise Exception("No param file '%s' exists!" % param_file) | 46 | params = load_params(param_file) |
| 49 | |||
| 50 | params = load_params(param_file) | ||
| 51 | 47 | ||
| 52 | # Store parameters in cm_builder, which will track which parameters change | 48 | # Store parameters in cm_builder, which will track which parameters change |
| 53 | # across experiments | 49 | # across experiments |
| 54 | for key, value in params.iteritems(): | 50 | for key, value in params.iteritems(): |
| 55 | cm_builder.try_add(key, value) | 51 | cm_builder.try_add(key, value) |
| 52 | else: | ||
| 53 | params = {} | ||
| 56 | 54 | ||
| 57 | # Cycles must be present for feather-trace measurement parsing | 55 | # Cycles must be present for feather-trace measurement parsing |
| 58 | if conf.PARAMS['cycles'] not in params: | 56 | if conf.PARAMS['cycles'] not in params: |
| @@ -164,16 +162,25 @@ def main(): | |||
| 164 | if opts.force and os.path.exists(opts.out): | 162 | if opts.force and os.path.exists(opts.out): |
| 165 | sh.rmtree(opts.out) | 163 | sh.rmtree(opts.out) |
| 166 | 164 | ||
| 167 | re | ||
