volcano.sh/volcano@v1.9.0/pkg/scheduler/plugins/numaaware/policy/factory.go (about)

     1  /*
     2  Copyright 2021 The Volcano 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 policy
    18  
    19  import (
    20  	v1 "k8s.io/api/core/v1"
    21  	"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
    22  	"k8s.io/utils/cpuset"
    23  
    24  	batch "volcano.sh/apis/pkg/apis/batch/v1alpha1"
    25  	nodeinfov1alpha1 "volcano.sh/apis/pkg/apis/nodeinfo/v1alpha1"
    26  
    27  	"volcano.sh/volcano/pkg/scheduler/api"
    28  )
    29  
    30  // TopologyHint is a struct containing the NUMANodeAffinity for a Container
    31  type TopologyHint struct {
    32  	NUMANodeAffinity bitmask.BitMask
    33  	// Preferred is set to true when the NUMANodeAffinity encodes a preferred
    34  	// allocation for the Container. It is set to false otherwise.
    35  	Preferred bool
    36  }
    37  
    38  // Policy is an interface for topology manager policy
    39  type Policy interface {
    40  	// Predicate Get the best hit.
    41  	Predicate(providersHints []map[string][]TopologyHint) (TopologyHint, bool)
    42  }
    43  
    44  // HintProvider is an interface for components that want to collaborate to
    45  // achieve globally optimal concrete resource alignment with respect to
    46  // NUMA locality.
    47  type HintProvider interface {
    48  	// Name returns provider name used for register and logging.
    49  	Name() string
    50  	// GetTopologyHints returns hints if this hint provider has a preference,
    51  	GetTopologyHints(container *v1.Container, topoInfo *api.NumatopoInfo, resNumaSets api.ResNumaSets) map[string][]TopologyHint
    52  	Allocate(container *v1.Container, bestHit *TopologyHint, topoInfo *api.NumatopoInfo, resNumaSets api.ResNumaSets) map[string]cpuset.CPUSet
    53  }
    54  
    55  // GetPolicy return the interface matched the input task topology config
    56  func GetPolicy(node *api.NodeInfo, numaNodes []int) Policy {
    57  	switch batch.NumaPolicy(node.NumaSchedulerInfo.Policies[nodeinfov1alpha1.TopologyManagerPolicy]) {
    58  	case batch.None:
    59  		return NewPolicyNone(numaNodes)
    60  	case batch.BestEffort:
    61  		return NewPolicyBestEffort(numaNodes)
    62  	case batch.Restricted:
    63  		return NewPolicyRestricted(numaNodes)
    64  	case batch.SingleNumaNode:
    65  		return NewPolicySingleNumaNode(numaNodes)
    66  	}
    67  
    68  	return &policyNone{}
    69  }
    70  
    71  // AccumulateProvidersHints return all TopologyHint collection from different providers
    72  func AccumulateProvidersHints(container *v1.Container,
    73  	topoInfo *api.NumatopoInfo, resNumaSets api.ResNumaSets,
    74  	hintProviders []HintProvider) (providersHints []map[string][]TopologyHint) {
    75  	for _, provider := range hintProviders {
    76  		hints := provider.GetTopologyHints(container, topoInfo, resNumaSets)
    77  		providersHints = append(providersHints, hints)
    78  	}
    79  
    80  	return providersHints
    81  }
    82  
    83  // Allocate return all resource assignment collection from different providers
    84  func Allocate(container *v1.Container, bestHit *TopologyHint,
    85  	topoInfo *api.NumatopoInfo, resNumaSets api.ResNumaSets, hintProviders []HintProvider) map[string]cpuset.CPUSet {
    86  	allResAlloc := make(map[string]cpuset.CPUSet)
    87  	for _, provider := range hintProviders {
    88  		resAlloc := provider.Allocate(container, bestHit, topoInfo, resNumaSets)
    89  		for resName, assign := range resAlloc {
    90  			allResAlloc[resName] = assign
    91  		}
    92  	}
    93  
    94  	return allResAlloc
    95  }