summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-07-25 11:41:35 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2019-07-25 11:41:35 +0200
commite0609155a809167cb260a441f708362a189852ab (patch)
tree7d4289cb9a0f73072b0085e038bdbf761c1b03ca
parent06d4b31d438c69dd47164c3661f3497fb5e869cb (diff)
analyze-timing: add function argument support
-rwxr-xr-xbin/analyze-timing.py6
-rwxr-xr-xlib/dfatool.py39
2 files changed, 41 insertions, 4 deletions
diff --git a/bin/analyze-timing.py b/bin/analyze-timing.py
index 66a67a8..19940b5 100755
--- a/bin/analyze-timing.py
+++ b/bin/analyze-timing.py
@@ -188,7 +188,7 @@ if __name__ == '__main__':
preprocessed_data = raw_data.get_preprocessed_data()
by_name, parameters, arg_count = pta_trace_to_aggregate(preprocessed_data, ignored_trace_indexes)
- model = AnalyticModel(by_name, parameters)
+ model = AnalyticModel(by_name, parameters, arg_count)
if xv_method:
xv = CrossValidator(AnalyticModel, by_name, parameters, arg_count)
@@ -239,6 +239,10 @@ if __name__ == '__main__':
print('{:10s} {:10s} {:10s} stddev {:f}'.format(
transition, attribute, param, model.stats.stats[transition][attribute]['std_by_param'][param]
))
+ for i, arg_stddev in enumerate(model.stats.stats[transition][attribute]['std_by_arg']):
+ print('{:10s} {:10s} arg{:d} stddev {:f}'.format(
+ transition, attribute, i, arg_stddev
+ ))
if info != None:
for param_name in sorted(info['fit_result'].keys(), key=str):
param_fit = info['fit_result'][param_name]['results']
diff --git a/lib/dfatool.py b/lib/dfatool.py
index ffe5a3b..995508e 100755
--- a/lib/dfatool.py
+++ b/lib/dfatool.py
@@ -520,6 +520,8 @@ class TimingData:
for log_entry in trace['trace']:
paramkeys = sorted(log_entry['parameter'].keys())
paramvalues = [soft_cast_int(log_entry['parameter'][x]) for x in paramkeys]
+ if arg_support_enabled and 'args' in log_entry:
+ paramvalues.extend(map(soft_cast_int, log_entry['args']))
if not 'param' in log_entry['offline_aggregates']:
log_entry['offline_aggregates']['param'] = list()
if 'duration' in log_entry['offline_aggregates']:
@@ -982,15 +984,46 @@ class AnalyticModel:
assess -- calculate model quality
"""
- def __init__(self, by_name, parameters, verbose = True):
- """Create a new AnalyticModel and compute parameter statistics."""
+ def __init__(self, by_name, parameters, arg_count = None, verbose = True):
+ """
+ Create a new AnalyticModel and compute parameter statistics.
+
+ parameters:
+ `by_name`: measurements aggregated by (function/state/...) name. Layout:
+ dictionary with one key per name ('send', 'TX', ...) or
+ one key per name and parameter combination
+ (('send', (1, 2)), ('send', (2, 3)), ('TX', (1, 2)), ('TX', (2, 3)), ...).
+
+ Parameter values must be ordered corresponding to the lexically sorted parameter names.
+
+ Each element is in turn a dict with the following elements:
+ - param: list of parameter values in each measurement (-> list of lists)
+ - attributes: list of keys that should be analyzed,
+ e.g. ['power', 'duration']
+ - for each attribute mentioned in 'attributes': A list with measurements.
+ All list except for 'attributes' must have the same length.
+
+ For example:
+ parameters = ['foo_count', 'irrelevant']
+ by_name = {
+ 'foo' : [1, 1, 2],
+ 'duration' : [5, 6, 7],
+ 'attributes' : ['foo', 'duration'],
+ 'param' : [[1, 0], [1, 0], [2, 0]]
+ # foo_count-^ ^-irrelevant
+ }
+ `parameters`: List of parameter names
+ `verbose`: Print debug/info output while generating the model?
+ """
self.cache = dict()
self.by_name = by_name
self.by_param = by_name_to_by_param(by_name)
self.names = sorted(by_name.keys())
self.parameters = sorted(parameters)
self.verbose = verbose
- self._num_args = _num_args_from_by_name(by_name)
+ self._num_args = arg_count
+ if self._num_args is None:
+ self._num_args = _num_args_from_by_name(by_name)
self.stats = ParamStats(self.by_name, self.by_param, self.parameters, self._num_args, verbose = verbose)