aboutsummaryrefslogtreecommitdiffstats
path: root/PyPI
diff options
context:
space:
mode:
authorVratko Polak <vrpolak@cisco.com>2023-10-17 16:31:35 +0200
committerVratko Polak <vrpolak@cisco.com>2023-10-18 08:10:06 +0000
commite5dbe10d9599b9a53fa07e6fadfaf427ba6d69e3 (patch)
tree147b7972bea35a093f6644e63c5f1fb4e4b2c9a0 /PyPI
parentc6dfb6c09c5dafd1d522f96b4b86c5ec5efc1c83 (diff)
feat(MLRsearch): MLRsearch v7
Replaces MLRv2, suitable for "big bang" upgrade across CSIT. PyPI metadata updated only partially (full edits will come separately). Pylint wants less complexity, but the differences are only minor. + Use the same (new CSIT) defaults everywhere, also in Python library. + Update also PLRsearch to use the new result class. + Make upper bound optional in UTI. + Fix ASTF approximate duration detection. + Do not keep approximated_receive_rate (for MRR) in result structure. Change-Id: I03406f32d5c93f56b527cb3f93791b61955dfd74 Signed-off-by: Vratko Polak <vrpolak@cisco.com>
Diffstat (limited to 'PyPI')
-rw-r--r--PyPI/MLRsearch/README.rst118
-rw-r--r--PyPI/MLRsearch/setup.py6
2 files changed, 117 insertions, 7 deletions
diff --git a/PyPI/MLRsearch/README.rst b/PyPI/MLRsearch/README.rst
index 8439fe71a1..92c2afe484 100644
--- a/PyPI/MLRsearch/README.rst
+++ b/PyPI/MLRsearch/README.rst
@@ -16,6 +16,11 @@ is only a symlink to the original place of tightly coupled CSIT code.
Change log
----------
+1.0.0: Logic improvements, independent selectors, exceed ratio support,
+better width rounding, conditional throughput as output.
+Implementation relies more on dataclasses, code split into smaller files.
+API changed considerably, mainly to avoid long argument lists.
+
0.4.0: Considarable logic improvements, more than two target ratios supported.
API is not backward compatible with previous versions.
@@ -28,17 +33,122 @@ API is not backward compatible with previous versions.
Usage
-----
-TODO.
+High level description
+______________________
+
+A complete application capable of testing performance using MLRsearch
+consists of three layers: Manager, Controller and Measurer.
+This library provides an implementation for the Controller only,
+including all the classes needed to define API between Controller
+and other two components.
+
+Users are supposed to implement the whole Manager layer,
+and also implement the Measurer layer.
+The Measurer instance is injected as a parameter
+when the manager calls the controller instance.
+
+The purpose of Measurer instance is to perform one trial measurement.
+Upon invocation of measure() method, the controller only specifies
+the intended duration and the intended load for the trial.
+The call is done using keyword arguments, so the signature has to be:
+
+.. code-block:: python3
+
+ def measure(self, intended_duration, intended_load):
+
+Usually, the trial measurement process also needs other values,
+collectively caller a traffic profile. User (the manager instance)
+is responsible for initiating the measurer instance accordingly.
+Also, the manager is supposed to set up SUT, traffic generator,
+and any other component that can affect the result.
+
+For specific input and output objects see the example below.
+
+Example
+_______
+
+This is a minimal example showing every configuration attribute.
+The measurer does not interact with any real SUT,
+it simulates a SUT that is able to forward exactly one million packets
+per second (unidirectional traffic only),
+not one packet more (fully deterministic).
+In these conditions, the conditional throughput for PDR
+happens to be accurate within one packet per second.
+
+This is the screen capture of interactive python interpreter
+(wrapped so long lines are readable):
+
+.. code-block:: python3
+
+ >>> import dataclasses
+ >>> from MLRsearch import (
+ ... AbstractMeasurer, Config, MeasurementResult,
+ ... MultipleLossRatioSearch, SearchGoal,
+ ... )
+ >>>
+ >>> class Hard1MppsMeasurer(AbstractMeasurer):
+ ... def measure(self, intended_duration, intended_load):
+ ... sent = int(intended_duration * intended_load)
+ ... received = min(sent, int(intended_duration * 1e6))
+ ... return MeasurementResult(
+ ... intended_duration=intended_duration,
+ ... intended_load=intended_load,
+ ... offered_count=sent,
+ ... forwarding_count=received,
+ ... )
+ ...
+ >>> def print_dot(_):
+ ... print(".", end="")
+ ...
+ >>> ndr_goal = SearchGoal(
+ ... loss_ratio=0.0,
+ ... exceed_ratio=0.005,
+ ... relative_width=0.005,
+ ... initial_trial_duration=1.0,
+ ... final_trial_duration=1.0,
+ ... duration_sum=61.0,
+ ... preceding_targets=2,
+ ... expansion_coefficient=2,
+ ... )
+ >>> pdr_goal = dataclasses.replace(ndr_goal, loss_ratio=0.005)
+ >>> config = Config(
+ ... goals=[ndr_goal, pdr_goal],
+ ... min_load=1e3,
+ ... max_load=1e9,
+ ... search_duration_max=1.0,
+ ... warmup_duration=None,
+ ... )
+ >>> controller = MultipleLossRatioSearch(config=config)
+ >>> result = controller.search(measurer=Hard1MppsMeasurer(), debug=print_dot)
+ ....................................................................................
+ ....................................................................................
+ ....................................................................................
+ ....................................................................................
+ ....................................................................................
+ ....................................................................................
+ ...>>> print(result)
+ {SearchGoal(loss_ratio=0.0, exceed_ratio=0.005, relative_width=0.005, initial_trial_
+ duration=1.0, final_trial_duration=1.0, duration_sum=61.0, preceding_targets=2, expa
+ nsion_coefficient=2): fl=997497.6029392382,s=(gl=61.0,bl=0.0,gs=0.0,bs=0.0), SearchG
+ oal(loss_ratio=0.005, exceed_ratio=0.005, relative_width=0.005, initial_trial_durati
+ on=1.0, final_trial_duration=1.0, duration_sum=61.0, preceding_targets=2, expansion_
+ coefficient=2): fl=1002508.6747611101,s=(gl=61.0,bl=0.0,gs=0.0,bs=0.0)}
+ >>> print(f"NDR conditional throughput: {float(result[ndr_goal].conditional_throughp
+ ut)}")
+ NDR conditional throughput: 997497.6029392382
+ >>> print(f"PDR conditional throughput: {float(result[pdr_goal].conditional_throughp
+ ut)}")
+ PDR conditional throughput: 1000000.6730730429
Operation logic
---------------
-The latest published `IETF draft`_ describes logic of version 0.3,
-version 0.4 logic will be descibed in next draft version.
+The currently published `IETF draft`_ describes the logic of version 0.4,
+the logic of version 1.0 will be descibed better in the next draft version (-05).
.. _CSIT: https://wiki.fd.io/view/CSIT
.. _fd.io: https://fd.io/
.. _LFN: https://www.linuxfoundation.org/projects/networking/
.. _PyPI: https://pypi.org/project/MLRsearch/
.. _directory: https://gerrit.fd.io/r/gitweb?p=csit.git;a=tree;f=PyPI/MLRsearch;hb=refs/heads/master
-.. _IETF draft: https://tools.ietf.org/html/draft-ietf-bmwg-mlrsearch-00
+.. _IETF draft: https://tools.ietf.org/html/draft-ietf-bmwg-mlrsearch-04
diff --git a/PyPI/MLRsearch/setup.py b/PyPI/MLRsearch/setup.py
index c3369e6589..1906ff3e87 100644
--- a/PyPI/MLRsearch/setup.py
+++ b/PyPI/MLRsearch/setup.py
@@ -16,7 +16,7 @@ with open(path.join(here, u"README.rst"), encoding=u"utf-8") as f:
setup(
name=u"MLRsearch",
- version=u"0.4.0", # This is currently the only place listing the version.
+ version=u"1.0.0", # This is currently the only place listing the version.
description=u"Library for speeding up binary search using shorter measurements.",
long_description=long_description,
long_description_content_type=u"text/x-rst",
@@ -29,12 +29,12 @@ setup(
u"Intended Audience :: Science/Research",
u"Intended Audience :: Telecommunications Industry",
u"License :: OSI Approved :: Apache Software License",
- u"Programming Language :: Python :: 3.6",
+ u"Programming Language :: Python :: 3.8",
u"Topic :: System :: Networking"
],
keywords=u"binary search throughput networking",
packages=find_packages(exclude=[]),
- python_requires=u"~=3.6",
+ python_requires=u"~=3.8",
install_requires=[],
# TODO: Include simulator and tests.
extras_require={