From 92ca373e8e8e0a3f21ca4dde083a4eab3985c4e2 Mon Sep 17 00:00:00 2001 From: DasPauluteli <67437654+DasPauluteli@users.noreply.github.com> Date: Fri, 13 Mar 2026 21:22:46 +0100 Subject: [PATCH 1/5] Add APU unified memory (GTT) support for Strix Halo and similar APUs - Track GTT pool (system RAM mapped for GPU use via AMD TTM) alongside VRAM - Auto-detect APUs by device name or size heuristic (GTT >= 4x VRAM < 8GB) - Show purple "Unified RAM (GTT)" bar in UI when APU is detected - Relabel VRAM bar as "reserved pool" on APUs to avoid misleading reads - Include is_apu, gtt_used/total/percent, device_name in WebSocket payload - Update README with APU/unified memory section and Strix Halo notes Co-Authored-By: Claude Sonnet 4.6 --- README.md | 20 ++++++-- __init__.py | 74 ++++++++++++++++++++++++--- web/monitor.js | 133 +++++++++++++++++++++++++++++++------------------ 3 files changed, 169 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 10d0756..b47d947 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AMD GPU Monitor for ComfyUI -A simple, lightweight AMD GPU monitoring tool for ComfyUI that displays real-time information about your AMD GPU directly in the UI. +A simple, lightweight AMD GPU monitoring tool for ComfyUI that displays real-time information about your AMD GPU directly in the UI. Supports both discrete AMD GPUs and APUs with unified memory (e.g. Strix Halo / gfx1151). ![AMD GPU Monitor Screenshot](https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor/raw/main/screenshot.png) @@ -8,12 +8,14 @@ A simple, lightweight AMD GPU monitoring tool for ComfyUI that displays real-tim - Real-time GPU utilization monitoring (%) - VRAM usage tracking (both in MB/GB and percentage) +- **GTT / Unified RAM tracking for APUs** — dynamically allocated system RAM used as GPU memory (shown automatically on APUs like Strix Halo) - GPU temperature monitoring (°C) +- Automatic APU detection — relabels VRAM as "reserved pool" and shows the GTT pool as "Unified RAM" for APUs - Color-coded indicators (blue for low, orange for medium, red for high usage) - Draggable, collapsible, and closable UI - Position persistence between sessions -- Works with ROCm-enabled GPUs -- Specifically tested with AMD Radeon RX 7900 XTX +- Works with ROCm-enabled GPUs and APUs +- Tested with AMD Radeon RX 7900 XTX (discrete) and Strix Halo APU (gfx1151) ## Installation @@ -42,9 +44,19 @@ No setup is required. Once installed, the monitor will automatically appear in t - **Collapse/Expand**: Click the "−" button to collapse the monitor to just the title bar - **Close**: Click the "×" button to close the monitor (a "Show AMD GPU Monitor" button will appear to bring it back) +## APU / Unified Memory Support + +On AMD APUs with dynamically allocated unified memory (e.g. **Strix Halo / gfx1151**, Phoenix, Hawk Point, Rembrandt, etc.), the GPU does not have a fixed VRAM pool. Instead, it uses system RAM via the **GTT (Graphics Translation Table)** pool managed by the kernel's TTM subsystem. + +The monitor detects this automatically and: + +- Shows a **"Unified RAM (GTT)"** bar (purple) representing the system RAM currently mapped for GPU use +- Relabels the VRAM bar as **"VRAM (reserved pool)"** to clarify it is just a small pre-allocated chunk, not the full available memory +- APU detection uses device name matching (Strix, Phoenix, Hawk Point, etc.) and a size heuristic (GTT ≥ 4× VRAM and VRAM < 8 GB) + ## How It Works -This extension uses the `rocm-smi` command-line tool to collect GPU information and displays it in a floating UI element in the ComfyUI interface. It does not affect the performance of ComfyUI or your GPU. +This extension polls `rocm-smi` (or `amd-smi`) in a background thread to collect GPU information and pushes updates to the frontend via WebSocket. The floating UI is updated in real time and does not affect ComfyUI or GPU performance. ## Troubleshooting diff --git a/__init__.py b/__init__.py index 9ffd20c..7e04cdb 100644 --- a/__init__.py +++ b/__init__.py @@ -13,7 +13,12 @@ "vram_used": 0, "vram_total": 0, "vram_used_percent": 0, + "gtt_used": 0, + "gtt_total": 0, + "gtt_used_percent": 0, "gpu_temperature": 0, + "is_apu": False, + "device_name": "", "last_update": 0 } @@ -94,24 +99,70 @@ def get_gpu_info(rocm_smi_path): except: pass + # Get device name for APU detection + try: + info = run_rocm_smi_command(rocm_smi_path, '--showproductname', '--json') + if isinstance(info, dict) and 'card0' in info: + card_info = info['card0'] + for key in ('Card Series', 'Card Model', 'Card Vendor', 'Card SKU'): + if key in card_info: + gpu_stats["device_name"] = str(card_info[key]) + break + except: + pass + # Get VRAM information try: info = run_rocm_smi_command(rocm_smi_path, '--showmeminfo', 'vram', '--json') if isinstance(info, dict) and 'card0' in info: card_info = info['card0'] # Use first GPU - + # Parse the B (bytes) format ROCm 5.x/6.x uses if 'VRAM Total Memory (B)' in card_info and 'VRAM Total Used Memory (B)' in card_info: vram_total_bytes = int(card_info['VRAM Total Memory (B)']) vram_used_bytes = int(card_info['VRAM Total Used Memory (B)']) - + # Convert to MB for display vram_total = vram_total_bytes / (1024 * 1024) vram_used = vram_used_bytes / (1024 * 1024) - + gpu_stats["vram_total"] = int(vram_total) gpu_stats["vram_used"] = int(vram_used) - gpu_stats["vram_used_percent"] = int((vram_used / vram_total) * 100) + gpu_stats["vram_used_percent"] = int((vram_used / vram_total) * 100) if vram_total > 0 else 0 + except: + pass + + # Get GTT (unified system RAM) information — critical for APUs like Strix Halo + try: + info = run_rocm_smi_command(rocm_smi_path, '--showmeminfo', 'gtt', '--json') + if isinstance(info, dict) and 'card0' in info: + card_info = info['card0'] + if 'GTT Total Memory (B)' in card_info and 'GTT Total Used Memory (B)' in card_info: + gtt_total_bytes = int(card_info['GTT Total Memory (B)']) + gtt_used_bytes = int(card_info['GTT Total Used Memory (B)']) + + gtt_total = gtt_total_bytes / (1024 * 1024) + gtt_used = gtt_used_bytes / (1024 * 1024) + + gpu_stats["gtt_total"] = int(gtt_total) + gpu_stats["gtt_used"] = int(gtt_used) + gpu_stats["gtt_used_percent"] = int((gtt_used / gtt_total) * 100) if gtt_total > 0 else 0 + except: + pass + + # Detect APU: GTT pool significantly larger than VRAM pool indicates unified memory architecture. + # Also catches explicit device name patterns (gfx1151 = Strix Halo, etc.) + try: + vram_total = gpu_stats["vram_total"] + gtt_total = gpu_stats["gtt_total"] + device_name = gpu_stats["device_name"].lower() + apu_name_hints = ("radeon 890m", "radeon 780m", "radeon 760m", "radeon 740m", + "strix", "phoenix", "hawk point", "mendocino", "rembrandt", + "raphael", "dragon range", "barcelo", "cezanne") + name_match = any(hint in device_name for hint in apu_name_hints) + # Heuristic: if GTT is at least 4x VRAM and VRAM < 8 GB, likely APU + size_match = gtt_total > 0 and vram_total > 0 and (gtt_total >= vram_total * 4) and vram_total < 8192 + gpu_stats["is_apu"] = bool(name_match or size_match) except: pass @@ -147,7 +198,12 @@ def send_monitor_update(): 'gpu_temperature': gpu_stats['gpu_temperature'], 'vram_total': gpu_stats['vram_total'], 'vram_used': gpu_stats['vram_used'], - 'vram_used_percent': gpu_stats['vram_used_percent'] + 'vram_used_percent': gpu_stats['vram_used_percent'], + 'gtt_total': gpu_stats['gtt_total'], + 'gtt_used': gpu_stats['gtt_used'], + 'gtt_used_percent': gpu_stats['gtt_used_percent'], + 'is_apu': gpu_stats['is_apu'], + 'device_name': gpu_stats['device_name'], }] } @@ -233,7 +289,13 @@ def monitor_gpu(self, update_interval): monitor_update_interval = update_interval # Return current stats as a string for debugging - stats = f"GPU: {gpu_stats['gpu_utilization']}% | VRAM: {gpu_stats['vram_used']}MB/{gpu_stats['vram_total']}MB ({gpu_stats['vram_used_percent']}%) | Temp: {gpu_stats['gpu_temperature']}°C" + apu_tag = " [APU]" if gpu_stats['is_apu'] else "" + stats = ( + f"GPU{apu_tag}: {gpu_stats['gpu_utilization']}% | " + f"VRAM: {gpu_stats['vram_used']}MB/{gpu_stats['vram_total']}MB ({gpu_stats['vram_used_percent']}%) | " + f"GTT: {gpu_stats['gtt_used']}MB/{gpu_stats['gtt_total']}MB ({gpu_stats['gtt_used_percent']}%) | " + f"Temp: {gpu_stats['gpu_temperature']}°C" + ) return (stats,) # Register our node when this script is imported diff --git a/web/monitor.js b/web/monitor.js index afd0c5c..56214b2 100644 --- a/web/monitor.js +++ b/web/monitor.js @@ -137,9 +137,48 @@ const createMonitorElement = () => { vramSection.appendChild(vramBarContainer); content.appendChild(vramSection); + // GTT / Unified RAM section (shown for APUs with dynamic unified memory) + const gttSection = document.createElement("div"); + gttSection.style.marginBottom = "8px"; + gttSection.style.display = "none"; // hidden until we know it's an APU + + const gttLabel = document.createElement("div"); + gttLabel.className = "amd-gtt-label"; + gttLabel.textContent = "Unified RAM (GTT):"; + gttLabel.style.marginBottom = "2px"; + + const gttBarContainer = document.createElement("div"); + gttBarContainer.style.height = "15px"; + gttBarContainer.style.backgroundColor = "#333"; + gttBarContainer.style.borderRadius = "3px"; + gttBarContainer.style.position = "relative"; + + const gttBar = document.createElement("div"); + gttBar.className = "amd-gtt-bar"; + gttBar.style.height = "100%"; + gttBar.style.width = "0%"; + gttBar.style.backgroundColor = "#a78bfa"; // Purple to distinguish from VRAM + gttBar.style.borderRadius = "3px"; + gttBar.style.transition = "width 0.5s ease-out, background-color 0.3s"; + + const gttText = document.createElement("div"); + gttText.className = "amd-gtt-text"; + gttText.textContent = "0MB / 0MB (0%)"; + gttText.style.position = "absolute"; + gttText.style.top = "0"; + gttText.style.left = "5px"; + gttText.style.lineHeight = "15px"; + gttText.style.textShadow = "1px 1px 1px #000"; + + gttBarContainer.appendChild(gttBar); + gttBarContainer.appendChild(gttText); + gttSection.appendChild(gttLabel); + gttSection.appendChild(gttBarContainer); + content.appendChild(gttSection); + // Temperature section const tempSection = document.createElement("div"); - + const tempLabel = document.createElement("div"); tempLabel.textContent = "GPU Temperature:"; tempLabel.style.marginBottom = "2px"; @@ -304,80 +343,78 @@ const createMonitorElement = () => { // Initial visibility check updateShowButtonVisibility(); - return { container, gpuBar, gpuText, vramBar, vramText, tempBar, tempText }; + return { container, gpuBar, gpuText, vramBar, vramText, vramLabel, vramSection, gttBar, gttText, gttSection, gttLabel, tempBar, tempText }; +}; + +const formatMemText = (usedMB, totalMB, percent) => { + if (totalMB >= 1024) { + return `${(usedMB / 1024).toFixed(1)}GB / ${(totalMB / 1024).toFixed(1)}GB (${percent}%)`; + } + return `${usedMB}MB / ${totalMB}MB (${percent}%)`; +}; + +const barColor = (percent, low = '#47a0ff', mid = '#ffad33', high = '#ff4d4d', midThresh = 70, highThresh = 85) => { + if (percent > highThresh) return high; + if (percent > midThresh) return mid; + return low; }; // Update the monitor UI with new data const updateMonitorUI = (monitor, data) => { // Check if we have GPU data if (!data || !data.gpus || data.gpus.length === 0) return; - + const gpu = data.gpus[0]; // Use the first GPU - + const isAPU = !!gpu.is_apu; + // Update GPU utilization if (monitor.gpuBar && monitor.gpuText) { const utilization = gpu.gpu_utilization || 0; monitor.gpuBar.style.width = `${utilization}%`; monitor.gpuText.textContent = `${utilization}%`; - - // Change color based on utilization - if (utilization > 80) { - monitor.gpuBar.style.backgroundColor = '#ff4d4d'; // Red for high - } else if (utilization > 50) { - monitor.gpuBar.style.backgroundColor = '#ffad33'; // Orange for medium - } else { - monitor.gpuBar.style.backgroundColor = '#47a0ff'; // Blue for low - } + monitor.gpuBar.style.backgroundColor = barColor(utilization, '#47a0ff', '#ffad33', '#ff4d4d', 50, 80); } - - // Update VRAM usage + + // Update VRAM usage — on APUs this is a small pre-allocated pool; label accordingly if (monitor.vramBar && monitor.vramText) { const vramPercent = gpu.vram_used_percent || 0; const vramUsed = gpu.vram_used || 0; const vramTotal = gpu.vram_total || 1; - + monitor.vramBar.style.width = `${vramPercent}%`; - - // Format the text to show MB or GB - let vramUsedText = vramUsed; - let vramTotalText = vramTotal; - let unit = 'MB'; - - if (vramTotal >= 1024) { - vramUsedText = (vramUsed / 1024).toFixed(1); - vramTotalText = (vramTotal / 1024).toFixed(1); - unit = 'GB'; + monitor.vramText.textContent = formatMemText(vramUsed, vramTotal, vramPercent); + monitor.vramBar.style.backgroundColor = barColor(vramPercent); + + // On APUs, VRAM is just the small reserved pool — label it clearly + if (monitor.vramLabel) { + monitor.vramLabel.textContent = isAPU ? "VRAM (reserved pool):" : "VRAM Usage:"; } - - monitor.vramText.textContent = `${vramUsedText}${unit} / ${vramTotalText}${unit} (${vramPercent}%)`; - - // Change color based on VRAM usage - if (vramPercent > 85) { - monitor.vramBar.style.backgroundColor = '#ff4d4d'; // Red for high - } else if (vramPercent > 70) { - monitor.vramBar.style.backgroundColor = '#ffad33'; // Orange for medium - } else { - monitor.vramBar.style.backgroundColor = '#47a0ff'; // Blue for low + } + + // Show/update GTT (unified RAM) section for APUs + if (monitor.gttSection) { + const hasGTT = (gpu.gtt_total || 0) > 0; + monitor.gttSection.style.display = (isAPU && hasGTT) ? "block" : "none"; + + if (isAPU && hasGTT && monitor.gttBar && monitor.gttText) { + const gttPercent = gpu.gtt_used_percent || 0; + const gttUsed = gpu.gtt_used || 0; + const gttTotal = gpu.gtt_total || 1; + + monitor.gttBar.style.width = `${gttPercent}%`; + monitor.gttText.textContent = formatMemText(gttUsed, gttTotal, gttPercent); + // Purple baseline; warn orange/red as system RAM fills up + monitor.gttBar.style.backgroundColor = barColor(gttPercent, '#a78bfa', '#ffad33', '#ff4d4d'); } } - + // Update temperature if (monitor.tempBar && monitor.tempText) { const temp = gpu.gpu_temperature || 0; - - // Assume max reasonable temp is 100°C for the progress bar const tempPercent = Math.min(temp, 100); monitor.tempBar.style.width = `${tempPercent}%`; monitor.tempText.textContent = `${temp}°C`; - - // Change color based on temperature - if (temp > 80) { - monitor.tempBar.style.backgroundColor = '#ff4d4d'; // Red for high - } else if (temp > 60) { - monitor.tempBar.style.backgroundColor = '#ffad33'; // Orange for medium - } else { - monitor.tempBar.style.backgroundColor = '#47a0ff'; // Blue for low - } + monitor.tempBar.style.backgroundColor = barColor(temp, '#47a0ff', '#ffad33', '#ff4d4d', 60, 80); } }; From ac78a8c67991c8d33e9cd576ffdd4ebcfb05d94b Mon Sep 17 00:00:00 2001 From: DasPauluteli <67437654+DasPauluteli@users.noreply.github.com> Date: Sat, 14 Mar 2026 13:38:41 +0100 Subject: [PATCH 2/5] Add files via upload --- screenshot2.png | Bin 0 -> 17885 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 screenshot2.png diff --git a/screenshot2.png b/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..9a7ab9e5ba71a258e77fabbe2f611d57944333f2 GIT binary patch literal 17885 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 FV1mO)6|evR literal 0 HcmV?d00001 From eabc95bc10854b613e68d564008c3f37e7d5a920 Mon Sep 17 00:00:00 2001 From: DasPauluteli <67437654+DasPauluteli@users.noreply.github.com> Date: Sat, 14 Mar 2026 13:40:57 +0100 Subject: [PATCH 3/5] Add APU monitor screenshot to README Added a screenshot for AMD APU monitoring. Currently doesn't load due to missing image in iDAPPA's repo. Will properly load once merged. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b47d947..27bb239 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ A simple, lightweight AMD GPU monitoring tool for ComfyUI that displays real-time information about your AMD GPU directly in the UI. Supports both discrete AMD GPUs and APUs with unified memory (e.g. Strix Halo / gfx1151). ![AMD GPU Monitor Screenshot](https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor/raw/main/screenshot.png) +![AMD APU Monitor Screenshot](https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor/blob/main/screenshot2.png) ## Features From 8bcece89e9e59e7ad09a09e1821accecdb0f6a47 Mon Sep 17 00:00:00 2001 From: DasPauluteli <67437654+DasPauluteli@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:27:45 +0200 Subject: [PATCH 4/5] Update README with amdsmi installation info Added installation instructions for amdsmi on Arch-based distros. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 27bb239..c5fbdb3 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ git clone https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor.git ## Requirements - An AMD GPU with ROCm support -- `rocm-smi` or `amd-smi` command-line tools installed and accessible in your PATH +- `rocm-smi` or `amd-smi` command-line tools installed and accessible in your PATH (On arch based distros: `pacman -S amdsmi`) - ComfyUI running on a Linux system with ROCm drivers ## Usage From 7bf6ed2f8cd96465b5095747c368e96ddb4c4262 Mon Sep 17 00:00:00 2001 From: DasPauluteli <67437654+DasPauluteli@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:04:00 +0200 Subject: [PATCH 5/5] updated readme.md --- README.md | 3 +-- screenshot.png | Bin 15459 -> 18234 bytes 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c5fbdb3..12b15e0 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ A simple, lightweight AMD GPU monitoring tool for ComfyUI that displays real-time information about your AMD GPU directly in the UI. Supports both discrete AMD GPUs and APUs with unified memory (e.g. Strix Halo / gfx1151). -![AMD GPU Monitor Screenshot](https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor/raw/main/screenshot.png) -![AMD APU Monitor Screenshot](https://github.com/iDAPPA/ComfyUI-AMDGPUMonitor/blob/main/screenshot2.png) +![AMD GPU Monitor Screenshot](./screenshot.png) ## Features diff --git a/screenshot.png b/screenshot.png index 65e999201ba0fb6622ea8490f1d03273e89ee7ea..8efbe8f396513da463a63ea787e149d225509054 100644 GIT binary patch literal 18234 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%0Dg?wF7JZJgyz(gy|%Ua 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