@@ -18,11 +18,13 @@ package v1
1818
1919import (
2020 "strconv"
21+ "time"
2122
2223 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2324 "k8s.io/utils/ptr"
2425
2526 "github.com/kai-scheduler/KAI-scheduler/pkg/apis/kai/v1/common"
27+ "github.com/kai-scheduler/KAI-scheduler/pkg/common/constants"
2628 usagedbapi "github.com/kai-scheduler/KAI-scheduler/pkg/scheduler/cache/usagedb/api"
2729)
2830
@@ -60,6 +62,23 @@ type ActionConfig struct {
6062 Priority * int `json:"priority,omitempty"`
6163}
6264
65+ type ScenarioSearchBudgets struct {
66+ // MaxActionSearchDuration limits total scenario search time per scheduler action.
67+ // Keys are action names, with "default" used as the fallback budget.
68+ MaxActionSearchDuration map [string ]metav1.Duration `json:"maxActionSearchDuration,omitempty"`
69+
70+ // MaxJobSearchDuration limits total scenario search time per pending job.
71+ MaxJobSearchDuration * metav1.Duration `json:"maxJobSearchDuration,omitempty"`
72+
73+ // MinJobSearchDuration guarantees each pending job this much scenario search time
74+ // before action and generator budgets can stop the job's search.
75+ MinJobSearchDuration * metav1.Duration `json:"minJobSearchDuration,omitempty"`
76+
77+ // MaxGeneratorSearchDuration limits scenario search time per generator attempt.
78+ // Keys are generator names, with "default" used as the fallback budget.
79+ MaxGeneratorSearchDuration map [string ]metav1.Duration `json:"maxGeneratorSearchDuration,omitempty"`
80+ }
81+
6382// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
6483
6584// SchedulingShardSpec defines the desired state of SchedulingShard
@@ -100,6 +119,10 @@ type SchedulingShardSpec struct {
100119 // +kubebuilder:validation:Optional
101120 UsageDBConfig * usagedbapi.UsageDBConfig `yaml:"usageDBConfig,omitempty" json:"usageDBConfig,omitempty"`
102121
122+ // ScenarioSearchBudgets configures alpha/experimental time budgets for scenario search.
123+ // +kubebuilder:validation:Optional
124+ ScenarioSearchBudgets * ScenarioSearchBudgets `json:"scenarioSearchBudgets,omitempty"`
125+
103126 // Plugins allows overriding plugin configuration. Keys are plugin names.
104127 // Built-in plugins can be disabled, reordered, or have their arguments changed.
105128 // New plugins can be added by specifying a name not in the default set.
@@ -108,7 +131,8 @@ type SchedulingShardSpec struct {
108131 // resourcetype=1500, podaffinity=1400, elastic=1300, kubeflow=1200,
109132 // ray=1100, subgrouporder=1000, taskorder=900, nominatednode=800,
110133 // dynamicresources=700, minruntime=600, topology=500, snapshot=400,
111- // gpupack/gpuspread=300, nodeplacement=200, gpusharingorder=100.
134+ // sg-nodelocalgreedy=360, sg-multinodegang=350, gpupack/gpuspread=300,
135+ // nodeplacement=200, gpusharingorder=100.
112136 // +kubebuilder:validation:Optional
113137 Plugins map [string ]PluginConfig `json:"plugins,omitempty"`
114138
@@ -127,31 +151,73 @@ func (s *SchedulingShardSpec) SetDefaultsWhereNeeded() {
127151
128152 s .setDefaultPlugins ()
129153 s .setDefaultActions ()
154+ s .ScenarioSearchBudgets = DefaultScenarioSearchBudgets (s .ScenarioSearchBudgets )
155+ }
156+
157+ func DefaultScenarioSearchBudgets (config * ScenarioSearchBudgets ) * ScenarioSearchBudgets {
158+ if config == nil {
159+ config = & ScenarioSearchBudgets {}
160+ }
161+ if config .MaxActionSearchDuration == nil {
162+ config .MaxActionSearchDuration = map [string ]metav1.Duration {}
163+ }
164+ if _ , found := config .MaxActionSearchDuration [constants .ActionDefault ]; ! found {
165+ config .MaxActionSearchDuration [constants .ActionDefault ] = mustParseScenarioSearchDuration (constants .DefaultActionBudget )
166+ }
167+ if config .MaxJobSearchDuration == nil {
168+ config .MaxJobSearchDuration = ptr .To (mustParseScenarioSearchDuration (constants .DefaultJobBudget ))
169+ }
170+ if config .MinJobSearchDuration == nil {
171+ config .MinJobSearchDuration = ptr .To (mustParseScenarioSearchDuration (constants .DefaultMinJobBudget ))
172+ }
173+ if config .MaxGeneratorSearchDuration == nil {
174+ config .MaxGeneratorSearchDuration = map [string ]metav1.Duration {}
175+ }
176+ if _ , found := config .MaxGeneratorSearchDuration [constants .ActionDefault ]; ! found {
177+ config .MaxGeneratorSearchDuration [constants .ActionDefault ] = mustParseScenarioSearchDuration (constants .DefaultGeneratorBudget )
178+ }
179+ if _ , found := config .MaxGeneratorSearchDuration [constants .GeneratorNodeLocalGreedy ]; ! found {
180+ config .MaxGeneratorSearchDuration [constants .GeneratorNodeLocalGreedy ] = mustParseScenarioSearchDuration (constants .DefaultNodeLocalGreedy )
181+ }
182+ if _ , found := config .MaxGeneratorSearchDuration [constants .GeneratorMultiNodeGang ]; ! found {
183+ config .MaxGeneratorSearchDuration [constants .GeneratorMultiNodeGang ] = mustParseScenarioSearchDuration (constants .DefaultMultiNodeGang )
184+ }
185+ return config
186+ }
187+
188+ func mustParseScenarioSearchDuration (value string ) metav1.Duration {
189+ duration , err := time .ParseDuration (value )
190+ if err != nil {
191+ panic (err )
192+ }
193+ return metav1.Duration {Duration : duration }
130194}
131195
132196// Default priorities preserve the current hardcoded ordering.
133197// Higher priority = runs first. Spaced by 100.
134198var defaultPluginPriorities = map [string ]int {
135- "predicates" : 1900 ,
136- "proportion" : 1800 ,
137- "priority" : 1700 ,
138- "nodeavailability" : 1600 ,
139- "resourcetype" : 1500 ,
140- "podaffinity" : 1400 ,
141- "elastic" : 1300 ,
142- "kubeflow" : 1200 ,
143- "ray" : 1100 ,
144- "subgrouporder" : 1000 ,
145- "taskorder" : 900 ,
146- "nominatednode" : 800 ,
147- "dynamicresources" : 700 ,
148- "minruntime" : 600 ,
149- "topology" : 500 ,
150- "snapshot" : 400 ,
151- "gpupack" : 300 ,
152- "gpuspread" : 300 ,
153- "nodeplacement" : 200 ,
154- "gpusharingorder" : 100 ,
199+ "predicates" : 1900 ,
200+ "proportion" : 1800 ,
201+ "priority" : 1700 ,
202+ "nodeavailability" : 1600 ,
203+ "resourcetype" : 1500 ,
204+ "podaffinity" : 1400 ,
205+ "elastic" : 1300 ,
206+ "kubeflow" : 1200 ,
207+ "ray" : 1100 ,
208+ "subgrouporder" : 1000 ,
209+ "taskorder" : 900 ,
210+ "nominatednode" : 800 ,
211+ "dynamicresources" : 700 ,
212+ "minruntime" : 600 ,
213+ "topology" : 500 ,
214+ "snapshot" : 400 ,
215+ "sg-nodelocalgreedy" : 360 ,
216+ "sg-multinodegang" : 350 ,
217+ "gpupack" : 300 ,
218+ "gpuspread" : 300 ,
219+ "nodeplacement" : 200 ,
220+ "gpusharingorder" : 100 ,
155221}
156222
157223var defaultActionPriorities = map [string ]int {
0 commit comments