Skip to content

Commit

Permalink
Fix unit conversions (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
obierlaire authored Oct 2, 2023
1 parent 20e3e2c commit 163a825
Show file tree
Hide file tree
Showing 18 changed files with 71 additions and 43 deletions.
2 changes: 1 addition & 1 deletion cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Example usages:
log.Fatal(err)
}

input := workdir
var input string
if len(args) != 0 {
input = args[0]
if !filepath.IsAbs(input) {
Expand Down
2 changes: 1 addition & 1 deletion internal/data/data/energy_coefficients.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"AWS": {
"cpu_min_wh": 0.74,
"cpu_max_wh": 3.5,
"cpu_max_wh": 5.23,
"storage_hdd_wh_tb": 0.65,
"storage_ssd_wh_tb": 1.2,
"networking_wh_gb": 1,
Expand Down
5 changes: 3 additions & 2 deletions internal/estimate/coefficients/coefficients.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (cps *CoefficientsProviders) GetByProvider(provider providers.Provider) Coe

func (cps *CoefficientsProviders) getByProviderName(name string) Coefficients {
r := reflect.ValueOf(cps)
coefficients := reflect.Indirect(r).FieldByName(name)
return coefficients.Interface().(Coefficients)
coefficientsVal := reflect.Indirect(r).FieldByName(name)
coefficients := coefficientsVal.Interface().(Coefficients)
return coefficients
}
2 changes: 1 addition & 1 deletion internal/estimate/estimate.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func EstimateResources(resourceList map[string]resources.Resource) estimation.Es
return estimation.EstimationReport{
Info: estimation.EstimationInfo{
UnitTime: viper.Get("unit.time").(string),
UnitWattTime: fmt.Sprintf("%s%s", viper.Get("unit.power"), viper.Get("unit.time")),
UnitWattTime: fmt.Sprintf("%s%s", "W", viper.Get("unit.time")),
UnitCarbonEmissionsTime: fmt.Sprintf("%sCO2eq/%s", viper.Get("unit.carbon"), viper.Get("unit.time")),
DateTime: time.Now(),
InfoByProvider: map[providers.Provider]estimation.InfoByProvider{
Expand Down
3 changes: 2 additions & 1 deletion internal/estimate/estimate/Energy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ func estimateWattHour(resource *resources.ComputeResource) decimal.Decimal {
log.Debugf("%v.%v Storage in Wh: %v", resource.Identification.ResourceType, resource.Identification.Name, storageInWh)
gpuEstimationInWh := EstimateWattGPU(resource)
log.Debugf("%v.%v GPUs in Wh: %v", resource.Identification.ResourceType, resource.Identification.Name, gpuEstimationInWh)
pue := coefficients.GetEnergyCoefficients().GCP.PueAverage
pue := coefficients.GetEnergyCoefficients().GetByProvider(resource.Identification.Provider).PueAverage

log.Debugf("%v.%v PUE %v", resource.Identification.ResourceType, resource.Identification.Name, pue)
rawWattEstimate := decimal.Sum(
cpuEstimationInWh,
Expand Down
67 changes: 34 additions & 33 deletions internal/estimate/estimate/Resource.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package estimate

import (
"strings"

"github.com/carboniferio/carbonifer/internal/estimate/coefficients"
"github.com/carboniferio/carbonifer/internal/estimate/estimation"

Expand All @@ -15,56 +17,55 @@ func EstimateSupportedResource(resource resources.Resource) *estimation.Estimati

var computeResource resources.ComputeResource = resource.(resources.ComputeResource)
// Electric power used per unit of time
avgWatt := estimateWattHour(&computeResource) // Watt hour
if viper.Get("unit.power").(string) == "kW" {
avgWatt = avgWatt.Div(decimal.NewFromInt(1000))
}
if viper.Get("unit.time").(string) == "m" {
avgWatt = avgWatt.Mul(decimal.NewFromInt(24 * 30))
}
if viper.Get("unit.time").(string) == "y" {
avgWatt = avgWatt.Mul(decimal.NewFromInt(24 * 365))
}
avgWattStr := avgWatt.String()
// It's computed first in watt per hour
avgWattHour := estimateWattHour(&computeResource) // Watt hour
avgKWattHour := avgWattHour.Div(decimal.NewFromInt(1000))

// Regional grid emission per unit of time
// regionEmissions are in gCO2/kWh
regionEmissions, err := coefficients.RegionEmission(resource.GetIdentification().Provider, resource.GetIdentification().Region) // gCO2eq /kWh
if err != nil {
log.Fatalf("Error while getting region emissions for %v: %v", resource.GetAddress(), err)
}
if viper.Get("unit.power").(string) == "W" {
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Div(decimal.NewFromInt(1000))

// Carbon Emissions
carbonEmissionInGCO2PerH := avgKWattHour.Mul(regionEmissions.GridCarbonIntensity)
carbonEmissionPerTime := carbonEmissionInGCO2PerH
if strings.ToLower(viper.GetString("unit.time")) == "d" {
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24))
}
if viper.Get("unit.time").(string) == "m" {
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Mul(decimal.NewFromInt(24 * 30))
if strings.ToLower(viper.GetString("unit.time")) == "m" {
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24 * 30))
}
if viper.Get("unit.time").(string) == "y" {
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Mul(decimal.NewFromInt(24 * 365))
if strings.ToLower(viper.GetString("unit.time")) == "y" {
carbonEmissionPerTime = carbonEmissionPerTime.Mul(decimal.NewFromInt(24 * 365))
}
if viper.Get("unit.carbon").(string) == "kg" {
regionEmissions.GridCarbonIntensity = regionEmissions.GridCarbonIntensity.Div(decimal.NewFromInt(1000))
if strings.ToLower(viper.GetString("unit.carbon")) == "kg" {
carbonEmissionPerTime = carbonEmissionPerTime.Div(decimal.NewFromInt(1000))
}

// Carbon Emissions
carbonEmissionPerTime := avgWatt.Mul(regionEmissions.GridCarbonIntensity)
carbonEmissionPerTimeStr := carbonEmissionPerTime.String()

log.Debugf(
"estimating resource %v.%v (%v): %v %v%v * %v %vCO2/%v%v = %v %vCO2/%v%v * %v",
"estimating resource %v.%v (%v): %v %v%v * %v %vCO2/%v%v = %v %vCO2/%v%v * %v = %v %vCO2/%v%v * %v",
computeResource.Identification.ResourceType,
computeResource.Identification.Name,
regionEmissions.Region,
avgWattStr,
viper.Get("unit.power").(string),
viper.Get("unit.time").(string),
avgKWattHour.String(),
"kW",
"h",
regionEmissions.GridCarbonIntensity,
viper.Get("unit.carbon").(string),
viper.Get("unit.power").(string),
viper.Get("unit.time").(string),
"g",
"kW",
"h",
carbonEmissionInGCO2PerH,
"g",
"kW",
"h",
resource.GetIdentification().Count,
carbonEmissionPerTimeStr,
viper.Get("unit.carbon").(string),
viper.Get("unit.power").(string),
viper.Get("unit.time").(string),
viper.GetString("unit.carbon"),
viper.GetString("unit.power"),
viper.GetString("unit.time"),
resource.GetIdentification().Count,
)

Expand All @@ -77,7 +78,7 @@ func EstimateSupportedResource(resource resources.Resource) *estimation.Estimati

est := &estimation.EstimationResource{
Resource: &computeResource,
Power: avgWatt.RoundFloor(10),
Power: avgWattHour.RoundFloor(10),
CarbonEmissions: carbonEmissionPerTime.RoundFloor(10),
AverageCPUUsage: decimal.NewFromFloat(viper.GetFloat64("provider.gcp.avg_cpu_use")).RoundFloor(10),
TotalCount: decimal.NewFromInt(count * replicationFactor),
Expand Down
8 changes: 4 additions & 4 deletions internal/estimate/estimate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ func TestEstimateResourceKilo(t *testing.T) {
args: args{resourceGCPComputeBasic},
want: &estimation.EstimationResource{
Resource: &resourceGCPComputeBasic,
Power: decimal.NewFromFloat(5472.56448).RoundFloor(10),
CarbonEmissions: decimal.NewFromFloat(232.4745391104).RoundFloor(10),
Power: decimal.NewFromFloat(7.600784).RoundFloor(10),
CarbonEmissions: decimal.NewFromFloat(0.3228813043).RoundFloor(10),
AverageCPUUsage: decimal.NewFromFloat(avgCPUUse),
TotalCount: decimal.NewFromInt(1),
},
Expand All @@ -160,8 +160,8 @@ func TestEstimateResourceKilo(t *testing.T) {
args: args{resourceGCPComputeCPUType},
want: &estimation.EstimationResource{
Resource: &resourceGCPComputeCPUType,
Power: decimal.NewFromFloat(6880.7275733647).RoundFloor(10),
CarbonEmissions: decimal.NewFromFloat(292.2933073165).RoundFloor(10),
Power: decimal.NewFromFloat(9.5565660741).RoundFloor(10),
CarbonEmissions: decimal.NewFromFloat(0.4059629268).RoundFloor(10),
AverageCPUUsage: decimal.NewFromFloat(avgCPUUse),
TotalCount: decimal.NewFromInt(1),
},
Expand Down
12 changes: 12 additions & 0 deletions internal/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,23 @@ func CarboniferPlan(input string) (*map[string]interface{}, error) {
// If the path points to a file, run show
if !fileInfo.IsDir() {
parentDir := filepath.Dir(input)
// Add the .carbonifer folder in workdir
viper.AddConfigPath(filepath.Join(parentDir, ".carbonifer"))
fileName := filepath.Base(input)
viper.Set("workdir", parentDir)
tfPlan, err := terraformShow(fileName)
return tfPlan, err
} else {
viper.AddConfigPath(filepath.Join(input, ".carbonifer"))
}

// Refresh viper config
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
log.Panic(err)
}
}

// If the path points to a directory, run plan
viper.Set("workdir", input)
tfPlan, err := TerraformPlan()
Expand Down
2 changes: 2 additions & 0 deletions internal/utils/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func basePath() string {
return filepath.Join(d, "../..")
}

var WorkDir string

func initViper(configFilePath string) {
loadViperDefaults()

Expand Down
1 change: 1 addition & 0 deletions test/terraform/gcp_1/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
provider "google" {
region = "europe-west9"
project = "dummy-project"
}

1 change: 1 addition & 0 deletions test/terraform/gcp_cit/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
provider "google" {
region = "europe-west9"
project = "dummy-project"
}

4 changes: 4 additions & 0 deletions test/terraform/gcp_gke/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ variable "region" {
default = "europe-west9"
}

variable "project" {
default = "dummy-project"
}

variable "project_id" {
default = "cbf-terraform"
}
Expand Down
1 change: 1 addition & 0 deletions test/terraform/gcp_global_module/global.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
provider "google" {
region = local.common_region
project = "dummy-project"
}

locals {
Expand Down
1 change: 1 addition & 0 deletions test/terraform/gcp_group/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ resource "google_compute_instance_group_manager" "my-group-manager" {
resource "google_compute_autoscaler" "autoscaler" {
name = "my-autoscaler"
target = google_compute_instance_group_manager.my-group-manager.id
zone = "europe-west9-a"

autoscaling_policy {
max_replicas = 10
Expand Down
1 change: 1 addition & 0 deletions test/terraform/gcp_group/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
provider "google" {
region = "europe-west9"
project = "dummy-project"
}

1 change: 1 addition & 0 deletions test/terraform/gcp_images/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
provider "google" {
region = "europe-west9"
project = "dummy-project"
}

Binary file modified test/terraform/planRaw/plan.tfplan
Binary file not shown.
1 change: 1 addition & 0 deletions test/terraform/planRaw/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
provider "google" {
region = "europe-west9"
project = "dummy-project"
}

0 comments on commit 163a825

Please sign in to comment.