Skip to content

Commit 36b76a5

Browse files
committed
feat: add config parsing
1 parent 3e8076a commit 36b76a5

File tree

2 files changed

+138
-1
lines changed

2 files changed

+138
-1
lines changed

internal/autoscaler/workloadstate.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package autoscaler
22

33
import (
4+
"strconv"
45
"time"
56

67
tfv1 "github.com/NexusGPU/tensor-fusion/api/v1"
@@ -17,7 +18,7 @@ const (
1718
DefaultAggregationInterval = time.Hour * 24
1819
// DefaultHistogramBucketSizeGrowth is the default value for HistogramBucketSizeGrowth.
1920
DefaultHistogramBucketSizeGrowth = 0.05 // Make each bucket 5% larger than the previous one.
20-
// DefaultVramHistogramDecayHalfLife is the default value for HistogramDecayHalfLife.
21+
// DefaultHistogramDecayHalfLife is the default value for HistogramDecayHalfLife.
2122
DefaultHistogramDecayHalfLife = time.Hour * 24
2223
)
2324

@@ -62,3 +63,42 @@ func (w *WorkloadState) UpdateSampleStats(metrics *WorkerMetrics) {
6263
}
6364
w.TotalSamplesCount++
6465
}
66+
67+
func (w *WorkloadState) GetResourceRecommenderConfig() *ResourceRecommenderConfig {
68+
cfg := DefaultResourceRecommenderConfig
69+
70+
asr := w.AutoScalingConfig.AutoSetResources
71+
fields := []struct {
72+
val string
73+
dst *float64
74+
}{
75+
{asr.TargetTflopsPercentile, &cfg.TargetTflopsPercentile},
76+
{asr.LowerBoundTflopsPercentile, &cfg.LowerBoundTflopsPercentile},
77+
{asr.UpperBoundTflopsPercentile, &cfg.UpperBoundTflopsPercentile},
78+
{asr.TargetVramPercentile, &cfg.TargetVramPercentile},
79+
{asr.LowerBoundVramPercentile, &cfg.LowerBoundVramPercentile},
80+
{asr.UpperBoundVramPercentile, &cfg.UpperBoundVramPercentile},
81+
{asr.RequestMarginFraction, &cfg.RequestMarginFraction},
82+
}
83+
for _, f := range fields {
84+
if f.val == "" {
85+
continue
86+
}
87+
if v, err := strconv.ParseFloat(f.val, 64); err == nil {
88+
*f.dst = v
89+
}
90+
}
91+
92+
if asr.ConfidenceInterval != "" {
93+
if d, err := time.ParseDuration(asr.ConfidenceInterval); err == nil {
94+
cfg.ConfidenceInterval = d
95+
}
96+
}
97+
98+
return &cfg
99+
}
100+
101+
func (w *WorkloadState) IsTargetResource(resourceName string) bool {
102+
target := w.AutoScalingConfig.AutoSetResources.TargetResource
103+
return target == "" || resourceName == target
104+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package autoscaler
2+
3+
import (
4+
"time"
5+
6+
tfv1 "github.com/NexusGPU/tensor-fusion/api/v1"
7+
. "github.com/onsi/ginkgo/v2"
8+
. "github.com/onsi/gomega"
9+
)
10+
11+
var _ = Describe("Workload State", func() {
12+
It("should return default config when no AutoScalingConfig is set", func() {
13+
ws := NewWorkloadState("test")
14+
cfg := ws.GetResourceRecommenderConfig()
15+
Expect(cfg).ToNot(BeNil())
16+
Expect(*cfg).To(Equal(DefaultResourceRecommenderConfig))
17+
})
18+
19+
It("should parse float fields from AutoSetResources", func() {
20+
ws := NewWorkloadState("test")
21+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
22+
AutoSetResources: tfv1.AutoSetResources{
23+
TargetTflopsPercentile: "0.8",
24+
LowerBoundTflopsPercentile: "0.1",
25+
UpperBoundTflopsPercentile: "0.95",
26+
TargetVramPercentile: "0.7",
27+
LowerBoundVramPercentile: "0.2",
28+
UpperBoundVramPercentile: "0.9",
29+
RequestMarginFraction: "0.15",
30+
},
31+
}
32+
cfg := ws.GetResourceRecommenderConfig()
33+
Expect(cfg.TargetTflopsPercentile).To(Equal(0.8))
34+
Expect(cfg.LowerBoundTflopsPercentile).To(Equal(0.1))
35+
Expect(cfg.UpperBoundTflopsPercentile).To(Equal(0.95))
36+
Expect(cfg.TargetVramPercentile).To(Equal(0.7))
37+
Expect(cfg.LowerBoundVramPercentile).To(Equal(0.2))
38+
Expect(cfg.UpperBoundVramPercentile).To(Equal(0.9))
39+
Expect(cfg.RequestMarginFraction).To(Equal(0.15))
40+
})
41+
42+
It("should ignore invalid float fields and keep defaults", func() {
43+
ws := NewWorkloadState("test")
44+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
45+
AutoSetResources: tfv1.AutoSetResources{
46+
TargetTflopsPercentile: "not-a-float",
47+
LowerBoundTflopsPercentile: "",
48+
UpperBoundTflopsPercentile: "0.99",
49+
},
50+
}
51+
cfg := ws.GetResourceRecommenderConfig()
52+
Expect(cfg.TargetTflopsPercentile).To(Equal(DefaultResourceRecommenderConfig.TargetTflopsPercentile))
53+
Expect(cfg.LowerBoundTflopsPercentile).To(Equal(DefaultResourceRecommenderConfig.LowerBoundTflopsPercentile))
54+
Expect(cfg.UpperBoundTflopsPercentile).To(Equal(0.99))
55+
})
56+
57+
It("should parse ConfidenceInterval if valid", func() {
58+
ws := NewWorkloadState("test")
59+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
60+
AutoSetResources: tfv1.AutoSetResources{
61+
ConfidenceInterval: "30m",
62+
},
63+
}
64+
cfg := ws.GetResourceRecommenderConfig()
65+
Expect(cfg.ConfidenceInterval).To(Equal(time.Duration(30 * time.Minute)))
66+
})
67+
68+
It("should ignore invalid ConfidenceInterval and keep default", func() {
69+
ws := NewWorkloadState("test")
70+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
71+
AutoSetResources: tfv1.AutoSetResources{
72+
ConfidenceInterval: "not-a-duration",
73+
},
74+
}
75+
cfg := ws.GetResourceRecommenderConfig()
76+
Expect(cfg.ConfidenceInterval).To(Equal(DefaultResourceRecommenderConfig.ConfidenceInterval))
77+
})
78+
79+
It("should correctly determine if a resource is the target based on config", func() {
80+
ws := NewWorkloadState("test")
81+
82+
Expect(ws.IsTargetResource("tflops")).To(BeTrue())
83+
Expect(ws.IsTargetResource("vram")).To(BeTrue())
84+
85+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
86+
AutoSetResources: tfv1.AutoSetResources{TargetResource: "tflops"},
87+
}
88+
Expect(ws.IsTargetResource("tflops")).To(BeTrue())
89+
Expect(ws.IsTargetResource("vram")).To(BeFalse())
90+
91+
ws.AutoScalingConfig = tfv1.AutoScalingConfig{
92+
AutoSetResources: tfv1.AutoSetResources{TargetResource: "vram"},
93+
}
94+
Expect(ws.IsTargetResource("tflops")).To(BeFalse())
95+
Expect(ws.IsTargetResource("vram")).To(BeTrue())
96+
})
97+
})

0 commit comments

Comments
 (0)