diff --git a/neat.conf b/neat.conf index 488f8dd..5ebe826 100644 --- a/neat.conf +++ b/neat.conf @@ -117,12 +117,14 @@ algorithm_underload_detection_parameters = {"threshold": 0.5, "n": 2} #algorithm_overload_detection_factory = neat.locals.overload.trivial.threshold_factory #algorithm_overload_detection_factory = neat.locals.overload.mhod.core.mhod_factory algorithm_overload_detection_factory = neat.locals.overload.trivial.last_n_average_threshold_factory +#algorithm_overload_detection_factory = neat.locals.overload.statistics.loess_factory # A JSON encoded parameters, which will be parsed and passed to the # specified overload detection algorithm factory #algorithm_overload_detection_parameters = {"threshold": 0.9} #algorithm_overload_detection_parameters = {"state_config": [0.95], "otf": 0.1, "window_sizes": [30, 40, 50, 60, 70, 80, 90, 100], "bruteforce_step": 0.2, "learning_steps": 30} algorithm_overload_detection_parameters = {"threshold": 0.95, "n": 2} +#algorithm_overload_detection_parameters = {"threshold": 0.8, "param": 1.0, "length": 30} # The fully qualified name of a Python factory function that returns a # function implementing a VM selection algorithm diff --git a/neat/locals/overload/statistics.py b/neat/locals/overload/statistics.py index 3f67da3..8acf157 100644 --- a/neat/locals/overload/statistics.py +++ b/neat/locals/overload/statistics.py @@ -44,7 +44,8 @@ def loess_factory(time_step, migration_time, params): """ migration_time_normalized = float(migration_time) / time_step return lambda utilization, state=None: \ - (loess(params['param'], + (loess(params['threshold'], + params['param'], params['length'], migration_time_normalized, utilization), @@ -69,7 +70,8 @@ def loess_robust_factory(time_step, migration_time, params): """ migration_time_normalized = float(migration_time) / time_step return lambda utilization, state=None: \ - (loess_robust(params['param'], + (loess_robust(params['threshold'], + params['param'], params['length'], migration_time_normalized, utilization), @@ -123,9 +125,12 @@ def iqr_threshold_factory(time_step, migration_time, params): @contract -def loess(param, length, migration_time, utilization): +def loess(threshold, param, length, migration_time, utilization): """ The Loess based overload detection algorithm. + :param threshold: The CPU utilization threshold. + :type threshold: float + :param param: The safety parameter. :type param: float @@ -142,6 +147,7 @@ def loess(param, length, migration_time, utilization): :rtype: bool """ return loess_abstract(loess_parameter_estimates, + threshold, param, length, migration_time, @@ -149,9 +155,12 @@ def loess(param, length, migration_time, utilization): @contract -def loess_robust(param, length, migration_time, utilization): +def loess_robust(threshold, param, length, migration_time, utilization): """ The robust Loess based overload detection algorithm. + :param threshold: The CPU utilization threshold. + :type threshold: float + :param param: The safety parameter. :type param: float @@ -168,6 +177,7 @@ def loess_robust(param, length, migration_time, utilization): :rtype: bool """ return loess_abstract(loess_robust_parameter_estimates, + threshold, param, length, migration_time, @@ -175,12 +185,15 @@ def loess_robust(param, length, migration_time, utilization): @contract -def loess_abstract(estimator, param, length, migration_time, utilization): +def loess_abstract(estimator, threshold, param, length, migration_time, utilization): """ The abstract Loess algorithm. :param estimator: A parameter estimation function. :type estimator: function + :param threshold: The CPU utilization threshold. + :type threshold: float + :param param: The safety parameter. :type param: float @@ -200,7 +213,7 @@ def loess_abstract(estimator, param, length, migration_time, utilization): return False estimates = estimator(utilization[-length:]) prediction = (estimates[0] + estimates[1] * (length + migration_time)) - return param * prediction >= 1. + return param * prediction >= threshold @contract diff --git a/tests/locals/overload/test_statistics.py b/tests/locals/overload/test_statistics.py index 6e5bea6..ac90b1c 100644 --- a/tests/locals/overload/test_statistics.py +++ b/tests/locals/overload/test_statistics.py @@ -25,7 +25,7 @@ class Statistics(TestCase): def test_loess_factory(self): alg = stats.loess_factory( - 300, 20., {'param': 1.2, 'length': 3}) + 300, 20., {'threshold': 1.0, 'param': 1.2, 'length': 3}) self.assertEqual(alg([]), (False, {})) data = [1.05, 1.09, 1.07, 1.12, 1.02, 1.18, @@ -39,7 +39,7 @@ class Statistics(TestCase): def test_loess_robust_factory(self): alg = stats.loess_robust_factory( - 300, 20., {'param': 1.2, 'length': 3}) + 300, 20., {'threshold': 1.0, 'param': 1.2, 'length': 3}) self.assertEqual(alg([]), (False, {})) data = [1.05, 1.09, 1.07, 1.12, 1.02, 1.18, @@ -78,28 +78,28 @@ class Statistics(TestCase): self.assertEqual(alg([0., 0., 1.0]), (True, {})) def test_loess(self): - assert not stats.loess(1.2, 3, 0.5, []) + assert not stats.loess(1.0, 1.2, 3, 0.5, []) data = [1.05, 1.09, 1.07, 1.12, 1.02, 1.18, 1.15, 1.04, 1.10, 1.16, 1.08] - assert stats.loess(1.2, 3, 0.5, data) + assert stats.loess(1.0, 1.2, 3, 0.5, data) data = [0.55, 0.60, 0.62, 0.59, 0.67, 0.73, 0.85, 0.97, 0.73, 0.68, 0.69, 0.52, 0.51, 0.55, 0.48, 0.46, 0.52, 0.55, 0.58, 0.65, 0.70] - assert not stats.loess(1.2, 3, 0.5, data) + assert not stats.loess(1.0, 1.2, 3, 0.5, data) def test_loess_robust(self): - assert not stats.loess_robust(1.2, 3, 0.5, []) + assert not stats.loess_robust(1.0, 1.2, 3, 0.5, []) data = [1.05, 1.09, 1.07, 1.12, 1.02, 1.18, 1.15, 1.04, 1.10, 1.16, 1.08] - assert stats.loess_robust(1.2, 3, 0.5, data) + assert stats.loess_robust(1.0, 1.2, 3, 0.5, data) data = [0.55, 0.60, 0.62, 0.59, 0.67, 0.73, 0.85, 0.97, 0.73, 0.68, 0.69, 0.52, 0.51, 0.55, 0.48, 0.46, 0.52, 0.55, 0.58, 0.65, 0.70] - assert not stats.loess_robust(1.2, 3, 0.5, data) + assert not stats.loess_robust(1.0, 1.2, 3, 0.5, data) def test_mad_threshold(self): with MockTransaction: