diff --git a/next.config.ts b/next.config.ts index a3e6800..eae6515 100644 --- a/next.config.ts +++ b/next.config.ts @@ -25,6 +25,14 @@ const nextConfig: NextConfig = { ]; return config; }, + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "avatars.githubusercontent.com", + }, + ], + }, }; export default nextConfig; diff --git a/public/amd/README.txt b/public/amd/README.txt new file mode 100644 index 0000000..83c969c --- /dev/null +++ b/public/amd/README.txt @@ -0,0 +1,6 @@ +Place amd-rocgfx-logo.png here. + +Download from: https://rocm.docs.amd.com/en/latest/_static/amd-rocgfx-logo.png +Alternative: https://raw.githubusercontent.com/RadeonOpenCompute/ROCm//docs/_static/amd-rocgfx-logo.png + +The component falls back to a styled text badge if this image is absent. diff --git a/src/app/api/gateway-metrics/route.ts b/src/app/api/gateway-metrics/route.ts index 2ea765a..89633d5 100644 --- a/src/app/api/gateway-metrics/route.ts +++ b/src/app/api/gateway-metrics/route.ts @@ -84,6 +84,9 @@ export interface SystemMetrics { uptime: number; hostname: string; platform: string; + // ROCm system-level info (available when rocmGpus.length > 0) + rocmDetected: boolean; + rocmRuntimeVersion: string; } interface GatewayPresence { @@ -134,8 +137,9 @@ async function getLocalMetrics(): Promise { // Detect ROCm GPU data if available let rocmGpus: ROCmGPUInfo[] = []; + let rocmInfo: { detected: boolean; gpus: ROCmGPUInfo[]; runtimeVersion?: string } = { detected: false, gpus: [] }; try { - const rocmInfo = await detectROCm(); + rocmInfo = await detectROCm(); if (rocmInfo.detected && rocmInfo.gpus.length > 0) { rocmGpus = rocmInfo.gpus; } @@ -255,6 +259,8 @@ async function getLocalMetrics(): Promise { uptime: Math.round(process.uptime()), hostname: osInfo.hostname, platform: `${osInfo.platform} ${osInfo.arch}`, + rocmDetected: rocmGpus.length > 0, + rocmRuntimeVersion: rocmInfo.runtimeVersion ?? "", }; } diff --git a/src/app/api/system/metrics/route.ts b/src/app/api/system/metrics/route.ts index f314d6c..716c893 100644 --- a/src/app/api/system/metrics/route.ts +++ b/src/app/api/system/metrics/route.ts @@ -75,6 +75,9 @@ export interface SystemMetrics { uptime: number; hostname: string; platform: string; + // ROCm system-level info (available when rocmGpus.length > 0) + rocmDetected: boolean; + rocmRuntimeVersion: string; // GPU fallback source info (indicates which detection method was used) gpuDetectionMethod?: "rocm" | "systeminfo" | "basic-sysfs" | "none"; } @@ -135,9 +138,11 @@ export async function GET( let rocmGpus: ROCmGPUInfo[] = []; let basicGpus: BasicGPUInfo[] = []; let gpuDetectionMethod: SystemMetrics["gpuDetectionMethod"] = "none"; + // Keep rocmInfo in scope so we can read runtimeVersion for the response + let rocmInfo: { detected: boolean; gpus: ROCmGPUInfo[]; runtimeVersion?: string } = { detected: false, gpus: [] }; try { - const rocmInfo = await detectROCm(); + rocmInfo = await detectROCm(); if (rocmInfo.detected && rocmInfo.gpus.length > 0) { rocmGpus = rocmInfo.gpus; } @@ -263,6 +268,8 @@ export async function GET( uptime: Math.round(process.uptime()), hostname: osInfo.hostname, platform: `${osInfo.platform} ${osInfo.arch}`, + rocmDetected: rocmGpus.length > 0, + rocmRuntimeVersion: rocmInfo.runtimeVersion ?? "", gpuDetectionMethod, }; diff --git a/src/components/SystemMetricsDashboard.tsx b/src/components/SystemMetricsDashboard.tsx index ac393e6..84b508c 100644 --- a/src/components/SystemMetricsDashboard.tsx +++ b/src/components/SystemMetricsDashboard.tsx @@ -1,5 +1,6 @@ "use client"; +import Image from "next/image"; import { useEffect, useState, useCallback } from "react"; import { Cpu, @@ -84,6 +85,9 @@ interface SystemMetrics { uptime: number; hostname: string; platform: string; + // ROCm system-level info (only populated when rocmGpus.length > 0) + rocmDetected: boolean; + rocmRuntimeVersion: string; } function MetricRow({ @@ -537,6 +541,22 @@ export function SystemMetricsDashboard() { )} + {/* ROCm Powered By — shown when ROCm is detected */} + {metrics.rocmDetected && ( +
+ AMD ROCm + + Powered by ROCm {metrics.rocmRuntimeVersion} + +
+ )} + {/* GPU Hardware Details — collapsible */} {(primaryGpu.deviceId || primaryGpu.driverVersion || primaryGpu.vbiosVersion) && (
diff --git a/src/lib/system/rocm.ts b/src/lib/system/rocm.ts index db41ce9..611ea17 100644 --- a/src/lib/system/rocm.ts +++ b/src/lib/system/rocm.ts @@ -448,8 +448,35 @@ async function getComprehensiveGpuInfo(rocmSmiPath: string): Promise<{ /** * Get ROCm runtime version + * Prefers /opt/rocm/.info/version-rocm (e.g. "7.2.1-81") which reflects the actual + * ROCm stack version. Falls back to rocminfo parsing which reports the GFX + * runtime version (e.g. "1.18" for gfx1151) rather than the ROCm release version. */ async function getRocmVersion(rocmInfoPath: string): Promise { + // Try the ROCm version file first — this is the actual ROCm release version + const versionFilePaths = [ + "/opt/rocm/.info/version-rocm", + "/opt/rocm/.info/version", + ]; + + for (const versionFile of versionFilePaths) { + try { + const { stdout } = await execAsync(`cat ${versionFile} 2>/dev/null`); + const trimmed = stdout.trim(); + // version files are in format "7.2.1-81" — strip the package suffix + const match = trimmed.match(/^(\d+\.\d+\.\d+)/); + if (match) { + return match[1]; + } + if (trimmed) { + return trimmed; + } + } catch { + // Continue to next file + } + } + + // Fallback: parse rocminfo output (less reliable — gives GFX runtime version) try { const { stdout } = await execAsync(`${rocmInfoPath} 2>&1`); const versionMatch = stdout.match(/Runtime Version:\s*([\d.]+)/);