Beispiel #1
0
def setup_and_simulate(
    formula: str,
    # file_request_distribution: np.ndarray,
    num_of_files: int,
    num_of_requests: int,
    cache_size: int,
    *args,
    **kwargs,
) -> np.ndarray:
    """
    Full, single-user simulation for a given set of arguments
    :param formula: sympy-ready formula
    :param file_request_distribution: given file distribution array
    :param num_of_requests: integer number of requests
    :param num_files_cached: integer number of files cached per user
    :param args: unused
    :param kwargs: (supply all arguments as keyword arguments in order
    to allow logic to utilize them for formula analysis)
    :return: caching results
    """

    # evaluate the formula
    formula = evaluate_string_to_valid_formula_str(formula)
    sympy_formula: Any = parse_to_sympy(formula)
    variables_to_fill = [
        var for var in _unique_vars_in_formula(formula)
        if var not in ["m", "r", "v"]
    ]
    var_dict = dict()

    for var in variables_to_fill:
        if var not in kwargs:
            import ipdb

            ipdb.set_trace()
        var_dict[var] = kwargs[var]

    file_request_distribution: np.ndarray = generate_distribution_curve(
        num_of_files, automatic=True, **kwargs)

    caching_dist = modify_distribution_curve(file_request_distribution,
                                             sympy_formula, **var_dict)

    # run evaluation
    result = evaluate(
        file_request_distribution,
        caching_dist,
        cache_size,
        num_of_requests,
        **var_dict,
    )

    return result
Beispiel #2
0
    def drive_multiple(self, formula: str) -> np.ndarray:
        """
        Driving multiple simulations.
        :param formula: formula string provided
        :param num_users: number of users (the number of the independent
         user simulations to perform
        :return: x,y matrix of TOTAL caching misses
        """

        # generate file distribution
        self.file_dist: np.ndarray = generate_distribution_curve(
            self.num_of_files, automatic=True)

        trials: List[np.ndarray] = []
        for i in range(self.num_of_users):
            trials.append(self.drive(formula=formula, generate_new_dist=False))

            bars_left_to_complete = int(20 * i / self.num_of_users)
            print(
                f":{bars_left_to_complete * '#'}{(20 - bars_left_to_complete) * '-'}: {(100 * i/self.num_of_users):.2f}%"
            )

        return sum(trials)
Beispiel #3
0
        **var_dict,
    )

    return result


if __name__ == "__main__":
    print(
        evaluate(np.array([0, 0.3, 0.4, 0.3, 0]), np.array([0.2, 0.8, 0, 0,
                                                            0]), 2, 2))

    argument_dict = {
        # "formula": "{p_r(m)^{1\\over\\alpha}}\\over" +
        # "{\\sum_{n=1}^{m}{p_r(n)^{1\\over\\alpha}}}}",
        "formula":
        "{p_r(m)^{1\\over\\alpha}}",
        "alpha":
        0.9,
        "beta":
        3,
        "num_files_cached":
        3,
        "num_users":
        2,
        "file_request_distribution":
        generate_distribution_curve(10, automatic=True),
        "num_of_requests":
        3,
    }
    print(setup_and_simulate(**argument_dict))
Beispiel #4
0
    def drive(self,
              formula: str,
              generate_new_dist: bool = False) -> np.ndarray:
        """
        Driving simulations.
        :param: formula: formula string provided
        :return: x,y matrix of caching misses
        """

        # evaluate the formula
        formula = evaluate_string_to_valid_formula_str(formula)

        if generate_new_dist:
            # generate file distribution
            self.file_dist: np.ndarray = generate_distribution_curve(
                self.num_of_files,
                automatic=True,
            )

        # pre-populate a matrix of arguments
        default_arguments: Dict[str, Any] = {
            "formula": formula,
            "alpha": self.alpha,
            "beta": self.beta,
            "cache_size": self.cache_size,
            "num_users": self.num_of_users,
            # "file_request_distribution": self.file_dist,
            "num_of_requests": self.number_of_files_requested,
            "num_of_files": self.num_of_files,
        }
        argument_matrix: List[List[Dict[str, Any]]] = []
        for _ in self.range_y:
            # shallow copy the arguments
            argument_matrix.append(
                [default_arguments.copy() for _ in self.range_x])

        # then, sweep for each range
        for index_y, value_y in enumerate(self.range_y):
            for index_x, value_x in enumerate(self.range_x):
                argument_matrix[index_y][index_x][
                    self.x_axis["name"]] = value_x
                argument_matrix[index_y][index_x][
                    self.y_axis["name"]] = value_y

        # now use multiprocessing to bring out the big guns to simulate
        caching_dists: List[List[np.ndarray]] = []
        try:
            with mp.Pool(len(self.range_x)) as p:
                for row in argument_matrix:
                    async_process = [
                        p.apply_async(setup_and_simulate, (), arg_dict)
                        for arg_dict in row
                    ]
                    caching_dists.append(
                        [result.get(timeout=10) for result in async_process])
        except Exception as e:
            if "division by zero" in e.args[0].lower():
                raise InvalidParametersException(
                    "Attempted to divide in range containing 0")

        for prc in mp.active_children():
            prc.terminate()

        # for now, return the length of caching purposes
        # if needed, exact indexes are still available for index

        for index, row in enumerate(caching_dists):
            caching_dists[index] = [len(item) for item in row]

        return np.array(caching_dists)
Beispiel #5
0
 def _update_distribution(self, *args, **kwargs) -> None:
     self.file_distribution = generate_distribution_curve(*args, **kwargs)
from matplotlib import pyplot as plt
import numpy as np

import config

config.USE_NUMPY_ZIPF = False
num_of_files = config.DEFAULT_NUM_OF_FILES
a = 1.05

from utils.generate_distribution_curves import generate_distribution_curve

file_dist: np.ndarray = generate_distribution_curve(num_of_files,
                                                    automatic=True,
                                                    **{"a": a})

plt.plot(np.arange(num_of_files), file_dist)
plt.title(f"File Distribution for Zipf a={a}")
plt.xlabel(f"Index (m)")
plt.ylabel(f"Probability of Caching (p_c)")
plt.show()