diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2021-02-22 13:19:28 +0100 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2021-02-22 13:19:28 +0100 |
commit | 75aa9086b84d875b20bf5db38a987159a633cf6b (patch) | |
tree | 55390f6ee4f1bbfed67550e38acbe8981346f3b1 | |
parent | 0fdf04c5cfb473cb9bcc0d5bf4eacb0d3c6f51e7 (diff) |
properly handle static submodel attributes
TODO: fitting and submodel usage in parent
-rwxr-xr-x | bin/analyze-archive.py | 57 | ||||
-rw-r--r-- | lib/model.py | 63 | ||||
-rw-r--r-- | lib/parameters.py | 10 |
3 files changed, 75 insertions, 55 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py index 193f151..1b37b89 100755 --- a/bin/analyze-archive.py +++ b/bin/analyze-archive.py @@ -339,6 +339,32 @@ def plot_traces(preprocessed_data, sot_name): ) +def print_static(model, static_model, name, attribute): + unit = " " + if attribute == "power": + unit = "µW" + elif attribute == "duration": + unit = "µs" + elif attribute == "substate_count": + unit = "su" + print( + "{:10s}: {:.0f} {:s} ({:.2f})".format( + name, + static_model(name, attribute), + unit, + model.attr_by_name[name][attribute].stats.generic_param_dependence_ratio(), + ) + ) + for param in model.parameters: + print( + "{:10s} dependence on {:15s}: {:.2f}".format( + "", + param, + model.attr_by_name[name][attribute].stats.param_dependence_ratio(param), + ) + ) + + if __name__ == "__main__": ignored_trace_indexes = [] @@ -670,31 +696,14 @@ if __name__ == "__main__": if "static" in show_models or "all" in show_models: for state in model.states(): for attribute in model.attributes(state): - unit = " " - if attribute == "power": - unit = "µW" - elif attribute == "substate_count": - unit = "su" - print( - "{:10s}: {:.0f} {:s} ({:.2f})".format( - state, - static_model(state, attribute), - unit, - model.attr_by_name[state][ - attribute - ].stats.generic_param_dependence_ratio(), - ) - ) - for param in model.parameters: - print( - "{:10s} dependence on {:15s}: {:.2f}".format( - "", - param, - model.attr_by_name[state][ - attribute - ].stats.param_dependence_ratio(param), + print_static(model, static_model, state, attribute) + if args.with_substates: + for submodel in model.submodel_by_nc.values(): + for substate in submodel.states(): + for subattribute in submodel.attributes(substate): + print_static( + submodel, submodel.get_static(), substate, subattribute ) - ) for trans in model.transitions(): if "energy" in model.attributes(trans): diff --git a/lib/model.py b/lib/model.py index c5908e3..9ac4560 100644 --- a/lib/model.py +++ b/lib/model.py @@ -353,6 +353,10 @@ class ModelAttribute: self.function_override = None self.param_model = None + def __repr__(self): + mean = np.mean(self.data) + return f"ModelAttribute<{self.name}, {self.attr}, mean={mean}>" + def get_static(self, use_mean=False): if use_mean: return np.mean(self.data) @@ -517,6 +521,10 @@ class AnalyticModel: self._compute_stats(by_name) + def __repr__(self): + names = ", ".join(self.by_name.keys()) + return f"AnalyticModel<names=[{names}]>" + def _compute_stats(self, by_name): paramstats = ParallelParamStats() @@ -703,6 +711,12 @@ class AnalyticModel: # TODO pass + def predict(self, trace, with_fitted=True, wth_lut=False): + pass + # TODO trace= ( (name, duration), (name, duration), ...) + # -> Return predicted (duration, mean power, cumulative energy) for trace + # Achtung: Teilweise schon in der PTA-Klasse implementiert. Am besten diese mitbenutzen. + class PTAModel(AnalyticModel): """ @@ -783,6 +797,7 @@ class PTAModel(AnalyticModel): self._use_corrcoef = use_corrcoef self.traces = traces self.function_override = function_override.copy() + self.submodel_by_nc = dict() self.fit_done = False @@ -791,6 +806,7 @@ class PTAModel(AnalyticModel): self.pelt = PELT(**pelt) self.find_substates() + print(self.submodel_by_nc) else: self.pelt = None @@ -802,6 +818,11 @@ class PTAModel(AnalyticModel): self.pta = pta self.ignore_trace_indexes = ignore_trace_indexes + def __repr__(self): + states = ", ".join(self.states()) + transitions = ", ".join(self.transitions()) + return f"PTAModel<states=[{states}], transitions=[{transitions}]>" + def _aggregate_to_ndarray(self, aggregate): for elem in aggregate.values(): for key in elem["attributes"]: @@ -923,8 +944,6 @@ class PTAModel(AnalyticModel): substate_counts_by_name[k[0]] = set() substate_counts_by_name[k[0]].add(num_substates) - print(substate_counts_by_name) - for name in self.names: for substate_count in substate_counts_by_name[name]: data = list() @@ -961,40 +980,30 @@ class PTAModel(AnalyticModel): # ... def mk_submodel(self, name, substate_count, data): paramstats = ParallelParamStats() + by_name = dict() sub_states = list() for substate_index in range(substate_count): - sub_name = f"{name}.{substate_index}" + sub_name = f"{name}.{substate_index+1}({substate_count})" durations = list() powers = list() param_values = list() for param, run in data: - durations.extend(run[substate_index]["duration"]) - powers.extend(run[substate_index]["power"]) + # data units are s / W, models use µs / µW + durations.extend(np.array(run[substate_index]["duration"]) * 1e6) + powers.extend(np.array(run[substate_index]["power"]) * 1e6) param_values.extend([param for i in run[substate_index]["duration"]]) - power_attr = ModelAttribute( - sub_name, "power", powers, param_values, self.parameters, 0 - ) - duration_attr = ModelAttribute( - sub_name, "duration", durations, param_values, self.parameters, 0 - ) - sub_states.append((duration_attr, power_attr)) - print(f"{sub_name} mean power: {power_attr.get_static()}") - print(f"{sub_name} mean duration: {duration_attr.get_static()}") - paramstats.enqueue((sub_name, "power"), power_attr) - paramstats.enqueue((sub_name, "duration"), duration_attr) - paramstats.compute() + by_name[sub_name] = { + "isa": "state", + "param": param_values, + "attributes": ["duration", "power"], + "duration": durations, + "power": powers, + } - for substate_index in range(substate_count): - sub_name = f"{name}.{substate_index}" - duration_attr, power_attr = sub_states[substate_index] - for param in self.parameters: - print( - f"{sub_name:16s} duration dependence on {param:15s}: {duration_attr.stats.param_dependence_ratio(param):.2f}" - ) - print( - f"{sub_name:16s} power dependence on {param:15s}: {power_attr.stats.param_dependence_ratio(param):.2f}" - ) + self.submodel_by_nc[(name, substate_count)] = PTAModel( + by_name, self.parameters, dict() + ) def get_substates(self): states = self.states() diff --git a/lib/parameters.py b/lib/parameters.py index e8347a3..078fa7a 100644 --- a/lib/parameters.py +++ b/lib/parameters.py @@ -81,7 +81,7 @@ def _reduce_param_matrix(matrix: np.ndarray, parameter_names: list) -> list: def _std_by_param(n_by_param, all_param_values, param_index): - u""" + """ Calculate standard deviations for a static model where all parameters but `param_index` are constant. :param n_by_param: measurements of a specific model attribute partitioned by parameter values. @@ -501,8 +501,8 @@ class ParamStats: if self.use_corrcoef: return 1 - np.abs(self.corr_by_param[param]) if self.std_by_param[param] == 0: - if self.std_param_lut != 0: - raise RuntimeError("wat") + # if self.std_param_lut != 0: + # raise RuntimeError(f"wat: std_by_param[{param}]==0, but std_param_lut=={self.std_param_lut} ≠ 0") # In general, std_param_lut < std_by_param. So, if std_by_param == 0, std_param_lut == 0 follows. # This means that the variation of param does not affect the model quality -> no influence, return 1 return 1.0 @@ -526,7 +526,9 @@ class ParamStats: return 1 - np.abs(self.corr_by_arg[arg_index]) if self.std_by_arg[arg_index] == 0: if self.std_param_lut != 0: - raise RuntimeError("wat") + raise RuntimeError( + f"wat: std_by_arg[{arg_index}]==0, but std_param_lut=={self.std_param_lut} ≠ 0" + ) # In general, std_param_lut < std_by_arg. So, if std_by_arg == 0, std_param_lut == 0 follows. # This means that the variation of arg does not affect the model quality -> no influence, return 1 return 1 |