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
}