[PR #234] fix(api/device): correct shared-memory accounting on N1X and DGX Spark #233

Open
opened 2026-10-25 22:03:34 -06:00 by gitea-mirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/XuehaiPan/nvitop/pull/234
Author: @johnnynunez
Created: 10/25/2026
Status: 🔄 Open

Base: main ← Head: fix/unified-memory-available


📝 Commits (1)

  • 1f39a73 fix(api/device): correct unified-memory available capacity

📊 Changes

4 files changed (+155 additions, -1 deletions)

View changed files

📝 .github/workflows/lint.yaml (+3 -0)
📝 nvitop/api/device.py (+11 -1)
➕ tests/__init__.py (+1 -0)
➕ tests/test_device_memory.py (+140 -0)

📄 Description

Issue Type

  • Bug fix

Description

Correct the existing unified-memory fallback in Device.memory_info():

  • Report psutil.virtual_memory().available as free shared memory, including reclaimable cache.
  • Report total - available as used shared memory so used + free equals total.
  • Preserve the existing NVML_ERROR_NOT_SUPPORTED and successful zero-total fallback triggers, and reserved memory as N/A.
  • Document that these values describe the shared CPU/GPU system pool, not GPU-only allocations.
  • Add 11 hardware-independent standard-library unittest tests and run them in the existing lint workflow.

Positive-total NVML responses, per-process GPU memory, and other NVML error handling are unchanged. No new dependencies, GPU-name checks, or RAM-size detection heuristics.

Motivation and Context

On coherent shared-memory machines, free excludes reclaimable cache and can severely understate allocatable memory. Combining vm.free with vm.used also gives an inconsistent total on Linux. In the live cache-heavy DGX Spark sample below, the old mapping would report 24.37 GiB free while the OS reports 113.61 GiB available.

Related: #193, #195, #208. This is a narrow accounting correction to the existing fallback, not the positive-total detection change proposed in #208. Raw NVML returned NVMLError_NotSupported on all three tested machines.

Runtime Environment and Hardware Validation

All machines: Linux aarch64, Python 3.14.4, nvidia-ml-py 12.550.89, psutil 7.1.0.

Hardware Driver Kernel System total (GiB) OS free (GiB) Corrected available/free (GiB)
RTX Spark N1X laptop X x 116.02 71.17 90.30
DGX Spark A (GB10) X X 119.56 24.37 113.61
DGX Spark B (GB10) X X 119.56 112.53 115.29

The patched source tree was exercised on all three machines using temporary copies; no system packages or driver configuration were changed.

Testing

  • Regression test observed failing before the production fix; the added accounting tests also fail against unmodified main.
  • python -m unittest discover -s tests -v: 11/11 pass locally and on both DGX Sparks.
  • Python 3.8.20 compatibility: 11/11 pass in an isolated environment.
  • Existing pre-commit hooks on changed files: pass, including Ruff lint/format, codespell, mypy, Pylint (10.00/10), YAML/AST validation, and private-key detection.
  • Live checks on all three machines: shared-memory identities against actual sampled OS data; memory helpers/percentage; oneshot caching; full device snapshots; GPU process enumeration.
  • python -m nvitop --once --readonly: exit 0 on all three; numeric memory totals displayed.
  • Interactive --monitor --readonly --interval 1 in 120x40 PTYs: start, refresh, and quit with q, exit 0 on all three; no tracebacks.

Tests cover both fallback triggers, reclaimable cache, dynamic available capacity and boundaries, derived metrics and oneshot consistency, preserved discrete-GPU v1/v2 results, unavailable results, missing handles, and permission/lost-GPU/unknown errors.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/XuehaiPan/nvitop/pull/234 **Author:** [@johnnynunez](https://github.com/johnnynunez) **Created:** 10/25/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/unified-memory-available` --- ### 📝 Commits (1) - [`1f39a73`](https://github.com/XuehaiPan/nvitop/commit/1f39a732b1ab2533d8d50ed4ca10541bea3b9b43) fix(api/device): correct unified-memory available capacity ### 📊 Changes **4 files changed** (+155 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/lint.yaml` (+3 -0) 📝 `nvitop/api/device.py` (+11 -1) ➕ `tests/__init__.py` (+1 -0) ➕ `tests/test_device_memory.py` (+140 -0) </details> ### 📄 Description #### Issue Type - Bug fix #### Description Correct the existing unified-memory fallback in `Device.memory_info()`: - Report `psutil.virtual_memory().available` as free shared memory, including reclaimable cache. - Report `total - available` as used shared memory so used + free equals total. - Preserve the existing `NVML_ERROR_NOT_SUPPORTED` and successful zero-total fallback triggers, and reserved memory as `N/A`. - Document that these values describe the shared CPU/GPU system pool, not GPU-only allocations. - Add 11 hardware-independent standard-library unittest tests and run them in the existing lint workflow. Positive-total NVML responses, per-process GPU memory, and other NVML error handling are unchanged. No new dependencies, GPU-name checks, or RAM-size detection heuristics. #### Motivation and Context On coherent shared-memory machines, `free` excludes reclaimable cache and can severely understate allocatable memory. Combining `vm.free` with `vm.used` also gives an inconsistent total on Linux. In the live cache-heavy DGX Spark sample below, the old mapping would report 24.37 GiB free while the OS reports 113.61 GiB available. Related: #193, #195, #208. This is a narrow accounting correction to the existing fallback, not the positive-total detection change proposed in #208. Raw NVML returned `NVMLError_NotSupported` on all three tested machines. #### Runtime Environment and Hardware Validation All machines: Linux aarch64, Python 3.14.4, `nvidia-ml-py` 12.550.89, psutil 7.1.0. | Hardware | Driver | Kernel | System total (GiB) | OS free (GiB) | Corrected available/free (GiB) | | --- | --- | --- | ---: | ---: | ---: | | RTX Spark N1X laptop | X | x | 116.02 | 71.17 | 90.30 | | DGX Spark A (GB10) | X | X | 119.56 | 24.37 | 113.61 | | DGX Spark B (GB10) | X | X | 119.56 | 112.53 | 115.29 | The patched source tree was exercised on all three machines using temporary copies; no system packages or driver configuration were changed. #### Testing - Regression test observed failing before the production fix; the added accounting tests also fail against unmodified main. - `python -m unittest discover -s tests -v`: 11/11 pass locally and on both DGX Sparks. - Python 3.8.20 compatibility: 11/11 pass in an isolated environment. - Existing pre-commit hooks on changed files: pass, including Ruff lint/format, codespell, mypy, Pylint (10.00/10), YAML/AST validation, and private-key detection. - Live checks on all three machines: shared-memory identities against actual sampled OS data; memory helpers/percentage; oneshot caching; full device snapshots; GPU process enumeration. - `python -m nvitop --once --readonly`: exit 0 on all three; numeric memory totals displayed. - Interactive `--monitor --readonly --interval 1` in 120x40 PTYs: start, refresh, and quit with `q`, exit 0 on all three; no tracebacks. Tests cover both fallback triggers, reclaimable cache, dynamic available capacity and boundaries, derived metrics and oneshot consistency, preserved discrete-GPU v1/v2 results, unavailable results, missing handles, and permission/lost-GPU/unknown errors. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
github-starred/nvitop#233
No description provided.