summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/analyze-archive.py5
-rwxr-xr-xlib/automata.py34
-rw-r--r--lib/dfatool.py21
3 files changed, 43 insertions, 17 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py
index 8470ab6..a70b23b 100755
--- a/bin/analyze-archive.py
+++ b/bin/analyze-archive.py
@@ -74,7 +74,7 @@ Options:
Load DFA hardware model from JSON or YAML
--export-energymodel=<model.json>
- Export energy model. Requires --hwmodel.
+ Export energy model. Works out of the box for v1 and v2 logfiles. Requires --hwmodel for v0 logfiles.
"""
import getopt
@@ -283,6 +283,9 @@ if __name__ == '__main__':
print('No valid data available. Abort.')
sys.exit(2)
+ if pta is None and raw_data.pta is not None:
+ pta = PTA.from_json(raw_data.pta)
+
by_name, parameters, arg_count = pta_trace_to_aggregate(preprocessed_data, ignored_trace_indexes)
filter_aggregate_by_param(by_name, parameters, opts['filter-param'])
diff --git a/lib/automata.py b/lib/automata.py
index 2c21389..d36acd7 100755
--- a/lib/automata.py
+++ b/lib/automata.py
@@ -914,17 +914,25 @@ class PTA:
def update(self, static_model, param_model):
for state in self.state.values():
if state.name != 'UNINITIALIZED':
- state.power = static_model(state.name, 'power')
- if param_model(state.name, 'power'):
- state.power_function = param_model(state.name, 'power')['function']
+ try:
+ state.power = static_model(state.name, 'power')
+ if param_model(state.name, 'power'):
+ state.power_function = param_model(state.name, 'power')['function']
+ except KeyError:
+ print('[W] skipping model update of state {} due to missing data'.format(state.name))
+ pass
for transition in self.transitions:
- transition.duration = static_model(transition.name, 'duration')
- if param_model(transition.name, 'duration'):
- transition.duration_function = param_model(transition.name, 'duration')['function']
- transition.energy = static_model(transition.name, 'energy')
- if param_model(transition.name, 'energy'):
- transition.energy_function = param_model(transition.name, 'energy')['function']
- if transition.is_interrupt:
- transition.timeout = static_model(transition.name, 'timeout')
- if param_model(transition.name, 'timeout'):
- transition.timeout_function = param_model(transition.name, 'timeout')['function']
+ try:
+ transition.duration = static_model(transition.name, 'duration')
+ if param_model(transition.name, 'duration'):
+ transition.duration_function = param_model(transition.name, 'duration')['function']
+ transition.energy = static_model(transition.name, 'energy')
+ if param_model(transition.name, 'energy'):
+ transition.energy_function = param_model(transition.name, 'energy')['function']
+ if transition.is_interrupt:
+ transition.timeout = static_model(transition.name, 'timeout')
+ if param_model(transition.name, 'timeout'):
+ transition.timeout_function = param_model(transition.name, 'timeout')['function']
+ except KeyError:
+ print('[W] skipping model update of transition {} due to missing data'.format(state.name))
+ pass \ No newline at end of file
diff --git a/lib/dfatool.py b/lib/dfatool.py
index 6b5b523..9583d73 100644
--- a/lib/dfatool.py
+++ b/lib/dfatool.py
@@ -560,10 +560,11 @@ class RawData:
self.preprocessed = False
self._parameter_names = None
self.ignore_clipping = False
+ self.pta = None
with tarfile.open(filenames[0]) as tf:
for member in tf.getmembers():
- if member.name == 'ptalog.json':
+ if member.name == 'ptalog.json' and self.version == 0:
self.version = 1
# might also be version 2
# depends on whether *.etlog exists or not
@@ -585,6 +586,8 @@ class RawData:
cache_data = json.load(f)
self.traces = cache_data['traces']
self.preprocessing_stats = cache_data['preprocessing_stats']
+ if 'pta' in cache_data:
+ self.pta = cache_data['pta']
self.preprocessed = True
def save_cache(self):
@@ -595,7 +598,8 @@ class RawData:
with open(self.cache_file, 'w') as f:
cache_data = {
'traces': self.traces,
- 'preprocessing_stats': self.preprocessing_stats
+ 'preprocessing_stats': self.preprocessing_stats,
+ 'pta': self.pta,
}
json.dump(cache_data, f)
@@ -909,6 +913,13 @@ class RawData:
# offline_aggregates['rel_energy_next'].append(offline_trace_part['W_mean_delta_next'] * offline_trace_part['s'] * 1e12)
def _concatenate_traces(self, list_of_traces):
+ """
+ Concatenate `list_of_traces` (list of lists) into a single trace while adjusting trace IDs.
+
+ :param list_of_traces: List of list of traces.
+ :returns: List of traces with ['id'] in ascending order and ['orig_id'] as previous ['id']
+ """
+
trace_output = list()
for trace in list_of_traces:
trace_output.extend(trace.copy())
@@ -1007,6 +1018,7 @@ class RawData:
new_filenames = list()
with tarfile.open(filename) as tf:
ptalog = json.load(tf.extractfile(tf.getmember('ptalog.json')))
+ self.pta = ptalog['pta']
# Benchmark code may be too large to be executed in a single
# run, so benchmarks (a benchmark is basically a list of DFA runs)
@@ -1056,6 +1068,7 @@ class RawData:
new_filenames = list()
with tarfile.open(filename) as tf:
ptalog = json.load(tf.extractfile(tf.getmember('ptalog.json')))
+ self.pta = ptalog['pta']
# Benchmark code may be too large to be executed in a single
# run, so benchmarks (a benchmark is basically a list of DFA runs)
@@ -2168,7 +2181,9 @@ class EnergyTraceLog:
Expects an EnergyTrace log file generated via msp430-etv / energytrace-util
and a dfatool-generated benchmark. An EnergyTrace log consits of a series
of measurements. Each measurement has a timestamp, mean current, voltage,
- and cumulative energy since start of measurement.
+ and cumulative energy since start of measurement. Each transition is
+ preceded by a Code128 barcode embedded into the energy consumption by
+ toggling a LED.
Note that the baseline power draw of board and peripherals is not subtracted
at the moment.