diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2021-08-19 09:50:40 +0200 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2021-08-19 09:50:40 +0200 |
commit | 26d07c8eae44d0a6919fd775728cdb1bb2808298 (patch) | |
tree | b0380add225649a5ccc16455856b8c508281a4ea | |
parent | 5312f01724edad7ef380ded9a6e34971b56c7939 (diff) |
ParallelParamFit -> ParamFit, optionally without parallelism
-rwxr-xr-x | bin/Proof_Of_Concept_PELT.py | 6 | ||||
-rw-r--r-- | lib/model.py | 6 | ||||
-rw-r--r-- | lib/parameters.py | 4 | ||||
-rw-r--r-- | lib/paramfit.py | 16 | ||||
-rw-r--r-- | lib/runner.py | 2 | ||||
-rw-r--r-- | lib/utils.py | 14 | ||||
-rwxr-xr-x | test/test_parameters.py | 6 |
7 files changed, 36 insertions, 18 deletions
diff --git a/bin/Proof_Of_Concept_PELT.py b/bin/Proof_Of_Concept_PELT.py index 0845f87..8c60cd7 100755 --- a/bin/Proof_Of_Concept_PELT.py +++ b/bin/Proof_Of_Concept_PELT.py @@ -17,7 +17,7 @@ import numpy as np from dfatool.functions import analytic from dfatool.loader import RawData from dfatool import parameters -from dfatool.model import ParallelParamFit, PTAModel +from dfatool.model import ParamFit, PTAModel from dfatool.utils import by_name_to_by_param # from scipy.cluster.hierarchy import dendrogram, linkage # for graphical display @@ -899,7 +899,7 @@ if __name__ == "__main__": # last_pow = power # plt.show() stats = parameters.ParamStats(by_name, by_param, param_names, dict()) - paramfit = ParallelParamFit(by_param) + paramfit = ParamFit(by_param) for state_name in by_name.keys(): for num_param, param_name in enumerate(param_names): if stats.depends_on_param(state_name, "power", param_name): @@ -1080,7 +1080,7 @@ if __name__ == "__main__": new_stats = parameters.ParamStats( new_by_name, new_by_param, param_names, dict() ) - new_paramfit = ParallelParamFit(new_by_param) + new_paramfit = ParamFit(new_by_param) for state_name in new_by_name.keys(): for num_param, param_name in enumerate(param_names): if new_stats.depends_on_param(state_name, "power", param_name): diff --git a/lib/model.py b/lib/model.py index 345dea5..98a9d4f 100644 --- a/lib/model.py +++ b/lib/model.py @@ -5,8 +5,8 @@ import numpy as np import os from .automata import PTA, ModelAttribute from .functions import StaticFunction, SubstateFunction, SplitFunction -from .parameters import ParallelParamStats, codependent_param_dict -from .paramfit import ParallelParamFit +from .parameters import ParallelParamStats, ParamStats, codependent_param_dict +from .paramfit import ParamFit from .utils import soft_cast_int, by_name_to_by_param, regression_measures logger = logging.getLogger(__name__) @@ -233,7 +233,7 @@ class AnalyticModel: if not self.fit_done: - paramfit = ParallelParamFit() + paramfit = ParamFit() for name in self.names: for attr in self.attr_by_name[name].keys(): diff --git a/lib/parameters.py b/lib/parameters.py index 41153a2..82b1fdc 100644 --- a/lib/parameters.py +++ b/lib/parameters.py @@ -319,11 +319,11 @@ class ParallelParamStats: def compute(self): """ - Fit functions on previously enqueue data. + Fit functions on previously enqueued data. Fitting is one in parallel with one process per core. - Results can be accessed using the public ParallelParamFit.results object. + Results can be accessed using the public ParamFit.results object. """ with Pool() as pool: results = pool.map(_compute_param_statistics_parallel, self.queue) diff --git a/lib/paramfit.py b/lib/paramfit.py index 8bc7505..5fdaf7a 100644 --- a/lib/paramfit.py +++ b/lib/paramfit.py @@ -17,7 +17,7 @@ from .utils import ( logger = logging.getLogger(__name__) -class ParallelParamFit: +class ParamFit: """ Fit a set of functions on parameterized measurements. @@ -25,9 +25,10 @@ class ParallelParamFit: function type for each parameter. """ - def __init__(self): - """Create a new ParallelParamFit object.""" + def __init__(self, parallel=True): + """Create a new ParamFit object.""" self.fit_queue = list() + self.parallel = parallel def enqueue(self, key, param, args, kwargs=dict()): """ @@ -49,10 +50,13 @@ class ParallelParamFit: Fitting is one in parallel with one process per core. - Results can be accessed using the public ParallelParamFit.results object. + Results can be accessed using the public ParamFit.results object. """ - with Pool() as pool: - self.results = pool.map(_try_fits_parallel, self.fit_queue) + if self.parallel: + with Pool() as pool: + self.results = pool.map(_try_fits_parallel, self.fit_queue) + else: + self.results = list(map(_try_fits_parallel, self.fit_queue)) def get_result(self, key): """ diff --git a/lib/runner.py b/lib/runner.py index aaa3807..3290913 100644 --- a/lib/runner.py +++ b/lib/runner.py @@ -652,7 +652,7 @@ class Multipass: universal_newlines=True, ) if res.returncode != 0: - raise RuntimeError("make info Failure") + raise RuntimeError(f"make info Failure. command = {command}") return res.stdout.split("\n") def _cached_info(self, opts=list()) -> list: diff --git a/lib/utils.py b/lib/utils.py index 22ac8da..2c879c0 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -190,6 +190,9 @@ def partition_by_param(data, param_values, ignore_parameters=list()): def param_dict_to_list(param_dict, parameter_names, default=None): + """ + Convert {"foo": 1, "bar": 2}, ["bar", "foo", "quux"] to [2, 1, None] + """ ret = list() for parameter_name in parameter_names: ret.append(param_dict.get(parameter_name, None)) @@ -197,6 +200,17 @@ def param_dict_to_list(param_dict, parameter_names, default=None): def observations_to_by_name(observations: list, attributes: list): + """ + Convert observation list to by_name dictionary for AnalyticModel analysis + + :param observations: list of dicts, each representing one measurement. dict keys: + "name": name of observed state/transition/... + "param": {"parameter name": parameter value, ...} dict + :param attributes: observed attributes (i.e., actual measurements). Each measurement dict must have an + entry holding the data value for each attribute. It should not be None. + + :returns: tuple (by_name, parameter_names) which can be passed to AnalyticModel + """ parameter_names = set() by_name = dict() for observation in observations: diff --git a/test/test_parameters.py b/test/test_parameters.py index 2141603..b633a43 100755 --- a/test/test_parameters.py +++ b/test/test_parameters.py @@ -3,7 +3,7 @@ from dfatool import parameters from dfatool.utils import by_name_to_by_param from dfatool.functions import analytic -from dfatool.model import ParallelParamFit +from dfatool.model import ParamFit import unittest import numpy as np @@ -56,7 +56,7 @@ class TestModels(unittest.TestCase): # Fit individual functions for each parameter (only "p_linear" in this case) - paramfit = ParallelParamFit() + paramfit = ParamFit() paramfit.enqueue(("TX", "power"), "p_linear", (stats.by_param, 1, False)) paramfit.fit() @@ -146,7 +146,7 @@ class TestModels(unittest.TestCase): self.assertEqual(ll_stats.depends_on_param("log_inv"), True) self.assertEqual(ll_stats.depends_on_param("square_none"), False) - paramfit = ParallelParamFit() + paramfit = ParamFit() paramfit.enqueue(("someKey", "lls"), "lin_lin", (lls_stats.by_param, 0, False)) paramfit.enqueue(("someKey", "lls"), "log_inv", (lls_stats.by_param, 1, False)) paramfit.enqueue( |