diff options
-rwxr-xr-x | bin/analyze-archive.py | 4 | ||||
-rwxr-xr-x | bin/test.py | 14 | ||||
-rwxr-xr-x | lib/dfatool.py | 69 | ||||
-rwxr-xr-x | lib/ipython_energymodel_prelude.py | 4 |
4 files changed, 73 insertions, 18 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py index dbfe0d1..307cbd2 100755 --- a/bin/analyze-archive.py +++ b/bin/analyze-archive.py @@ -5,7 +5,7 @@ import json import plotter import re import sys -from dfatool import EnergyModel, RawData +from dfatool import PTAModel, RawData from dfatool import soft_cast_int, is_numeric, gplearn_to_function opts = {} @@ -147,7 +147,7 @@ if __name__ == '__main__': raw_data = RawData(args) preprocessed_data = raw_data.get_preprocessed_data() - model = EnergyModel(preprocessed_data, + model = PTAModel(preprocessed_data, ignore_trace_indexes = ignored_trace_indexes, discard_outliers = discard_outliers, function_override = function_override, diff --git a/bin/test.py b/bin/test.py index 0b015f4..ae72df2 100755 --- a/bin/test.py +++ b/bin/test.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 -from dfatool import EnergyModel, RawData, analytic +from dfatool import PTAModel, RawData, analytic import unittest class TestStaticModel(unittest.TestCase): def test_model_singlefile_rf24(self): raw_data = RawData(['../data/20170220_164723_RF24_int_A.tar']) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'POWERDOWN RX STANDBY1 TX'.split(' ')) self.assertEqual(model.transitions(), 'begin epilogue powerDown powerUp setDataRate_num setPALevel_num startListening stopListening write_nb'.split(' ')) static_model = model.get_static() @@ -72,7 +72,7 @@ class TestStaticModel(unittest.TestCase): def test_model_singlefile_mmparam(self): raw_data = RawData(['../data/20161221_123347_mmparam.tar']) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'OFF ON'.split(' ')) self.assertEqual(model.transitions(), 'off setBrightness'.split(' ')) static_model = model.get_static() @@ -100,7 +100,7 @@ class TestStaticModel(unittest.TestCase): ] raw_data = RawData(testfiles) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'ACTIVE POWEROFF'.split(' ')) self.assertEqual(model.transitions(), 'getTemp setHyst setOS shutdown start'.split(' ')) static_model = model.get_static() @@ -129,7 +129,7 @@ class TestStaticModel(unittest.TestCase): ] raw_data = RawData(testfiles) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'DISABLED ENABLED'.split(' ')) self.assertEqual(model.transitions(), 'clear disable enable ioInit sendLine toggleVCOM'.split(' ')) static_model = model.get_static() @@ -161,7 +161,7 @@ class TestStaticModel(unittest.TestCase): ] raw_data = RawData(testfiles) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'B G OFF R'.split(' ')) self.assertEqual(model.transitions(), 'blue green off red'.split(' ')) static_model = model.get_static() @@ -193,7 +193,7 @@ class TestStaticModel(unittest.TestCase): ] raw_data = RawData(testfiles) preprocessed_data = raw_data.get_preprocessed_data(verbose = False) - model = EnergyModel(preprocessed_data, verbose = False) + model = PTAModel(preprocessed_data, verbose = False) self.assertEqual(model.states(), 'IDLE RX SLEEP SLEEP_EWOR SYNTH_ON TX XOFF'.split(' ')) self.assertEqual(model.transitions(), 'crystal_off eWOR idle init prepare_xmit receive send setSymbolRate setTxPower sleep txDone'.split(' ')) static_model = model.get_static() diff --git a/lib/dfatool.py b/lib/dfatool.py index 372adee..b71df98 100755 --- a/lib/dfatool.py +++ b/lib/dfatool.py @@ -249,7 +249,7 @@ 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) + x = PTAModel.from_model(em.by_name, em._parameter_names) def _preprocess_measurement(measurement): @@ -397,7 +397,7 @@ class RawData: Expects a specific trace format and UART log output (as produced by the dfatool benchmark generator). Loads data, prunes bogus measurements, and - provides preprocessed data suitable for EnergyModel. + provides preprocessed data suitable for PTAModel. """ def __init__(self, filenames): @@ -586,8 +586,8 @@ class RawData: """ Return a list of DFA traces annotated with energy, timing, and parameter data. - Suitable for the EnergyModel constructor. - See EnergyModel(...) docstring for format details. + Suitable for the PTAModel constructor. + See PTAModel(...) docstring for format details. """ self.verbose = verbose if self.preprocessed: @@ -758,14 +758,69 @@ def _try_fits(by_param, state_or_tran, model_attribute, param_index, safe_functi 'results' : results } -class EnergyModel: +class AnalyticModel: u""" - parameter-aware PTA-based energy model. + Parameter-aware analytic energy/data size/... model. Supports both static and parameter-based model attributes, and automatic detection of parameter-dependence. The model heavily relies on two internal data structures: - EnergyModel.by_name and EnergyModel.by_param. + PTAModel.by_name and PTAModel.by_param. + + These provide measurements aggregated by (function/state/...) name + and (for by_param) parameter values. 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. + """ + + def __init__(self, by_name, by_param, parameters): + self.by_name = by_name + self.by_param = by_param + self.parameters = sorted(parameters) + + self.stats = ParamStats(self.by_name, self.by_param, self.parameters) + + def _fit(self): + paramfit = ParallelParamFit(self.by_param) + + for name in self.by_name.keys(): + for attribute in self.by_name[fname]['attributes']: + for param_index, param in enumerate(self.parameters): + ratio = self.stats.param_dependence_ratio(fname, attribute, param) + if self.stats.depends_on_param(fname, attribute, param): + paramfit.enqueue(fname, attribute, param_index, param, False) + + paramfit.fit() + + for name in self.by_name.keys(): + for attribute in self.by_name[fname]['attributes']: + fit_result = {} + for result in paramfit.results: + if result['key'][0] == name and result['key'][1] == attribute and result['result']['best'] != None: + fit_result[result['key'][2]] = result['result'] + if len(fit_result.keys()): + x = analytic.function_powerset(fit_result, parameters) + x.fit(by_param, fname, attribute) + + +class PTAModel: + u""" + Parameter-aware PTA-based energy model. + + Supports both static and parameter-based model attributes, and automatic detection of parameter-dependence. + + The model heavily relies on two internal data structures: + PTAModel.by_name and PTAModel.by_param. These provide measurements aggregated by state/transition name and (in case of by_para) parameter values. Layout: diff --git a/lib/ipython_energymodel_prelude.py b/lib/ipython_energymodel_prelude.py index a44a5d7..6777b17 100755 --- a/lib/ipython_energymodel_prelude.py +++ b/lib/ipython_energymodel_prelude.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import numpy as np -from dfatool import EnergyModel, RawData, soft_cast_int +from dfatool import PTAModel, RawData, soft_cast_int ignored_trace_indexes = None @@ -10,4 +10,4 @@ files = '../data/20170125_125433_cc1200.tar ../data/20170125_142420_cc1200.tar . raw_data = RawData(files) preprocessed_data = raw_data.get_preprocessed_data() -model = EnergyModel(preprocessed_data, ignore_trace_indexes = ignored_trace_indexes) +model = PTAModel(preprocessed_data, ignore_trace_indexes = ignored_trace_indexes) |