Implement GPU info for nvidia GPU

This commit is contained in:
Nicolas Mowen 2024-10-07 19:34:41 -06:00
parent 75ba023b5d
commit bc2ad7f9be
4 changed files with 135 additions and 67 deletions

View File

@ -0,0 +1,100 @@
import useSWR from "swr";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "../ui/dialog";
import ActivityIndicator from "../indicators/activity-indicator";
import { GpuInfo, Nvinfo, Vainfo } from "@/types/stats";
import { Button } from "../ui/button";
import copy from "copy-to-clipboard";
type GPUInfoDialogProps = {
showGpuInfo: boolean;
gpuType: GpuInfo;
setShowGpuInfo: (show: boolean) => void;
};
export default function GPUInfoDialog({
showGpuInfo,
gpuType,
setShowGpuInfo,
}: GPUInfoDialogProps) {
const { data: vainfo } = useSWR<Vainfo>(
showGpuInfo && gpuType == "vainfo" ? "vainfo" : null,
);
const { data: nvinfo } = useSWR<Nvinfo>(
showGpuInfo && gpuType == "nvinfo" ? "nvinfo" : null,
);
const onCopyInfo = async () => {
copy(
JSON.stringify(gpuType == "vainfo" ? vainfo : nvinfo).replace(
/[\\\s]+/gi,
"",
),
);
setShowGpuInfo(false);
};
if (gpuType == "vainfo") {
return (
<Dialog open={showGpuInfo} onOpenChange={setShowGpuInfo}>
<DialogContent>
<DialogHeader>
<DialogTitle>Vainfo Output</DialogTitle>
</DialogHeader>
{vainfo ? (
<div className="scrollbar-container mb-2 max-h-96 overflow-y-scroll whitespace-pre-line">
<div>Return Code: {vainfo.return_code}</div>
<br />
<div>Process {vainfo.return_code == 0 ? "Output" : "Error"}:</div>
<br />
<div>
{vainfo.return_code == 0 ? vainfo.stdout : vainfo.stderr}
</div>
</div>
) : (
<ActivityIndicator />
)}
<DialogFooter>
<Button onClick={() => setShowGpuInfo(false)}>Close</Button>
<Button variant="select" onClick={() => onCopyInfo()}>
Copy
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
} else {
return (
<Dialog open={showGpuInfo} onOpenChange={setShowGpuInfo}>
<DialogContent>
<DialogHeader>
<DialogTitle>Nvidia SMI Output</DialogTitle>
</DialogHeader>
{nvinfo ? (
<div className="scrollbar-container mb-2 max-h-96 overflow-y-scroll whitespace-pre-line">
<div>Name: {nvinfo["0"].name}</div>
<br />
<div>Driver: {nvinfo["0"].driver}</div>
<br />
<div>Cuda Compute Capability: {nvinfo["0"].cuda_compute}</div>
<br />
<div>VBios Info: {nvinfo["0"].vbios}</div>
</div>
) : (
<ActivityIndicator />
)}
<DialogFooter>
<Button onClick={() => setShowGpuInfo(false)}>Close</Button>
<Button variant="select" onClick={() => onCopyInfo()}>
Copy
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
}

View File

@ -1,55 +0,0 @@
import useSWR from "swr";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "../ui/dialog";
import ActivityIndicator from "../indicators/activity-indicator";
import { Vainfo } from "@/types/stats";
import { Button } from "../ui/button";
import copy from "copy-to-clipboard";
type VainfoDialogProps = {
showVainfo: boolean;
setShowVainfo: (show: boolean) => void;
};
export default function VainfoDialog({
showVainfo,
setShowVainfo,
}: VainfoDialogProps) {
const { data: vainfo } = useSWR<Vainfo>(showVainfo ? "vainfo" : null);
const onCopyVainfo = async () => {
copy(JSON.stringify(vainfo).replace(/[\\\s]+/gi, ""));
setShowVainfo(false);
};
return (
<Dialog open={showVainfo} onOpenChange={setShowVainfo}>
<DialogContent>
<DialogHeader>
<DialogTitle>Vainfo Output</DialogTitle>
</DialogHeader>
{vainfo ? (
<div className="scrollbar-container mb-2 max-h-96 overflow-y-scroll whitespace-pre-line">
<div>Return Code: {vainfo.return_code}</div>
<br />
<div>Process {vainfo.return_code == 0 ? "Output" : "Error"}:</div>
<br />
<div>{vainfo.return_code == 0 ? vainfo.stdout : vainfo.stderr}</div>
</div>
) : (
<ActivityIndicator />
)}
<DialogFooter>
<Button onClick={() => setShowVainfo(false)}>Close</Button>
<Button variant="select" onClick={() => onCopyVainfo()}>
Copy
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View File

@ -46,6 +46,8 @@ export type GpuStats = {
pstate?: string; pstate?: string;
}; };
export type GpuInfo = "vainfo" | "nvinfo";
export type ServiceStats = { export type ServiceStats = {
last_updated: number; last_updated: number;
storage: { [path: string]: StorageStats }; storage: { [path: string]: StorageStats };
@ -74,6 +76,15 @@ export type Vainfo = {
stderr: string; stderr: string;
}; };
export type Nvinfo = {
[key: string]: {
name: string;
driver: string;
cuda_compute: string;
vbios: string;
};
};
export type Ffprobe = { export type Ffprobe = {
return_code: number; return_code: number;
stderr: string; stderr: string;

View File

@ -1,5 +1,5 @@
import useSWR from "swr"; import useSWR from "swr";
import { FrigateStats } from "@/types/stats"; import { FrigateStats, GpuInfo } from "@/types/stats";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useMemo, useState } from "react";
import { useFrigateStats } from "@/api/ws"; import { useFrigateStats } from "@/api/ws";
import { import {
@ -11,7 +11,7 @@ import {
InferenceThreshold, InferenceThreshold,
} from "@/types/graph"; } from "@/types/graph";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import VainfoDialog from "@/components/overlay/VainfoDialog"; import GPUInfoDialog from "@/components/overlay/GPUInfoDialog";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { ThresholdBarGraph } from "@/components/graph/SystemGraph"; import { ThresholdBarGraph } from "@/components/graph/SystemGraph";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@ -63,15 +63,23 @@ export default function GeneralMetrics({
} }
}, [initialStats, updatedStats, statsHistory, lastUpdated, setLastUpdated]); }, [initialStats, updatedStats, statsHistory, lastUpdated, setLastUpdated]);
const canGetGpuInfo = useMemo( const [canGetGpuInfo, gpuType] = useMemo<[boolean, GpuInfo]>(() => {
() => let vaCount = 0;
let nvCount = 0;
statsHistory.length > 0 && statsHistory.length > 0 &&
Object.keys(statsHistory[0]?.gpu_usages ?? {}).filter( Object.keys(statsHistory[0]?.gpu_usages ?? {}).forEach((key) => {
(key) => if (key == "amd-vaapi" || key == "intel-vaapi" || key == "intel-qsv") {
key == "amd-vaapi" || key == "intel-vaapi" || key == "intel-qsv", vaCount += 1;
).length > 0, }
[statsHistory],
); if (key.includes("NVIDIA")) {
nvCount += 1;
}
});
return [vaCount > 0 || nvCount > 0, nvCount > 0 ? "nvinfo" : "vainfo"];
}, [statsHistory]);
// timestamps // timestamps
@ -432,7 +440,11 @@ export default function GeneralMetrics({
return ( return (
<> <>
<VainfoDialog showVainfo={showVainfo} setShowVainfo={setShowVainfo} /> <GPUInfoDialog
showGpuInfo={showVainfo}
gpuType={gpuType}
setShowGpuInfo={setShowVainfo}
/>
<div className="scrollbar-container mt-4 flex size-full flex-col overflow-y-auto"> <div className="scrollbar-container mt-4 flex size-full flex-col overflow-y-auto">
<div className="text-sm font-medium text-muted-foreground"> <div className="text-sm font-medium text-muted-foreground">