Conversation
Signed-off-by: tryuuu <ryu23210@gmail.com>
|
Thank you @tryuuu for your contribution. On an initial glance, this looks fine to me. Let me run some more tests against this branch and get back to you sometime next week |
| if gi != e.GpuInstanceId || ci != e.ComputeInstanceId { | ||
| continue | ||
| for _, d := range ds { | ||
| if d.IsMigDevice() && e.GpuInstanceId != 0xFFFFFFFF && e.ComputeInstanceId != 0xFFFFFFFF { |
There was a problem hiding this comment.
NVML I believe reports GPU instance Id and Compute Instance Id independently. I believe we can have an Xid event like
GI=0, CI=FFFFFFFF
GI=1, CI=0
In this case GI 1 should remain healthy, but currently we end up skipping the entire GPU and mark all instances of that GPU unhealthy, is that intended ?. I think we should individually verify the GIs and CIs
for _, d := range ds {
if d.IsMigDevice() {
gi := deviceIDToGiMap[d.ID]
ci := deviceIDToCiMap[d.ID]
if e.GpuInstanceId != 0xFFFFFFFF && gi != e.GpuInstanceId {
continue
}
if e.ComputeInstanceId != 0xFFFFFFFF && ci != e.ComputeInstanceId {
continue
}
}
klog.Infof("XidCriticalError: Xid=%d on Device=%s; marking device as unhealthy.", e.EventData, d.ID)
unhealthy <- d
}
We should also add a unit test for this case.
|
@tryuuu About the testing changes: this small map fan-out fix adds five NVML fakes and ~266 lines. Existing tests isolate deterministic data transformations instead of simulating raw NVML (eg. testing I'm thinking we could create a type in type placedDevice struct {
parentUUID string
device *Device
}
func groupByParent(devices []placedDevice) map[string][]*Device {
grouped := make(map[string][]*Device)
for _, d := range devices {
grouped[d.parentUUID] = append(grouped[d.parentUUID], d.device)
}
return grouped
}You would call This allows for easy unit testing: func TestGroupByParent(t *testing.T) {
parentA := "GPU-A"
parentB := "GPU-B"
deviceA0 := &Device{Device: pluginapi.Device{ID: "GPU-A::0"}}
deviceA1 := &Device{Device: pluginapi.Device{ID: "GPU-A::1"}}
deviceB0 := &Device{Device: pluginapi.Device{ID: "GPU-B::0"}}
grouped := groupByParent([]placedDevice{
{parentUUID: parentA, device: deviceA0},
{parentUUID: parentA, device: deviceA1},
{parentUUID: parentB, device: deviceB0},
})
require.Equal(t, []*Device{deviceA0, deviceA1}, grouped[parentA])
require.Equal(t, []*Device{deviceB0}, grouped[parentB])
} |
| continue | ||
| } | ||
|
|
||
| ret = gpu.RegisterEvents(eventMask&supportedEvents, eventSet) |
There was a problem hiding this comment.
Duplicate gpu registration has been an issue before this PR as well (and still is). Just something to note for a future fix.
Signed-off-by: tryuuu <ryu23210@gmail.com>
Signed-off-by: tryuuu <ryu23210@gmail.com>
|
@kvalliyurnatt @aryangorwade |
Fixes #1929
checkHealthkept only one*Deviceper physical GPU UUID inparentToDeviceMap, so devices sharing a physical GPU overwrote each other. As a result, an Xid event marked at most one device as unhealthy.With replication (time-slicing or MPS), the other replicas of the affected GPU remained schedulable. With MIG, an event could be dropped entirely if the single device retained in the map did not match the event's GI and CI.
This PR groups all logical devices by their parent GPU UUID and processes each device associated with the event UUID. Replicated devices are all reported as unhealthy, while MIG devices are filtered using each available event ID independently. If either the GI or CI is unavailable, the remaining available ID is still used to identify the affected devices.