Skip to content

Commit

Permalink
TAS: Sort domains by the level values, change leaves' ids to hostname…
Browse files Browse the repository at this point in the history
… values
  • Loading branch information
PBundyra committed Dec 2, 2024
1 parent 4bb02d4 commit fe02c08
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 192 deletions.
64 changes: 64 additions & 0 deletions pkg/cache/tas_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1072,3 +1072,67 @@ func TestFindTopologyAssignment(t *testing.T) {
})
}
}

func TestLexSortDomains(t *testing.T) {
// Define test cases as a map
testCases := map[string]struct {
domainA *domain
domainB *domain
expected int
}{
"Domain A smaller": {
domainA: &domain{
levelValues: []string{"a", "b", "c"},
},
domainB: &domain{
levelValues: []string{"a", "b", "d"},
},
expected: -1,
},
"Domain A greater": {
domainA: &domain{
levelValues: []string{"a", "c", "b"},
},
domainB: &domain{
levelValues: []string{"a", "b", "d"},
},
expected: 1,
},
"Domains equal": {
domainA: &domain{
levelValues: []string{"a", "b", "c"},
},
domainB: &domain{
levelValues: []string{"a", "b", "c"},
},
expected: 0,
},
"Domain A shorter": {
domainA: &domain{
levelValues: []string{"a", "b"},
},
domainB: &domain{
levelValues: []string{"a", "b", "c"},
},
expected: -1,
},
"Domain A longer": {
domainA: &domain{
levelValues: []string{"a", "b", "c"},
},
domainB: &domain{
levelValues: []string{"a", "b"},
},
expected: 1,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
gotResult := lexSortDomains(tc.domainA, tc.domainB)

if diff := cmp.Diff(tc.expected, gotResult); diff != "" {
t.Errorf("unexpected result (-want,+got): %s", diff)
}
})
}
}
36 changes: 31 additions & 5 deletions pkg/cache/tas_flavor_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package cache

import (
"cmp"
"errors"
"fmt"
"slices"
Expand Down Expand Up @@ -125,6 +124,9 @@ func newTASFlavorSnapshot(log logr.Logger, topologyName kueue.TopologyReference,
func (s *TASFlavorSnapshot) addNode(node corev1.Node) utiltas.TopologyDomainID {
levelValues := utiltas.LevelValues(s.levelKeys, node.Labels)
domainID := utiltas.DomainID(levelValues)
if s.isLowestLevelNode() {
domainID = utiltas.DomainID(levelValues[len(levelValues)-1:])
}
if _, found := s.leaves[domainID]; !found {
leafDomain := leafDomain{
domain: domain{
Expand Down Expand Up @@ -338,9 +340,7 @@ func (s *TASFlavorSnapshot) buildTopologyAssignmentForLevels(domains []*domain,

func (s *TASFlavorSnapshot) buildAssignment(domains []*domain) *kueue.TopologyAssignment {
// lex sort domains
slices.SortFunc(domains, func(a, b *domain) int {
return cmp.Compare(a.id, b.id)
})
slices.SortFunc(domains, lexSortDomains)
levelIdx := 0
// assign only hostname values if topology defines it
if s.isLowestLevelNode() {
Expand All @@ -363,7 +363,7 @@ func (s *TASFlavorSnapshot) sortedDomains(domains []*domain) []*domain {
slices.SortFunc(result, func(a, b *domain) int {
switch {
case a.state == b.state:
return cmp.Compare(a.id, b.id)
return lexSortDomains(a, b)
case a.state > b.state:
return -1
default:
Expand Down Expand Up @@ -414,3 +414,29 @@ func (s *TASFlavorSnapshot) notFitMessage(fitCount, totalCount int32) string {
}
return fmt.Sprintf("topology %q allows to fit only %v out of %v pod(s)", s.topologyName, fitCount, totalCount)
}

// lexSortDomains return order of two domains ordered by their levelValues
func lexSortDomains(a, b *domain) int {
aLevelValues := a.levelValues
bLevelValues := b.levelValues
minLen := len(aLevelValues)
if len(bLevelValues) < minLen {
minLen = len(bLevelValues)
}

for i := 0; i < minLen; i++ {
if aLevelValues[i] < bLevelValues[i] {
return -1 // a is lexicographically smaller
} else if aLevelValues[i] > bLevelValues[i] {
return 1 // a is lexicographically greater
}
}

// If all compared elements are equal, the shorter array is smaller
if len(aLevelValues) < len(bLevelValues) {
return -1
} else if len(aLevelValues) > len(bLevelValues) {
return 1
}
return 0 // Arrays are lexicographically equal
}
10 changes: 6 additions & 4 deletions pkg/util/testing/wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,16 +399,18 @@ func (p *PodSetWrapper) RuntimeClass(name string) *PodSetWrapper {
}

func (p *PodSetWrapper) RequiredTopologyRequest(level string) *PodSetWrapper {
p.TopologyRequest = &kueue.PodSetTopologyRequest{
Required: ptr.To(level),
if p.TopologyRequest == nil {
p.TopologyRequest = &kueue.PodSetTopologyRequest{}
}
p.TopologyRequest.Required = &level
return p
}

func (p *PodSetWrapper) PreferredTopologyRequest(level string) *PodSetWrapper {
p.TopologyRequest = &kueue.PodSetTopologyRequest{
Preferred: ptr.To(level),
if p.TopologyRequest == nil {
p.TopologyRequest = &kueue.PodSetTopologyRequest{}
}
p.TopologyRequest.Preferred = &level
return p
}

Expand Down
Loading

0 comments on commit fe02c08

Please sign in to comment.