GPU: support memory, core count detection

This commit is contained in:
李通洲
2023-10-28 13:12:04 +08:00
parent 9d664e2b61
commit 38d5791d57
7 changed files with 84 additions and 31 deletions
+4 -4
View File
@@ -97,7 +97,7 @@ endif()
set(WARNING_FLAGS "-Wall -Wextra -Wconversion -Werror=uninitialized -Werror=return-type")
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} -Werror=incompatible-pointer-types -Werror=implicit-function-declaration -Werror=int-conversion")
if(WIN32 OR ENABLE_DIRECTX_HEADERS)
enable_language(CXX)
@@ -392,6 +392,7 @@ if(LINUX)
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_linux.c
src/detection/gpu/gpu_nvidia.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_linux.c
src/detection/icons/icons_linux.c
@@ -412,7 +413,6 @@ if(LINUX)
src/detection/sound/sound_linux.c
src/detection/swap/swap_linux.c
src/detection/temps/temps_linux.c
src/detection/temps/temps_nvidia.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
@@ -499,6 +499,7 @@ elseif(BSD)
src/detection/displayserver/linux/xlib.c
src/detection/font/font_linux.c
src/detection/gpu/gpu_linux.c
src/detection/gpu/gpu_nvidia.c
src/detection/gtk_qt/gtk.c
src/detection/host/host_bsd.c
src/detection/lm/lm_linux.c
@@ -519,7 +520,6 @@ elseif(BSD)
src/detection/sound/sound_linux.c
src/detection/swap/swap_bsd.c
src/detection/temps/temps_bsd.c
src/detection/temps/temps_nvidia.c
src/detection/terminalfont/terminalfont_linux.c
src/detection/terminalshell/terminalshell_linux.c
src/detection/terminalsize/terminalsize_linux.c
@@ -603,6 +603,7 @@ elseif(WIN32)
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
src/detection/gpu/gpu_windows.c
src/detection/gpu/gpu_nvidia.c
src/detection/host/host_windows.c
src/detection/icons/icons_windows.c
src/detection/libc/libc_windows.cpp
@@ -624,7 +625,6 @@ elseif(WIN32)
src/detection/terminalshell/terminalshell_windows.c
src/detection/terminalsize/terminalsize_windows.c
src/detection/temps/temps_windows.cpp
src/detection/temps/temps_nvidia.c
src/detection/theme/theme_nosupport.c
src/detection/uptime/uptime_windows.c
src/detection/users/users_windows.c
+10 -3
View File
@@ -1,6 +1,6 @@
#include "detection/gpu/gpu.h"
#include "detection/gpu/gpu_nvidia.h"
#include "detection/vulkan/vulkan.h"
#include "detection/temps/temps_nvidia.h"
#ifdef FF_HAVE_LIBPCI
#include "common/io/io.h"
@@ -247,11 +247,18 @@ static void pciHandleDevice(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
pciDetectTemp(gpu, device);
#endif
if (gpu->temperature != gpu->temperature && gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
{
char pciDeviceId[32];
snprintf(pciDeviceId, sizeof(pciDeviceId) - 1, "%04x:%02x:%02x.%d", device->domain, device->bus, device->dev, device->func);
ffDetectNvidiaGpuTemp(&gpu->temperature, pciDeviceId, 0, 0);
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) { .pciBusId = pciDeviceId }, (FFGpuNvidiaResult) {
.temp = gpu->temperature != gpu->temperature ? &gpu->temperature : NULL,
.memory = &gpu->dedicated,
.coreCount = (uint32_t*) &gpu->coreCount,
});
gpu->type = gpu->dedicated.total > 1024 * 1024 * 1024 ? FF_GPU_TYPE_DISCRETE : FF_GPU_TYPE_INTEGRATED;
}
}
@@ -1,4 +1,4 @@
#include "temps_nvidia.h"
#include "gpu_nvidia.h"
#include "3rdparty/nvml/nvml.h"
#include "common/library.h"
@@ -9,14 +9,13 @@ struct FFNvmlData {
FF_LIBRARY_SYMBOL(nvmlDeviceGetHandleByPciBusId_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetPciInfo_v3)
FF_LIBRARY_SYMBOL(nvmlDeviceGetTemperature)
FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2)
FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores)
bool inited;
} nvmlData;
// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise
// pciBusId = "domain:bus:device.function"
// pciDeviceId = (deviceId << 16) | vendorId
const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t pciDeviceId, uint32_t pciSubSystemId)
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result)
{
if (!nvmlData.inited)
{
@@ -27,7 +26,7 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p
#else
"libnvidia-ml"
#endif
FF_LIBRARY_EXTENSION, -1
FF_LIBRARY_EXTENSION, -1
);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlInit_v2)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libnvml, nvmlShutdown)
@@ -36,23 +35,25 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetHandleByPciBusId_v2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetPciInfo_v3)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetTemperature)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2)
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores)
if (ffnvmlInit_v2() != NVML_SUCCESS)
{
nvmlData.ffnvmlDeviceGetTemperature = NULL;
nvmlData.ffnvmlDeviceGetNumGpuCores = NULL;
return "nvmlInit_v2() failed";
}
atexit((void*) ffnvmlShutdown);
libnvml = NULL; // don't close nvml
}
if (nvmlData.ffnvmlDeviceGetTemperature == NULL)
if (nvmlData.ffnvmlDeviceGetNumGpuCores == NULL)
return "loading nvml library failed";
nvmlDevice_t device = NULL;
if (pciBusId)
if (cond.pciBusId)
{
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(pciBusId, &device);
nvmlReturn_t ret = nvmlData.ffnvmlDeviceGetHandleByPciBusId_v2(cond.pciBusId, &device);
if (ret != NVML_SUCCESS)
return "nvmlDeviceGetHandleByPciBusId_v2() failed";
}
@@ -71,7 +72,7 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p
if (nvmlData.ffnvmlDeviceGetPciInfo_v3(device, &pciInfo) != NVML_SUCCESS)
continue;
if (pciInfo.pciDeviceId != pciDeviceId || pciInfo.pciSubSystemId != pciSubSystemId)
if (pciInfo.pciDeviceId != cond.pciDeviceId || pciInfo.pciSubSystemId != cond.pciSubSystemId)
continue;
break;
@@ -79,10 +80,25 @@ const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t p
if (!device) return "Device not found";
}
uint32_t value;
if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) != NVML_SUCCESS)
return "nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) failed";
if (result.temp)
{
uint32_t value;
if (nvmlData.ffnvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &value) == NVML_SUCCESS)
*result.temp = value;
}
if (result.memory)
{
nvmlMemory_v2_t memory = { .version = nvmlMemory_v2 };
if (nvmlData.ffnvmlDeviceGetMemoryInfo_v2(device, &memory) == NVML_SUCCESS)
{
result.memory->total = memory.used + memory.free;
result.memory->used = memory.used;
}
}
if (result.coreCount)
nvmlData.ffnvmlDeviceGetNumGpuCores(device, result.coreCount);
*temp = value;
return NULL;
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "gpu.h"
// Use pciBusId if not NULL; use pciDeviceId and pciSubSystemId otherwise
// pciBusId = "domain:bus:device.function"
// pciDeviceId = (deviceId << 16) | vendorId
typedef struct FFGpuNvidiaCondition
{
const char* pciBusId;
uint32_t pciDeviceId;
uint32_t pciSubSystemId;
} FFGpuNvidiaCondition;
// detect x if not NULL
typedef struct FFGpuNvidiaResult
{
double* temp;
FFGPUMemory* memory;
uint32_t* coreCount;
} FFGpuNvidiaResult;
const char* ffDetectNvidiaGpuInfo(FFGpuNvidiaCondition cond, FFGpuNvidiaResult result);
+12 -3
View File
@@ -1,5 +1,5 @@
#include "gpu.h"
#include "detection/temps/temps_nvidia.h"
#include "detection/gpu/gpu_nvidia.h"
#include "util/windows/unicode.h"
#include "util/windows/registry.h"
@@ -85,13 +85,22 @@ const char* ffDetectGPUImpl(FF_MAYBE_UNUSED const FFGPUOptions* options, FFlist*
}
}
if (options->temp && gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA)
if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_NVIDIA && (options->temp || instance.config.general.allowSlowOperations))
{
uint32_t vendorId, deviceId, subSystemId;
// See: https://download.nvidia.com/XFree86/Linux-x86_64/545.23.06/README/supportedchips.html
// displayDevice.DeviceID = MatchingDeviceId "PCI\\VEN_10DE&DEV_2782&SUBSYS_513417AA&REV_A1"
if (swscanf(displayDevice.DeviceID, L"PCI\\VEN_%x&DEV_%x&SUBSYS_%x", &vendorId, &deviceId, &subSystemId) == 3)
ffDetectNvidiaGpuTemp(&gpu->temperature, NULL, (deviceId << 16) | vendorId, subSystemId);
{
ffDetectNvidiaGpuInfo((FFGpuNvidiaCondition) {
.pciDeviceId = (deviceId << 16) | vendorId,
.pciSubSystemId = subSystemId,
}, (FFGpuNvidiaResult) {
.temp = options->temp ? &gpu->temperature : NULL,
.memory = &gpu->dedicated,
.coreCount = (uint32_t*) &gpu->coreCount,
});
}
}
}
-5
View File
@@ -1,5 +0,0 @@
#pragma once
#include <stdint.h>
const char* ffDetectNvidiaGpuTemp(double* temp, const char* pciBusId, uint32_t pciDeviceId, uint32_t pciSubSystemId);
+4 -1
View File
@@ -275,7 +275,10 @@ void ffGenerateGPUJsonResult(FFGPUOptions* options, yyjson_mut_doc* doc, yyjson_
else
yyjson_mut_obj_add_null(doc, sharedObj, "used");
yyjson_mut_obj_add_null(doc, obj, "temperature");
if(gpu->temperature == gpu->temperature) //FF_GPU_TEMP_UNSET
yyjson_mut_obj_add_real(doc, obj, "temperature", gpu->temperature);
else
yyjson_mut_obj_add_null(doc, obj, "temperature");
const char* type;
switch (gpu->type)