Boavizta / boaviztapi

🛠 Giving access to BOAVIZTA reference data and methodologies trough a RESTful API
GNU Affero General Public License v3.0
66 stars 21 forks source link

The impact of RAM and CPU usage is counted twice #287

Open da-ekchajzer opened 2 months ago

da-ekchajzer commented 2 months ago

Bug description

RAM and CPUs power are assessed for the number of units. When their impacts are assessed, we also apply the number of units. RAM and CPU impacts. It has no consequences on the server and cloud impact calculation since we use diretcly use the power for RAM and CPU

CPU consumption

  def model_power_consumption(self) -> ImpactFactor:
        self.usage.consumption_profile = CPUConsumptionProfileModel()

        self.usage.consumption_profile.compute_consumption_profile_model(cpu_manufacturer=self.manufacturer.value,
                                                                         cpu_model_range=self.model_range.value,
                                                                         cpu_tdp=self.tdp.value)

        if type(self.usage.time_workload.value) in (float, int):
            self.usage.avg_power.set_completed(
                self.usage.consumption_profile.apply_consumption_profile(self.usage.time_workload.value))
        else:
            self.usage.avg_power.set_completed(
                self.usage.consumption_profile.apply_multiple_workloads(self.usage.time_workload.value))

        return ImpactFactor(
            value=rd.round_to_sigfig(self.usage.avg_power.value, 5) * self.units.value,
            min=rd.round_to_sigfig(self.usage.avg_power.value, 5) * self.units.min,
            max=rd.round_to_sigfig(self.usage.avg_power.value, 5) * self.units.max
        )

RAM consumption

    def model_power_consumption(self, ) -> ImpactFactor:
        self.usage.consumption_profile = RAMConsumptionProfileModel()
        self.usage.consumption_profile.compute_consumption_profile_model(ram_capacity=self.capacity.value)

        if type(self.usage.time_workload.value) in (float, int):
            self.usage.avg_power.set_completed(
                self.usage.consumption_profile.apply_consumption_profile(self.usage.time_workload.value))
        else:
            self.usage.avg_power.set_completed(
                self.usage.consumption_profile.apply_multiple_workloads(self.usage.time_workload.value))

        return ImpactFactor(
            value=rd.round_to_sigfig(self.usage.avg_power.value, 5)*self.units.value,
            min=rd.round_to_sigfig(self.usage.avg_power.value, 5)*self.units.min,
            max=rd.round_to_sigfig(self.usage.avg_power.value, 5)*self.units.max
        )

Impact assesment

def compute_single_impact(model: Union[Component, Device, Service],
                          phase: str,
                          criteria: str,
                          duration: Union[int, str] = config["default_duration"],
                          allocation: float = 1) -> Optional[Impact]:
    try:
        impact_function = get_impact_function(model, phase)

        impact, min_impact, max_impact, warnings = impact_function(criteria, duration, model)

        result = Impact(
            value=impact * model.units.value * allocation,
            min=min_impact * model.units.min * allocation,
            max=max_impact * model.units.max * allocation,
            warnings=list(set(warnings))
        )

        model.add_impacts(result, criteria, phase)

        return result
    except (AttributeError, NotImplementedError):
        model.add_impacts(None, criteria, phase)
        return None