From 29c02d42e60abcd3953e403265d7af9ada285974 Mon Sep 17 00:00:00 2001 From: davidLif Date: Mon, 10 Aug 2026 11:20:35 +0300 Subject: [PATCH 1/2] feat(api): add fractional GPU group type Signed-off-by: davidLif --- .../unreleased/added-20260810-112001.yaml | 3 + .../crds/scheduling.run.ai_bindrequests.yaml | 12 ++++ .../scheduling/v1alpha2/bindrequest_types.go | 69 +++++++++++++++++++ .../v1alpha2/zz_generated.deepcopy.go | 19 +++++ pkg/common/constants/constants.go | 2 + 5 files changed, 105 insertions(+) create mode 100644 .changes/unreleased/added-20260810-112001.yaml diff --git a/.changes/unreleased/added-20260810-112001.yaml b/.changes/unreleased/added-20260810-112001.yaml new file mode 100644 index 000000000..6115ca502 --- /dev/null +++ b/.changes/unreleased/added-20260810-112001.yaml @@ -0,0 +1,3 @@ +kind: Added +body: |- + Add typed fractional GPU group API diff --git a/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml b/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml index c53df351a..816f43208 100644 --- a/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml +++ b/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml @@ -1329,6 +1329,18 @@ spec: type: string type: object type: array + selectedFractionalGpuGroups: + description: |- + SelectedFractionalGpuGroups is the selected GPU groups for fractional GPU resources. + Only if the RecievedResourceType is "Fraction" + items: + properties: + computeSharingMode: + type: string + id: + type: string + type: object + type: array selectedGPUGroups: description: |- SelectedGPUGroups is the name of the selected GPU groups for fractional GPU resources. diff --git a/pkg/apis/scheduling/v1alpha2/bindrequest_types.go b/pkg/apis/scheduling/v1alpha2/bindrequest_types.go index 1b7a2012a..830a19c8f 100644 --- a/pkg/apis/scheduling/v1alpha2/bindrequest_types.go +++ b/pkg/apis/scheduling/v1alpha2/bindrequest_types.go @@ -25,8 +25,13 @@ type BindRequestSpec struct { // SelectedGPUGroups is the name of the selected GPU groups for fractional GPU resources. // Only if the RecievedResourceType is "Fraction" + // Deprecated: Use SelectedFractionalGpuGroups instead SelectedGPUGroups []string `json:"selectedGPUGroups,omitempty"` + // SelectedFractionalGpuGroups is the selected GPU groups for fractional GPU resources. + // Only if the RecievedResourceType is "Fraction" + SelectedFractionalGpuGroups []FractionalGpuGroup `json:"selectedFractionalGpuGroups,omitempty"` + // ResourceClaims is the list of resource claims that need to be bound for this pod ResourceClaimAllocations []ResourceClaimAllocation `json:"resourceClaimAllocations,omitempty"` @@ -42,6 +47,70 @@ type BindRequestSpec struct { BackoffLimit *int32 `json:"backoffLimit,omitempty"` } +type GPUComputeSharingMode string + +const ( + GPUComputeSharingModeTimeSlicing GPUComputeSharingMode = "time-slicing" + GPUComputeSharingModeSMSharing GPUComputeSharingMode = "sm-sharing" +) + +type FractionalGpuGroup struct { + ID string `json:"id,omitempty"` + ComputeSharingMode GPUComputeSharingMode `json:"computeSharingMode,omitempty"` +} + +func (group FractionalGpuGroup) WithDefaults() FractionalGpuGroup { + if group.ComputeSharingMode == "" { + group.ComputeSharingMode = GPUComputeSharingModeTimeSlicing + } + return group +} + +func NewFractionalGpuGroups(gpuGroups []string, mode GPUComputeSharingMode) []FractionalGpuGroup { + if len(gpuGroups) == 0 { + return nil + } + mode = DefaultGPUComputeSharingMode(mode) + fractionalGpuGroups := make([]FractionalGpuGroup, 0, len(gpuGroups)) + for _, gpuGroup := range gpuGroups { + fractionalGpuGroups = append(fractionalGpuGroups, FractionalGpuGroup{ + ID: gpuGroup, + ComputeSharingMode: mode, + }) + } + return fractionalGpuGroups +} + +func DefaultGPUComputeSharingMode(mode GPUComputeSharingMode) GPUComputeSharingMode { + if mode == "" { + return GPUComputeSharingModeTimeSlicing + } + return mode +} + +func (spec *BindRequestSpec) SelectedFractionalGpuGroupsOrDefault() []FractionalGpuGroup { + if len(spec.SelectedFractionalGpuGroups) > 0 { + fractionalGpuGroups := make([]FractionalGpuGroup, 0, len(spec.SelectedFractionalGpuGroups)) + for _, fractionalGpuGroup := range spec.SelectedFractionalGpuGroups { + fractionalGpuGroups = append(fractionalGpuGroups, fractionalGpuGroup.WithDefaults()) + } + return fractionalGpuGroups + } + return NewFractionalGpuGroups(spec.SelectedGPUGroups, GPUComputeSharingModeTimeSlicing) +} + +func (spec *BindRequestSpec) SelectedFractionalGpuGroupIDs() []string { + fractionalGpuGroups := spec.SelectedFractionalGpuGroupsOrDefault() + if len(fractionalGpuGroups) == 0 { + return nil + } + gpuGroups := make([]string, 0, len(fractionalGpuGroups)) + for _, fractionalGpuGroup := range fractionalGpuGroups { + gpuGroups = append(gpuGroups, fractionalGpuGroup.ID) + } + return gpuGroups +} + type ReceivedGPU struct { // Count is the amount of GPUs devices that were received Count int `json:"count,omitempty"` diff --git a/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go index a6e74d272..22a4cf20e 100644 --- a/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go @@ -87,6 +87,11 @@ func (in *BindRequestSpec) DeepCopyInto(out *BindRequestSpec) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.SelectedFractionalGpuGroups != nil { + in, out := &in.SelectedFractionalGpuGroups, &out.SelectedFractionalGpuGroups + *out = make([]FractionalGpuGroup, len(*in)) + copy(*out, *in) + } if in.ResourceClaimAllocations != nil { in, out := &in.ResourceClaimAllocations, &out.ResourceClaimAllocations *out = make([]ResourceClaimAllocation, len(*in)) @@ -138,6 +143,20 @@ func (in *BindRequestStatus) DeepCopy() *BindRequestStatus { return out } +func (in *FractionalGpuGroup) DeepCopyInto(out *FractionalGpuGroup) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FractionalGpuGroup. +func (in *FractionalGpuGroup) DeepCopy() *FractionalGpuGroup { + if in == nil { + return nil + } + out := new(FractionalGpuGroup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtendedResourceClaimAllocation) DeepCopyInto(out *ExtendedResourceClaimAllocation) { *out = *in diff --git a/pkg/common/constants/constants.go b/pkg/common/constants/constants.go index d0c6a3119..0b33bf2b7 100644 --- a/pkg/common/constants/constants.go +++ b/pkg/common/constants/constants.go @@ -21,6 +21,7 @@ const ( DefaultSchedulerName = "kai-scheduler" DefaultKAINamespace = "kai-scheduler" DefaultResourceReservationName = "kai-resource-reservation" + GPUReservationPodPrefix = "gpu-reservation" DefaultScaleAdjustName = "kai-scale-adjust" DefaultKAIConfigSingeltonInstanceName = "kai-config" DefaultNodePoolLabelKey = "kai.scheduler/node-pool" @@ -55,6 +56,7 @@ const ( SkipPodGrouperAnnotation = "kai.scheduler/skip-podgrouper" GpuFraction = "gpu-fraction" GpuFractionContainerName = "gpu-fraction-container-name" + GpuComputeSharingMode = "kai.scheduler/gpu-compute-sharing-mode" GpuMemory = "gpu-memory" ReceivedResourceType = "received-resource-type" GpuFractionsNumDevices = "gpu-fraction-num-devices" From 6198be6d9c09cccd8982c1b93585dc70cb6bdbb5 Mon Sep 17 00:00:00 2001 From: davidLif Date: Wed, 12 Aug 2026 01:13:02 +0300 Subject: [PATCH 2/2] Update crd yaml Signed-off-by: davidLif --- .../crds/scheduling.run.ai_bindrequests.yaml | 1 + .../v1alpha2/zz_generated.deepcopy.go | 29 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml b/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml index 816f43208..3a81722e0 100644 --- a/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml +++ b/deployments/kai-scheduler/crds/scheduling.run.ai_bindrequests.yaml @@ -1345,6 +1345,7 @@ spec: description: |- SelectedGPUGroups is the name of the selected GPU groups for fractional GPU resources. Only if the RecievedResourceType is "Fraction" + Deprecated: Use SelectedFractionalGpuGroups instead items: type: string type: array diff --git a/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go index 22a4cf20e..185eec44e 100644 --- a/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/scheduling/v1alpha2/zz_generated.deepcopy.go @@ -143,20 +143,6 @@ func (in *BindRequestStatus) DeepCopy() *BindRequestStatus { return out } -func (in *FractionalGpuGroup) DeepCopyInto(out *FractionalGpuGroup) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FractionalGpuGroup. -func (in *FractionalGpuGroup) DeepCopy() *FractionalGpuGroup { - if in == nil { - return nil - } - out := new(FractionalGpuGroup) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtendedResourceClaimAllocation) DeepCopyInto(out *ExtendedResourceClaimAllocation) { *out = *in @@ -189,6 +175,21 @@ func (in *ExtendedResourceClaimAllocation) DeepCopy() *ExtendedResourceClaimAllo return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FractionalGpuGroup) DeepCopyInto(out *FractionalGpuGroup) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FractionalGpuGroup. +func (in *FractionalGpuGroup) DeepCopy() *FractionalGpuGroup { + if in == nil { + return nil + } + out := new(FractionalGpuGroup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NUMAZonePlacement) DeepCopyInto(out *NUMAZonePlacement) { *out = *in