77 "context"
88 "errors"
99 "fmt"
10+ "strconv"
1011 "strings"
1112
1213 "golang.org/x/exp/slices"
@@ -15,10 +16,11 @@ import (
1516 "sigs.k8s.io/controller-runtime/pkg/log"
1617
1718 "github.com/kai-scheduler/KAI-scheduler/pkg/apis/scheduling/v1alpha2"
18- "github.com/kai-scheduler/KAI-scheduler/pkg/binder/common/gpusharingconfigmap"
19-
2019 "github.com/kai-scheduler/KAI-scheduler/pkg/binder/common"
20+ "github.com/kai-scheduler/KAI-scheduler/pkg/binder/common/gpusharingconfigmap"
2121 "github.com/kai-scheduler/KAI-scheduler/pkg/binder/plugins/state"
22+ "github.com/kai-scheduler/KAI-scheduler/pkg/common/constants"
23+ "github.com/kai-scheduler/KAI-scheduler/pkg/common/resources"
2224)
2325
2426const (
@@ -42,7 +44,7 @@ func (p *GPUSharing) Name() string {
4244}
4345
4446func (p * GPUSharing ) PreBind (
45- ctx context.Context , pod * v1.Pod , _ * v1.Node , bindRequest * v1alpha2.BindRequest , state * state.BindingState ,
47+ ctx context.Context , pod * v1.Pod , node * v1.Node , bindRequest * v1alpha2.BindRequest , state * state.BindingState ,
4648) error {
4749 if ! common .IsSharedGPUAllocation (bindRequest ) {
4850 return nil
@@ -60,6 +62,11 @@ func (p *GPUSharing) PreBind(
6062 return fmt .Errorf ("failed to get fraction container ref: %w" , err )
6163 }
6264
65+ err = addNvFractionsAnnotationIfMissing (pod , node , bindRequest , containerRef , state )
66+ if err != nil {
67+ return fmt .Errorf ("failed to add NvFractions annotation: %w" , err )
68+ }
69+
6370 err = p .createCapabilitiesConfigMapIfMissing (ctx , pod , containerRef )
6471 if err != nil {
6572 return fmt .Errorf ("failed to create capabilities configmap: %w" , err )
@@ -79,6 +86,44 @@ func (p *GPUSharing) PreBind(
7986 return common .SetGPUPortion (ctx , p .kubeClient , pod , containerRef , bindRequest .Spec .ReceivedGPU .Portion )
8087}
8188
89+ func addNvFractionsAnnotationIfMissing (pod * v1.Pod , node * v1.Node , bindRequest * v1alpha2.BindRequest ,
90+ containerRef * gpusharingconfigmap.PodContainerRef , bindingState * state.BindingState ) error {
91+ annotationKey := resources .CalcGpuFractionAnnotationForContainer (containerRef .Container .Name )
92+ if _ , found := pod .Annotations [annotationKey ]; found {
93+ return nil
94+ }
95+
96+ if node == nil || bindRequest == nil || bindRequest .Spec .ReceivedGPU == nil {
97+ return fmt .Errorf ("missing data for NvFractions annotation calculation" )
98+ }
99+
100+ gpuMemoryStr , foundGPUMemory := node .Labels [constants .NvidiaGpuMemory ]
101+ if ! foundGPUMemory {
102+ return fmt .Errorf ("node does not include %s label - failed to add NvFractions annotation" , constants .NvidiaGpuMemory )
103+ }
104+
105+ totalGPUMemoryMiB , err := strconv .ParseFloat (gpuMemoryStr , 64 )
106+ if err != nil || totalGPUMemoryMiB <= 0 {
107+ return fmt .Errorf ("invalid %s label value %q - failed to add NvFractions annotation" , constants .NvidiaGpuMemory , gpuMemoryStr )
108+ }
109+
110+ gpuPortion , err := strconv .ParseFloat (bindRequest .Spec .ReceivedGPU .Portion , 64 )
111+ if err != nil || gpuPortion <= 0 {
112+ return fmt .Errorf ("invalid received gpu portion %q - failed to add NvFractions annotation" , bindRequest .Spec .ReceivedGPU .Portion )
113+ }
114+
115+ gpuMemory := uint64 (totalGPUMemoryMiB * gpuPortion )
116+ if gpuMemory == 0 {
117+ return fmt .Errorf ("calculated gpu memory request is zero" )
118+ }
119+
120+ if bindingState .BindingPodAnnotations == nil {
121+ bindingState .BindingPodAnnotations = map [string ]string {}
122+ }
123+ bindingState .BindingPodAnnotations [annotationKey ] = resources .GpuMemoryAnnotationToNvFractionsMemoryRequest (gpuMemory ).String ()
124+ return nil
125+ }
126+
82127func (p * GPUSharing ) createCapabilitiesConfigMapIfMissing (ctx context.Context , pod * v1.Pod ,
83128 containerRef * gpusharingconfigmap.PodContainerRef ) error {
84129 capabilitiesConfigMapName , err := gpusharingconfigmap .ExtractCapabilitiesConfigMapName (pod , containerRef )
0 commit comments