diff --git a/CHANGELOG.md b/CHANGELOG.md index c09ed01f1..43c6c196d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [v0.9.13] - 2026-03-04 +## [Unreleased] + +### Fixed + +- Updated resource enumeration logic to exclude resources with count of 0. [#1120](https://github.com/NVIDIA/KAI-Scheduler/issues/1120) + +## [v0.13.0] - 2026-03-02 +### Added +- Added `global.nodeSelector` propagation from Helm values to Config CR, ensuring operator-created sub-component deployments (admission, binder, scheduler, pod-grouper, etc.) receive the configured nodeSelector [#1102](https://github.com/NVIDIA/KAI-Scheduler/pull/1102) [yuanchen8911](https://github.com/yuanchen8911) +- Added `plugins` and `actions` fields to SchedulingShard spec, allowing per-shard customization of scheduler plugin/action enablement, priority, and arguments [gshaibi](https://github.com/gshaibi) +- Added support for Kubeflow Trainer v2 TrainJob workloads via skipTopOwner grouper pattern +- Added `binder.cdiEnabled` Helm value to allow explicit override of CDI auto-detection for environments without ClusterPolicy +- Added metric for tracking evicted pods in pod groups, including nodepool, eviction action, and gang size +- Block scheduling of pods with shared (non-template) DRA GPU claims that lack a queue label or have a mismatched queue label [gshaibi](https://github.com/gshaibi) +- Added the option to disable prometheus service monitor creation [#810](https://github.com/NVIDIA/KAI-Scheduler/pull/810) [itsomri](https://github.com/itsomri) +- Fixed prometheus instance deprecation - ensure single instance [#779](https://github.com/NVIDIA/KAI-Scheduler/pull/779) [itsomri](https://github.com/itsomri) +- Added clear error messages for jobs referencing missing or orphan queues, reporting via events and conditions [#820](https://github.com/NVIDIA/KAI-Scheduler/pull/820) [gshaibi](https://github.com/gshaibi) +- Added rule selector for resource accounting prometheus [#818](https://github.com/NVIDIA/KAI-Scheduler/pull/818) [itsomri](https://github.com/itsomri) +- Made accounting labels configurable [#818](https://github.com/NVIDIA/KAI-Scheduler/pull/818) [itsomri](https://github.com/itsomri) +- Added support for Grove hierarchical topology constraints in PodGroup subgroups +- Added support for n-level queue hierarchies [#858](https://github.com/NVIDIA/KAI-Scheduler/pull/858) [gshaibi](https://github.com/gshaibi) +- Added labels and annotations propagation from topOwner in SkipTopOwner grouper [#861](https://github.com/NVIDIA/KAI-Scheduler/pull/861) [SiorMeir](https://github.com/siormeir) +- Added scheduler name match conditions to admission webhooks to improve cluster stability +- Add Gpu Dra claims and resource slices accounting for the purpose of resource management and quota guarantees. *** This change doesn't support shared gpu claims or gpu claims with FirstAvailable *** [#900](https://github.com/NVIDIA/KAI-Scheduler/pull/900) [davidLif](https://github.com/davidLif) +- Added DRA resources recording to snapshot [#830](https://github.com/NVIDIA/KAI-Scheduler/pull/830) +- Temporarily Prevent device-plugin GPU pods on DRA-only nodes - until translation between device-plugin notation and DRA is implemented +- Implemented subgroups for pytorchjobs [#935](https://github.com/NVIDIA/KAI-Scheduler/pull/935) [itsomri](https://github.com/itsomri) +- Made KAI images distroless [#745](https://github.com/NVIDIA/KAI-Scheduler/pull/745) [dttung2905](https://github.com/dttung2905) +- Allow setting empty gpuPodRuntimeClassName during helm install [#972](https://github.com/NVIDIA/KAI-Scheduler/pull/972) [steved](https://github.com/steved) +- Created scale tests scenarios for running scale tests for KAI [#967](https://github.com/NVIDIA/KAI-Scheduler/pull/967) +- Implemented block-level segmentation for pytorchjobs [#938](https://github.com/NVIDIA/KAI-Scheduler/pull/938) [itsomri](https://github.com/itsomri) +- Added scale test environment setup script and updated service monitors for KAI scheduler [#1031](https://github.com/NVIDIA/KAI-Scheduler/pull/1031) +- Implemented subgroups for leaderworkerset [#1046](https://github.com/NVIDIA/KAI-Scheduler/pull/1046) [davidLif](https://github.com/davidLif) +- Added discovery data to snapshot for more accurate debugging [#1047](https://github.com/NVIDIA/KAI-Scheduler/pull/1047) [itsomri](https://github.com/itsomri) +- Implemented subgroup segmentation (with topology segment definitions) for leaderworkerset [#1058](https://github.com/NVIDIA/KAI-Scheduler/pull/10586) [davidLif](https://github.com/davidLif) ### Fixed - Fixed a bug where queue status did not reflect its podgroups resources correctly [#1049](https://github.com/NVIDIA/KAI-Scheduler/pull/1049) diff --git a/pkg/scheduler/api/resource_info/resource_info.go b/pkg/scheduler/api/resource_info/resource_info.go index 5fea8f2a1..de8dad104 100644 --- a/pkg/scheduler/api/resource_info/resource_info.go +++ b/pkg/scheduler/api/resource_info/resource_info.go @@ -52,6 +52,9 @@ func NewResource(milliCPU float64, memory float64, gpus float64) *Resource { func ResourceFromResourceList(rList v1.ResourceList) *Resource { r := EmptyResource() for rName, rQuant := range rList { + if rQuant.IsZero() { + continue + } switch rName { case v1.ResourceCPU: r.milliCpu += float64(rQuant.MilliValue()) diff --git a/pkg/scheduler/api/resource_info/resource_info_test.go b/pkg/scheduler/api/resource_info/resource_info_test.go new file mode 100644 index 000000000..82c745399 --- /dev/null +++ b/pkg/scheduler/api/resource_info/resource_info_test.go @@ -0,0 +1,42 @@ +// Copyright 2025 NVIDIA CORPORATION +// SPDX-License-Identifier: Apache-2.0 + +package resource_info + +import ( + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Resource internal logic", func() { + Context("ResourceFromResourceList", func() { + It("should skip resources with zero quantity", func() { + resourceList := v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("1"), + v1.ResourceMemory: resource.MustParse("5G"), + GPUResourceName: resource.MustParse("1"), + v1.ResourceName("nvidia.com/mig-1g.24gb"): resource.MustParse("0"), + v1.ResourceName("nvidia.com/mig-2g.48gb"): resource.MustParse("0"), + v1.ResourceName("rdma/ib0"): resource.MustParse("0"), + } + + resource := ResourceFromResourceList(resourceList) + + Expect(resource.milliCpu).To(Equal(float64(1000))) + Expect(resource.memory).To(Equal(float64(5000000000))) + Expect(resource.gpus).To(Equal(float64(1))) + + scalarResources := resource.ScalarResources() + _, hasMig1g := scalarResources[v1.ResourceName("nvidia.com/mig-1g.24gb")] + _, hasMig2g := scalarResources[v1.ResourceName("nvidia.com/mig-2g.48gb")] + _, hasRdma := scalarResources[v1.ResourceName("rdma/ib0")] + + Expect(hasMig1g).To(BeFalse()) + Expect(hasMig2g).To(BeFalse()) + Expect(hasRdma).To(BeFalse()) + }) + }) +})