Non Drop Rate Benchmark API

We will show a simple use of the API, for example one can implement a simple version of find_ndr in the following way:

def simple_find_ndr():

    first_run_results = self.__find_max_rate()
    self.update_opt_stats(first_run_results)

    drop_percent = self.results.stats['drop_rate_percentage']
    q_full_percent = self.results.stats['queue_full_percentage']

    if drop_percent > self.config.pdr:
        self.results.update(self.perf_run_interval(100, 0))
    elif q_full_percent >= self.config.q_full_resolution:
        self.results.update(self.perf_run_interval(100.00, 0.00))
    else:
        # ndr found at max rate

    self.calculate_ndr_points()

Another implementation of a simple find_ndr using the optimized binary search is:

def simple_optimized_find_ndr():

    first_run_results = self.__find_max_rate()
    self.update_opt_stats(first_run_results)

    drop_percent = self.results.stats['drop_rate_percentage']
    q_full_percent = self.results.stats['queue_full_percentage']

    if drop_percent > self.config.pdr:
        self.results.update(self.optimized_binary_search(drop_percent, self.config.pdr, 'drop_rate_percentage'))
    elif q_full_percent >= self.config.q_full_resolution:
        self.results.update(self.optimized_binary_search(q_full_percent, self.config.q_full_resolution, 'queue_full_percentage'))
    else:
        # ndr found at max rate

    self.calculate_ndr_points()

And lastly a version that would allow the plugin pre and post iteration:

def simple_plugin_find_ndr():

    self.plugin_pre_iteration(finding_max_rate=True, run_results=None, **self.config.tunables)
    first_run_results = self.__find_max_rate()
    self.update_opt_stats(first_run_results)
    plugin_stop = self.plugin_post_iteration(finding_max_rate=True, run_results=first_run_results, **self.config.tunables)
    if plugin_stop:
        self.calculate_ndr_points()
        return

    drop_percent = self.results.stats['drop_rate_percentage']
    q_full_percent = self.results.stats['queue_full_percentage']

    if drop_percent > self.config.pdr:
        #Inside perf_run we take care of plugins prior and post each iteration
        self.results.update(self.perf_run_interval(100, 0))
    elif q_full_percent >= self.config.q_full_resolution:
        #Inside perf_run we take care of plugins prior and post each iteration
        self.results.update(self.perf_run_interval(100.00, 0.00))
    else:
        # ndr found at max rate
        pass

    self.calculate_ndr_points()

Let’s finally see a simple implementation of the optimized binary search algorithm:

def simple_optimized_bin_search(self, lost_percentage, lost_allowed_percentage, stat_type):

    current_run_stats = deepcopy(self.results.stats)

    max_rate = Rate(self.results.stats['max_rate_bps'])
    assumed_ndr_rate = Rate(max_rate.convert_percent_to_rate(100 - lost_percentage))
    upper_bound = min(max_rate.rate, assumed_ndr_rate.convert_percent_to_rate(100 + self.config.opt_binary_search_percentage))
    upper_bound_percentage_of_max_rate = max_rate.convert_rate_to_percent_of_max_rate(upper_bound)

    if not max_rate.is_close(upper_bound):
        # in case we are not close to the max rate, try with the upper bound of the assumed NDR
        current_run_stats['rate_p'] = upper_bound_percentage_of_max_rate
        current_run_stats['rate_tx_bps'] = upper_bound
        current_run_stats['iteration'] = "Upper bound of assumed NDR"
        current_run_stats.update(self.perf_run(upper_bound_percentage_of_max_rate))
        self.results.update(current_run_stats)
        self.update_opt_stats(current_run_stats)

        upper_bound_lost_percentage = current_run_stats[stat_type]
        if upper_bound_lost_percentage <= lost_allowed_percentage:
            return self.perf_run_interval(100, upper_bound_percentage_of_max_rate)

    # if you got here -> upper bound of assumed ndr has too many drops
    lower_bound = assumed_ndr_rate.convert_percent_to_rate(100 - self.config.opt_binary_search_percentage)
    lower_bound_percentage_of_max_rate = max_rate.convert_rate_to_percent_of_max_rate(lower_bound)

    current_run_stats['rate_p'] = lower_bound_percentage_of_max_rate
    current_run_stats['rate_tx_bps'] = lower_bound
    current_run_stats['iteration'] = "Lower bound of assumed NDR"

    current_run_stats.update(self.perf_run(lower_bound_percentage_of_max_rate))
    self.results.update(current_run_stats)
    self.update_opt_stats(current_run_stats)

    lower_bound_lost_percentage = current_run_stats[stat_type]
    if lower_bound_lost_percentage <= lost_allowed_percentage:
        return self.perf_run_interval(upper_bound_percentage_of_max_rate, lower_bound_percentage_of_max_rate)

    # if you got here -> lower bound of assumed ndr has too many drops
    else:
        return self.perf_run_interval(lower_bound_percentage_of_max_rate, 0)

Rate class

class trex.examples.stl.ndr_bench.Rate(rate)[source]

A rate repressenting class.

Parameters
rate: float

Rate in bps

convert_percent_to_rate(percent_of_rate)[source]

Converts percent of the rate (defined in init) to an actual rate.

Parameters
percent_of_rate: float

Percentage of rate that defined when class initialized.

Returns

float,Rate in bps

convert_rate_to_percent_of_max_rate(rate_portion)[source]

Converts a rate in bps to percentage of rate that was defined in init.

Parameters
rate_portion: float

Rate in bps

Returns

float, percentage

is_close(rate, rel_tol=0.05, abs_tol=1000000)[source]

Returns if a rate is close to the rate that was defined in init.

Parameters
rate: float

Rate to compare to the rate that was defined upon initialization.

rel_tol: float
is a relative tolerance, it is multiplied by the greater of the magnitudes of the two arguments;

as the values get larger, so does the allowed difference between them while still considering them equal. Default Value = 5%.

abs_tol: int

is an absolute tolerance that is applied as-is in all cases. If the difference is less than either of those tolerances, the values are considered equal. Default value = 1 Mbit

Returns

A boolean flag indicating it the given rate is close.

NdrBenchConfig class

class trex.examples.stl.ndr_bench.NdrBenchConfig(ports, title='Title', cores=1, iteration_duration=20.0, q_full_resolution=2.0, first_run_duration=20.0, pdr=0.1, pdr_error=1.0, ndr_results=1, max_iterations=10, max_latency=0, lat_tolerance=0, verbose=False, bi_dir=False, plugin_file=None, tunables={}, opt_binary_search=False, opt_binary_search_percentage=5, total_cores=1, **kwargs)[source]

Configuration parameters for the benchmark.

Parameters
ports: list

List of ports to transmit. Even ports will transmit and odd ones will receive, unless bi-directional traffic.

title: string

Title of the benchmark.

cores: int

Number of cores.

iteration_duration: float

Duration of the iteration.

q_full_resolution: float

Percent of queue full allowed.

first_run_duration: float

Duration of the first run.

pdr: float

Percentage of drop rate.

pdr_error: float

Percentage of allowed error in pdr.

ndr_results: int

Calculates the benchmark at each point scaled linearly under NDR [1-10]. Number of points

max_iterations: int

Max number of iterations allowed.

max_latency: int

Max value of latency allowed in msec.

lat_tolerance: int

Percentage of latency packets allowed above max latency. Default value is 0 %. (Max Latency will be compared against total max)

verbose: boolean

Verbose mode

bi_dir: boolean

Bi-directional traffic if true, else uni-directional.

plugin_file: string

Path to the plugin file.

tunables: dict

Tunables for the plugin file.

opt_binary_search: boolean

Flag to indicate if to search using the optimized binary mode or not.

opt_binary_search_percentage: int

Percentage around assumed ndr allowed to search.

kwargs: dict

get_optimal_core_mask(num_of_cores, num_of_ports)[source]

Optimal core mask in case of bi directional traffic.

Parameters
num_of_cores: int

Number of cores per dual port

num_of_ports: int

Number of ports

Returns

List of masks per each port to offer optimal traffic.

classmethod load_plugin(plugin_file)[source]

Load dynamically a plugin module so that we can provide the user with pre and post iteration API.

Parameters
plugin_file: string

Path to the plugin file.

config_to_dict()[source]

Create a dictionary of the configuration.

Returns

Dictionary of configurations

NdrBenchResults class

class trex.examples.stl.ndr_bench.NdrBenchResults(config=None, results={})[source]

NDR Bench Results

Parameters
config: NdrBenchConfig

User configuration of parameters. Default value is none.

results: dict

A dictionary containing partial or full results from a run.

update(updated_dict)[source]

Updates the elapsed time, and the stats of the class with the parameter

Parameters
updated_dict: dict

Dictionary that we use as an reference to update our stats.

convert_rate(rate_bps, packet=False)[source]

Converts rate from bps or pps to a string.

Parameters
rate_bps: float

Value of of rate in bps or pps based on the packet parameter.

packet: boolean

If true then the rate is PPS, else bps.

Returns

Rate as a formatted string.

print_latency()[source]

Prints the latency stats in case there are any.

print_run_stats()[source]

Prints the T-REX stats after a run (transmission).

print_iteration_data()[source]

Prints data regarding the current iteration.

print_final()[source]

Prints the final data regarding where the NDR is found.

to_json()[source]

Output the results to a json.

human_readable_dict()[source]

Return a human readable dictionary of the results.

NdrBench class

class trex.examples.stl.ndr_bench.NdrBench(stl_client, config)[source]

NDR Bench

Parameters
stl_client: STLClient

STL Client

config: NdrBenchConfig

Configurations and parameters for the benchmark

plugin_pre_iteration(finding_max_rate, run_results=None, **kwargs)[source]

Plugin pre iteration wrapper in order to pass the plugin a deep copy of the run results, since the user might change the actual run results. Consult the Plugin API for more information.

plugin_post_iteration(finding_max_rate, run_results, **kwargs)[source]

Plugin pre iteration wrapper in order to pass the plugin a deep copy of the run results, since the user might change the actual run results. Consult the Plugin API for more information.

calculate_max_latency_received(latency_data)[source]

Calculates the max latency of a run. Call this only if latency tolerance is 0%.

Parameters
latency_data: dict

The latency field of get_stats() of the STLClient

Returns

The max latency in that run.

calculate_latency_percentage(latency_data)[source]

Calculates the percentage of latency packets beyond the max latency parameter. The percentage is calculated independently for each pg id and the maximal percentage is returned. Call this only if latency tolerance is more than 0%.

Parameters
latency_data: dict

The latency field of get_stats() of the STLClient

Returns

A float represeting the percentage of latency packets above max latency.

is_valid_latency(latency_data)[source]

Returns a boolean flag indicating if the latency of a run is valid. In case latency was not set then it returns True.

Parameters
latency_data: dict

The latency field of get_stats() of the STLClient

Returns

A boolean flag indiciating the latency was valid.

calculate_ndr_points()[source]

Calculates NDR points based on the ndr_results parameter in the NdrBenchConfig object.

update_opt_stats(new_stats)[source]

Updates the optimal stats if the new_stats are better.

Parameters
new_stats: dict

Statistics of some run.

Performs the Optimized Binary search algorithm.

Parameters
lost_percentage: float

Percentage of drops/queue full in the previous run.

lost_allowed_percentage: float

Percentage/Resolution of allowed drops/queue full.

stat_type: string

Type of statistic that had drops. stat_type should be either “drop_rate_percentage”, “queue_full_percentage” or “valid_latency”. Drops have priority over queue full which has priority over valid_latency,

Returns

Dictionary of the optimal run stats found in the interval, based on the criterions defined in NdrBenchConfig,

perf_run(rate_mb_percent, run_max=False)[source]

Transmits traffic through the STL client object in the class.

Parameters
rate_mb_percent: float

Rate of transmit in Mbit.

run_max: boolean

Flag indicating if we are transmitting the maximal rate.

Returns

Dictionary with the results of the run.

perf_run_interval(high_bound, low_bound)[source]

Searches for NDR in an given interval bounded by the two parameters. Based on the number of iterations which is supplied in the NdrBenchConfig object of the class will perform multiple transmitting runs until one of the stopping conditions is met.

Parameters
high_bound: float

In percents of maximal rate.

low_bound: float

In percents of maximal rate

Returns

Dictionary of the optimal run stats found in the interval, based on the criterions defined in NdrBenchConfig,

find_ndr()[source]

Finds the NDR of the STL client that the class received. The function updates the NdrBenchResults object that NdrBench contains. Decisions which algorithms to choose or if to apply a plugin are based on the object of type NdrBenchConfig that this class contains.

This is the top level function that finds the NDR and the user can use.