Skip to content

Commit 87c7914

Browse files
committed
Add unified memory support for NVIDIA GPUs
Detect and handle NVIDIA GPUs with unified memory architecture (e.g., GB10) that use system RAM instead of dedicated VRAM. When nvmlDeviceGetMemoryInfo fails or returns zero memory, fall back to querying system memory via sysinfo() to report total, used, and free memory statistics. This approach mirrors the existing unified memory handling for Apple M1/M2 GPUs and enables proper memory monitoring for NVIDIA GPUs with integrated graphics.
1 parent 339ee0b commit 87c7914

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

src/extract_gpuinfo_nvidia.c

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <stdio.h>
3030
#include <stdlib.h>
3131
#include <string.h>
32+
#include <sys/sysinfo.h>
3233

3334
#define NVML_SUCCESS 0
3435
#define NVML_ERROR_INSUFFICIENT_SIZE 7
@@ -607,26 +608,62 @@ static void gpuinfo_nvidia_refresh_dynamic_info(struct gpu_info *_gpu_info) {
607608

608609
// Device memory info (total,used,free)
609610
bool got_meminfo = false;
611+
bool has_unified_memory = false;
612+
610613
if (nvmlDeviceGetMemoryInfo_v2) {
611614
nvmlMemory_v2_t memory_info;
612615
memory_info.version = 2;
613616
last_nvml_return_status = nvmlDeviceGetMemoryInfo_v2(device, &memory_info);
614617
if (last_nvml_return_status == NVML_SUCCESS) {
615-
got_meminfo = true;
616-
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
617-
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
618-
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
619-
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
618+
// Check if this is a unified memory GPU (total == 0 indicates unified memory)
619+
if (memory_info.total == 0) {
620+
has_unified_memory = true;
621+
} else {
622+
got_meminfo = true;
623+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
624+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
625+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
626+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
627+
}
628+
} else {
629+
// Memory query failed - likely unified memory GPU (error code 13 = NOT_SUPPORTED)
630+
has_unified_memory = true;
620631
}
621632
}
622-
if (!got_meminfo && nvmlDeviceGetMemoryInfo) {
633+
if (!got_meminfo && !has_unified_memory && nvmlDeviceGetMemoryInfo) {
623634
nvmlMemory_v1_t memory_info;
624635
last_nvml_return_status = nvmlDeviceGetMemoryInfo(device, &memory_info);
625636
if (last_nvml_return_status == NVML_SUCCESS) {
626-
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
627-
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
628-
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
629-
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
637+
// Check if this is a unified memory GPU (total == 0 indicates unified memory)
638+
if (memory_info.total == 0) {
639+
has_unified_memory = true;
640+
} else {
641+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, memory_info.total);
642+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, memory_info.used);
643+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, memory_info.free);
644+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, memory_info.used * 100 / memory_info.total);
645+
}
646+
} else {
647+
// Memory query failed - likely unified memory GPU
648+
has_unified_memory = true;
649+
}
650+
}
651+
652+
// Handle unified memory GPUs - query system memory instead
653+
if (has_unified_memory) {
654+
struct sysinfo si;
655+
if (sysinfo(&si) == 0) {
656+
// Total system RAM
657+
unsigned long long total_ram = si.totalram * si.mem_unit;
658+
unsigned long long free_ram = si.freeram * si.mem_unit;
659+
unsigned long long used_ram = total_ram - free_ram;
660+
661+
SET_GPUINFO_DYNAMIC(dynamic_info, total_memory, total_ram);
662+
SET_GPUINFO_DYNAMIC(dynamic_info, used_memory, used_ram);
663+
SET_GPUINFO_DYNAMIC(dynamic_info, free_memory, free_ram);
664+
if (total_ram > 0) {
665+
SET_GPUINFO_DYNAMIC(dynamic_info, mem_util_rate, used_ram * 100 / total_ram);
666+
}
630667
}
631668
}
632669

0 commit comments

Comments
 (0)