Skip to content

feat(monitor): add DeviceProcessCount metric to expose tracked GPU process count - #2505

Closed
Nakshatra480 wants to merge 1 commit into
Project-HAMi:masterfrom
Nakshatra480:feat/container-device-process-count-metric
Closed

feat(monitor): add DeviceProcessCount metric to expose tracked GPU process count#2505
Nakshatra480 wants to merge 1 commit into
Project-HAMi:masterfrom
Nakshatra480:feat/container-device-process-count-metric

Conversation

@Nakshatra480

@Nakshatra480 Nakshatra480 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Add hami_container_device_process_count, a per-device Prometheus gauge
that reports the number of process slots in a container's shared-memory
region that have status != 0 and a nonzero memory footprint on the
queried virtual device.

Why this matters: When a child process or a process reached through SSH
bypasses libvgpu's LD_PRELOAD hook it never gets a shared-memory slot
allocated. The count therefore drops below the real number of CUDA processes
in the container. Operators and alert rules can use this metric to detect
GPU memory isolation failures early before a memory overrun occurs by
comparing hami_container_device_process_count against the expected number
of tracked GPU processes.

Changes

File Change
pkg/monitor/nvidia/cudevshr.go Add DeviceProcessCount(idx int) int to UsageInfo interface
pkg/monitor/nvidia/v0/spec.go Implement: counts slots where status != 0 and total+contextSize+moduleSize > 0 for device idx
pkg/monitor/nvidia/v1/spec.go Identical implementation for v1 layout
pkg/monitor/nvidia/v0/spec_test.go 5 unit tests: no processes, one active, device-specific exclusion, dead slot, corrupt procnum
pkg/monitor/nvidia/v1/spec_test.go Same 5 cases for v1
cmd/vGPUmonitor/feedback_test.go Add stub method to satisfy updated interface
cmd/vGPUmonitor/metrics.go Register ctrDeviceProcessCountDesc, emit in collectContainerMetrics
cmd/vGPUmonitor/metrics_container_test.go Update expected metric counts and add count to want map

Example output

hami_container_device_process_count{container="worker",device_uuid="GPU-abc123...", namespace="team-a",pod="trainer-0",vdevice_index="0"} 2

If a child process escapes slot tracking, this drops to 1 while the real
GPU process count remains 2, the isolation failure becomes immediately
observable in Grafana.

Which issue(s) this PR fixes:
Part of #2126 (LFX observability hardening)

AI Disclosure:
AI assistance was used for code inspection and draft formatting; all logic,
test cases, and verification were manually reviewed and validated.

Summary by CodeRabbit

  • New Features

    • Added a Prometheus metric reporting active processes using each container’s device.
    • Process counts are calculated per device and exclude inactive or invalid entries.
    • Available across supported NVIDIA monitoring versions.
  • Bug Fixes

    • Improved resilience when processing malformed device process data.
  • Tests

    • Added coverage for device-specific counts, inactive processes, terminated entries, context-only usage, and invalid data.

@hami-robot
hami-robot Bot requested review from DSFans2014 and FouoF August 9, 2026 10:18
@hami-robot

hami-robot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Nakshatra480
Once this PR has been reviewed and has the lgtm label, please assign wawa0210 for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions github-actions Bot added the kind/feature new function label Aug 9, 2026
@hami-robot hami-robot Bot added the size/L label Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 239ddb23-c5a1-4dd7-a350-e4108cd4238c

📥 Commits

Reviewing files that changed from the base of the PR and between b639414 and a9b22c3.

📒 Files selected for processing (4)
  • pkg/monitor/nvidia/v0/spec.go
  • pkg/monitor/nvidia/v0/spec_test.go
  • pkg/monitor/nvidia/v1/spec.go
  • pkg/monitor/nvidia/v1/spec_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/monitor/nvidia/v1/spec.go
  • pkg/monitor/nvidia/v0/spec.go
  • pkg/monitor/nvidia/v0/spec_test.go
  • pkg/monitor/nvidia/v1/spec_test.go

📝 Walkthrough

Walkthrough

The NVIDIA monitor now counts active processes for each device and exports the count as a container-device Prometheus gauge. The v0 and v1 implementations bound process-slot access and check process status and memory usage.

Changes

Device process metrics

Layer / File(s) Summary
Process count API and implementations
pkg/monitor/nvidia/cudevshr.go, pkg/monitor/nvidia/v0/spec.go, pkg/monitor/nvidia/v1/spec.go, pkg/monitor/nvidia/*/spec_test.go, cmd/vGPUmonitor/feedback_test.go
UsageInfo and both NVIDIA specification versions now implement DeviceProcessCount. Tests cover inactive, dead, device-mismatched, context-only, module-only, and invalid process slots.
Container metric collection
cmd/vGPUmonitor/metrics.go, cmd/vGPUmonitor/metrics_container_test.go
The collector describes and emits the per-device process-count gauge. Container metric tests include the new metric and updated metric counts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ContainerCollector
  participant UsageInfo
  participant NVIDIASpec
  participant Prometheus

  ContainerCollector->>UsageInfo: Request DeviceProcessCount(device index)
  UsageInfo->>NVIDIASpec: Count bounded active process slots
  NVIDIASpec-->>UsageInfo: Return device process count
  UsageInfo-->>ContainerCollector: Return count
  ContainerCollector->>Prometheus: Emit process-count gauge
Loading

Possibly related PRs

Suggested reviewers: dsfans2014, fouof

Poem

A rabbit counts each process slot,
Checks the memory each one has got.
The gauge reports the device view,
And tests confirm the count is true.
Prometheus hops with data new.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding the DeviceProcessCount metric to monitor tracked GPU processes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/monitor/nvidia/v1/spec_test.go (1)

1392-1470: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the combined memory footprint.

Add cases where total is zero and contextSize or moduleSize is nonzero. The current cases do not detect the total-only predicate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/monitor/nvidia/v1/spec_test.go` around lines 1392 - 1470, Extend
TestSpec_DeviceProcessCount with cases where deviceMemory.total is zero but
contextSize or moduleSize is nonzero, covering each field and the expected
process-count behavior. Keep the existing active-process and device-selection
coverage unchanged, and ensure the assertions detect whether DeviceProcessCount
uses the combined memory footprint rather than total alone.
pkg/monitor/nvidia/v0/spec_test.go (1)

492-570: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test the combined memory footprint.

Add cases where total is zero and contextSize or moduleSize is nonzero. The current cases do not detect the total-only predicate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/monitor/nvidia/v0/spec_test.go` around lines 492 - 570, Extend
TestSpec_DeviceProcessCount with cases where a process has zero
deviceMemory.total but a nonzero contextSize or moduleSize on the selected
device, and assert it is counted. Keep the existing total-memory cases and vary
the fields independently so the test verifies the combined memory-footprint
predicate rather than total alone.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/monitor/nvidia/v0/spec.go`:
- Around line 165-173: Update Spec.DeviceProcessCount in
pkg/monitor/nvidia/v0/spec.go:165-173 and pkg/monitor/nvidia/v1/spec.go:179-187
to count active slots when total, contextSize, or moduleSize is nonzero. Extend
the existing tests in pkg/monitor/nvidia/v0/spec_test.go:492-570 and
pkg/monitor/nvidia/v1/spec_test.go:1392-1470 with context-only and module-only
cases, preserving the current total-memory coverage.

---

Nitpick comments:
In `@pkg/monitor/nvidia/v0/spec_test.go`:
- Around line 492-570: Extend TestSpec_DeviceProcessCount with cases where a
process has zero deviceMemory.total but a nonzero contextSize or moduleSize on
the selected device, and assert it is counted. Keep the existing total-memory
cases and vary the fields independently so the test verifies the combined
memory-footprint predicate rather than total alone.

In `@pkg/monitor/nvidia/v1/spec_test.go`:
- Around line 1392-1470: Extend TestSpec_DeviceProcessCount with cases where
deviceMemory.total is zero but contextSize or moduleSize is nonzero, covering
each field and the expected process-count behavior. Keep the existing
active-process and device-selection coverage unchanged, and ensure the
assertions detect whether DeviceProcessCount uses the combined memory footprint
rather than total alone.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 84ab2744-9703-4da6-a50d-f8c3f87d548a

📥 Commits

Reviewing files that changed from the base of the PR and between 3616313 and b639414.

📒 Files selected for processing (8)
  • cmd/vGPUmonitor/feedback_test.go
  • cmd/vGPUmonitor/metrics.go
  • cmd/vGPUmonitor/metrics_container_test.go
  • pkg/monitor/nvidia/cudevshr.go
  • pkg/monitor/nvidia/v0/spec.go
  • pkg/monitor/nvidia/v0/spec_test.go
  • pkg/monitor/nvidia/v1/spec.go
  • pkg/monitor/nvidia/v1/spec_test.go

Comment thread pkg/monitor/nvidia/v0/spec.go
…ocess count

Add hami_container_device_process_count, a per-device Prometheus gauge
that reports the number of process slots in a container's shared-memory
region that have status != 0 and a nonzero memory footprint on the
queried device.

When a child process or a process reached through SSH bypasses libvgpu's
LD_PRELOAD hook it never gets a shared-memory slot allocated. The count
therefore drops below the real number of CUDA processes in the container,
giving operators a direct Prometheus signal that GPU memory isolation has
broken down before a memory overrun occurs.

Changes:
- Add DeviceProcessCount(idx int) int to the UsageInfo interface.
- Implement in pkg/monitor/nvidia/v0/spec.go and v1/spec.go.
  Counts process slots where status != 0 and the sum of total,
  contextSize, and moduleSize for device idx is nonzero.
- Add unit tests to v0/spec_test.go and v1/spec_test.go covering:
  no active processes, one active process, process active on a
  different device only, dead slot within procnum, and corrupt
  procnum clamped without panic.
- Add DeviceProcessCount to the stubInfo in feedback_test.go.
- Register ctrDeviceProcessCountDesc and emit the metric in
  collectContainerMetrics alongside the other per-device gauges.
- Update metrics_container_test.go expected metric counts.

Signed-off-by: Nakshatra Sharma <nakshatra.sharma3012@gmail.com>
@Nakshatra480
Nakshatra480 force-pushed the feat/container-device-process-count-metric branch from b639414 to a9b22c3 Compare August 9, 2026 10:24
@codecov

codecov Bot commented Aug 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.35294% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/vGPUmonitor/metrics.go 40.00% 2 Missing and 1 partial ⚠️
Flag Coverage Δ
unittests 64.28% <82.35%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
pkg/monitor/nvidia/cudevshr.go 86.74% <ø> (ø)
pkg/monitor/nvidia/v0/spec.go 96.42% <100.00%> (+0.27%) ⬆️
pkg/monitor/nvidia/v1/spec.go 100.00% <100.00%> (ø)
cmd/vGPUmonitor/metrics.go 43.43% <40.00%> (-0.06%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@FouoF

FouoF commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Thanks for the metrics proposal. DeviceProcessCount is presented as a count of tracked GPU processes, but the implementation counts slots with any non-zero memory, context, or module field. It cannot distinguish the untracked-process case described in the PR and has no independent process inventory against which the value is validated. That would publish a misleading metric contract, so we are closing the current PR. A future proposal should first define the exact population and prove it against a real process source.

@FouoF FouoF closed this Aug 10, 2026
@Nakshatra480

Copy link
Copy Markdown
Contributor Author

Thanks for the metrics proposal. DeviceProcessCount is presented as a count of tracked GPU processes, but the implementation counts slots with any non-zero memory, context, or module field. It cannot distinguish the untracked-process case described in the PR and has no independent process inventory against which the value is validated. That would publish a misleading metric contract, so we are closing the current PR. A future proposal should first define the exact population and prove it against a real process source.

Thank you for the detailed feedback, your point about not having an independent process source to verify the slot count against is a valid one. I will submit a proposal which cross-references either /proc or NVML in order to establish a ground-truth process inventory before the metric is displayed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants