aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python/MLRsearch
diff options
context:
space:
mode:
authorVratko Polak <vrpolak@cisco.com>2018-07-30 17:48:50 +0200
committerPeter Mikus <pmikus@cisco.com>2018-08-22 06:40:35 +0000
commit56fe9e512019d90a5647f4a244ffb8b6f6ff9c47 (patch)
tree8aa98f5422767232b72e71ac577f8a0e3b2c9777 /resources/libraries/python/MLRsearch
parentbc49817b524f0478900da35aaec5f8418e698392 (diff)
CSIT-1222: Do two doublings in external MLRsearch
Make number of doublings configurable, keep Python default at 1, set Robot default to 2. Also make docstring types unique (pylint was complaining about classes and modules having the same name). Increase MLRsearch version to 0.2.0. Change-Id: Ib846032e79ff52994503c0cfef2f86655502c275 Signed-off-by: Vratko Polak <vrpolak@cisco.com>
Diffstat (limited to 'resources/libraries/python/MLRsearch')
-rw-r--r--resources/libraries/python/MLRsearch/AbstractMeasurer.py2
-rw-r--r--resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py4
-rw-r--r--resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py67
-rw-r--r--resources/libraries/python/MLRsearch/NdrPdrResult.py4
-rw-r--r--resources/libraries/python/MLRsearch/ReceiveRateInterval.py4
5 files changed, 63 insertions, 18 deletions
diff --git a/resources/libraries/python/MLRsearch/AbstractMeasurer.py b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
index b972c4eb18..c9b5987124 100644
--- a/resources/libraries/python/MLRsearch/AbstractMeasurer.py
+++ b/resources/libraries/python/MLRsearch/AbstractMeasurer.py
@@ -30,6 +30,6 @@ class AbstractMeasurer(object):
:type duration: float
:type transmit_rate: float
:returns: Structure containing the result of the measurement.
- :rtype: ReceiveRateMeasurement
+ :rtype: ReceiveRateMeasurement.ReceiveRateMeasurement
"""
pass
diff --git a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
index 538322a42c..08f8b7e0a9 100644
--- a/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
+++ b/resources/libraries/python/MLRsearch/AbstractSearchAlgorithm.py
@@ -25,7 +25,7 @@ class AbstractSearchAlgorithm(object):
"""Store the rate provider.
:param measurer: Object able to perform trial or composite measurements.
- :type measurer: AbstractMeasurer
+ :type measurer: AbstractMeasurer.AbstractMeasurer
"""
# TODO: Type check for AbstractMeasurer?
self.measurer = measurer
@@ -45,7 +45,7 @@ class AbstractSearchAlgorithm(object):
:type packet_loss_ratio: float
:returns: Structure containing narrowed down intervals
and their measurements.
- :rtype: NdrPdrResult
+ :rtype: NdrPdrResult.NdrPdrResult
"""
# TODO: Do we agree on arguments related to precision or trial duration?
pass
diff --git a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
index 0eb1d7da4c..be7ffba3a3 100644
--- a/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
+++ b/resources/libraries/python/MLRsearch/MultipleLossRatioSearch.py
@@ -97,7 +97,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
for the current search [pps].
:param maximum_transmit_rate: Maximum target transmit rate
for the current search [pps].
- :type result: NdrPdrResult
+ :type result: NdrPdrResult.NdrPdrResult
:type phases: int
:type duration: float
:type width_goal: float
@@ -115,7 +115,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
def __init__(self, measurer, final_relative_width=0.005,
final_trial_duration=30.0, initial_trial_duration=1.0,
- number_of_intermediate_phases=2, timeout=600.0):
+ number_of_intermediate_phases=2, timeout=600.0, doublings=1):
"""Store the measurer object and additional arguments.
:param measurer: Rate provider to use by this search object.
@@ -128,12 +128,16 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
to perform before the final phase [1].
:param timeout: The search will fail itself when not finished
before this overall time [s].
- :type measurer: AbstractMeasurer
+ :param doublings: How many doublings to do in external search step.
+ Default 1 is suitable for fairly stable tests,
+ less stable tests might get better overal duration with 2 or more.
+ :type measurer: AbstractMeasurer.AbstractMeasurer
:type final_relative_width: float
:type final_trial_duration: float
:type initial_trial_duration: int
:type number_of_intermediate_phases: int
:type timeout: float
+ :type doublings: int
"""
super(MultipleLossRatioSearch, self).__init__(measurer)
self.final_trial_duration = float(final_trial_duration)
@@ -141,6 +145,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
self.number_of_intermediate_phases = int(number_of_intermediate_phases)
self.initial_trial_duration = float(initial_trial_duration)
self.timeout = float(timeout)
+ self.doublings = int(doublings)
@staticmethod
@@ -172,6 +177,24 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
relative_width))
@staticmethod
+ def expand_down(relative_width, doublings, current_bound):
+ """Return rate of expanded logarithmic width below.
+
+ :param relative_width: The base relative width to double.
+ :param doublings: How many doublings to do for expansion.
+ :param current_bound: The current target transmit rate to move [pps].
+ :type relative_width: float
+ :type doublings: int
+ :type current_bound: float
+ :returns: Transmit rate smaller by logarithmically double width [pps].
+ :rtype: float
+ """
+ for _ in range(doublings):
+ relative_width = MultipleLossRatioSearch.double_relative_width(
+ relative_width)
+ return current_bound * (1.0 - relative_width)
+
+ @staticmethod
def double_step_up(relative_width, current_bound):
"""Return rate of double logarithmic width above.
@@ -187,6 +210,24 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
relative_width))
@staticmethod
+ def expand_up(relative_width, doublings, current_bound):
+ """Return rate of expanded logarithmic width above.
+
+ :param relative_width: The base relative width to double.
+ :param doublings: How many doublings to do for expansion.
+ :param current_bound: The current target transmit rate to move [pps].
+ :type relative_width: float
+ :type doublings: int
+ :type current_bound: float
+ :returns: Transmit rate smaller by logarithmically double width [pps].
+ :rtype: float
+ """
+ for _ in range(doublings):
+ relative_width = MultipleLossRatioSearch.double_relative_width(
+ relative_width)
+ return current_bound / (1.0 - relative_width)
+
+ @staticmethod
def half_relative_width(relative_width):
"""Return relative width corresponding to half logarithmic width.
@@ -224,7 +265,7 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:type packet_loss_ratio: float
:returns: Structure containing narrowed down intervals
and their measurements.
- :rtype: NdrPdrResult
+ :rtype: NdrPdrResult.NdrPdrResult
:raises RuntimeError: If total duration is larger than timeout.
"""
minimum_transmit_rate = float(minimum_transmit_rate)
@@ -296,11 +337,11 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
:param old_interval: The current interval before the measurement.
:param measurement: The new meaqsurement to take into account.
:param packet_loss_ratio: Fraction for PDR (or zero for NDR).
- :type old_interval: ReceiveRateInterval
- :type measurement: ReceiveRateMeasurement
+ :type old_interval: ReceiveRateInterval.ReceiveRateInterval
+ :type measurement: ReceiveRateMeasurement.ReceiveRateMeasurement
:type packet_loss_ratio: float
:returns: The updated interval.
- :rtype: ReceiveRateInterval
+ :rtype: ReceiveRateInterval.ReceiveRateInterval
"""
old_lo, old_hi = old_interval.measured_low, old_interval.measured_high
# Priority zero: direct replace if the target Tr is the same.
@@ -399,7 +440,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if ndr_lo.target_tr > state.minimum_transmit_rate:
new_tr = max(
state.minimum_transmit_rate,
- self.double_step_down(ndr_rel_width, ndr_lo.target_tr))
+ self.expand_down(
+ ndr_rel_width, self.doublings, ndr_lo.target_tr))
logging.info("ndr lo external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -412,7 +454,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if pdr_lo.target_tr > state.minimum_transmit_rate:
new_tr = max(
state.minimum_transmit_rate,
- self.double_step_down(pdr_rel_width, pdr_lo.target_tr))
+ self.expand_down(
+ pdr_rel_width, self.doublings, pdr_lo.target_tr))
logging.info("pdr lo external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -425,7 +468,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if ndr_hi.target_tr < state.maximum_transmit_rate:
new_tr = min(
state.maximum_transmit_rate,
- self.double_step_up(ndr_rel_width, ndr_hi.target_tr))
+ self.expand_up(
+ ndr_rel_width, self.doublings, ndr_hi.target_tr))
logging.info("ndr hi external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
@@ -438,7 +482,8 @@ class MultipleLossRatioSearch(AbstractSearchAlgorithm):
if pdr_hi.target_tr < state.maximum_transmit_rate:
new_tr = min(
state.maximum_transmit_rate,
- self.double_step_up(pdr_rel_width, pdr_hi.target_tr))
+ self.expand_up(
+ pdr_rel_width, self.doublings, pdr_hi.target_tr))
logging.info("pdr hi external %s", new_tr)
state = self._measure_and_update_state(state, new_tr)
continue
diff --git a/resources/libraries/python/MLRsearch/NdrPdrResult.py b/resources/libraries/python/MLRsearch/NdrPdrResult.py
index b69a57ecbe..80df0ef333 100644
--- a/resources/libraries/python/MLRsearch/NdrPdrResult.py
+++ b/resources/libraries/python/MLRsearch/NdrPdrResult.py
@@ -27,8 +27,8 @@ class NdrPdrResult(object):
:param ndr_interval: Object containing data for NDR part of the result.
:param pdr_interval: Object containing data for PDR part of the result.
- :type ndr_interval: ReceiveRateInterval
- :type pdr_interval: ReceiveRateInterval
+ :type ndr_interval: ReceiveRateInterval.ReceiveRateInterval
+ :type pdr_interval: ReceiveRateInterval.ReceiveRateInterval
"""
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?
diff --git a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
index 05e0f10013..6dff1b8a7a 100644
--- a/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
+++ b/resources/libraries/python/MLRsearch/ReceiveRateInterval.py
@@ -26,8 +26,8 @@ class ReceiveRateInterval(object):
:param measured_low: Measurement for the lower bound.
:param measured_high: Measurement for the upper bound.
- :type measured_low: ReceiveRateMeasurement
- :type measured_high: ReceiveRateMeasurement
+ :type measured_low: ReceiveRateMeasurement.ReceiveRateMeasurement
+ :type measured_high: ReceiveRateMeasurement.ReceiveRateMeasurement
"""
# TODO: Type checking is not very pythonic,
# perhaps users can fix wrong usage without it?