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  }