Add 2048B file size cps rps tests in job specs for http-ldpreload-nginx-1_21_5.
[csit.git] / resources / libraries / python / MLRsearch / multiple_loss_ratio_search.py
index b48e2e7..4d3ff7c 100644 (file)
@@ -25,6 +25,7 @@ from .dataclass import secondary_field
 from .discrete_load import DiscreteLoad
 from .discrete_result import DiscreteResult
 from .expander import GlobalWidth
+from .goal_result import GoalResult
 from .limit_handler import LimitHandler
 from .load_rounding import LoadRounding
 from .measurement_database import MeasurementDatabase
@@ -33,12 +34,14 @@ from .search_goal import SearchGoal
 from .selector import Selector
 from .target_scaling import TargetScaling
 from .trial_measurement import AbstractMeasurer
-from .trimmed_stat import TrimmedStat
 
 
 @dataclass
 class MultipleLossRatioSearch:
-    """Optimized binary search algorithm for finding conditional throughputs.
+    """Implementation of the controller part of MLRsearch algorithm.
+
+    The manager part is creating and calling this,
+    the measurer part is injected.
 
     Traditional binary search algorithm needs initial interval
     (lower and upper bound), and returns final narrow bounds
@@ -88,6 +91,14 @@ class MultipleLossRatioSearch:
 
     There are also subtle optimizations related to candidate selection
     and uneven splitting of intervals, too numerous to list here.
+
+    The return values describe performance at the relevant lower bound
+    as "conditional throughput", which is based on loss ratio of one of trials
+    selected as a quantile based on exceed ratio parameter.
+    Usually this value may be quite pessimistic, as MLRsearch stops
+    measuring a load as soon as it becomes a lower bound,
+    so conditional throughput is usually based on forwarding rate
+    of the worst on the good long trials.
     """
 
     config: Config
@@ -115,7 +126,7 @@ class MultipleLossRatioSearch:
         self,
         measurer: AbstractMeasurer,
         debug: Optional[Callable[[str], None]] = None,
-    ) -> Pep3140Dict[SearchGoal, Optional[TrimmedStat]]:
+    ) -> Pep3140Dict[SearchGoal, GoalResult]:
         """Perform initial trials, create state object, proceed with main loop.
 
         Stateful arguments (measurer and debug) are stored.
@@ -123,12 +134,12 @@ class MultipleLossRatioSearch:
 
         :param measurer: Measurement provider to use by this search object.
         :param debug: Callable to optionally use instead of logging.debug().
-        :returns: Structure containing conditional throughputs and other stats,
-            one for each search goal.
         :type measurer: AbstractMeasurer
         :type debug: Optional[Callable[[str], None]]
-        :returns: Mapping from goal to lower bound (none if min load is hit).
-        :rtype: Pep3140Dict[SearchGoal, Optional[TrimmedStat]]
+        :returns: Structure containing conditional throughputs and other stats,
+            one for each search goal. If a value is None it means there is
+            no lower bound (min load turned out to be an upper bound).
+        :rtype: Pep3140Dict[SearchGoal, GoalResult]
         :raises RuntimeError: If total duration is larger than timeout,
             or if min load becomes an upper bound for a search goal
             that has fail fast true.
@@ -157,7 +168,7 @@ class MultipleLossRatioSearch:
         for goal in self.config.goals:
             target = self.scaling.goal_to_final_target[goal]
             bounds = self.database.get_relevant_bounds(target=target)
-            ret_dict[goal] = bounds.clo
+            ret_dict[goal] = GoalResult.from_bounds(bounds=bounds)
         return ret_dict
 
     def measure(self, duration: float, load: DiscreteLoad) -> DiscreteResult: