diff options
-rwxr-xr-x | bin/analyze-archive.py | 14 | ||||
-rwxr-xr-x | bin/generate-dfa-benchmark.py | 6 | ||||
-rwxr-xr-x | lib/automata.py | 12 | ||||
-rw-r--r-- | lib/dfatool.py | 11 |
4 files changed, 25 insertions, 18 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py index 685ce92..4551cda 100755 --- a/bin/analyze-archive.py +++ b/bin/analyze-archive.py @@ -70,8 +70,8 @@ Options: not been set yet) are discarded. Note that this may remove entire function calls from the model. ---hwmodel=<hwmodel.json> - Load DFA hardware model from JSON +--hwmodel=<hwmodel.json|hwmodel.dfa> + Load DFA hardware model from JSON or YAML --export-energymodel=<model.json> Export energy model. Requires --hwmodel. @@ -86,6 +86,7 @@ from dfatool import PTAModel, RawData, pta_trace_to_aggregate from dfatool import soft_cast_int, is_numeric, gplearn_to_function from dfatool import CrossValidator from utils import filter_aggregate_by_param +from automata import PTA opts = {} @@ -211,7 +212,7 @@ if __name__ == '__main__': function_override = {} show_models = [] show_quality = [] - hwmodel = None + pta = None energymodel_export_file = None xv_method = None xv_count = 10 @@ -262,8 +263,7 @@ if __name__ == '__main__': safe_functions_enabled = True if 'hwmodel' in opts: - with open(opts['hwmodel'], 'r') as f: - hwmodel = json.load(f) + pta = PTA.from_file(opts['hwmodel']) except getopt.GetoptError as err: print(err) @@ -280,7 +280,7 @@ if __name__ == '__main__': traces = preprocessed_data, discard_outliers = discard_outliers, function_override = function_override, - hwmodel = hwmodel) + pta = pta) if xv_method: xv = CrossValidator(PTAModel, by_name, parameters, arg_count) @@ -416,7 +416,7 @@ if __name__ == '__main__': plotter.plot_param(model, state_or_trans, attribute, model.param_index(param_name), extra_function=function) if 'export-energymodel' in opts: - if not hwmodel: + if not pta: print('[E] --export-energymodel requires --hwmodel to be set') sys.exit(1) json_model = model.to_json() diff --git a/bin/generate-dfa-benchmark.py b/bin/generate-dfa-benchmark.py index 7f67e1b..3ae51e6 100755 --- a/bin/generate-dfa-benchmark.py +++ b/bin/generate-dfa-benchmark.py @@ -302,11 +302,7 @@ if __name__ == '__main__': modelfile = args[0] - with open(modelfile, 'r') as f: - if '.json' in modelfile: - pta = PTA.from_json(json.load(f)) - else: - pta = PTA.from_yaml(yaml.safe_load(f)) + pta = PTA.from_file(modelfile) if 'shrink' in opt: pta.shrink_argument_values() diff --git a/lib/automata.py b/lib/automata.py index 2387734..6d90e4c 100755 --- a/lib/automata.py +++ b/lib/automata.py @@ -4,6 +4,7 @@ from functions import AnalyticFunction, NormalizationFunction from utils import is_numeric import itertools import numpy as np +import json, yaml def _dict_to_list(input_dict: dict) -> list: return [input_dict[x] for x in sorted(input_dict.keys())] @@ -100,6 +101,8 @@ class State: :returns: Generator object for depth-first search. Each access yields a list of (Transition, (arguments)) elements describing a single run through the PTA. """ + # TODO parametergewahrer Trace-Filter, z.B. "setHeaterDuration nur wenn bme680 power mode => FORCED und GAS_ENABLED" + # A '$' entry in trace_filter indicates that the trace should (successfully) terminate here regardless of `depth`. if trace_filter is not None and next(filter(lambda x: x == '$', map(lambda x: x[0], trace_filter)), None) is not None: yield [] @@ -403,6 +406,15 @@ class PTA: return normalized_param @classmethod + def from_file(cls, model_file: str): + """Return PTA loaded from the provided JSON or YAML file.""" + with open(model_file, 'r') as f: + if '.json' in model_file: + return cls.from_json(json.load(f)) + else: + return cls.from_yaml(yaml.safe_load(f)) + + @classmethod def from_json(cls, json_input: dict): """ Return a PTA created from the provided JSON data. diff --git a/lib/dfatool.py b/lib/dfatool.py index a3d5c0f..363c2a2 100644 --- a/lib/dfatool.py +++ b/lib/dfatool.py @@ -1505,7 +1505,7 @@ class PTAModel: - rel_energy_next: transition energy relative to next state mean power in pJ """ - def __init__(self, by_name, parameters, arg_count, traces = [], ignore_trace_indexes = [], discard_outliers = None, function_override = {}, verbose = True, use_corrcoef = False, hwmodel = None): + def __init__(self, by_name, parameters, arg_count, traces = [], ignore_trace_indexes = [], discard_outliers = None, function_override = {}, verbose = True, use_corrcoef = False, pta = None): """ Prepare a new PTA energy model. @@ -1534,7 +1534,7 @@ class PTAModel: verbose -- print informative output, e.g. when removing an outlier use_corrcoef -- use correlation coefficient instead of stddev comparison to detect whether a model attribute depends on a parameter - hwmodel -- hardware model suitable for PTA.from_hwmodel + pta -- hardware model as `PTA` object """ self.by_name = by_name self.by_param = by_name_to_by_param(by_name) @@ -1548,7 +1548,7 @@ class PTAModel: self._outlier_threshold = discard_outliers self.function_override = function_override.copy() self.verbose = verbose - self.hwmodel = hwmodel + self.pta = pta self.ignore_trace_indexes = ignore_trace_indexes self._aggregate_to_ndarray(self.by_name) @@ -1715,9 +1715,8 @@ class PTAModel: def to_json(self): static_model = self.get_static() _, param_info = self.get_fitted() - pta = PTA.from_json(self.hwmodel) - pta.update(static_model, param_info) - return pta.to_json() + self.pta.update(static_model, param_info) + return self.pta.to_json() def states(self): return sorted(list(filter(lambda k: self.by_name[k]['isa'] == 'state', self.by_name.keys()))) |