func()

in calculator/calculator.go [366:510]


func (service *PricingService) DecideComputeClass(workloadName string, machineType string, mCPU int64, memory int64, gpu int64, gpuModel string, arm64 bool) cluster.ComputeClass {
	ratio := math.Ceil(float64(memory) / float64(mCPU))

	ratioRegularMin, _ := service.Config.Section("ratios").Key("generalpurpose_min").Float64()
	ratioRegularMax, _ := service.Config.Section("ratios").Key("generalpurpose_max").Float64()
	ratioBalancedMin, _ := service.Config.Section("ratios").Key("balanced_min").Float64()
	ratioBalancedMax, _ := service.Config.Section("ratios").Key("balanced_max").Float64()
	ratioScaleoutMin, _ := service.Config.Section("ratios").Key("scaleout_min").Float64()
	ratioScaleoutMax, _ := service.Config.Section("ratios").Key("scaleout_max").Float64()
	ratioPerformanceMin, _ := service.Config.Section("ratios").Key("performance_min").Float64()
	ratioPerformanceMax, _ := service.Config.Section("ratios").Key("performance_max").Float64()

	scaleoutMcpuMax, _ := service.Config.Section("limits").Key("scaleout_mcpu_max").Int64()
	scaleoutMemoryMax, _ := service.Config.Section("limits").Key("scaleout_memory_max").Int64()
	scaleoutArmMcpuMax, _ := service.Config.Section("limits").Key("scaleout_arm_mcpu_max").Int64()
	scaleoutArmMemoryMax, _ := service.Config.Section("limits").Key("scaleout_arm_memory_max").Int64()
	regularMcpuMax, _ := service.Config.Section("limits").Key("generalpurpose_mcpu_max").Int64()
	regularMemoryMax, _ := service.Config.Section("limits").Key("generalpurpose_memory_max").Int64()
	balancedMcpuMax, _ := service.Config.Section("limits").Key("balanced_mcpu_max").Int64()
	balancedMemoryMax, _ := service.Config.Section("limits").Key("balanced_mcpu_max").Int64()
	performanceMcpuMax, _ := service.Config.Section("limits").Key("performance_mcpu_max").Int64()
	performanceMemoryMax, _ := service.Config.Section("limits").Key("performance_memory_max").Int64()

	gpupodT4McpuMin, _ := service.Config.Section("limits").Key("gpupod_t4_mcpu_min").Int64()
	gpupodT4McpuMax, _ := service.Config.Section("limits").Key("gpupod_t4_mcpu_max").Int64()
	gpupodT4MemoryMin, _ := service.Config.Section("limits").Key("gpupod_t4_memory_min").Int64()
	gpupodT4MemoryMax, _ := service.Config.Section("limits").Key("gpupod_t4_memory_max").Int64()

	gpupodL4McpuMin, _ := service.Config.Section("limits").Key("gpupod_l4_mcpu_min").Int64()
	gpupodL4McpuMax, _ := service.Config.Section("limits").Key("gpupod_l4_mcpu_max").Int64()
	gpupodL4MemoryMin, _ := service.Config.Section("limits").Key("gpupod_l4_memory_min").Int64()
	gpupodL4MemoryMax, _ := service.Config.Section("limits").Key("gpupod_l4_memory_max").Int64()

	gpupodA10040McpuMin, _ := service.Config.Section("limits").Key("gpupod_a100_40_mcpu_min").Int64()
	gpupodA10040McpuMax, _ := service.Config.Section("limits").Key("gpupod_a100_40_mcpu_max").Int64()
	gpupodA10040MemoryMin, _ := service.Config.Section("limits").Key("gpupod_a100_40_memory_min").Int64()
	gpupodA10040MemoryMax, _ := service.Config.Section("limits").Key("gpupod_a100_40_memory_max").Int64()

	gpupodA10080McpuMin, _ := service.Config.Section("limits").Key("gpupod_a100_80_mcpu_min").Int64()
	gpupodA10080McpuMax, _ := service.Config.Section("limits").Key("gpupod_a100_80_mcpu_max").Int64()
	gpupodA10080MemoryMin, _ := service.Config.Section("limits").Key("gpupod_a100_80_memory_min").Int64()
	gpupodA10080MemoryMax, _ := service.Config.Section("limits").Key("gpupod_a100_80_memory_max").Int64()

	accelerator_mcpu_min, _ := service.Config.Section("limits").Key("accelerator_mcpu_min").Int64()
	accelerator_memory_min, _ := service.Config.Section("limits").Key("accelerator_memory_min").Int64()
	accelerator_h100_80_mcpu_max, _ := service.Config.Section("limits").Key("accelerator_h100_80_mcpu_max").Int64()
	accelerator_h100_80_memory_max, _ := service.Config.Section("limits").Key("accelerator_h100_80_memory_max").Int64()

	computeOptimizedMachineTypes := strings.Split(service.Config.Section("").Key("gce_compute_optimized_prefixed").String(), ",")
	for _, computeOptimizedMachineType := range computeOptimizedMachineTypes {
		if strings.Contains(machineType, computeOptimizedMachineType) {
			return cluster.ComputeClassPerformance
		}
	}

	// check if GPU is H100, then return ComputeClassAccelerator since it's the only one supporting these GPUs
	if gpuModel == service.Config.Section("").Key("nvidia_h100_identifier").String() {
		if ratio < ratioPerformanceMin || ratio > ratioPerformanceMax || mCPU > performanceMcpuMax || memory > performanceMemoryMax {
			log.Printf("Requested memory or CPU out of acceptable range for Performance compute class (%s) workload (%s).\n", machineType, workloadName)
		}

		return cluster.ComputeClassPerformance
	}

	acceleratorOptimizedMachineTypes := strings.Split(service.Config.Section("").Key("gce_accelerator_optimized_prefixed").String(), ",")
	for _, acceleratorOptimizedMachineType := range acceleratorOptimizedMachineTypes {
		if strings.Contains(machineType, acceleratorOptimizedMachineType) {
			switch gpuModel {
			case "nvidia-tesla-t4":
				if mCPU > gpupodT4McpuMax || mCPU < accelerator_mcpu_min || memory > gpupodT4MemoryMax || memory < accelerator_memory_min {
					log.Printf("Requested memory or CPU out of acceptable range for %s Accelerator compute class (%s) workload (%s).\n", machineType, gpuModel, workloadName)
				}
			case "nvidia-l4":
				if mCPU > gpupodL4McpuMax || mCPU < accelerator_mcpu_min || memory > gpupodL4MemoryMax || memory < accelerator_memory_min {
					log.Printf("Requested memory or CPU out of acceptable range for %s Accelerator compute class (%s) workload (%s).\n", machineType, gpuModel, workloadName)
				}
			case "nvidia-tesla-a100":
				if mCPU > gpupodA10040McpuMax || mCPU < accelerator_mcpu_min || memory > gpupodA10040MemoryMax || memory < accelerator_memory_min {
					log.Printf("Requested memory or CPU out of acceptable range for %s Accelerator compute class (%s) workload (%s).\n", machineType, gpuModel, workloadName)
				}
			case "nvidia-a100-80gb":
				if mCPU > gpupodA10080McpuMax || mCPU < accelerator_mcpu_min || memory > gpupodA10080MemoryMax || memory < accelerator_memory_min {
					log.Printf("Requested memory or CPU out of acceptable range for %s Accelerator compute class (%s) workload (%s).\n", machineType, gpuModel, workloadName)
				}
			case "nvidia-h100-80gb":
				if mCPU > accelerator_h100_80_mcpu_max || mCPU < accelerator_mcpu_min || memory > accelerator_h100_80_memory_max || memory < accelerator_memory_min {
					log.Printf("Requested memory or CPU out of acceptable range for %s Accelerator compute class (%s) workload (%s).\n", machineType, gpuModel, workloadName)
				}
			}

			return cluster.ComputeClassAccelerator
		}
	}

	// Ok, not an accelerator based workload nor is H100, so we can get a regular GPU Pod type
	if gpu > 0 {
		switch gpuModel {
		case "nvidia-tesla-t4":
			if mCPU > gpupodT4McpuMax || mCPU < gpupodT4McpuMin || memory > gpupodT4MemoryMax || memory < gpupodT4MemoryMin {
				log.Printf("Requested memory or CPU out of acceptable range for %s GPU workload (%s).\n", gpuModel, workloadName)
			}
		case "nvidia-l4":
			if mCPU > gpupodL4McpuMax || mCPU < gpupodL4McpuMin || memory > gpupodL4MemoryMax || memory < gpupodL4MemoryMin {
				log.Printf("Requested memory or CPU out of acceptable range for %s GPU workload (%s).\n", gpuModel, workloadName)
			}
		case "nvidia-tesla-a100":
			if mCPU > gpupodA10040McpuMax || mCPU < gpupodA10040McpuMin || memory > gpupodA10040MemoryMax || memory < gpupodA10040MemoryMin {
				log.Printf("Requested memory or CPU out of acceptable range for %s GPU workload (%s).\n", gpuModel, workloadName)
			}
		case "nvidia-a100-80gb":
			if mCPU > gpupodA10080McpuMax || mCPU < gpupodA10080McpuMin || memory > gpupodA10080MemoryMax || memory < gpupodA10080MemoryMin {
				log.Printf("Requested memory or CPU out of acceptable range for %s GPU workload (%s).\n", gpuModel, workloadName)
			}
		}
		return cluster.ComputeClassGPUPod
	}

	// ARM64 is still experimental
	if arm64 {
		if ratio < ratioScaleoutMin || ratio > ratioScaleoutMax || mCPU > scaleoutArmMcpuMax || memory > scaleoutArmMemoryMax {
			log.Printf("Requesting arm64 but requested mCPU () or memory or ratio are out of accepted range(%s).\n", workloadName)
		}

		return cluster.ComputeClassScaleoutArm
	}

	// For T2a machines, default to scale-out compute class, since it's the only one supporting it
	if ratio >= ratioRegularMin && ratio <= ratioRegularMax && mCPU <= regularMcpuMax && memory <= regularMemoryMax {
		return cluster.ComputeClassGeneralPurpose
	}

	// If we are out of Regular range, suggest Scale-Out
	if ratio >= ratioScaleoutMin && ratio <= ratioScaleoutMax && mCPU <= scaleoutMcpuMax && memory <= scaleoutMemoryMax {
		return cluster.ComputeClassScaleout
	}

	// If usage is more than general-purpose limits, default to balanced
	if ratio >= ratioBalancedMin && ratio <= ratioBalancedMax && mCPU <= balancedMcpuMax && memory <= balancedMemoryMax {
		return cluster.ComputeClassBalanced
	}

	log.Printf("Couldn't find a matching compute class for %s. Defaulting to 'General-purpose'. Please check the pricing manually.\n", workloadName)

	return cluster.ComputeClassGeneralPurpose
}