summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/harness.py80
-rw-r--r--lib/runner.py30
2 files changed, 84 insertions, 26 deletions
diff --git a/lib/harness.py b/lib/harness.py
index af74977..76b658c 100644
--- a/lib/harness.py
+++ b/lib/harness.py
@@ -96,25 +96,66 @@ class TransitionHarness:
def stop_benchmark(self):
return ''
+ def _append_nondeterministic_parameter_value(self, log_data_target, parameter_name, parameter_value):
+ if log_data_target['parameter'][parameter_name] is None:
+ log_data_target['parameter'][parameter_name] = list()
+ log_data_target['parameter'][parameter_name].append(parameter_value)
+
def parser_cb(self, line):
- pass
-
- def parse_log(self, lines):
- sync = False
- for line in lines:
- print(line)
- res = re.fullmatch(r'\[PTA\] (.*=.*)', line)
- if re.fullmatch(r'\[PTA\] benchmark start, id=(.*)', line):
- print('> got sync')
- sync = True
- elif not sync:
- continue
- elif re.fullmatch(r'\[PTA\] trace, count=(.*)', line):
- print('> got transition')
- pass
- elif res:
- print(dict(map(lambda x: x.split('='), res.group(1).split())))
- pass
+ #print('[HARNESS] got line {}'.format(line))
+ if re.match(r'\[PTA\] benchmark start, id=(\S+)', line):
+ self.synced = True
+ print('[HARNESS] synced')
+ if self.synced:
+ res = re.match(r'\[PTA\] trace=(\S+) count=(\S+)', line)
+ if res:
+ self.trace_id = int(res.group(1))
+ self.trace_length = int(res.group(2))
+ self.current_transition_in_trace = 0
+ #print('[HARNESS] trace {:d} contains {:d} transitions. Expecting {:d} transitions.'.format(self.trace_id, self.trace_length, len(self.traces[self.trace_id]['trace']) // 2))
+ if self.log_return_values:
+ res = re.match(r'\[PTA\] transition=(\S+) return=(\S+)', line)
+ else:
+ res = re.match(r'\[PTA\] transition=(\S+)', line)
+ if res:
+ transition_id = int(res.group(1))
+ # self.traces contains transitions and states, UART output only contains transitions -> use index * 2
+ try:
+ log_data_target = self.traces[self.trace_id]['trace'][self.current_transition_in_trace * 2]
+ except IndexError:
+ transition_name = None
+ if self.pta:
+ transition_name = self.pta.transitions[transition_id].name
+ print('[HARNESS] benchmark id={:d} trace={:d}: transition #{:d} (ID {:d}, name {}) is out of bounds'.format(0, self.trace_id, self.current_transition_in_trace, transition_id, transition_name))
+ print(' Offending line: {}'.format(line))
+ return
+ if log_data_target['isa'] != 'transition':
+ raise RuntimeError('Log mismatch: Expected transition, got {:s}'.format(log_data_target['isa']))
+ if self.pta:
+ transition = self.pta.transitions[transition_id]
+ if transition.name != log_data_target['name']:
+ raise RuntimeError('Log mismatch: Expected transition {:s}, got transition {:s}'.format(log_data_target['name'], transition.name))
+ if self.log_return_values and len(transition.return_value_handlers):
+ for handler in transition.return_value_handlers:
+ if 'parameter' in handler:
+ parameter_value = return_value = int(res.group(2))
+
+ if 'return_values' not in log_data_target:
+ log_data_target['return_values'] = list()
+ log_data_target['return_values'].append(return_value)
+
+ if 'formula' in handler:
+ parameter_value = handler['formula'].eval(return_value)
+
+ self._append_nondeterministic_parameter_value(log_data_target, handler['parameter'], parameter_value)
+ for following_log_data_target in self.traces[self.trace_id]['trace'][(self.current_transition_in_trace * 2 + 1) :]:
+ self._append_nondeterministic_parameter_value(following_log_data_target, handler['parameter'], parameter_value)
+ if 'apply_from' in handler and any(map(lambda x: x['name'] == handler['apply_from'], self.traces[self.trace_id]['trace'][: (self.current_transition_in_trace * 2 + 1)])):
+ for preceding_log_data_target in reversed(self.traces[self.trace_id]['trace'][: (self.current_transition_in_trace * 2)]):
+ self._append_nondeterministic_parameter_value(preceding_log_data_target, handler['parameter'], parameter_value)
+ if preceding_log_data_target['name'] == handler['apply_from']:
+ break
+ self.current_transition_in_trace += 1
class OnboardTimerHarness(TransitionHarness):
"""Bar."""
@@ -179,13 +220,12 @@ class OnboardTimerHarness(TransitionHarness):
res = re.match(r'\[PTA\] transition=(\S+) cycles=(\S+)/(\S+)', line)
if res:
transition_id = int(res.group(1))
- # TODO Handle Overflows (requires knowledge of arch-specific max cycle value)
cycles = int(res.group(2))
overflow = int(res.group(3))
if overflow >= self.counter_max_overflow:
raise RuntimeError('Counter overflow ({:d}/{:d}) in benchmark id={:d} trace={:d}: transition #{:d} (ID {:d})'.format(cycles, overflow, 0, self.trace_id, self.current_transition_in_trace, transition_id))
duration_us = cycles * self.one_cycle_in_us + overflow * self.one_overflow_in_us
- # self.traces contains transitions and states, UART output only contains trnasitions -> use index * 2
+ # self.traces contains transitions and states, UART output only contains transitions -> use index * 2
try:
log_data_target = self.traces[self.trace_id]['trace'][self.current_transition_in_trace * 2]
except IndexError:
diff --git a/lib/runner.py b/lib/runner.py
index e5c75b8..588bd4d 100644
--- a/lib/runner.py
+++ b/lib/runner.py
@@ -114,9 +114,15 @@ class SerialMonitor:
time.sleep(timeout)
return self.reader.get_lines()
- def get_lines(self) ->list:
+ def get_lines(self) -> list:
return self.reader.get_lines()
+ def get_files(self) -> list:
+ return list()
+
+ def get_config(self) -> dict:
+ return dict()
+
def close(self):
"""Close serial connection."""
self.worker.stop()
@@ -147,13 +153,12 @@ class MIMOSAMonitor(SerialMonitor):
raise RuntimeError('{} returned {}'.format(' '.join(cmd), res.returncode))
def _start_mimosa(self):
+ self._mimosactl('disconnect')
self._mimosacmd(['--start'])
self._mimosacmd(['--parameter', 'offset', str(self._offset)])
self._mimosacmd(['--parameter', 'shunt', str(self._shunt)])
self._mimosacmd(['--parameter', 'voltage', str(self._voltage)])
self._mimosacmd(['--mimosa-start'])
- time.sleep(1)
- self._mimosactl('disconnect')
time.sleep(2)
self._mimosactl('1k') # 987 ohm
time.sleep(2)
@@ -166,7 +171,11 @@ class MIMOSAMonitor(SerialMonitor):
mtime_changed = True
mim_file = None
time.sleep(1)
- for filename in os.listdir():
+ # reverse sort ensures that we will get the latest file, which must
+ # belong to the current measurements. This ensures that older .mim
+ # files lying around in the directory will not confuse our
+ # heuristic.
+ for filename in sorted(os.listdir(), reverse = True):
if re.search(r'[.]mim$', filename):
mim_file = filename
break
@@ -180,8 +189,17 @@ class MIMOSAMonitor(SerialMonitor):
def close(self):
super().close()
- mim_file = self._stop_mimosa()
- os.remove(mim_file)
+ self.mim_file = self._stop_mimosa()
+
+ def get_files(self) -> list:
+ return [self.mim_file]
+
+ def get_config(self) -> dict:
+ return {
+ 'offset' : self._offset,
+ 'shunt' : self._shunt,
+ 'voltage' : self._voltage,
+ }
class ShellMonitor:
"""SerialMonitor runs a program and captures its output for a specific amount of time."""