Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion go/inventory/v1/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package v1

func (nd *NodeCapabilities) Dup() NodeCapabilities {
res := NodeCapabilities{
StorageClasses: make([]string, 0, len(nd.StorageClasses)),
StorageClasses: make([]string, 0, len(nd.StorageClasses)),
RDMAResourceName: nd.RDMAResourceName,
RDMAFabric: nd.RDMAFabric,
NCCLHCAPrefix: nd.NCCLHCAPrefix,
}

res.StorageClasses = append(res.StorageClasses, nd.StorageClasses...)
Expand Down
220 changes: 196 additions & 24 deletions go/inventory/v1/node.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions go/inventory/v1/node_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package v1

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestNodeCapabilities_Dup_PreservesRDMAFields(t *testing.T) {
src := NodeCapabilities{
StorageClasses: []string{"beta3", "default"},
RDMAResourceName: "rdma/rdma_shared_device_ib",
RDMAFabric: "infiniband",
NCCLHCAPrefix: "mlx5",
}

got := src.Dup()

require.Equal(t, src.StorageClasses, got.StorageClasses)
require.Equal(t, "rdma/rdma_shared_device_ib", got.RDMAResourceName)
require.Equal(t, "infiniband", got.RDMAFabric)
require.Equal(t, "mlx5", got.NCCLHCAPrefix)

// mutating dup must not affect the source (Dup is a deep copy)
got.StorageClasses[0] = "mutated"
got.RDMAResourceName = "rdma/rdma_shared_device_eth"
require.Equal(t, "beta3", src.StorageClasses[0])
require.Equal(t, "rdma/rdma_shared_device_ib", src.RDMAResourceName)
}

func TestNodeCapabilities_Dup_ZeroValueRDMA(t *testing.T) {
// A non-RDMA node leaves the new fields at zero value.
src := NodeCapabilities{
StorageClasses: []string{"default"},
}

got := src.Dup()

require.Empty(t, got.RDMAResourceName)
require.Empty(t, got.RDMAFabric)
require.Empty(t, got.NCCLHCAPrefix)
}
50 changes: 41 additions & 9 deletions go/inventory/v1/resourcepair.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,51 @@ func (m *ResourcePair) LT(rhs ResourcePair) bool {
return m.Allocatable.Cmp(*rhs.Allocatable) == -1
}

// IsZero reports whether the ResourcePair has been initialized. A
// zero-valued ResourcePair has nil quantity pointers and is the natural
// state for, e.g., a node that does not have RDMA capacity (and therefore
// leaves `NodeResources.RDMA` untouched).
func (m *ResourcePair) IsZero() bool {
if m == nil {
return true
}
return m.Capacity == nil && m.Allocatable == nil && m.Allocated == nil && len(m.Attributes) == 0
}

func (m *ResourcePair) Dup() ResourcePair {
capacity := m.Capacity.DeepCopy()
allocatable := m.Allocatable.DeepCopy()
allocated := m.Allocated.DeepCopy()
// A zero-valued ResourcePair (all quantity pointers nil) must round-trip
// through Dup() without panicking. Without this guard, calling Dup()
// against e.g. an unpopulated `NodeResources.RDMA` on a non-RDMA node
// nil-derefs Capacity.DeepCopy().
if m == nil || m.IsZero() {
return ResourcePair{}
}

res := ResourcePair{
Capacity: &capacity,
Allocatable: &allocatable,
Allocated: &allocated,
Attributes: m.Attributes.Dup(),
// Preserve the nil/non-nil shape of each quantity pointer. Returning
// `&zeroQuantity` for an originally-nil field would change protobuf
// field-presence semantics (and the JSON serialization the manifest
// version hash is computed from), so a partially-populated source
// must Dup to a structurally identical copy.
var capacity, allocatable, allocated *resource.Quantity
if m.Capacity != nil {
c := m.Capacity.DeepCopy()
capacity = &c
}
if m.Allocatable != nil {
a := m.Allocatable.DeepCopy()
allocatable = &a
}
if m.Allocated != nil {
al := m.Allocated.DeepCopy()
allocated = &al
}

return res
return ResourcePair{
Capacity: capacity,
Allocatable: allocatable,
Allocated: allocated,
Attributes: m.Attributes.Dup(),
}
}

func (m *ResourcePair) SubMilliNLZ(val types.ResourceValue) bool {
Expand Down
Loading
Loading