diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-11-20 16:02:40 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-11-20 16:02:40 -0500 |
| commit | 41c867480f1e20bd3b168258ed71450499ea6ccf (patch) | |
| tree | b47963b417ba9bdd53f03d5c621b72bcca297ef6 | |
| parent | 1abea5f67c2c70053af0a59db715a210df2e0bef (diff) | |
Removed 2-step parse for overheads.
| -rw-r--r-- | parse/ft.py | 129 | ||||
| -rw-r--r-- | parse/sched.py | 1 | ||||
| -rwxr-xr-x | parse_exps.py | 24 | ||||
| -rwxr-xr-x | run_exps.py | 6 |
4 files changed, 56 insertions, 104 deletions
diff --git a/parse/ft.py b/parse/ft.py index cbf75f2..c5f1522 100644 --- a/parse/ft.py +++ b/parse/ft.py | |||
| @@ -7,94 +7,68 @@ import subprocess | |||
| 7 | 7 | ||
| 8 | from point import Measurement,Type | 8 | from point import Measurement,Type |
| 9 | 9 | ||
| 10 | SPLIT_DATA_NAME = "overhead={}.bin" | 10 | FT_SPLIT_NAME = "overhead={}.bin" |
| 11 | FT_DATA_NAME = "sorted-ft.bin" | 11 | FT_SORTED_NAME = "sorted-ft.bin" |
| 12 | FIELDS = ["Overhead", "samples", "max", "avg", "min", "med", "std", "var"] | 12 | FT_ERR_NAME = "err-ft" |
| 13 | 13 | ||
| 14 | def get_ft_output(data_dir, cycles, out_dir, force=False): | 14 | def extract_ft_data(result, data_dir, cycles, tmp_dir): |
| 15 | """ | ||
| 16 | Create and return file containing analyzed overhead data | ||
| 17 | """ | ||
| 18 | freg = conf.FILES['ft_data'] + "$" | 15 | freg = conf.FILES['ft_data'] + "$" |
| 19 | bins = [f for f in os.listdir(data_dir) if re.match(freg, f)] | 16 | bins = [f for f in os.listdir(data_dir) if re.match(freg, f)] |
| 20 | 17 | ||
| 21 | output_file = "{}/out-ft".format(out_dir) | 18 | if not len(bins): |
| 19 | return False | ||
| 22 | 20 | ||
| 23 | if os.path.isfile(output_file): | 21 | bin_file = "{}/{}".format(data_dir, bins[0]) |
| 24 | if force: | ||
| 25 | os.remove(output_file) | ||
| 26 | else: | ||
| 27 | return output_file | ||
| 28 | 22 | ||
| 29 | if len(bins) != 0: | 23 | with open("%s/%s" % (tmp_dir, FT_ERR_NAME), 'w') as err_file: |
| 30 | bin_file = "{}/{}".format(data_dir, bins[0]) | 24 | sorted_bin = sort_ft(bin_file, err_file, tmp_dir) |
| 31 | err_file = open("%s/err-ft" % out_dir, 'w') | ||
| 32 | 25 | ||
| 33 | sorted_bin = sort_ft(bin_file, err_file, out_dir) | 26 | for event in conf.BASE_EVENTS: |
| 34 | make_data_file(sorted_bin, cycles, output_file, err_file, out_dir) | 27 | parse_overhead(result, sorted_bin, event, cycles, |
| 28 | tmp_dir, err_file) | ||
| 35 | 29 | ||
| 36 | os.remove(sorted_bin) | 30 | os.remove(sorted_bin) |
| 37 | 31 | ||
| 38 | return output_file | 32 | return True |
| 39 | else: | ||
| 40 | return None | ||
| 41 | return output_file | ||
| 42 | 33 | ||
| 43 | def fmt_cell(x): | 34 | def parse_overhead(result, overhead_bin, overhead, cycles, out_dir, err_file): |
| 44 | if type(x) == str: | 35 | ovh_fname = "{}/{}".format(out_dir, FT_SPLIT_NAME).format(overhead) |
| 45 | return "%15s" % x | ||
| 46 | if type(x) == int: | ||
| 47 | return "%15d" % x | ||
| 48 | else: | ||
| 49 | return "%15.3f" % x | ||
| 50 | 36 | ||
| 51 | def make_data_file(sorted_bin, cycles, out_fname, err_file, out_dir): | 37 | if os.path.exists(ovh_fname): |
| 52 | """ | 38 | os.remove(ovh_fname) |
| 53 | Create file containing all overhead information. | 39 | ovh_file = open(ovh_fname, 'w') |
| 54 | """ | ||
| 55 | base_name = "{}/{}".format(out_dir, SPLIT_DATA_NAME) | ||
| 56 | 40 | ||
| 57 | with open(out_fname, "w") as f: | 41 | # Extract matching overhead events into a seperate file |
| 58 | f.write("#%s" % ", ".join(fmt_cell(x) for x in FIELDS)) | 42 | cmd = [conf.BINS["split"], "-r", "-b", overhead, overhead_bin] |
| 59 | f.write("\n") | 43 | ret = subprocess.call(cmd, cwd=out_dir, stderr=err_file, stdout=ovh_file) |
| 44 | size = os.stat(ovh_fname).st_size | ||
| 60 | 45 | ||
| 61 | for event in conf.BASE_EVENTS: | 46 | if ret: |
| 62 | ovh_fname = base_name.format(event.replace("_", "-")) | 47 | raise Exception("Failed (%d) with command: %s" % (ret, " ".join(cmd))) |
| 63 | 48 | if not size: | |
| 64 | if os.path.exists(ovh_fname): | 49 | os.remove(ovh_fname) |
| 65 | os.remove(ovh_fname) | ||
| 66 | ovh_file = open(ovh_fname, 'w') | ||
| 67 | |||
| 68 | # Extract matching overhead events into a seperate file | ||
| 69 | cmd = [conf.BINS["split"], "-r", "-b", event, sorted_bin] | ||
| 70 | ret = subprocess.call(cmd, cwd=out_dir, | ||
| 71 | stderr=err_file, stdout=ovh_file) | ||
| 72 | size = os.stat(ovh_fname).st_size | ||
| 73 | 50 | ||
| 74 | if ret: | 51 | if size and not ret: |
| 75 | err_file.write("Failed with command: %s" % " ".join(cmd)) | 52 | # Map and sort file for stats |
| 76 | if not size: | 53 | data = np.memmap(ovh_fname, dtype="float32", mode='c') |
| 77 | os.remove(ovh_fname) | 54 | data /= float(cycles) # Scale for processor speed |
| 78 | if not size or ret: | 55 | data.sort() |
| 79 | continue | ||
| 80 | 56 | ||
| 81 | # Map and sort file for stats | 57 | m = Measurement("%s-%s" % (overhead_bin, overhead)) |
| 82 | data = np.memmap(ovh_fname, dtype="float32", mode='c') | 58 | m[Type.Max] = data[-1] |
| 83 | data /= float(cycles) # Scale for processor speed | 59 | m[Type.Avg] = np.mean(data) |
| 84 | data.sort() | 60 | m[Type.Min] = data[0] |
| 61 | m[Type.Var] = np.var(data) | ||
| 85 | 62 | ||
| 86 | stats = [event, len(data), data[-1], np.mean(data), data[0], | 63 | result[overhead] = m |
| 87 | np.median(data), np.std(data, ddof=1), np.var(data)] | ||
| 88 | f.write(", ".join([fmt_cell(x) for x in stats])) | ||
| 89 | f.write("\n") | ||
| 90 | 64 | ||
| 91 | os.remove(ovh_fname) | 65 | os.remove(ovh_fname) |
| 92 | 66 | ||
| 93 | def sort_ft(ft_file, err_file, out_dir): | 67 | def sort_ft(ft_file, err_file, out_dir): |
| 94 | """ | 68 | """ |
| 95 | Create and return file with sorted overheads from @ft_file. | 69 | Create and return file with sorted overheads from @ft_file. |
| 96 | """ | 70 | """ |
| 97 | out_fname = "{}/{}".format(out_dir, FT_DATA_NAME) | 71 | out_fname = "{}/{}".format(out_dir, FT_SORTED_NAME) |
| 98 | 72 | ||
| 99 | # Sort happens in-place | 73 | # Sort happens in-place |
| 100 | sh.copyfile(ft_file, out_fname) | 74 | sh.copyfile(ft_file, out_fname) |
| @@ -105,28 +79,3 @@ def sort_ft(ft_file, err_file, out_dir): | |||
| 105 | raise Exception("Sort failed with command: %s" % " ".join(cmd)) | 79 | raise Exception("Sort failed with command: %s" % " ".join(cmd)) |
| 106 | 80 | ||
| 107 | return out_fname | 81 | return out_fname |
| 108 | |||
| 109 | def extract_ft_data(data_file, result, overheads): | ||
| 110 | """ | ||
| 111 | Return exp point with overhead measurements from data_file | ||
| 112 | """ | ||
| 113 | with open(data_file) as f: | ||
| 114 | data = f.read() | ||
| 115 | |||
| 116 | for ovh in overheads: | ||
| 117 | regex = r"({}[^\n]*)".format(ovh) | ||
| 118 | line = re.search(regex, data) | ||
| 119 | |||
| 120 | if not line: | ||
| 121 | continue | ||
| 122 | |||
| 123 | vals = re.split(r"[,\s]+", line.groups(1)[0]) | ||
| 124 | |||
| 125 | measure = Measurement("%s-%s" % (data_file, ovh)) | ||
| 126 | measure[Type.Max] = float(vals[FIELDS.index("max")]) | ||
| 127 | measure[Type.Avg] = float(vals[FIELDS.index("avg")]) | ||
| 128 | measure[Type.Var] = float(vals[FIELDS.index("var")]) | ||
| 129 | |||
| 130 | result[ovh] = measure | ||
| 131 | |||
| 132 | return result | ||
diff --git a/parse/sched.py b/parse/sched.py index bbf6e10..3e30880 100644 --- a/parse/sched.py +++ b/parse/sched.py | |||
| @@ -11,7 +11,6 @@ import os | |||
| 11 | import re | 11 | import re |
| 12 | import numpy as np | 12 | import numpy as np |
| 13 | import subprocess | 13 | import subprocess |
| 14 | import pprint | ||
| 15 | 14 | ||
| 16 | from collections import namedtuple,defaultdict | 15 | from collections import namedtuple,defaultdict |
| 17 | from operator import methodcaller | 16 | from operator import methodcaller |
diff --git a/parse_exps.py b/parse_exps.py index 24bdb85..d932b0d 100755 --- a/parse_exps.py +++ b/parse_exps.py | |||
| @@ -42,7 +42,7 @@ def parse_args(): | |||
| 42 | return parser.parse_args() | 42 | return parser.parse_args() |
| 43 | 43 | ||
| 44 | ExpData = namedtuple('ExpData', ['name', 'params', 'data_files', 'is_base']) | 44 | ExpData = namedtuple('ExpData', ['name', 'params', 'data_files', 'is_base']) |
| 45 | DataFiles = namedtuple('DataFiles', ['ft','st']) | 45 | DataFiles = namedtuple('DataFiles', ['st']) |
| 46 | 46 | ||
| 47 | def get_exp_params(data_dir, col_map): | 47 | def get_exp_params(data_dir, col_map): |
| 48 | param_file = "%s/%s" % (data_dir, conf.DEFAULTS['params_file']) | 48 | param_file = "%s/%s" % (data_dir, conf.DEFAULTS['params_file']) |
| @@ -82,10 +82,7 @@ def gen_exp_data(exp_dirs, base_conf, col_map, force): | |||
| 82 | 82 | ||
| 83 | # Read and translate exp output files | 83 | # Read and translate exp output files |
| 84 | params = get_exp_params(data_dir, col_map) | 84 | params = get_exp_params(data_dir, col_map) |
| 85 | cycles = int(params[conf.PARAMS['cycles']]) | ||
| 86 | st_output = st.get_st_output(data_dir, tmp_dir, force) | 85 | st_output = st.get_st_output(data_dir, tmp_dir, force) |
| 87 | ft_output = ft.get_ft_output(data_dir, cycles, tmp_dir, force) | ||
| 88 | |||
| 89 | 86 | ||
| 90 | if base_conf and base_conf.viewitems() & params.viewitems(): | 87 | if base_conf and base_conf.viewitems() & params.viewitems(): |
| 91 | if not st_output: | 88 | if not st_output: |
| @@ -97,14 +94,14 @@ def gen_exp_data(exp_dirs, base_conf, col_map, force): | |||
| 97 | base_params.pop(base_conf.keys()[0]) | 94 | base_params.pop(base_conf.keys()[0]) |
| 98 | 95 | ||
| 99 | base_exp = ExpData(data_dir, base_params, | 96 | base_exp = ExpData(data_dir, base_params, |
| 100 | DataFiles(ft_output, st_output), True) | 97 | DataFiles(st_output), True) |
| 101 | scaling_bases += [base_exp] | 98 | scaling_bases += [base_exp] |
| 102 | else: | 99 | else: |
| 103 | is_base = False | 100 | is_base = False |
| 104 | 101 | ||
| 105 | # Create experiment named after the data dir | 102 | # Create experiment named after the data dir |
| 106 | exp_data = ExpData(data_dir, params, | 103 | exp_data = ExpData(data_dir, params, |
| 107 | DataFiles(ft_output, st_output), is_base) | 104 | DataFiles(st_output), is_base) |
| 108 | 105 | ||
| 109 | plain_exps += [exp_data] | 106 | plain_exps += [exp_data] |
| 110 | 107 | ||
| @@ -142,13 +139,20 @@ def main(): | |||
| 142 | base_table.add_exp(base.params, base) | 139 | base_table.add_exp(base.params, base) |
| 143 | 140 | ||
| 144 | sys.stderr.write("Parsing data...\n") | 141 | sys.stderr.write("Parsing data...\n") |
| 142 | for exp in args: | ||
| 143 | result = ExpPoint(exp) | ||
| 144 | params = get_exp_params(exp, col_map) | ||
| 145 | # Write overheads into result | ||
| 146 | ft.extract_ft_data(result, exp, | ||
| 147 | params[conf.PARAMS['cycles']], | ||
| 148 | exp + "/tmp") | ||
| 149 | |||
| 150 | if opts.verbose: | ||
| 151 | print(result) | ||
| 152 | |||
| 145 | for i,exp in enumerate(plain_exps): | 153 | for i,exp in enumerate(plain_exps): |
| 146 | result = ExpPoint(exp.name) | 154 | result = ExpPoint(exp.name) |
| 147 | 155 | ||
| 148 | if exp.data_files.ft: | ||
| 149 | # Write overheads into result | ||
| 150 | ft.extract_ft_data(exp.data_files.ft, result, conf.BASE_EVENTS) | ||
| 151 | |||
| 152 | if exp.data_files.st: | 156 | if exp.data_files.st: |
| 153 | base = None | 157 | base = None |
| 154 | if base_conf and not exp.is_base: | 158 | if base_conf and not exp.is_base: |
diff --git a/run_exps.py b/run_exps.py index 3efb09d..1d2cc2e 100755 --- a/run_exps.py +++ b/run_exps.py | |||
| @@ -67,8 +67,8 @@ def convert_data(data): | |||
| 67 | return {'proc' : procs, 'spin' : spins} | 67 | return {'proc' : procs, 'spin' : spins} |
| 68 | 68 | ||
| 69 | def fix_paths(schedule, exp_dir, sched_file): | 69 | def fix_paths(schedule, exp_dir, sched_file): |
| 70 | """Replace relative paths of command line arguments with absolute ones.""" | ||
| 70 | for (idx, (spin, args)) in enumerate(schedule['spin']): | 71 | for (idx, (spin, args)) in enumerate(schedule['spin']): |
| 71 | # Replace relative paths (if present) with absolute ones | ||
| 72 | for arg in re.split(" +", args): | 72 | for arg in re.split(" +", args): |
| 73 | abspath = "%s/%s" % (exp_dir, arg) | 73 | abspath = "%s/%s" % (exp_dir, arg) |
| 74 | if os.path.exists(abspath): | 74 | if os.path.exists(abspath): |
| @@ -136,8 +136,8 @@ def run_exp(name, schedule, scheduler, kernel, duration, work_dir, out_dir): | |||
| 136 | proc_entries = [] | 136 | proc_entries = [] |
| 137 | executables = [] | 137 | executables = [] |
| 138 | 138 | ||
| 139 | # if kernel and not lu.uname_matches(kernel): | 139 | if kernel and not lu.uname_matches(kernel): |
| 140 | # raise InvalidKernel(kernel) | 140 | raise InvalidKernel(kernel) |
| 141 | 141 | ||
| 142 | # Parse values for proc entries | 142 | # Parse values for proc entries |
| 143 | for entry_conf in schedule['proc']: | 143 | for entry_conf in schedule['proc']: |
