summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-02-22 13:19:28 +0100
committerDaniel Friesel <daniel.friesel@uos.de>2021-02-22 13:19:28 +0100
commit75aa9086b84d875b20bf5db38a987159a633cf6b (patch)
tree55390f6ee4f1bbfed67550e38acbe8981346f3b1
parent0fdf04c5cfb473cb9bcc0d5bf4eacb0d3c6f51e7 (diff)
properly handle static submodel attributes
TODO: fitting and submodel usage in parent
-rwxr-xr-xbin/analyze-archive.py57
-rw-r--r--lib/model.py63
-rw-r--r--lib/parameters.py10
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