summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-11-21 08:40:34 +0100
committerDaniel Friesel <daniel.friesel@uos.de>2019-11-21 08:40:34 +0100
commitbffa9cba304c5ff1a2a11e1ea3a9b1fede1cacfb (patch)
tree37151133ea113566c49159a98436361e9c4d270f
parent0d4616db3975919c46b73cfbd4c6054b94e55aa6 (diff)
flake8 code style
-rwxr-xr-xbin/generate-dfa-benchmark.py53
-rw-r--r--lib/codegen.py104
2 files changed, 83 insertions, 74 deletions
diff --git a/bin/generate-dfa-benchmark.py b/bin/generate-dfa-benchmark.py
index 62808de..02b90f8 100755
--- a/bin/generate-dfa-benchmark.py
+++ b/bin/generate-dfa-benchmark.py
@@ -53,7 +53,7 @@ Options:
Only consider traces whose beginning matches one of the provided transition sequences.
E.g. --trace-filter='init,foo init,bar' will only consider traces with init as first and foo or bar as second transition,
and --trace-filter='init,foo,$ init,bar,$' will only consider the traces init -> foo and init -> bar.
-
+
"""
import getopt
@@ -68,13 +68,14 @@ import io
import yaml
from aspectc import Repo
from automata import PTA
-from codegen import *
+from codegen import get_accountingmethod, MultipassDriver
from harness import OnboardTimerHarness, TransitionHarness
from utils import flatten
opt = dict()
-def benchmark_from_runs(pta: PTA, runs: list, harness: OnboardTimerHarness, benchmark_id: int = 0, dummy = False, repeat = 0) -> io.StringIO:
+
+def benchmark_from_runs(pta: PTA, runs: list, harness: OnboardTimerHarness, benchmark_id: int = 0, dummy=False, repeat=0) -> io.StringIO:
outbuf = io.StringIO()
outbuf.write('#include "arch.h"\n')
@@ -146,7 +147,7 @@ def benchmark_from_runs(pta: PTA, runs: list, harness: OnboardTimerHarness, benc
transition_code = '// TODO add startTransition / stopTransition calls to interrupt routine'
else:
transition_code = '{}{}({});'.format(class_prefix, transition.name, ', '.join(map(str, arguments)))
- outbuf.write(harness.pass_transition(pta.get_transition_id(transition), transition_code, transition = transition))
+ outbuf.write(harness.pass_transition(pta.get_transition_id(transition), transition_code, transition=transition))
param = parameter
@@ -176,17 +177,18 @@ def benchmark_from_runs(pta: PTA, runs: list, harness: OnboardTimerHarness, benc
return outbuf
-def run_benchmark(application_file: str, pta: PTA, runs: list, arch: str, app: str, run_args: list, harness: object, sleep: int = 0, repeat: int = 0, run_offset: int = 0, runs_total: int = 0, dummy = False):
+
+def run_benchmark(application_file: str, pta: PTA, runs: list, arch: str, app: str, run_args: list, harness: object, sleep: int = 0, repeat: int = 0, run_offset: int = 0, runs_total: int = 0, dummy=False):
if 'mimosa' in opt or 'energytrace' in opt:
- outbuf = benchmark_from_runs(pta, runs, harness, dummy = dummy, repeat = 1)
+ outbuf = benchmark_from_runs(pta, runs, harness, dummy=dummy, repeat=1)
else:
- outbuf = benchmark_from_runs(pta, runs, harness, dummy = dummy, repeat = repeat)
+ outbuf = benchmark_from_runs(pta, runs, harness, dummy=dummy, repeat=repeat)
with open(application_file, 'w') as f:
f.write(outbuf.getvalue())
print('[MAKE] building benchmark with {:d} runs'.format(len(runs)))
# assume an average of 10ms per transition. Mind the 10s start delay.
- run_timeout = 10 + num_transitions * (sleep+10) / 1000
+ run_timeout = 10 + num_transitions * (sleep + 10) / 1000
if repeat:
run_timeout *= repeat
@@ -212,20 +214,19 @@ def run_benchmark(application_file: str, pta: PTA, runs: list, arch: str, app: s
mid = len(runs) // 2
# Previously prepared trace data is useless
harness.reset()
- results = run_benchmark(application_file, pta, runs[:mid], arch, app, run_args, harness.copy(), sleep, repeat, run_offset = run_offset, runs_total = runs_total, dummy = dummy)
- results.extend(run_benchmark(application_file, pta, runs[mid:], arch, app, run_args, harness.copy(), sleep, repeat, run_offset = run_offset + mid, runs_total = runs_total, dummy = dummy))
+ results = run_benchmark(application_file, pta, runs[:mid], arch, app, run_args, harness.copy(), sleep, repeat, run_offset=run_offset, runs_total=runs_total, dummy=dummy)
+ results.extend(run_benchmark(application_file, pta, runs[mid:], arch, app, run_args, harness.copy(), sleep, repeat, run_offset=run_offset + mid, runs_total=runs_total, dummy=dummy))
return results
-
if 'mimosa' in opt or 'energytrace' in opt:
files = list()
i = 0
while i < opt['repeat']:
runner.flash(arch, app, run_args)
if 'mimosa' in opt:
- monitor = runner.get_monitor(arch, callback = harness.parser_cb, mimosa = opt['mimosa'])
+ monitor = runner.get_monitor(arch, callback=harness.parser_cb, mimosa=opt['mimosa'])
elif 'energytrace' in opt:
- monitor = runner.get_monitor(arch, callback = harness.parser_cb, energytrace = opt['energytrace'])
+ monitor = runner.get_monitor(arch, callback=harness.parser_cb, energytrace=opt['energytrace'])
sync_error = False
try:
@@ -263,7 +264,7 @@ def run_benchmark(application_file: str, pta: PTA, runs: list, arch: str, app: s
return [(runs, harness, monitor, files)]
else:
runner.flash(arch, app, run_args)
- monitor = runner.get_monitor(arch, callback = harness.parser_cb)
+ monitor = runner.get_monitor(arch, callback=harness.parser_cb)
if arch == 'posix':
print('[RUN] Will run benchmark for {:.0f} seconds'.format(run_timeout))
@@ -398,7 +399,7 @@ if __name__ == '__main__':
if run_flags is None:
run_flags = opt['run'].split()
- runs = list(pta.dfs(opt['depth'], with_arguments = True, with_parameters = True, trace_filter = opt['trace-filter']))
+ runs = list(pta.dfs(opt['depth'], with_arguments=True, with_parameters=True, trace_filter=opt['trace-filter']))
num_transitions = len(runs)
@@ -411,21 +412,21 @@ if __name__ == '__main__':
need_return_values = True
if 'mimosa' in opt:
- harness = TransitionHarness(gpio_pin = timer_pin, pta = pta, log_return_values = need_return_values, repeat = 1, post_transition_delay_us = 20)
+ harness = TransitionHarness(gpio_pin=timer_pin, pta=pta, log_return_values=need_return_values, repeat=1, post_transition_delay_us=20)
elif 'energytrace' in opt:
- harness = OnboardTimerHarness(gpio_pin = timer_pin, gpio_mode = 'bar', pta = pta, counter_limits = runner.get_counter_limits_us(opt['arch']), log_return_values = need_return_values, repeat = 1)
+ harness = OnboardTimerHarness(gpio_pin=timer_pin, gpio_mode='bar', pta=pta, counter_limits=runner.get_counter_limits_us(opt['arch']), log_return_values=need_return_values, repeat=1)
elif 'timing' in opt:
- harness = OnboardTimerHarness(gpio_pin = timer_pin, pta = pta, counter_limits = runner.get_counter_limits_us(opt['arch']), log_return_values = need_return_values, repeat = opt['repeat'])
+ harness = OnboardTimerHarness(gpio_pin=timer_pin, pta=pta, counter_limits=runner.get_counter_limits_us(opt['arch']), log_return_values=need_return_values, repeat=opt['repeat'])
if len(args) > 1:
- results = run_benchmark(args[1], pta, runs, opt['arch'], opt['app'], run_flags, harness, opt['sleep'], opt['repeat'], runs_total = len(runs), dummy = 'dummy' in opt)
+ results = run_benchmark(args[1], pta, runs, opt['arch'], opt['app'], run_flags, harness, opt['sleep'], opt['repeat'], runs_total=len(runs), dummy='dummy' in opt)
json_out = {
- 'opt' : opt,
- 'pta' : pta.to_json(),
- 'traces' : list(map(lambda x: x[1].traces, results)),
- 'raw_output' : list(map(lambda x: x[2].get_lines(), results)),
- 'files' : list(map(lambda x: x[3], results)),
- 'configs' : list(map(lambda x: x[2].get_config(), results)),
+ 'opt': opt,
+ 'pta': pta.to_json(),
+ 'traces': list(map(lambda x: x[1].traces, results)),
+ 'raw_output': list(map(lambda x: x[2].get_lines(), results)),
+ 'files': list(map(lambda x: x[3], results)),
+ 'configs': list(map(lambda x: x[2].get_config(), results)),
}
extra_files = flatten(json_out['files'])
if 'instance' in pta.codegen:
@@ -448,7 +449,7 @@ if __name__ == '__main__':
json.dump(json_out, f)
print(' --> {}.json'.format(output_prefix))
else:
- outbuf = benchmark_from_runs(pta, runs, harness, repeat = opt['repeat'])
+ outbuf = benchmark_from_runs(pta, runs, harness, repeat=opt['repeat'])
print(outbuf.getvalue())
sys.exit(0)
diff --git a/lib/codegen.py b/lib/codegen.py
index 75c5102..45ae8f7 100644
--- a/lib/codegen.py
+++ b/lib/codegen.py
@@ -2,7 +2,6 @@
from automata import PTA, Transition
from modular_arithmetic import simulate_int_type
-import numpy as np
header_template = """
#ifndef DFATOOL_{name}_H
@@ -40,6 +39,7 @@ array_template = """
{type} const {name}[{length}] = {{{elements}}};
"""
+
class ClassFunction:
def __init__(self, class_name, return_type, name, arguments, body):
"""
@@ -65,6 +65,7 @@ class ClassFunction:
return ''
return '{} {}::{}({}) {{\n{}}}\n'.format(self.return_type, self.class_name, self.name, ', '.join(self.arguments), self.body)
+
def get_accountingmethod(method):
"""Return AccountingMethod class for method."""
if method == 'static_state_immediate':
@@ -77,6 +78,7 @@ def get_accountingmethod(method):
return StaticAccounting
raise ValueError('Unknown accounting method: {}'.format(method))
+
def get_simulated_accountingmethod(method):
"""Return SimulatedAccountingMethod class for method."""
if method == 'static_state_immediate':
@@ -89,6 +91,7 @@ def get_simulated_accountingmethod(method):
return SimulatedStaticAccounting
raise ValueError('Unknown accounting method: {}'.format(method))
+
class SimulatedAccountingMethod:
"""
Simulates overflows and timing inaccuracies in online energy accounting on embedded devices.
@@ -99,10 +102,10 @@ class SimulatedAccountingMethod:
* variable size for accounting of durations, power and energy values
"""
- def __init__(self, pta: PTA, timer_freq_hz, timer_type, ts_type, power_type, energy_type, ts_granularity = 1e-6, power_granularity = 1e-6, energy_granularity = 1e-12):
+ def __init__(self, pta: PTA, timer_freq_hz, timer_type, ts_type, power_type, energy_type, ts_granularity=1e-6, power_granularity=1e-6, energy_granularity=1e-12):
"""
Simulate Online Accounting for a given PTA.
-
+
:param pta: PTA object
:param timer_freq_hz: Frequency of timer used for state time measurement, in Hz
:param timer_type: Size of timer counter register, as C standard type (uint8_t / uint16_t / uint32_t / uint64_t)
@@ -157,6 +160,7 @@ class SimulatedAccountingMethod:
"""Return total energy in pJ."""
return self.energy.val * self.energy_granularity * 1e12
+
class SimulatedStaticStateOnlyAccountingImmediateCalculation(SimulatedAccountingMethod):
"""
Simulated state-only energy accounting with immediate calculation.
@@ -178,6 +182,7 @@ class SimulatedStaticStateOnlyAccountingImmediateCalculation(SimulatedAccounting
energy = self._energy_from_power_and_time(time, power)
self.energy += energy
+
class SimulatedStaticAccountingImmediateCalculation(SimulatedAccountingMethod):
"""
Simulated energy accounting with states and transitions, immediate calculation.
@@ -206,6 +211,7 @@ class SimulatedStaticAccountingImmediateCalculation(SimulatedAccountingMethod):
self.energy += int(transition.energy)
super().pass_transition(transition)
+
class SimulatedStaticAccounting(SimulatedAccountingMethod):
"""
Simulated energy accounting with states and transitions, deferred energy calculation.
@@ -270,6 +276,7 @@ class SimulatedStaticStateOnlyAccounting(SimulatedAccountingMethod):
energy += self._energy_from_power_and_time(self.time_in_state[state.name], int(state.power))
return energy.val
+
class AccountingMethod:
def __init__(self, class_name: str, pta: PTA):
self.class_name = class_name
@@ -279,7 +286,7 @@ class AccountingMethod:
self.public_variables = list()
self.private_functions = list()
self.public_functions = list()
-
+
def pre_transition_hook(self, transition):
return ''
@@ -289,8 +296,9 @@ class AccountingMethod:
def get_includes(self):
return map(lambda x: '#include "{}"'.format(x), self.include_paths)
+
class StaticStateOnlyAccountingImmediateCalculation(AccountingMethod):
- def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'):
+ def __init__(self, class_name: str, pta: PTA, ts_type='unsigned int', power_type='unsigned int', energy_type='unsigned long'):
super().__init__(class_name, pta)
self.ts_type = ts_type
self.include_paths.append('driver/uptime.h')
@@ -298,10 +306,10 @@ class StaticStateOnlyAccountingImmediateCalculation(AccountingMethod):
self.private_variables.append('{} lastStateChange;'.format(ts_type))
self.private_variables.append('{} totalEnergy;'.format(energy_type))
self.private_variables.append(array_template.format(
- type = power_type,
- name = 'state_power',
- length = len(pta.state),
- elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
+ type=power_type,
+ name='state_power',
+ length=len(pta.state),
+ elements=', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
))
get_energy_function = """return totalEnergy;"""
@@ -320,20 +328,21 @@ class StaticStateOnlyAccountingImmediateCalculation(AccountingMethod):
totalEnergy = 0;
lastStateChange = 0;
lastState = 0;
- """.format(num_states = len(self.pta.state))
+ """.format(num_states=len(self.pta.state))
+
class StaticStateOnlyAccounting(AccountingMethod):
- def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'):
+ def __init__(self, class_name: str, pta: PTA, ts_type='unsigned int', power_type='unsigned int', energy_type='unsigned long'):
super().__init__(class_name, pta)
self.ts_type = ts_type
self.include_paths.append('driver/uptime.h')
self.private_variables.append('unsigned char lastState;')
self.private_variables.append('{} lastStateChange;'.format(ts_type))
self.private_variables.append(array_template.format(
- type = power_type,
- name = 'state_power',
- length = len(pta.state),
- elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
+ type=power_type,
+ name='state_power',
+ length=len(pta.state),
+ elements=', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
))
self.private_variables.append('{} timeInState[{}];'.format(ts_type, len(pta.state)))
@@ -343,7 +352,7 @@ class StaticStateOnlyAccounting(AccountingMethod):
total_energy += timeInState[i] * state_power[i];
}}
return total_energy;
- """.format(energy_type = energy_type, num_states = len(pta.state))
+ """.format(energy_type=energy_type, num_states=len(pta.state))
self.public_functions.append(ClassFunction(class_name, energy_type, 'getEnergy', list(), get_energy_function))
def pre_transition_hook(self, transition):
@@ -361,26 +370,27 @@ class StaticStateOnlyAccounting(AccountingMethod):
}}
lastState = 0;
lastStateChange = 0;
- """.format(num_states = len(self.pta.state))
-
+ """.format(num_states=len(self.pta.state))
+
+
class StaticAccounting(AccountingMethod):
- def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'):
+ def __init__(self, class_name: str, pta: PTA, ts_type='unsigned int', power_type='unsigned int', energy_type='unsigned long'):
super().__init__(class_name, pta)
self.ts_type = ts_type
self.include_paths.append('driver/uptime.h')
self.private_variables.append('unsigned char lastState;')
self.private_variables.append('{} lastStateChange;'.format(ts_type))
self.private_variables.append(array_template.format(
- type = power_type,
- name = 'state_power',
- length = len(pta.state),
- elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
+ type=power_type,
+ name='state_power',
+ length=len(pta.state),
+ elements=', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
))
self.private_variables.append(array_template.format(
- type = energy_type,
- name = 'transition_energy',
- length = len(pta.get_unique_transitions()),
- elements = ', '.join(map(lambda transition: '{:.0f}'.format(transition.energy), pta.get_unique_transitions()))
+ type=energy_type,
+ name='transition_energy',
+ length=len(pta.get_unique_transitions()),
+ elements=', '.join(map(lambda transition: '{:.0f}'.format(transition.energy), pta.get_unique_transitions()))
))
self.private_variables.append('{} timeInState[{}];'.format(ts_type, len(pta.state)))
self.private_variables.append('{} transitionCount[{}];'.format('unsigned int', len(pta.get_unique_transitions())))
@@ -394,7 +404,7 @@ class StaticAccounting(AccountingMethod):
total_energy += transitionCount[i] * transition_energy[i];
}}
return total_energy;
- """.format(energy_type = energy_type, num_states = len(pta.state), num_transitions = len(pta.get_unique_transitions()))
+ """.format(energy_type=energy_type, num_states=len(pta.state), num_transitions=len(pta.get_unique_transitions()))
self.public_functions.append(ClassFunction(class_name, energy_type, 'getEnergy', list(), get_energy_function))
def pre_transition_hook(self, transition):
@@ -416,11 +426,11 @@ class StaticAccounting(AccountingMethod):
}}
lastState = 0;
lastStateChange = 0;
- """.format(num_states = len(self.pta.state), num_transitions = len(self.pta.get_unique_transitions()))
+ """.format(num_states=len(self.pta.state), num_transitions=len(self.pta.get_unique_transitions()))
class StaticAccountingImmediateCalculation(AccountingMethod):
- def __init__(self, class_name: str, pta: PTA, ts_type = 'unsigned int', power_type = 'unsigned int', energy_type = 'unsigned long'):
+ def __init__(self, class_name: str, pta: PTA, ts_type='unsigned int', power_type='unsigned int', energy_type='unsigned long'):
super().__init__(class_name, pta)
self.ts_type = ts_type
self.include_paths.append('driver/uptime.h')
@@ -428,15 +438,15 @@ class StaticAccountingImmediateCalculation(AccountingMethod):
self.private_variables.append('{} lastStateChange;'.format(ts_type))
self.private_variables.append('{} totalEnergy;'.format(energy_type))
self.private_variables.append(array_template.format(
- type = power_type,
- name = 'state_power',
- length = len(pta.state),
- elements = ', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
+ type=power_type,
+ name='state_power',
+ length=len(pta.state),
+ elements=', '.join(map(lambda state_name: '{:.0f}'.format(pta.state[state_name].power), pta.get_state_names()))
))
get_energy_function = """
return totalEnergy;
- """.format(energy_type = energy_type, num_states = len(pta.state), num_transitions = len(pta.get_unique_transitions()))
+ """.format(energy_type=energy_type, num_states=len(pta.state), num_transitions=len(pta.get_unique_transitions()))
self.public_functions.append(ClassFunction(class_name, energy_type, 'getEnergy', list(), get_energy_function))
def pre_transition_hook(self, transition):
@@ -452,12 +462,13 @@ class StaticAccountingImmediateCalculation(AccountingMethod):
return """
lastState = 0;
lastStateChange = 0;
- """.format(num_states = len(self.pta.state), num_transitions = len(self.pta.get_unique_transitions()))
+ """.format(num_states=len(self.pta.state), num_transitions=len(self.pta.get_unique_transitions()))
+
class MultipassDriver:
"""Generate C++ header and no-op implementation for a multipass driver based on a DFA model."""
- def __init__(self, name, pta, class_info, enum = dict(), accounting = AccountingMethod):
+ def __init__(self, name, pta, class_info, enum=dict(), accounting=AccountingMethod):
self.impl = ''
self.header = ''
self.name = name
@@ -487,9 +498,6 @@ class MultipassDriver:
for i in range(len(transition.arguments)):
function_arguments.append('{} {}'.format(function_info.argument_types[i], transition.arguments[i]))
- function_definition = '{} {}({})'.format(function_info.return_type, transition.name, ', '.join(function_arguments))
- function_head = '{} {}::{}({})'.format(function_info.return_type, self.name, transition.name, ', '.join(function_arguments))
-
function_body = accounting.pre_transition_hook(transition)
if function_info.return_type != 'void':
@@ -509,11 +517,11 @@ class MultipassDriver:
public_variables.extend(accounting.public_variables)
self.header = header_template.format(
- name = self.name, name_lower = self.name.lower(),
- includes = '\n'.join(includes),
- private_variables = '\n'.join(private_variables),
- public_variables = '\n'.join(public_variables),
- public_functions = '\n'.join(map(lambda x: x.get_definition(), public_functions)),
- private_functions = '',
- enums = '\n'.join(enums))
- self.impl = implementation_template.format(name = self.name, name_lower = self.name.lower(), functions = '\n\n'.join(map(lambda x: x.get_implementation(), public_functions)))
+ name=self.name, name_lower=self.name.lower(),
+ includes='\n'.join(includes),
+ private_variables='\n'.join(private_variables),
+ public_variables='\n'.join(public_variables),
+ public_functions='\n'.join(map(lambda x: x.get_definition(), public_functions)),
+ private_functions='',
+ enums='\n'.join(enums))
+ self.impl = implementation_template.format(name=self.name, name_lower=self.name.lower(), functions='\n\n'.join(map(lambda x: x.get_implementation(), public_functions)))