summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-11-01 10:07:55 +0100
committerDaniel Friesel <daniel.friesel@uos.de>2021-11-01 10:07:55 +0100
commit49c2c463ff6b454c944af3b023139ad4448c8ce4 (patch)
treed90d2e07be933a749dcae58a3769a664ac0aeaa5
parentf1a0129b36d9abb96669d08e09ea4b958bc99b54 (diff)
move model quality table to dfatool.cli; add quality output to analyze-kconfig
-rwxr-xr-xbin/analyze-archive.py59
-rwxr-xr-xbin/analyze-kconfig.py37
-rw-r--r--lib/cli.py51
3 files changed, 94 insertions, 53 deletions
diff --git a/bin/analyze-archive.py b/bin/analyze-archive.py
index 3a09b96..bd523c8 100755
--- a/bin/analyze-archive.py
+++ b/bin/analyze-archive.py
@@ -77,81 +77,36 @@ def print_model_quality(results):
print("{:20s} {:15s} {:.0f}".format(state_or_tran, key, result["mae"]))
-def format_quality_measures(result):
- if "smape" in result:
- return "{:6.2f}% / {:9.0f}".format(result["smape"], result["mae"])
- else:
- return "{:6} {:9.0f}".format("", result["mae"])
-
-
-def model_quality_table(header, result_lists, info_list):
- print(
- "{:20s} {:15s} {:19s} {:19s} {:19s}".format(
- "key",
- "attribute",
- header[0].center(19),
- header[1].center(19),
- header[2].center(19),
- )
- )
- for state_or_tran in result_lists[0].keys():
- for key in result_lists[0][state_or_tran].keys():
- buf = "{:20s} {:15s}".format(state_or_tran, key)
- for i, results in enumerate(result_lists):
- info = info_list[i]
- buf += " ||| "
- if (
- info is None
- or (
- key != "energy_Pt"
- and type(info(state_or_tran, key)) is not StaticFunction
- )
- or (
- key == "energy_Pt"
- and (
- type(info(state_or_tran, "power")) is not StaticFunction
- or type(info(state_or_tran, "duration"))
- is not StaticFunction
- )
- )
- ):
- result = results[state_or_tran][key]
- buf += format_quality_measures(result)
- else:
- buf += "{:7}----{:8}".format("", "")
- print(buf)
-
-
def model_summary_table(result_list):
buf = "transition duration"
for results in result_list:
if len(buf):
buf += " ||| "
- buf += format_quality_measures(results["duration_by_trace"])
+ buf += dfatool.cli.format_quality_measures(results["duration_by_trace"])
print(buf)
buf = "total energy "
for results in result_list:
if len(buf):
buf += " ||| "
- buf += format_quality_measures(results["energy_by_trace"])
+ buf += dfatool.cli.format_quality_measures(results["energy_by_trace"])
print(buf)
buf = "rel total energy "
for results in result_list:
if len(buf):
buf += " ||| "
- buf += format_quality_measures(results["rel_energy_by_trace"])
+ buf += dfatool.cli.format_quality_measures(results["rel_energy_by_trace"])
print(buf)
buf = "state-only energy "
for results in result_list:
if len(buf):
buf += " ||| "
- buf += format_quality_measures(results["state_energy_by_trace"])
+ buf += dfatool.cli.format_quality_measures(results["state_energy_by_trace"])
print(buf)
buf = "transition timeout "
for results in result_list:
if len(buf):
buf += " ||| "
- buf += format_quality_measures(results["timeout_by_trace"])
+ buf += dfatool.cli.format_quality_measures(results["timeout_by_trace"])
print(buf)
@@ -1038,7 +993,7 @@ if __name__ == "__main__":
)
if "table" in show_quality or "all" in show_quality:
- model_quality_table(
+ dfatool.cli.model_quality_table(
["static", "parameterized", "LUT"],
[static_quality, analytic_quality, lut_quality],
[None, param_info, None],
@@ -1051,7 +1006,7 @@ if __name__ == "__main__":
sub_lut_quality = submodel.assess(sub_lut_model)
sub_param_model, sub_param_info = submodel.get_fitted()
sub_analytic_quality = submodel.assess(sub_param_model)
- model_quality_table(
+ dfatool.cli.model_quality_table(
["static", "parameterized", "LUT"],
[sub_static_quality, sub_analytic_quality, sub_lut_quality],
[None, sub_param_info, None],
diff --git a/bin/analyze-kconfig.py b/bin/analyze-kconfig.py
index 56b2925..1db43da 100755
--- a/bin/analyze-kconfig.py
+++ b/bin/analyze-kconfig.py
@@ -15,6 +15,7 @@ import os
import numpy as np
+import dfatool.cli
import dfatool.utils
from dfatool.loader import KConfigAttributes
from dfatool.model import AnalyticModel
@@ -96,6 +97,28 @@ def main():
help="Report modul accuracy via Cross-Validation",
metavar="METHOD:COUNT",
)
+ parser.add_argument(
+ "--show-model",
+ choices=["static", "paramdetection", "param", "all", "tex", "html"],
+ action="append",
+ default=list(),
+ help="static: show static model values as well as parameter detection heuristic.\n"
+ "paramdetection: show stddev of static/lut/fitted model\n"
+ "param: show parameterized model functions and regression variable values\n"
+ "all: all of the above\n"
+ "tex: print tex/pgfplots-compatible model data on stdout\n"
+ "html: print model and quality data as HTML table on stdout",
+ )
+ parser.add_argument(
+ "--show-quality",
+ choices=["table", "summary", "all", "tex", "html"],
+ action="append",
+ default=list(),
+ help="table: show static/fitted/lut SMAPE and MAE for each name and attribute.\n"
+ "summary: show static/fitted/lut SMAPE and MAE for each attribute, averaged over all states/transitions.\n"
+ "all: all of the above.\n"
+ "tex: print tex/pgfplots-compatible model quality data on stdout.",
+ )
parser.add_argument("kconfig_path", type=str, help="Path to Kconfig file")
parser.add_argument(
"model",
@@ -110,8 +133,13 @@ def main():
else:
print(f"Invalid log level. Setting log level to INFO.", file=sys.stderr)
+ if args.export_dref:
+ dref = dict()
+
if os.path.isdir(args.model):
attributes = KConfigAttributes(args.kconfig_path, args.model)
+ if args.export_dref:
+ dref.update(attributes.to_dref())
if args.show_failing_symbols:
show_failing_symbols(attributes)
@@ -235,6 +263,13 @@ def main():
else:
lut_quality = None
+ if "table" in args.show_quality or "all" in args.show_quality:
+ dfatool.cli.model_quality_table(
+ ["static", "parameterized", "LUT"],
+ [static_quality, analytic_quality, lut_quality],
+ [None, param_info, None],
+ )
+
print("Model Error on Training Data:")
for name in model.names:
for attribute, error in analytic_quality[name].items():
@@ -272,7 +307,7 @@ def main():
static_quality = model.assess(static_model)
if args.export_dref:
- dref = model.to_dref(static_quality, lut_quality, analytic_quality)
+ dref.update(model.to_dref(static_quality, lut_quality, analytic_quality))
with open(args.export_dref, "w") as f:
for k, v in dref.items():
if type(v) is not tuple:
diff --git a/lib/cli.py b/lib/cli.py
index 6c6419c..2972ca5 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -1,5 +1,11 @@
#!/usr/bin/env python3
+from dfatool.functions import (
+ SplitFunction,
+ AnalyticFunction,
+ StaticFunction,
+)
+
def print_static(model, static_model, name, attribute):
unit = " "
@@ -25,3 +31,48 @@ def print_static(model, static_model, name, attribute):
model.attr_by_name[name][attribute].stats.param_dependence_ratio(param),
)
)
+
+
+def format_quality_measures(result):
+ if "smape" in result:
+ return "{:6.2f}% / {:9.0f}".format(result["smape"], result["mae"])
+ else:
+ return "{:6} {:9.0f}".format("", result["mae"])
+
+
+def model_quality_table(header, result_lists, info_list):
+ print(
+ "{:20s} {:15s} {:19s} {:19s} {:19s}".format(
+ "key",
+ "attribute",
+ header[0].center(19),
+ header[1].center(19),
+ header[2].center(19),
+ )
+ )
+ for state_or_tran in result_lists[0].keys():
+ for key in result_lists[0][state_or_tran].keys():
+ buf = "{:20s} {:15s}".format(state_or_tran, key)
+ for i, results in enumerate(result_lists):
+ info = info_list[i]
+ buf += " ||| "
+ if (
+ info is None
+ or (
+ key != "energy_Pt"
+ and type(info(state_or_tran, key)) is not StaticFunction
+ )
+ or (
+ key == "energy_Pt"
+ and (
+ type(info(state_or_tran, "power")) is not StaticFunction
+ or type(info(state_or_tran, "duration"))
+ is not StaticFunction
+ )
+ )
+ ):
+ result = results[state_or_tran][key]
+ buf += format_quality_measures(result)
+ else:
+ buf += "{:7}----{:8}".format("", "")
+ print(buf)