@@ -34,16 +34,18 @@ type Interface interface {
3434 Sync (ctx context.Context ) error
3535 SyncForNode (ctx context.Context , nodeName string ) error
3636 SyncForGpuGroup (ctx context.Context , gpuGroup string ) error
37- ReserveGpuDevice (ctx context.Context , pod * v1.Pod , nodeName string , gpuGroup string ) (string , error )
37+ ReserveGpuDevice (
38+ ctx context.Context , pod * v1.Pod , nodeName string ,
39+ fractionalGpuGroup schedulingv1alpha2.FractionalGpuGroup ,
40+ ) (string , error )
3841 RemovePodGpuGroupsConnection (ctx context.Context , pod * v1.Pod ) error
3942}
4043
4144const (
42- resourceReservation = "resource-reservation"
43- gpuReservationPodPrefix = "gpu-reservation"
44- gpuIndexAnnotationName = "run.ai/reserve_for_gpu_index"
45- numberOfGPUsToReserve = 1
46- unknownGpuIndicator = "-1"
45+ resourceReservation = "resource-reservation"
46+ gpuIndexAnnotationName = "run.ai/reserve_for_gpu_index"
47+ numberOfGPUsToReserve = 1
48+ unknownGpuIndicator = "-1"
4749)
4850
4951type service struct {
@@ -240,19 +242,23 @@ func (rsc *service) hasActiveBindRequestsForGpuGroup(ctx context.Context, gpuGro
240242 br .Status .Phase == schedulingv1alpha2 .BindRequestPhaseFailed {
241243 continue
242244 }
243- if slices .Contains (br .Spec .SelectedGPUGroups , gpuGroup ) {
245+ if slices .Contains (br .Spec .SelectedFractionalGpuGroupIDs () , gpuGroup ) {
244246 return true , nil
245247 }
246248 }
247249 return false , nil
248250}
249- func (rsc * service ) ReserveGpuDevice (ctx context.Context , pod * v1.Pod , nodeName string , gpuGroup string ) (string , error ) {
251+ func (rsc * service ) ReserveGpuDevice (
252+ ctx context.Context , pod * v1.Pod , nodeName string , fractionalGpuGroup schedulingv1alpha2.FractionalGpuGroup ,
253+ ) (string , error ) {
250254 logger := log .FromContext (ctx )
255+ fractionalGpuGroup = fractionalGpuGroup .WithDefaults ()
256+ gpuGroup := fractionalGpuGroup .ID
251257
252258 rsc .gpuGroupMutex .LockMutexForGroup (gpuGroup )
253259 defer rsc .gpuGroupMutex .ReleaseMutex (gpuGroup )
254260
255- gpuIndex , err := rsc .acquireGPUIndexByGroup (ctx , pod , nodeName , gpuGroup )
261+ gpuIndex , err := rsc .acquireGPUIndexByGroup (ctx , nodeName , fractionalGpuGroup )
256262 if err != nil {
257263 return unknownGpuIndicator , err
258264 }
@@ -333,16 +339,16 @@ func escapeJSONPointer(s string) string {
333339}
334340
335341func (rsc * service ) acquireGPUIndexByGroup (
336- ctx context.Context , sourcePod * v1. Pod , nodeName , gpuGroup string ,
342+ ctx context.Context , nodeName string , fractionalGpuGroup schedulingv1alpha2. FractionalGpuGroup ,
337343) (string , error ) {
338- gpuIndex , err := rsc .findGPUIndexByGroup (gpuGroup )
344+ gpuIndex , err := rsc .findGPUIndexByGroup (fractionalGpuGroup . ID )
339345 if err != nil {
340346 return "" , err
341347 }
342348 if gpuIndex != "" {
343349 return gpuIndex , err
344350 }
345- return rsc .createGPUReservationPodAndGetIndex (ctx , sourcePod , nodeName , gpuGroup )
351+ return rsc .createGPUReservationPodAndGetIndex (ctx , nodeName , fractionalGpuGroup )
346352}
347353
348354func (rsc * service ) findGPUIndexByGroup (gpuGroup string ) (
@@ -369,11 +375,11 @@ func (rsc *service) findGPUIndexByGroup(gpuGroup string) (
369375}
370376
371377func (rsc * service ) createGPUReservationPodAndGetIndex (
372- ctx context.Context , sourcePod * v1. Pod , nodeName , gpuGroup string ,
378+ ctx context.Context , nodeName string , fractionalGpuGroup schedulingv1alpha2. FractionalGpuGroup ,
373379) (
374380 gpuIndex string , err error ) {
375381 logger := log .FromContext (ctx )
376- pod , err := rsc .createGPUReservationPod (ctx , sourcePod , nodeName , gpuGroup )
382+ pod , err := rsc .createGPUReservationPod (ctx , nodeName , fractionalGpuGroup )
377383 if err != nil {
378384 return unknownGpuIndicator , err
379385 }
@@ -426,14 +432,14 @@ func (rsc *service) deleteReservationPod(ctx context.Context, pod *v1.Pod) error
426432}
427433
428434func (rsc * service ) createGPUReservationPod (
429- ctx context.Context , sourcePod * v1. Pod , nodeName , gpuGroup string ,
435+ ctx context.Context , nodeName string , fractionalGpuGroup schedulingv1alpha2. FractionalGpuGroup ,
430436) (* v1.Pod , error ) {
431437 logger := log .FromContext (ctx )
432438 if rsc .isScalingUp (ctx ) {
433439 return nil , fmt .Errorf ("cluster is scaling up, could not create reservation pod" )
434440 }
435441
436- podName := reservationPodName (nodeName , gpuGroup )
442+ podName := reservationPodName (nodeName , fractionalGpuGroup . ID )
437443
438444 // Build resource requirements starting with GPU resources
439445 resources := v1.ResourceRequirements {
@@ -456,15 +462,15 @@ func (rsc *service) createGPUReservationPod(
456462 }
457463 }
458464
459- pod , err := rsc .createResourceReservationPod (sourcePod , nodeName , gpuGroup , podName , resources )
465+ pod , err := rsc .createResourceReservationPod (nodeName , fractionalGpuGroup , podName , resources )
460466 if err != nil {
461467 // The reservation pod name is deterministic per (node, gpu-group). AlreadyExists
462468 // means another actor (a concurrent bind, a retry, or another binder replica)
463469 // already created the reservation pod for this gpu-group, so reuse it rather than
464470 // creating a duplicate on a different physical GPU.
465471 if apierrors .IsAlreadyExists (err ) {
466472 logger .Info ("GPU reservation pod already exists for gpu group, reusing" ,
467- "nodeName" , nodeName , "namespace" , rsc .namespace , "name" , podName , "gpuGroup" , gpuGroup )
473+ "nodeName" , nodeName , "namespace" , rsc .namespace , "name" , podName , "gpuGroup" , fractionalGpuGroup . ID )
468474 return pod , nil
469475 }
470476 logger .Error (err , "Failed to create GPU reservation pod on node" ,
@@ -531,29 +537,25 @@ func (rsc *service) waitForGPUReservationPodAllocation(
531537}
532538
533539func (rsc * service ) createResourceReservationPod (
534- sourcePod * v1.Pod , nodeName , gpuGroup , podName string , resources v1.ResourceRequirements ,
540+ nodeName string , fractionalGpuGroup schedulingv1alpha2.FractionalGpuGroup ,
541+ podName string , resources v1.ResourceRequirements ,
535542) (* v1.Pod , error ) {
536- var tolerations []v1.Toleration
537- if sourcePod != nil {
538- sourcePodSpec := sourcePod .Spec .DeepCopy ()
539- tolerations = sourcePodSpec .Tolerations
540- }
541-
543+ fractionalGpuGroup = fractionalGpuGroup .WithDefaults ()
542544 podSpec := & v1.Pod {
543545 ObjectMeta : metav1.ObjectMeta {
544546 Name : podName ,
545547 Namespace : rsc .namespace ,
546548 Labels : map [string ]string {
547549 constants .AppLabelName : rsc .appLabelValue ,
548- constants .GPUGroup : gpuGroup ,
550+ constants .GPUGroup : fractionalGpuGroup . ID ,
549551 },
550552 Annotations : map [string ]string {
551553 karpenterv1 .DoNotDisruptAnnotationKey : "true" ,
554+ constants .GpuComputeSharingMode : string (fractionalGpuGroup .ComputeSharingMode ),
552555 },
553556 },
554557 Spec : v1.PodSpec {
555- NodeName : nodeName ,
556- Tolerations : tolerations ,
558+ NodeName : nodeName ,
557559 RuntimeClassName : func () * string {
558560 if len (rsc .runtimeClassName ) == 0 {
559561 return nil
@@ -633,7 +635,7 @@ func (rsc *service) isScalingUp(ctx context.Context) bool {
633635}
634636
635637func IsGPUReservationPod (pod * v1.Pod ) bool {
636- return strings .HasPrefix (pod .Name , gpuReservationPodPrefix )
638+ return strings .HasPrefix (pod .Name , constants . GPUReservationPodPrefix )
637639}
638640
639641// reservationPodName derives a deterministic reservation pod name from the node and
@@ -642,5 +644,5 @@ func IsGPUReservationPod(pod *v1.Pod) bool {
642644// pods on different physical GPUs.
643645func reservationPodName (nodeName , gpuGroup string ) string {
644646 hash := sha256 .Sum256 ([]byte (nodeName + "/" + gpuGroup ))
645- return fmt .Sprintf ("%s-%s" , gpuReservationPodPrefix , hex .EncodeToString (hash [:8 ]))
647+ return fmt .Sprintf ("%s-%s" , constants . GPUReservationPodPrefix , hex .EncodeToString (hash [:8 ]))
646648}
0 commit comments