Improve GPU vendor handling

This commit is contained in:
Nicolas Mowen 2026-05-13 14:58:48 -06:00
parent 6c83a4fc80
commit 6f266256c6
5 changed files with 40 additions and 27 deletions

View File

@ -243,6 +243,7 @@ async def set_gpu_stats(
if nvidia_usage: if nvidia_usage:
for i in range(len(nvidia_usage)): for i in range(len(nvidia_usage)):
stats[nvidia_usage[i]["name"]] = { stats[nvidia_usage[i]["name"]] = {
"vendor": "nvidia",
"gpu": str(round(float(nvidia_usage[i]["gpu"]), 2)) + "%", "gpu": str(round(float(nvidia_usage[i]["gpu"]), 2)) + "%",
"mem": str(round(float(nvidia_usage[i]["mem"]), 2)) + "%", "mem": str(round(float(nvidia_usage[i]["mem"]), 2)) + "%",
"enc": str(round(float(nvidia_usage[i]["enc"]), 2)) + "%", "enc": str(round(float(nvidia_usage[i]["enc"]), 2)) + "%",
@ -251,16 +252,16 @@ async def set_gpu_stats(
} }
else: else:
stats["nvidia-gpu"] = {"gpu": "", "mem": ""} stats["nvidia-gpu"] = {"vendor": "nvidia", "gpu": "", "mem": ""}
hwaccel_errors.append(args) hwaccel_errors.append(args)
elif "nvmpi" in args or "jetson" in args: elif "nvmpi" in args or "jetson" in args:
# nvidia Jetson # nvidia Jetson
jetson_usage = get_jetson_stats() jetson_usage = get_jetson_stats()
if jetson_usage: if jetson_usage:
stats["jetson-gpu"] = jetson_usage stats["jetson-gpu"] = {"vendor": "nvidia", **jetson_usage}
else: else:
stats["jetson-gpu"] = {"gpu": "", "mem": ""} stats["jetson-gpu"] = {"vendor": "nvidia", "gpu": "", "mem": ""}
hwaccel_errors.append(args) hwaccel_errors.append(args)
elif "qsv" in args or ("vaapi" in args and not is_vaapi_amd_driver()): elif "qsv" in args or ("vaapi" in args and not is_vaapi_amd_driver()):
if not config.telemetry.stats.intel_gpu_stats: if not config.telemetry.stats.intel_gpu_stats:
@ -278,7 +279,7 @@ async def set_gpu_stats(
name = entry.pop("name") name = entry.pop("name")
stats[name] = entry stats[name] = entry
else: else:
stats["intel-gpu"] = {"gpu": "", "mem": ""} stats["intel-gpu"] = {"vendor": "intel", "gpu": "", "mem": ""}
hwaccel_errors.append(args) hwaccel_errors.append(args)
elif "vaapi" in args: elif "vaapi" in args:
if not config.telemetry.stats.amd_gpu_stats: if not config.telemetry.stats.amd_gpu_stats:
@ -288,18 +289,18 @@ async def set_gpu_stats(
amd_usage = get_amd_gpu_stats() amd_usage = get_amd_gpu_stats()
if amd_usage: if amd_usage:
stats["amd-vaapi"] = amd_usage stats["amd-vaapi"] = {"vendor": "amd", **amd_usage}
else: else:
stats["amd-vaapi"] = {"gpu": "", "mem": ""} stats["amd-vaapi"] = {"vendor": "amd", "gpu": "", "mem": ""}
hwaccel_errors.append(args) hwaccel_errors.append(args)
elif "preset-rk" in args: elif "preset-rk" in args:
rga_usage = get_rockchip_gpu_stats() rga_usage = get_rockchip_gpu_stats()
if rga_usage: if rga_usage:
stats["rockchip"] = rga_usage stats["rockchip"] = {"vendor": "rockchip", **rga_usage}
elif "v4l2m2m" in args or "rpi" in args: elif "v4l2m2m" in args or "rpi" in args:
# RPi v4l2m2m is currently not able to get usage stats # RPi v4l2m2m is currently not able to get usage stats
stats["rpi-v4l2m2m"] = {"gpu": "", "mem": ""} stats["rpi-v4l2m2m"] = {"vendor": "rpi", "gpu": "", "mem": ""}
if stats: if stats:
all_stats["gpu_usages"] = stats all_stats["gpu_usages"] = stats

View File

@ -83,6 +83,7 @@ class TestGpuStats(unittest.TestCase):
assert intel_stats == { assert intel_stats == {
"0000:00:02.0": { "0000:00:02.0": {
"name": "Intel Graphics", "name": "Intel Graphics",
"vendor": "intel",
"gpu": "90.0%", "gpu": "90.0%",
"mem": "-%", "mem": "-%",
"compute": "30.0%", "compute": "30.0%",

View File

@ -479,6 +479,7 @@ def get_intel_gpu_stats(
entry: dict[str, Any] = { entry: dict[str, Any] = {
"name": names.get(pdev) or f"Intel GPU {pdev}", "name": names.get(pdev) or f"Intel GPU {pdev}",
"vendor": "intel",
"gpu": f"{round(overall_pct, 2)}%", "gpu": f"{round(overall_pct, 2)}%",
"mem": "-%", "mem": "-%",
"compute": f"{round(compute_pct, 2)}%", "compute": f"{round(compute_pct, 2)}%",

View File

@ -62,7 +62,10 @@ export type ExtraProcessStats = {
mem?: string; mem?: string;
}; };
export type GpuVendor = "intel" | "amd" | "nvidia" | "rockchip" | "rpi";
export type GpuStats = { export type GpuStats = {
vendor?: GpuVendor;
gpu: string; gpu: string;
mem: string; mem: string;
enc?: string; enc?: string;

View File

@ -98,13 +98,11 @@ export default function GeneralMetrics({
let nvCount = 0; let nvCount = 0;
statsHistory.length > 0 && statsHistory.length > 0 &&
Object.keys(statsHistory[0]?.gpu_usages ?? {}).forEach((key) => { Object.values(statsHistory[0]?.gpu_usages ?? {}).forEach((stats) => {
if (key == "amd-vaapi" || key == "intel-gpu") { if (stats.vendor === "nvidia") {
vaCount += 1;
}
if (key.includes("NVIDIA")) {
nvCount += 1; nvCount += 1;
} else if (stats.vendor === "intel" || stats.vendor === "amd") {
vaCount += 1;
} }
}); });
@ -288,11 +286,14 @@ export default function GeneralMetrics({
return []; return [];
} }
// Intel doesn't expose VRAM usage, so hide the memory section
// entirely when every reporting GPU is Intel.
const firstUsages = statsHistory[0]?.gpu_usages ?? {};
const firstEntries = Object.values(firstUsages);
if ( if (
Object.keys(statsHistory?.at(0)?.gpu_usages ?? {}).length == 1 && firstEntries.length > 0 &&
Object.keys(statsHistory?.at(0)?.gpu_usages ?? {})[0] === "intel-gpu" firstEntries.every((s) => s.vendor === "intel")
) { ) {
// intel gpu stats do not support memory
return undefined; return undefined;
} }
@ -307,6 +308,10 @@ export default function GeneralMetrics({
} }
Object.entries(stats.gpu_usages || {}).forEach(([key, stats]) => { Object.entries(stats.gpu_usages || {}).forEach(([key, stats]) => {
if (stats.vendor === "intel") {
return;
}
if (!(key in series)) { if (!(key in series)) {
series[key] = { name: key, data: [] }; series[key] = { name: key, data: [] };
} }
@ -470,8 +475,9 @@ export default function GeneralMetrics({
return false; return false;
} }
const gpuKeys = Object.keys(statsHistory[0]?.gpu_usages ?? {}); const hasIntelGpu = Object.values(statsHistory[0]?.gpu_usages ?? {}).some(
const hasIntelGpu = gpuKeys.some((key) => key === "intel-gpu"); (stats) => stats.vendor === "intel",
);
if (!hasIntelGpu) { if (!hasIntelGpu) {
return false; return false;
@ -486,14 +492,15 @@ export default function GeneralMetrics({
continue; continue;
} }
Object.entries(stats.gpu_usages || {}).forEach(([key, gpuStats]) => { Object.values(stats.gpu_usages || {}).forEach((gpuStats) => {
if (key === "intel-gpu") { if (gpuStats.vendor !== "intel") {
if (gpuStats.gpu) { return;
hasDataPoints = true; }
const gpuValue = parseFloat(gpuStats.gpu.slice(0, -1)); if (gpuStats.gpu) {
if (!isNaN(gpuValue) && gpuValue > 0) { hasDataPoints = true;
allZero = false; const gpuValue = parseFloat(gpuStats.gpu.slice(0, -1));
} if (!isNaN(gpuValue) && gpuValue > 0) {
allZero = false;
} }
} }
}); });