diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2021-11-01 10:07:55 +0100 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2021-11-01 10:07:55 +0100 |
commit | 49c2c463ff6b454c944af3b023139ad4448c8ce4 (patch) | |
tree | d90d2e07be933a749dcae58a3769a664ac0aeaa5 | |
parent | f1a0129b36d9abb96669d08e09ea4b958bc99b54 (diff) |
move model quality table to dfatool.cli; add quality output to analyze-kconfig
-rwxr-xr-x | bin/analyze-archive.py | 59 | ||||
-rwxr-xr-x | bin/analyze-kconfig.py | 37 | ||||
-rw-r--r-- | lib/cli.py | 51 |
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: @@ -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) |