API

System definition

The System is defined from the InstanceClasses which compose it. Instance classes belong to LimitingSets, and have different PerformanceValues for different Apps. To allow for different scenarios, the same system could have different performance values, and these are identified as PerformanceSets.

class malloovia.LimitingSet(id, name, max_vms, max_cores)[source]

LimitingSet restrictions.

property id

str: arbitrary id for limiting set object.

property name

str: name of the limiting set.

property max_vms

int: maximum number of VMs which can be running inside this limiting set. Defaults to 0 which means “no limit”.

property max_cores

float: maximum number of cores which can be running inside this limiting set. Defaults to 0 which means “no limit”.

class malloovia.InstanceClass(id, name, limiting_sets, max_vms, price, time_unit, is_reserved, cores, is_private)[source]

InstanceClass characterization

property id

str: arbitrary id for the instance class object.

property name

str: name of the instance class, usually built from the name of the VM type and the name of the limiting set in which it is deployed.

property limiting_sets

Set[LimitingSet]: tuple of LimitingSet objects to which this instance class belongs. Usually this tuple has a single element, but in principle an instance class can be restricted by several limiting sets.

property max_vms

int: maximum number of VMs which can be deployed from this instance class. The value 0 means “no limit”.

property price

float: price per timeslot of this instance class.

property time_unit

str: length of the timeslot used in price (“y”, “h”, “m”, or “s”).

property is_reserved

bool: True if this instance class is reserved (defaults to False).

property cores

int: number of cores this instance class has (defaults to 1).

property is_private

bool: True if this instance class belongs to the private cloud in a hybrid model (defaults to False)

class malloovia.App(id, name)[source]

App identifier.

property id

str: arbitrary id for the App object

property name

name of the app

class malloovia.PerformanceValues(data)[source]

Stores the performance of each app for each instance class.

If p is an instance of this class, performance data can be accessed like this: p[ic, app], being ic and app instances of InstanceClass and App, respectively.

Also p.get_by_id(ic_id, app_id) can be used, being ic_id and app_id strings (corresponding to ic.id and app.id fields of InstanceClass and App)

PerformanceValues implements the iterator interface, so you can loop over it, as for example for (i, a, v) in p: Each iteration yields a tuple (instance_class, app, value). The order in which the items are retrieved is deterministic, alphabetical by id.

Constructor:

Parameters:data (dict) –

It is expected that the keys are instance classes, and the values are nested dictionaries with apps as keys and performances (float) as values.

This dictionary is copied inside the class, so that later modifications to the passed dictionary do not affect the internal copy.

get_by_ids(ins_id, app_id)[source]

Get the performance of a pair (instance class, app) by their ids.

Parameters:
  • ins_id (str) – id of the instance class
  • app_id (str) – id of the app
Return type:

float

Returns:

The performance value for that pair

Raises:

KeyError – when no instance class or app with those ids can be found.

items()[source]

Returns a view of the items in the private dictionary

keys()[source]

Returns a view of the keys in the private dictionary

class malloovia.PerformanceSet(id, values, time_unit)[source]

Stores the performance of each pair (app, instance class).

property id

str: arbitrary id for the PerformanceSet object.

property values

PerformanceValues: storage of the performance values per app and instance class.

property time_unit

str: length of the timeslot used in performance values (“y”, “h”, “m”, or “s”).

Problem definition

The Problem is defined by the system components (instance classes and performances), plus a Workload prediction. A System is a Problem without the workloads. Utility function system_from_problem() can be used to extract the system from a problem.

class malloovia.Workload(id, description, values, app, time_unit, intra_slot_distribution, filename)[source]

Workload description

property id

str: arbitrary id for the workload object.

property description

str: description of the workload.

property values

Tuple[float, …]: the value of the predicted workload for several timeslots. It can store also a single value if it is the short-term workload prediction, but even in this case it must be a tuple (with a single element).

property app

App: The application which generates this workload.

property time_unit

string: length of the timeslot used in values (“y”, “h”, “m”, or “s”).

property intra_slot_distribution

str: optional identifier of the statistical distribution of this workload inside the timeslot. Malloovia does not use this attribute, but it can be used by other tools, like simulators.

property filename

str: optional name of the file from which this workload was read, or None if the filename is unknown.

class malloovia.Problem(id, name, workloads, instance_classes, performances, description)[source]

Problem description.

property id

str: arbitary id for the problem object.

property name

str: name for the problem.

property workloads

Tuple [Workload, …]: Tuple of workloads, one per application.

property instance_classes

Tuple[InstanceClass, …]: Tuple of Instance Classes, describing the cloud infrastructure which has to serve the workload.

property performances

PerformanceSet: Object describing the performance of each instance class for each kind of application.

property description

str: optional description for the problem.

class malloovia.System(id, name, apps, instance_classes, performances)[source]

Stores the part of a problem which does not depend on the workload.

property id

str: arbitary id for the system object.

property name

str: name for the problem.

property apps

Tuple[App, …]: Tuple of objects of type App describing the applications that are used in the system.

property instance_classes

Tuple[InstanceClass, …]: Tuple of objects of type InstanceClass, describing the cloud infrastructure which has to serve the workload.

property performances

PerformanceSet: Object describing the performance of each instance class for each kind of application.

malloovia.system_from_problem(problem)[source]

Extracts the “system” part of a problem.

Parameters:problem (Problem) – Problem description
Return type:System
Returns:A System object containing a copy of the relevant parts of the problem.

Solving

The solver operates in two phases.

  • PhaseI solves the whole reservation period and provides a SolutionI object, which contains SolvingStats, MallooviaStats, the optimal AllocationInfo for each possible load-level, and the ReservedAllocation useful for the next phase.
  • PhaseII allows to solve single timeslots, or to perform a simulation of a complete reservation period, by solving separately each timeslot. It provides a SolutionII as result, which contains GlobalSolvingStats which aggregates statistics about all solved timeslots, and the AllocationInfo with the optimal allocation for each timeslot. Optionally it can accept a STWPredictor from which it obtains the short-term workload prediction of each timeslot. An example of such a predictor is OmniscientSTWPredictor.
class malloovia.PhaseI(problem)[source]

Interface to the solver for the PhaseI of the method.

Usage:

phase_i = PhaseI(problem)
solution = phase_i.solve()

Constructor.

Parameters:problem (Problem) – the problem (instances, performances and workload per app) to solve.
Raises:ValueError – if the problem stores inconsistent information.
solve(gcd=True, solver=None, relaxed=False)[source]

Creates Malloovia’s LP problem, solves it, and returns the solution.

Parameters:
  • gcd (bool) – boolean to denote if quantization using GCD should be used
  • solver (Optional[Any]) – optional Pulp solver. It can have custom arguments, such as fracGap and maxSeconds.
  • relaxed (bool) – boolean; if True, the problem uses continuous variables instead of integer ones.
Return type:

SolutionI

Returns:

The solution of the problem, which includes solving_stats, reserved_allocation and (full) allocation.

property solution

Stored solution of the problem (type SolutionI). It is None if the problem has not been yet solved.

class malloovia.ReservedAllocation(instance_classes, vms_number)[source]

Stores the number of reserved instances to allocate during the whole reservation period.

property instance_classes

List[InstanceClass, …]: list of reserved instance classes in the allocation.

property vms_number

List[float, …]: list of numbers, representing the number of instance classes to be reserved of each type. The corresponding instance class is obtained from the instance_classes attribute using the same index.

class malloovia.PhaseII(problem, phase_i_solution, solver=None, reuse_rsv=True)[source]

Solves phase II, either for a single timeslot or for the whole reservation period.

This class is used for solving Phase II. It receives in the constructor (see below) a problem and a solution for Phase I already computed, which contains the allocation for the reserved instances.

It provides the methods self.solve_timeslot() to solve a single timeslot, and self.solve_period() to solve the whole reservation period by iteratively solving each timeslot.

Constructor.

Parameters:
  • problem (Problem) – the problem to solve, usually the same used in Phase I, but it can be different as long as it contains references to the same apps and reserved instance classes.
  • phase_i_solution (SolutionI) – the solution returned by Phase I
  • solver (Optional[Any]) – optional Pulp solver. It can have custom arguments, such as fracGap and maxSeconds.
  • reuse_rsv (bool) – boolean indicating if reserved instances that were assigned in phase I to an application can be reused for another application.
solve_timeslot(workloads, system=None, solver=None)[source]

Solve one timeslot of phase II for the workload received.

The solution is stored in the field ‘self._solutions’ using the pairs (system, workloads) as keys. If a solution for that key is already present, the same solution is returned.

Parameters:
  • workloads (Sequence[Workload]) – tuple with one Workload per app. Only the first value in the values field of each workload is used, as the prediction for the timeslot to solve.
  • system (Optional[System]) – the part of the problem which does not depend on the workload. If None, the system will be extracted from self.problem.
  • solver (Optional[Any]) – Pulp solver. It can have custom arguments, such as fracGap and maxSeconds.
Return type:

SolutionI

Returns:

The solution for that timeslot, stored in a SolutionI object.

solve_period(predictor=None)[source]

Solves the complete reserved period by iteratively solving each timeslot.

Parameters:predictor (Optional[STWPredictor]) – a generator which yields one prediction tuple per timeslot. If None, a default OmniscientSTWPredictor is instantiated which iterates over the Problem.workloads values.
Return type:SolutionII
Returns:The global solution for phase II, which contains the allocation for each timeslot and SolvingStats for each timeslot.
class malloovia.PhaseIIGuided(*args, **kwargs)[source]

Extends PhaseII class to override the self.solve_timeslot() method, to allow it to receive a preallocation parameter which enforces some minimum number of on-demand instances and a fixed number of reserved instances.

solve_timeslot(workloads, system=None, solver=None, preallocation=None)[source]

Solve one timeslot of phase II for the workload received.

The solution is stored in the field ‘self._solutions’ using the tuples (system, preallocation, workloads) as keys. If a solution for that key is already present, the same solution is returned.

Parameters:
  • workloads (Sequence[Workload]) – tuple with one Workload per app. Only the first value in the values field of each workload is used, as the prediction for the timeslot to solve.
  • system (Optional[System]) – the part of the problem which does not depend on the workload. If None, the system will be extracted from self.problem.
  • solver (Optional[Any]) – Pulp solver. It can have custom arguments, such as fracGap and maxSeconds.
  • preallocation (Optional[ReservedAllocation]) – allocation for a minimum number of on-demand instances, to keep active from previous timeslots. An external driver should compute these numbers and pass them to the solver through this parameter.
Returns:

The solution for that timeslot, stored in a SolutionI object.

Solutions

class malloovia.SolutionI(id, problem, solving_stats, allocation, reserved_allocation)[source]

Stores a solution for phase I.

property id

str: arbitrary id for this object.

property problem

Problem: reference to the problem which originated this solution.

property solving_stats

SolvingStats: statistics about this solution.

property allocation

AllocationInfo: allocation provided in this solution.

property reserved_allocation

ReservedAllocation: allocation for reserved instances only.

class malloovia.SolvingStats(algorithm, creation_time, solving_time, optimal_cost)[source]

Stores the statistics that can be gathered from a solution of Phase I, or one single timeslot in Phase II.

property algorithm

MallooviaStats: additional info related to the particular algorithm used to solve the problem.

property creation_time

float: time required to create the LP problem.

property solving_time

float: time required to solve the LP problem.

property optimal_cost

float: optimal cost as reported by the LP solver, or None if no solution was found.

class malloovia.MallooviaStats(gcd, status, gcd_multiplier, frac_gap, max_seconds, lower_bound)[source]

Stores data related to the Malloovia solver.

property gcd

bool: whether GCD technique was used or not.

property status

Status: status of the solution.

property gcd_multiplier

float: the multiplier used in GCD technique (defaults to 1.0).

property frac_gap

float: the fracGap passed to cbc solver (defaults to None).

property max_seconds

float: the maxSeconds passed to cbc solver (defaults to None).

property lower_bound

float: the lower bound of the solution as reported by cbc when the optimal solution is not available (defaults to None).

class malloovia.Status[source]

Possible status of malloovia’s solution

unsolved = 0
optimal = 1
infeasible = 2
integer_infeasible = 3
overfull = 4
trivial = 5
aborted = 6
cbc_error = 7
unknown = 8
class malloovia.AllocationInfo(values, units, apps, instance_classes, workload_tuples, repeats)[source]

Stores the allocation for a series of timeslots. It can be a single timeslot, or the sequence of allocations for the whole reservation period.

property values

Tuple[Tuple[Tuple[float, …], …], …]: contains a list with one element per timeslot. Each element in this sequence is a list (with one element per app), which is in turn a list (with one element per instance class). These values are numbers which can represent the number of instance classes of that type to be allocated for that app during that timeslot, or the cost associated with these instance classes, or the performance given by these instance classes, depending on the units field. So, for example, if units is "vms", then values[2][1][3] represents the number of VMs of the instance class 3 to be allocated for application 1 during the timseslot 2.

Note that, if the allocation contains a single timeslot, it is still necessary to specify the index (0) in the first dimension, e.g. vms_number[0][1][3].

To match the indexes in those arrays to actual instance classes and apps, the attributes instance_classes and apps should be used. So, for the above example, the application would be apps[1] and the instance class would be instance_classes[3]. If required, the workload for that particular timeslot (2) can also be retrieved from workload_tuples[2].

property units

str: a string identifying the kind of information stored in the values field. It can be "vms" (number of VM instances), "cost" or any currency (cost of these instances) or "rph" (performance of these instances).

property apps

Sequence[App]: is a list of apps to give meaning to the second index in values.

property instance_classes

Sequence[InstanceClass]: is a list of instance classes to give meaning to the third index in values.

property workload_tuples

Sequence[Tuple[float, …]]: is a list of workload tuples to give meaning to the first index in values. Each element is a tuple with as many values as apps, being each one the workload for each app.

property repeats

List[int]: number of repetitions of each workload_tuple, for the case in which the allocation is per load-level (histogram). It can be an empty list (default value) for the case in which the allocation is per time-slot.

class malloovia.SolutionII(id, problem, solving_stats, global_solving_stats, previous_phase, allocation)[source]

Stores a solution for phase II.

property id

str: arbitrary id for this object.

property problem

Problem: reference to the problem which originated this solution.

property solving_stats

:Sequence[class:.SolvingStats]: list of the SolvingStats for each timeslot.

property global_solving_stats

GlobalSolvingStats: summary of the solving stats.

property previous_phase

SolutionI: reference to the solution of the previous phase.

property allocation

AllocationInfo: allocation for the whole period, built from the allocations of the individual timeslots.

class malloovia.GlobalSolvingStats(creation_time, solving_time, optimal_cost, status, default_algorithm)[source]

Stores the global statistics for Phase II, which are a sum of the statistics of each timeslot.

property creation_time

float: sum of the time required to create the LP problem for each timeslot.

property solving_time

float: sum of the time required to solve the LP problem for each timeslot.

property optimal_cost

float: sum of the optimal costs as reported by the LP problem for each timeslot.

property status

Status: global status computed from the status of each timeslot.

property default_algorithm

Currently unused

class malloovia.STWPredictor[source]

Abstract base class for short-term workload predictors

class malloovia.OmniscientSTWPredictor(stwp)[source]

Concrete implementation of STWP_Predictor which knows in advance the STWP for all timeslots in the future.

Implements the iterable interface and when looping over it, it returns one tuple at a time, whose elements are Workload whose values have a length of 1 (the workload for the next timeslot).

Constructor.

Parameters:stwp (Tuple[Workload, …]) – Tuple of Workload objects, one per app. Each workload contains in the field values a sequence of predicted workloads for the whole reservation period.
Raises:ValueError – if the lengths of the workloads do not match.

Internal solver

Phase I and II make use of MallooviaLp class, which is the core of the solver. Although using this class is not usually required, it is exposed because it can be useful to inherit from it to implement other LP constraints. Also, phase II makes use of MallooviaLpMaximizeTimeslotPerformance for the timeslots in which the demanded performance cannot be achieved without breaking the limits.

class malloovia.MallooviaLp(system, workloads, preallocation=None, relaxed=False)[source]

Solves the allocation problem, using Linear Programming.

This class contains methods to create a linear programming problem (using PuLP), to add restrictions and extra variables to it, to solve it (using PuLP supported solvers), and to retrieve the solution in a format amenable to further analysis and display.

The LP problem instantiates these variables:

  • For reserved instances: Y_(_a,_ic), where Y is a fixed prefix, a is a string representation of each application and ic is the string representation of each reserved instance class considered. After solving the LP problem, the value of the variable is the number of reserved machines of instance class ic for application a, for the whole reservation period.
  • For on-demand instances: X_(_a,_ic,_l), where X is a fixed prefix, a is a string representation of each application, ic is the string representation of each on-demand instance class considered and l is a string representation of a “workload tuple”, which is a tuple of numbers, e.g: (1230, 442, 123), each one representing the workload of one of the apps. After solving the LP problem, the value of the variable is the number of on-demand machines of instance class ic deployed for application a at a timeslot which has a workload prediction equal to the tuple l.

Intended usage:

  1. Instantiate the class (see constructor parameters below).
  2. Call object’s .create_problem().
  3. Call object’s .solve().
  4. Retrieve solution by calling object’s .get_allocation() to get the solution for all variables, or .get_reserved_allocation() to get ony the number of reserved instances of each type.
  5. Retrieve the cost of the solution via object’s .get_solution().

You can use object’s property pulp_problem to access the PuLP problem object which represents the linear programming problem, to inspect or save it if required.

Constructor:

Parameters:
  • system (System) – namedtuple containing “name”, “apps”, “instance_classes” and “performances” for the problem to solve.
  • workloads (Sequence[Workload]) – list of workloads, one per app. Each workload is a namedtuple which contains a reference to the app, and a sequence of N numbers which is the prediction for the next N timeslots. This sequence must have the same length for all workloads in the list.
  • preallocation (Optional[ReservedAllocation]) – number of reserved instances which are preallocated. In phase I this parameter can be omitted (defaults to None), and in phase II it should contain the object returned by get_reserved_allocation() after solving phase I.
  • relaxed (bool) – if True, the problem uses continuous variables instead of integer ones.
create_problem()[source]

Creates the PuLP problem with all variables and restrictions.

Returns:instance of the PuLP problem.
Return type:pulp.LpProblem
performance_restriction()[source]

Adds performance restriction to the problem.

This restriction forces, for each workload tuple, the performance of the solution to be greater than or equal to that workload level for all applications.

Return type:None
limit_instances_per_class_restriction()[source]

Adds max_vms per instance class restriction.

If the ic instance has a max_vms attribute, this is a limit for all Y_*_ic and X_*_ic_* variables.

Return type:None
set_fixed_instances_restriction()[source]

Adds restrictions for variables with pre-fixed values.

For every ic in self.fixed_vms a restriction is added which forces the total number of those instance classes in the solution to be at equal to a given value for reserved instances, and at least equal to a given value for on-demand instances. This is used mainly in phase II to ensure that reserved instances are fixed, or to allow to keep at least some number of on-demand instances running from previous timeslots, when using “guided” strategies”.

Return type:None
limit_instances_per_limiting_set_restriction()[source]

Adds max_vms per limiting set restriction.

If the limiting set provides a max_vms > 0, then the sum of all instances which are member of that limiting set should be limited to that maximum.

Return type:None
limit_cores_per_limiting_set_restriction()[source]

Adds max_cores per limiting set restriction.

If the limiting set provides a max_cores > 0, then the sum of all instance cores among all instance classes which are member of that limiting set should be limited to that maximum.

Return type:None
solve(*args, **kwargs)[source]

Calls PuLP solver.

Parameters:
  • *args – positional args passed to LpProblem.solve()
  • **kwargs – keyword args passed to LpProblem.solve().
Returns:

the value returned by LpProblem.solve().

get_status()[source]

Returns the status of the problem

Return type:Status
get_cost()[source]

Gets the cost of the problem, obtained after solving it.

Return type:float
Returns:The cost of the optimal solution found by PuLP.
Raises:ValueError – when the problem is yet unsolved.
get_allocation()[source]

Retrieves the allocation given by the solution of the LP problem.

Return type:AllocationInfo
Returns:The allocation given by the solution.
Raises:ValueError – if no solution is available (unsolved or infeasible problem)
get_reserved_allocation()[source]

Retrieves the allocation of reserved instances from the solution of the LP problem.

Return type:ReservedAllocation
Returns:The total number of reserved instance classes of each type to be purchased for the whole reservation period.
Raises:ValueError – if no solution is available (unsolved or infeasible problem)
class malloovia.MallooviaLpMaximizeTimeslotPerformance(system, workloads, preallocation=None, relaxed=False)[source]

Find the allocation which maximizes performance for a single timeslot.

This problem is the dual of MallooviaLp. Instead of minimizing the cost while providing the minimum performances, the problem to solve now is to maximize the performance without breaking the limits.

The class inherits from Malloovia the initialization methods as well as the ones to get the cost and allocation of the solution, but overrides the function to be optimized and some of the constraints.

Constructor:

Parameters:
  • system (System) – namedtuple containing “name”, “apps”, “instance_classes” and “performances” for the problem to solve.
  • workloads (Sequence[Workload]) – list of workloads, one per app. Each workload is a namedtuple which contains a reference to the app, and a sequence of N numbers which is the prediction for the next N timeslots. This sequence must have the same length for all workloads in the list.
  • preallocation (Optional[ReservedAllocation]) – number of reserved instances which are preallocated. In phase I this parameter can be omitted (defaults to None), and in phase II it should contain the object returned by get_reserved_allocation() after solving phase I.
  • relaxed (bool) – if True, the problem uses continuous variables instead of integer ones.
create_problem()[source]

This method creates the PuLP problem, and calls other methods to add variables and restrictions to it. It initializes the attribute ‘self.prob’ with the instance of the PuLP problem created.

Return type:MallooviaLpMaximizeTimeslotPerformance
performance_restriction()[source]

Adds performance restriction to the problem.

This restriction forces, for each workload tuple, the performance of the solution to be less than or equal to that workload level, for all applications.

Return type:None
get_cost()[source]

Gets the cost of the problem, obtained after solving it.

Return type:float
Returns:The cost of the optimal solution found by PuLP.
Raises:ValueError – when the problem is yet unsolved.

Input/Output and utility functions

malloovia.read_problems_from_yaml(filename)[source]

Reads the problem(s) definition from a YAML file.

Parameters:filename (str) – name of the YAML file to read, it has to have the extension .yaml or .yaml.gz (which is automatically decompressed on read).
Return type:Mapping[str, Problem]
Returns:A dictionary whose keys are problem ids, and the values are Problem objects.
Raises:ValueError if the file has not the expected extension.
malloovia.read_problems_from_github(dataset, _id=None, base_url=None)[source]

Reads a problem or set of problems from a GitHub repository.

Parameters:
  • dataset (str) – the name of the yaml file which contains the set of problems, without extension.
  • id – the id of the particular problem to load, if omitted all problems are read and a dictionary is returned, whose keys are problem ids and the values are the Problem instances.
  • base_url (Optional[str]) – the url to the folder where the file is stored. If None, it will read from https://raw.githubusercontent.com/asi-uniovi/malloovia/master/tests/test_data/problems/
Return type:

Union[Problem, Mapping[str, Problem]]

Returns:

A dictionary whose keys are problem ids, and the values are Problem objects, or a single Problem if the id is passed as argument.

malloovia.problems_to_yaml(problems)[source]

Converts problems from the classes used by malloovia to a yaml string.

Parameters:problems (Mapping[str, Problem]) – it is a dictionary whose keys are the ids of the problems, and the values are instances of Problem, which indirectly contains the full specification of the system, apps, workloads and performances, through references to other classes
Return type:str
Returns:A string with a yaml representation of the problem and all the data associated with it. The YAML contains separate fields for “Apps”, “Workloads”, “Limiting_sets”, “Instance_classes”, “Performances” and “Problems”, each one containing a list of apps, workloads, etc. respectively. These lists are dynamically built and contains the entities which are directly or indirectly referenced from the dict of problems received as input.

The generated yaml contains internal anchors (automatically generated from the ids of the objects) and yaml references to those anchors, so that when the yaml is parsed back to python, the resulting dict contains internal references (instead of copies) to other dicts.

malloovia.solutions_to_yaml(solutions)[source]

Converts a list of solutions to a YAML string.

Parameters:solutions (Sequence[Union[SolutionI, SolutionII]]) – list of solutions to convert, each one can be a SolutionI or a SolutionII.
Return type:str
Returns:A string with a YAML representation of the solution and the associated problem. The YAML uses anchors and references to tie up the different parts.
malloovia.check_valid_problem(problem)[source]

Performs some sanity checks on the problem’s definition.

Parameters:problem (Problem) – the problem to check
Return type:Problem
Returns:The same problem if all is correct
Raises:ValueError – if some error is detected.
malloovia.compute_allocation_cost(alloc)[source]

Computes the cost of each element of the allocation.

Parameters:alloc (AllocationInfo) – the allocation whose cost has to be computed
Return type:AllocationInfo
Returns:Another allocation in which the values field contains the cost of that element (it is the original values multiplied by the cost of the corresponding instance class)
malloovia.compute_allocation_performance(alloc, performances)[source]

Computes the performance of each element of the allocation.

Parameters:
  • alloc (AllocationInfo) – the allocation whose performance has to be computed
  • performances (PerformanceValues) – the set of performances for each pair of instance class and application
Return type:

AllocationInfo

Returns:

Another allocation in which the values field contains the performance of that element (it is the original values multiplied by the performance of the corresponding instance class for the corresponding app)

malloovia.get_load_hist_from_load(workloads)[source]

Computes the histogram of the workloads.

Parameters:workloads (Sequence[Workload]) – a sequence of Workload objects, each one containing the fields app (which identifies the app producing this workload) and values (which stores a sequence of numbers representing the workload for each timeslot for that app).
Return type:MallooviaHistogram
Returns:A dictionary where the key is the workload for one timeslot, expressed as a tuple with one element for each application, and the value is the number of timeslots in which that workload was found.
malloovia.allocation_info_as_dicts(alloc, use_ids=True, include_timeslot=True, include_workloads=True, include_repeats=True)[source]

Converts the AllocationInfo structure to a sequence of dicts, which are more convenient for analysis with pandas. Each element of the returned sequence is a python dictionary whose keys and values are:

  • “instance_class” -> either the id or the reference to an instance class
  • “app” -> either the id or the reference to an app
  • “timeslot” -> the integer which represents the timeslot for this particular allocation
  • “workload” -> a tuple with the workload to be fulfilled by this particular allocation
  • “repeats” -> the number of times this workload appears in phaseI (always 1 for phase II)
  • AllocationInfo.units -> value for this particular allocation. If the units is “vms”, the value represents the number of VMs of the kind “instance_class” to be activated during timeslot “timeslot” (in phase II), or when the workload is “workload” (in phase I), for the application “app”.

Some of these fields are useful only for Phase I, while others are for Phase II. Some boolean arguments allow the selection of these specific fields.

Parameters:
  • alloc (AllocationInfo) – The AllocationInfo to convert
  • use_ids – True to use the ids of instance classes and apps, instead of the objects which store those entities. False to use references to instance classes and apps instead of the ids. The ids version produces a more compact representation when used with pandas.
  • include_timeslot – False if you don’t want the “timeslot” field (it conveys no meaning for Phase I allocations)
  • include_workloads – False if you don’t want the “workload” field
  • include_repeats – False if you don’t want the “repeats” field (it is always 1 for Phase II allocations)
Return type:

Iterable[Mapping[Any, Any]]

Returns:

A generator for sequence of dictionaries with the required fields. You can iterate over the generator, or pass it directly to pandas DataFrame constructor.

Example

>>> import pandas as pd
>>> df = (pd.DataFrame(
        allocation_info_as_dicts(
            alloc = phase_i_solution.allocation,
            use_ids=True,
            include_repeats=True,
            include_workloads=True,
            include_timeslot=False))
        .set_index(["repeats", "workload", "app", "instance_class"])
        .unstack()
    )
>>> df
                              vms
instance_class            m3large   m3large_r
repeats workload    app
1       (30, 1194)  app0     0.0       3.0
                    app1     0.0       3.0
        (32, 1200)  app0     1.0       3.0
                    app1     0.0       3.0
2       (30, 1003)  app0     0.0       3.0
                    app1     0.0       3.0
>>> df2 = (pd.DataFrame(
        allocation_info_as_dicts(
            alloc = phase_ii_solution.allocation,
            use_ids=True,
            include_repeats=False,
            include_workloads=True,
            include_timeslot=True))
        .set_index(["timeslot", "workload", "app", "instance_class"])
        .unstack()
    )
>>> df
                             vms
instance_class           m3large   m3large_r
timeslot workload   app
0        (30, 1003) app0     0.0       3.0
                    app1     0.0       3.0
1        (32, 1200) app0     1.0       3.0
                    app1     0.0       3.0
2        (30, 1194) app0     0.0       3.0
                    app1     0.0       3.0
3        (30, 1003) app0     0.0       3.0
                    app1     0.0       3.0