Skip to content

Commit 5032766

Browse files
authored
Merge branch 'main' into chore/sign-CLA
2 parents 1732668 + 552d8e1 commit 5032766

File tree

2 files changed

+193
-4
lines changed

2 files changed

+193
-4
lines changed

pkg/solver/matcher/match.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,50 @@ func (result ramMismatch) attributes() []attribute.KeyValue {
8181
}
8282
}
8383

84+
type vramMismatch struct {
85+
resourceOffer data.ResourceOffer
86+
jobOffer data.JobOffer
87+
}
88+
89+
func (_ vramMismatch) matched() bool { return false }
90+
func (_ vramMismatch) message() string { return "did not match VRAM" }
91+
func (result vramMismatch) attributes() []attribute.KeyValue {
92+
var resourceOfferVRAMs []int
93+
for _, gpu := range result.resourceOffer.Spec.GPUs {
94+
resourceOfferVRAMs = append(resourceOfferVRAMs, gpu.VRAM)
95+
}
96+
97+
var jobOfferVRAMS []int
98+
for _, gpu := range result.jobOffer.Spec.GPUs {
99+
jobOfferVRAMS = append(jobOfferVRAMS, gpu.VRAM)
100+
}
101+
102+
return []attribute.KeyValue{
103+
attribute.String("match_result", fmt.Sprintf("%T", result)),
104+
attribute.Bool("match_result.matched", result.matched()),
105+
attribute.String("match_result.message", result.message()),
106+
attribute.IntSlice("match_result.resource_offer.spec.gpus.vram", resourceOfferVRAMs),
107+
attribute.IntSlice("match_result.job_offer.spec.gpus.vram", jobOfferVRAMS),
108+
}
109+
}
110+
111+
type diskSpaceMismatch struct {
112+
resourceOffer data.ResourceOffer
113+
jobOffer data.JobOffer
114+
}
115+
116+
func (_ diskSpaceMismatch) matched() bool { return false }
117+
func (_ diskSpaceMismatch) message() string { return "did not match disk space" }
118+
func (result diskSpaceMismatch) attributes() []attribute.KeyValue {
119+
return []attribute.KeyValue{
120+
attribute.String("match_result", fmt.Sprintf("%T", result)),
121+
attribute.Bool("match_result.matched", result.matched()),
122+
attribute.String("match_result.message", result.message()),
123+
attribute.Int("match_result.job_offer.spec.disk", result.jobOffer.Spec.Disk),
124+
attribute.Int("match_result.resource_offer.spec.disk", result.resourceOffer.Spec.Disk),
125+
}
126+
}
127+
84128
type moduleIDError struct {
85129
resourceOffer data.ResourceOffer
86130
jobOffer data.JobOffer
@@ -227,6 +271,34 @@ func matchOffers(
227271
}
228272
}
229273

274+
// Skip VRAM check when job offer does not request VRAM
275+
if len(jobOffer.Spec.GPUs) > 0 {
276+
// Mismatch if job offer requests VRAM but resource provider has none
277+
if len(resourceOffer.Spec.GPUs) == 0 {
278+
return &vramMismatch{
279+
jobOffer: jobOffer,
280+
resourceOffer: resourceOffer,
281+
}
282+
}
283+
284+
// Mismatch if job offer largest VRAM is greater than resource offer largest VRAM
285+
largestResourceOfferVRAM := getLargestVRAM(resourceOffer.Spec.GPUs)
286+
largestJobOfferVRAM := getLargestVRAM(jobOffer.Spec.GPUs)
287+
if largestResourceOfferVRAM < largestJobOfferVRAM {
288+
return &vramMismatch{
289+
jobOffer: jobOffer,
290+
resourceOffer: resourceOffer,
291+
}
292+
}
293+
}
294+
295+
if resourceOffer.Spec.Disk < jobOffer.Spec.Disk {
296+
return &diskSpaceMismatch{
297+
jobOffer: jobOffer,
298+
resourceOffer: resourceOffer,
299+
}
300+
}
301+
230302
moduleID, err := data.GetModuleID(jobOffer.Module)
231303
if err != nil {
232304
return &moduleIDError{
@@ -295,6 +367,16 @@ func matchOffers(
295367
}
296368
}
297369

370+
func getLargestVRAM(gpus []data.GPUSpec) int {
371+
largestVRAM := 0
372+
for _, gpu := range gpus {
373+
if gpu.VRAM > largestVRAM {
374+
largestVRAM = gpu.VRAM
375+
}
376+
}
377+
return largestVRAM
378+
}
379+
298380
func logMatch(result matchResult) {
299381
switch r := result.(type) {
300382
case offersMatched:

pkg/solver/matcher/matcher_test.go

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ func TestMatchOffers(t *testing.T) {
1919
CPU: 1000,
2020
GPU: 1000,
2121
RAM: 1024,
22+
GPUs: []data.GPUSpec{
23+
{
24+
Name: "NVIDIA RTX 4090",
25+
Vendor: "NVIDIA",
26+
VRAM: 24576, // MB
27+
},
28+
},
29+
Disk: 2924295844659, // Bytes
2230
},
2331
DefaultPricing: data.DealPricing{
2432
InstructionPrice: 10,
@@ -29,9 +37,11 @@ func TestMatchOffers(t *testing.T) {
2937

3038
basicJobOffer := data.JobOffer{
3139
Spec: data.MachineSpec{
32-
CPU: 1000,
33-
GPU: 1000,
34-
RAM: 1024,
40+
CPU: 1000,
41+
GPU: 1000,
42+
RAM: 1024,
43+
GPUs: []data.GPUSpec{},
44+
Disk: 0, // Bytes
3545
},
3646
Mode: data.MarketPrice,
3747
Services: services,
@@ -51,6 +61,13 @@ func TestMatchOffers(t *testing.T) {
5161
Path: "/lilypad_module.json.tmpl",
5262
}
5363

64+
sdxlModuleConfig := data.ModuleConfig{
65+
Name: "",
66+
Repo: "https://github.com/Lilypad-Tech/lilypad-module-sdxl",
67+
Hash: "v0.9-lilypad1",
68+
Path: "/lilypad_module.json.tmpl",
69+
}
70+
5471
testCases := []struct {
5572
name string
5673
resourceOffer func(offer data.ResourceOffer) data.ResourceOffer
@@ -100,6 +117,96 @@ func TestMatchOffers(t *testing.T) {
100117
},
101118
shouldMatch: false,
102119
},
120+
{
121+
name: "VRAM match when job creator specifies VRAM",
122+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
123+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 24576}}
124+
return offer
125+
},
126+
jobOffer: func(offer data.JobOffer) data.JobOffer {
127+
offer.Module = sdxlModuleConfig
128+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 20000}}
129+
return offer
130+
},
131+
shouldMatch: true,
132+
},
133+
{
134+
name: "VRAM match when job creator does not specify VRAM",
135+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
136+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 24576}}
137+
return offer
138+
},
139+
jobOffer: func(offer data.JobOffer) data.JobOffer {
140+
offer.Module = sdxlModuleConfig
141+
offer.Spec.GPUs = []data.GPUSpec{}
142+
return offer
143+
},
144+
shouldMatch: true,
145+
},
146+
{
147+
name: "VRAM requested is more than resource offer VRAM",
148+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
149+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 24576}}
150+
return offer
151+
},
152+
jobOffer: func(offer data.JobOffer) data.JobOffer {
153+
offer.Module = sdxlModuleConfig
154+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 40000}}
155+
return offer
156+
},
157+
shouldMatch: false,
158+
},
159+
{
160+
name: "VRAM requested but resource offer has none",
161+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
162+
offer.Spec.GPUs = []data.GPUSpec{}
163+
return offer
164+
},
165+
jobOffer: func(offer data.JobOffer) data.JobOffer {
166+
offer.Module = sdxlModuleConfig
167+
offer.Spec.GPUs = []data.GPUSpec{{VRAM: 49152}}
168+
return offer
169+
},
170+
shouldMatch: false,
171+
},
172+
{
173+
name: "Disk space match when job creator specifies disk space",
174+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
175+
offer.Spec.Disk = 2924295844659 // Bytes
176+
return offer
177+
},
178+
jobOffer: func(offer data.JobOffer) data.JobOffer {
179+
offer.Module = sdxlModuleConfig
180+
offer.Spec.Disk = 1000000000000
181+
return offer
182+
},
183+
shouldMatch: true,
184+
},
185+
{
186+
name: "Disk space match when job creator does not specify disk space",
187+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
188+
offer.Spec.Disk = 2924295844659 // Bytes
189+
return offer
190+
},
191+
jobOffer: func(offer data.JobOffer) data.JobOffer {
192+
offer.Module = sdxlModuleConfig
193+
offer.Spec.Disk = 0 // zero-value
194+
return offer
195+
},
196+
shouldMatch: true,
197+
},
198+
{
199+
name: "Disk space requested is more than resource offer disk space",
200+
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
201+
offer.Spec.Disk = 2924295844659 // Bytes
202+
return offer
203+
},
204+
jobOffer: func(offer data.JobOffer) data.JobOffer {
205+
offer.Spec.Disk = 4000000000000
206+
return offer
207+
},
208+
shouldMatch: false,
209+
},
103210
{
104211
name: "Resource provider supports module",
105212
resourceOffer: func(offer data.ResourceOffer) data.ResourceOffer {
@@ -212,7 +319,7 @@ func TestMatchOffers(t *testing.T) {
212319
t.Run(tc.name, func(t *testing.T) {
213320
result := matchOffers(tc.resourceOffer(basicResourceOffer), tc.jobOffer(basicJobOffer))
214321
if result.matched() != tc.shouldMatch {
215-
t.Errorf("Expected match to be %v, but got %v", tc.shouldMatch, result)
322+
t.Errorf("Expected match to be %v, but got %+v", tc.shouldMatch, result)
216323
}
217324
})
218325
}

0 commit comments

Comments
 (0)