Skip to content

Add T-Head PPU monitoring through HGML - #546

Merged
Syllo merged 14 commits into
Syllo:masterfrom
playnee:feat/t-head-ppu-support
Nov 14, 2026
Merged

Syllo merged 14 commits into
Syllo:masterfrom
playnee:feat/t-head-ppu-support

Conversation

@playnee

@playnee playnee commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Adds monitoring for T-Head PPUs through the dynamically loaded HGML runtime. PPU devices now appear in NVTOP with utilization, memory, compute/memory clocks, temperature, power, PCIe telemetry, and compute process memory and utilization.

  • Enable PPU_SUPPORT by default on Linux without requiring vendor development headers at build time.
  • Use the HGML PCI ABI and normalize PCI addresses without truncating their function number; label device charts as PPU.
  • Match the newest valid SM utilization sample to each PID, track timestamps per device, and bound buffer-resize retries. Unsupported metrics, failed queries, and refreshes without fresh process samples remain unavailable rather than retaining stale percentages.
  • Add standalone backend tests and document runtime discovery and sampling behavior.

Validation:

  • Built the full application with PPU_SUPPORT=ON; CTest passed.
  • Backend tests passed with AddressSanitizer and UndefinedBehaviorSanitizer locally and on Linux, covering PCI normalization, optional metrics, process enumeration, buffer growth, unavailable memory, out-of-order utilization samples, timestamp deduplication, invalid percentages, and query failures.
  • Tested against HGML on a Linux host with 16 PPU-ZW810E devices, each with 96 GiB of memory. Verified device telemetry, compute process enumeration, repeated process utilization sampling, and interactive startup/refresh/exit.
  • Observed live SGLang process utilization values including 1%, 4%, 8%, 10%, and 14% in NVTOP.

playnee and others added 14 commits November 4, 2026 15:30
HGML defines hgmlDevice_t as a struct containing the opaque handle
pointer, not as a pointer typedef. The old definition happened to work
through the calling convention, but it did not match the ABI in hgml.h.
Use the same wrapper struct as the SDK and update the test mock.
HGML uses a 28-byte busId and puts globalPpuId at offset 64, keeping
the structure the same size as NVML's PCI info. The previous 32-byte
busId shifted globalPpuId to offset 68 and made the structure four
bytes too large. Assert the expected layout in the backend test.
The clock, temperature, and PCIe selectors are HGML enums, not plain
unsigned values. Declare the corresponding types and use their named
constants so the dynamically loaded prototypes match hgml.h exactly.
Mark processes without a fresh utilization sample as 0% when the HGML
query succeeded or reported no samples, so idle processes do not show
N/A. Leave the value unset when per-process utilization is unavailable
or the query fails. Update the tests and documentation accordingly.
Use reallocarray and COMMON_PROCESS_LINEAR_REALLOC_INC so adding a
process does not reallocate on every refresh. Check the addition for
overflow and keep the existing graceful failure behavior.
Add add_sanitizers(ppuTests) and HAS_REALLOCARRAY like the NVIDIA test.
Cover PCI normalization failures and fallback, static information,
invalid dynamic values, and an empty process list.
Preserve dlerror() on load failures, use hgmlErrorString() for HGML
return codes when available, and include strerror() for allocation
failures. Reset the error state after a successful initialization.
Fall back to the unversioned hgmlDeviceGetPciInfo when the v3/v2
symbols are missing, and prefer hgmlDeviceGetMemoryInfo_v2 with a v1
fallback. Test both memory paths and the missing PCI symbol.
Merge the duplicate supported-vendor list, add the HGML build
dependency, reflow the T-Head section, and clarify that process
enumeration is compute-only.
hgmlDeviceGetTemperature is deprecated as of HGML API 13 in favor of
hgmlDeviceGetTemperatureV, which takes an hgmlTemperature_t and reports
the sensor type explicitly. Load the versioned symbol when present and
fall back to the legacy query for older runtimes or when it fails.

A negative temperature from the versioned query is HGML's "not
available" sentinel, so leave the value unset instead of falling back
to a possibly stale legacy reading.
A failed initialization left the dynamically loaded HGML function
pointers dangling after dlclose, and calling get_device_handles twice
would overwrite the previous device array and leak it. Clear the loaded
symbols on shutdown and before a fresh load, make initialization
idempotent, and refuse to enumerate the same devices twice.

Add tests for the symbol cleanup and the double-enumeration guard.
@Syllo
Syllo merged commit 1e7f594 into Syllo:master Nov 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants