summaryrefslogtreecommitdiff
path: root/lib/dfatool.py
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-03-08 15:59:34 +0100
committerDaniel Friesel <derf@finalrewind.org>2018-03-08 15:59:34 +0100
commitfd84e12530ff1712fc65f20abcaa97b822f73414 (patch)
tree842e1457ca3671054246529b82c8dfd3e7d3a558 /lib/dfatool.py
parent6c035085a54ccaf01a635b67b95bffd98684931b (diff)
do not hardcode analyzed model attributes
Diffstat (limited to 'lib/dfatool.py')
-rwxr-xr-xlib/dfatool.py97
1 files changed, 59 insertions, 38 deletions
diff --git a/lib/dfatool.py b/lib/dfatool.py
index 422b838..41bb76c 100755
--- a/lib/dfatool.py
+++ b/lib/dfatool.py
@@ -122,6 +122,33 @@ class Keysight:
currents[i] = float(row[2]) * -1
return timestamps, currents
+def _xv_partitions_kfold(length, num_slices):
+ pairs = []
+ indexes = np.arange(length)
+ for i in range(0, num_slices):
+ training = np.delete(indexes, slice(i, None, num_slices))
+ validation = indexes[i::num_slices]
+ pairs.append((training, validation))
+ return pairs
+
+def _xv_partitions_montecarlo(length, num_slices):
+ pairs = []
+ for i in range(0, num_slices):
+ shuffled = np.random.permutation(np.arange(length))
+ border = int(length * float(2) / 3)
+ training = shuffled[:border]
+ validation = shuffled[border:]
+ pairs.append((training, validation))
+ return pairs
+
+class CrossValidation:
+
+ def __init__(self, em, num_partitions):
+ self._em = em
+ self._num_partitions = num_partitions
+ x = EnergyModel.from_model(em.by_name, em._parameter_names)
+
+
def _preprocess_measurement(measurement):
setup = measurement['setup']
mim = MIMOSA(float(setup['mimosa_voltage']), int(setup['mimosa_shunt']))
@@ -287,9 +314,9 @@ class RawData:
'param': [],
}
if online_trace_part['isa'] == 'transition':
- online_trace_part['offline_aggregates']['timeout'] = []
online_trace_part['offline_aggregates']['rel_energy_prev'] = []
online_trace_part['offline_aggregates']['rel_energy_next'] = []
+ online_trace_part['offline_aggregates']['timeout'] = []
# Note: All state/transitions are 20us "too long" due to injected
# active wait states. These are needed to work around MIMOSA's
@@ -305,12 +332,12 @@ class RawData:
online_trace_part['offline_aggregates']['paramkeys'].append(paramkeys)
online_trace_part['offline_aggregates']['param'].append(paramvalue)
if online_trace_part['isa'] == 'transition':
- online_trace_part['offline_aggregates']['timeout'].append(
- offline_trace_part['timeout'])
online_trace_part['offline_aggregates']['rel_energy_prev'].append(
offline_trace_part['uW_mean_delta_prev'] * (offline_trace_part['us'] - 20))
online_trace_part['offline_aggregates']['rel_energy_next'].append(
offline_trace_part['uW_mean_delta_next'] * (offline_trace_part['us'] - 20))
+ online_trace_part['offline_aggregates']['timeout'].append(
+ offline_trace_part['timeout'])
def _concatenate_analyzed_traces(self):
self.traces = []
@@ -683,7 +710,7 @@ def _compute_param_statistics(by_name, by_param, parameter_names, num_args, stat
for param_idx, param in enumerate(parameter_names):
ret['std_by_param'][param] = _mean_std_by_param(by_param, state_or_trans, key, param_idx)
- if arg_support_enabled and by_name[state_or_trans]['isa'] == 'transition':
+ if arg_support_enabled and state_or_trans in num_args:
for arg_index in range(num_args[state_or_trans]):
ret['std_by_arg'].append(_mean_std_by_param(by_param, state_or_trans, key, len(parameter_names) + arg_index))
@@ -718,6 +745,7 @@ class EnergyModel:
self.stats = {}
np.seterr('raise')
self._parameter_names = sorted(self.traces[0]['trace'][0]['parameter'].keys())
+ self._epilogue_functions = set()
self._num_args = {}
for run in self.traces:
if ignore_trace_indexes == None or int(run['id']) not in ignore_trace_indexes:
@@ -726,8 +754,9 @@ class EnergyModel:
self._load_run_elem(i, elem)
if elem['isa'] == 'transition' and not elem['name'] in self._num_args and 'args' in elem:
self._num_args[elem['name']] = len(elem['args'])
- else:
- print('[I] ignored trace index #{:d}'.format(int(run['id'])))
+ #if elem['isa'] == 'transition' and elem['plan']['level'] == 'epilogue':
+ # self._epilogue_functions.add(elem['name'])
+ print(self._epilogue_functions)
self._aggregate_to_ndarray(self.by_name)
self._compute_all_param_statistics()
@@ -735,7 +764,7 @@ class EnergyModel:
queue = []
for state_or_trans in self.by_name.keys():
self.stats[state_or_trans] = {}
- for key in ['power', 'energy', 'duration', 'timeout', 'rel_energy_prev', 'rel_energy_next']:
+ for key in self.by_name[state_or_trans]['attributes']:
if key in self.by_name[state_or_trans]:
self.stats[state_or_trans][key] = _compute_param_statistics(self.by_name, self.by_param, self._parameter_names, self._num_args, state_or_trans, key)
#queue.append({
@@ -768,18 +797,24 @@ class EnergyModel:
def _aggregate_to_ndarray(self, aggregate):
for elem in aggregate.values():
- for key in ['power', 'power_std', 'energy', 'duration', 'timeout', 'rel_energy_prev', 'rel_energy_next']:
- if key in elem:
- elem[key] = np.array(elem[key])
+ for key in elem['attributes']:
+ elem[key] = np.array(elem[key])
def _add_data_to_aggregate(self, aggregate, key, element):
if not key in aggregate:
aggregate[key] = {
- 'isa' : element['isa']
+ 'isa' : element['isa'],
+ 'attributes' : list(element['offline_aggregates'].keys())
}
for datakey in element['offline_aggregates'].keys():
aggregate[key][datakey] = []
+ if element['isa'] == 'state':
+ aggregate[key]['attributes'] = ['power']
+ else:
+ aggregate[key]['attributes'] = ['duration', 'energy', 'rel_energy_prev', 'rel_energy_next']
+ if element['plan']['level'] == 'epilogue':
+ aggregate[key]['attributes'].insert(0, 'timeout')
for datakey, dataval in element['offline_aggregates'].items():
aggregate[key][datakey].extend(dataval)
@@ -822,14 +857,13 @@ class EnergyModel:
model = {}
for name, elem in model_dict.items():
model[name] = {}
- for key in ['power', 'energy', 'duration', 'timeout', 'rel_energy_prev', 'rel_energy_next']:
- if key in elem:
- try:
- model[name][key] = model_function(elem[key])
- except RuntimeWarning:
- print('[W] Got no data for {} {}'.format(name, key))
- except FloatingPointError as fpe:
- print('[W] Got no data for {} {}: {}'.format(name, key, fpe))
+ for key in elem['attributes']:
+ try:
+ model[name][key] = model_function(elem[key])
+ except RuntimeWarning:
+ print('[W] Got no data for {} {}'.format(name, key))
+ except FloatingPointError as fpe:
+ print('[W] Got no data for {} {}: {}'.format(name, key, fpe))
return model
def get_static(self):
@@ -867,11 +901,7 @@ class EnergyModel:
for state_or_tran in self.by_name.keys():
param_keys = filter(lambda k: k[0] == state_or_tran, self.by_param.keys())
param_subdict = dict(map(lambda k: [k, self.by_param[k]], param_keys))
- if self.by_name[state_or_tran]['isa'] == 'state':
- attributes = ['power']
- else:
- attributes = ['energy', 'duration', 'timeout', 'rel_energy_prev', 'rel_energy_next']
- for model_attribute in attributes:
+ for model_attribute in self.by_name[state_or_tran]['attributes']:
fit_results = {}
for parameter_index, parameter_name in enumerate(self._parameter_names):
if self.param_dependence_ratio(state_or_tran, model_attribute, parameter_name) > 0.5:
@@ -898,11 +928,7 @@ class EnergyModel:
num_args = 0
if arg_support_enabled and self.by_name[state_or_tran]['isa'] == 'transition':
num_args = self._num_args[state_or_tran]
- if self.by_name[state_or_tran]['isa'] == 'state':
- attributes = ['power']
- else:
- attributes = ['energy', 'duration', 'timeout', 'rel_energy_prev', 'rel_energy_next']
- for model_attribute in attributes:
+ for model_attribute in self.by_name[state_or_tran]['attributes']:
fit_results = {}
for result in all_fit_results:
if result['key'][0] == state_or_tran and result['key'][1] == model_attribute:
@@ -956,15 +982,10 @@ class EnergyModel:
results = {}
for name, elem in sorted(self.by_name.items()):
results[name] = {}
- if elem['isa'] == 'state':
- predicted_data = np.array(list(map(lambda i: model_function(name, 'power', param=elem['param'][i]), range(len(elem['power'])))))
- measures = regression_measures(predicted_data, elem['power'])
- results[name]['power'] = measures
- else:
- for key in ['duration', 'energy', 'rel_energy_prev', 'rel_energy_next', 'timeout']:
- predicted_data = np.array(list(map(lambda i: model_function(name, key, param=elem['param'][i]), range(len(elem[key])))))
- measures = regression_measures(predicted_data, elem[key])
- results[name][key] = measures
+ for key in elem['attributes']:
+ predicted_data = np.array(list(map(lambda i: model_function(name, key, param=elem['param'][i]), range(len(elem[key])))))
+ measures = regression_measures(predicted_data, elem[key])
+ results[name][key] = measures
return results