volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/util/util.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package util 18 19 import ( 20 "strings" 21 22 v1 "k8s.io/api/core/v1" 23 v1helper "k8s.io/kubernetes/pkg/scheduler/util" 24 25 "volcano.sh/volcano/pkg/scheduler/api" 26 ) 27 28 const ( 29 // Permit indicates that plugin callback function permits job to be inqueue, pipelined, or other status 30 Permit = 1 31 // Abstain indicates that plugin callback function abstains in voting job to be inqueue, pipelined, or other status 32 Abstain = 0 33 // Reject indicates that plugin callback function rejects job to be inqueue, pipelined, or other status 34 Reject = -1 35 ) 36 37 // NormalizeScore normalizes the score for each filteredNode 38 func NormalizeScore(maxPriority int64, reverse bool, scores []api.ScoredNode) { 39 var maxCount int64 40 for _, scoreNode := range scores { 41 if scoreNode.Score > maxCount { 42 maxCount = scoreNode.Score 43 } 44 } 45 46 if maxCount == 0 { 47 if reverse { 48 for idx := range scores { 49 scores[idx].Score = maxPriority 50 } 51 } 52 return 53 } 54 55 for idx, scoreNode := range scores { 56 score := maxPriority * scoreNode.Score / maxCount 57 if reverse { 58 score = maxPriority - score 59 } 60 61 scores[idx].Score = score 62 } 63 } 64 65 // GetAllocatedResource returns allocated resource for given job 66 func GetAllocatedResource(job *api.JobInfo) *api.Resource { 67 allocated := &api.Resource{} 68 for status, tasks := range job.TaskStatusIndex { 69 if api.AllocatedStatus(status) { 70 for _, t := range tasks { 71 allocated.Add(t.Resreq) 72 } 73 } 74 } 75 return allocated 76 } 77 78 // CalculateAllocatedTaskNum returns allocated resource num for given job 79 func CalculateAllocatedTaskNum(job *api.JobInfo) int { 80 allocatedNum := 0 81 for status, tasks := range job.TaskStatusIndex { 82 if api.AllocatedStatus(status) { 83 allocatedNum += len(tasks) 84 } 85 } 86 return allocatedNum 87 } 88 89 // GetInqueueResource returns reserved resource for running job whose part of pods have not been allocated resource. 90 func GetInqueueResource(job *api.JobInfo, allocated *api.Resource) *api.Resource { 91 inqueue := &api.Resource{} 92 for rName, rQuantity := range *job.PodGroup.Spec.MinResources { 93 switch rName { 94 case v1.ResourceCPU: 95 reservedCPU := float64(rQuantity.MilliValue()) - allocated.MilliCPU 96 if reservedCPU > 0 { 97 inqueue.MilliCPU = reservedCPU 98 } 99 case v1.ResourceMemory: 100 reservedMemory := float64(rQuantity.Value()) - allocated.Memory 101 if reservedMemory > 0 { 102 inqueue.Memory = reservedMemory 103 } 104 default: 105 if api.IsCountQuota(rName) || !v1helper.IsScalarResourceName(rName) { 106 continue 107 } 108 ignore := false 109 api.IgnoredDevicesList.Range(func(_ int, ignoredDevice string) bool { 110 if len(ignoredDevice) > 0 && strings.Contains(rName.String(), ignoredDevice) { 111 ignore = true 112 return false 113 } 114 return true 115 }) 116 if ignore { 117 continue 118 } 119 if inqueue.ScalarResources == nil { 120 inqueue.ScalarResources = make(map[v1.ResourceName]float64) 121 } 122 if allocatedMount, ok := allocated.ScalarResources[rName]; !ok { 123 inqueue.ScalarResources[rName] = float64(rQuantity.Value()) 124 } else { 125 reservedScalarRes := float64(rQuantity.Value()) - allocatedMount 126 if reservedScalarRes > 0 { 127 inqueue.ScalarResources[rName] = reservedScalarRes 128 } 129 } 130 } 131 } 132 return inqueue 133 }