Skip to content

refactor(vGPUmonitor): use nvml.Interface - #2629

Closed
Kanika0306 wants to merge 1 commit into
Project-HAMi:masterfrom
Kanika0306:refactor/vgpu-monitor-nvml-interface
Closed

refactor(vGPUmonitor): use nvml.Interface#2629
Kanika0306 wants to merge 1 commit into
Project-HAMi:masterfrom
Kanika0306:refactor/vgpu-monitor-nvml-interface

Conversation

@Kanika0306

@Kanika0306 Kanika0306 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Refactors cmd/vGPUmonitor to replace package-level NVML CGo calls with the injected nvml.Interface.

This removes the direct dependency on package-level NVML symbols such as nvml.SUCCESS and nvml.ERROR_NOT_SUPPORTED and makes vGPUmonitor consistent with the interface-based NVML usage in the project.

Changes

  • Replaced package-level NVML CGo calls with nvml.Interface.
  • Updated vGPUmonitor to use the injected NVML interface.
  • Removed direct usage of package-level NVML return-code constants where applicable.
  • Updated the affected code to preserve the existing behavior.
  • Updated tests/mocks where required.

Why?

Using nvml.Interface keeps the implementation consistent with the project's dependency-injection approach and makes the code easier to test and maintain.

It also avoids relying on package-level NVML CGo symbols that are not available through the interface-based implementation.

Testing

  • Ran the relevant tests for cmd/vGPUmonitor.
  • Ran make verify.
  • Verified that the refactored implementation preserves the existing behavior.

Related Issue

Closes #2627

AI Assistance Disclosure

I consulted ChatGPT to understand the codebase and the NVML interface usage. The implementation was reviewed and understood by me, and I verified the changes and tests locally.

Summary by CodeRabbit

  • New Features

    • Monitoring continues operating in environments without NVIDIA GPU management support.
    • GPU metrics are collected when NVIDIA management support is available.
  • Bug Fixes

    • Improved handling and reporting of GPU management initialization and status errors.
    • Prevented failures or crashes when GPU support is unavailable.
  • Tests

    • Added coverage for monitoring and metrics collection without GPU management support.

Copilot AI lite review requested due to automatic review settings August 12, 2026 19:32
@hami-robot
hami-robot Bot requested review from DSFans2014 and FouoF August 12, 2026 19:32
@hami-robot

hami-robot Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Kanika0306
Once this PR has been reviewed and has the lgtm label, please assign fouof 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

@Kanika0306

Copy link
Copy Markdown
Contributor Author

/assign

@hami-robot hami-robot Bot added the size/L label Aug 12, 2026
@github-actions github-actions Bot added the kind/enhancement New feature or request label Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: 50388452-5ec9-401f-93d0-606c2b7f58a7

📥 Commits

Reviewing files that changed from the base of the PR and between 635acd5 and f47146d.

📒 Files selected for processing (1)
  • cmd/vGPUmonitor/main.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/vGPUmonitor/main.go

📝 Walkthrough

Walkthrough

The vGPU monitor now receives an injected nvml.Interface. Production startup creates one shared implementation. Metrics and feedback paths support nil NVML operation, use interface methods, and wrap NVML status errors for errors.Is checks.

Changes

NVML interface injection

Layer / File(s) Summary
NVML dependency wiring
cmd/vGPUmonitor/main.go, cmd/vGPUmonitor/metrics.go, go.mod
Startup creates one NVML implementation and passes it to feedback monitoring and NewClusterManager. ClusterManager stores the interface. The Prometheus client model dependency is direct.
Injected GPU metric collection
cmd/vGPUmonitor/metrics.go, cmd/vGPUmonitor/metrics_test.go
GPU collection uses injected NVML methods, skips physical metrics when the interface is nil, and wraps NVML status errors. Tests cover nil-NVML collection.
Feedback degraded operation
cmd/vGPUmonitor/feedback.go, cmd/vGPUmonitor/feedback_test.go
Feedback monitoring conditionally initializes and shuts down NVML. Nil NVML support and canceled-context handling are tested.

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

Possibly related PRs

Suggested reviewers: fouof, dsfans2014

Poem

A rabbit checks the GPU glow,
Through interfaces data flows.
Nil NVML? The monitor stays,
Wrapped errors guide its ways.
Metrics hop, and feedback runs. 🐇

🚥 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 identifies the primary refactor to use nvml.Interface in vGPUmonitor.
Linked Issues check ✅ Passed The changes implement the requested NVML interface injection, nil guards, production initialization, error handling, and mock-oriented tests for issue #2627.
Out of Scope Changes check ✅ Passed The changes remain focused on NVML dependency injection, compatibility, testing, and the related direct dependency declaration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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: 2

🤖 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 `@cmd/vGPUmonitor/main.go`:
- Line 105: Update start to create a single nvml.Interface instance, then pass
that shared interface to both watchAndFeedback and initMetrics instead of
constructing NVML objects independently. Adjust the affected function signatures
and call sites while preserving existing monitoring and metrics behavior.

In `@cmd/vGPUmonitor/nvml_degraded_test.go`:
- Line 1: Add the repository’s standard Apache 2.0 license header to the top of
the new Go file, before the package declaration in the main package.
🪄 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: 7a3363dc-c421-4e3d-aa71-8ce12b653819

📥 Commits

Reviewing files that changed from the base of the PR and between e34913f and 0744b23.

📒 Files selected for processing (5)
  • cmd/vGPUmonitor/feedback.go
  • cmd/vGPUmonitor/main.go
  • cmd/vGPUmonitor/metrics.go
  • cmd/vGPUmonitor/nvml_degraded_test.go
  • commit_message.txt

Comment thread cmd/vGPUmonitor/main.go Outdated
Comment thread cmd/vGPUmonitor/nvml_degraded_test.go Outdated
@@ -0,0 +1,48 @@
package main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add the Apache 2.0 license header.

This new Go file has no required license header. Copy the standard Apache 2.0 header from an existing repository Go file.

As per coding guidelines, "**/*.go: All Go files require an Apache 2.0 license header."

🤖 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 `@cmd/vGPUmonitor/nvml_degraded_test.go` at line 1, Add the repository’s
standard Apache 2.0 license header to the top of the new Go file, before the
package declaration in the main package.

Source: Coding guidelines

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors cmd/vGPUmonitor to stop using package-level NVML CGo calls directly and instead use an injected nvml.Interface, aligning vGPUmonitor with the interface-based NVML dependency-injection pattern used elsewhere in HAMi (per issue #2627). It also adds tests to ensure the “degraded mode” behavior works when no NVML interface is provided.

Changes:

  • Inject nvml.Interface into the vGPUmonitor GPU metrics collection path and update NVML init/device discovery to use the interface.
  • Update watchAndFeedback to accept an nvml.Interface and support a nil-interface degraded mode.
  • Add unit tests covering nil-NVML degraded behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
commit_message.txt Documents the refactor and the added degraded-mode unit tests.
cmd/vGPUmonitor/nvml_degraded_test.go Adds focused tests ensuring nil-NVML degraded paths return promptly and without error.
cmd/vGPUmonitor/metrics.go Refactors NVML usage to go through injected nvml.Interface and adds a nil guard to skip physical GPU metrics when NVML isn’t configured.
cmd/vGPUmonitor/main.go Wires a real NVML interface (nvml.New()) into metrics and feedback paths.
cmd/vGPUmonitor/feedback.go Updates watchAndFeedback to use injected NVML and adds degraded-mode behavior when NVML is nil.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/vGPUmonitor/main.go
Comment on lines 103 to 106
wg.Go(func() {
for {
if err := watchAndFeedback(ctx, containerLister, lockChannel); err != nil {
if err := watchAndFeedback(ctx, containerLister, nvmlgo.New(), lockChannel); err != nil {
// if err is temporary closed, wait for lock file to be removed
@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch from 0744b23 to cd4b363 Compare August 12, 2026 19:38
return fmt.Errorf("nvml Init err: %s", nvml.ErrorString(nvret))
func (cc ClusterManagerCollector) initNVML(nvmllib nvml.Interface) error {
nvret := nvmllib.Init()
if !errors.Is(nvret, nvml.SUCCESS) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pr body and coderabbit both say tests were added or updated, but no _test.go file is in this diff. where are they?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching that! The test additions were previously omitted from the commit diff. I have now added unit tests in metrics_test.go (TestCollectGPUInfo_NilNVML) and feedback_test.go (TestWatchAndFeedback_NilNVML) covering NewClusterManager, collectGPUInfo, and watchAndFeedback under a nil NVML interface / degraded mode

return 0, fmt.Errorf("nvml GetDeviceCount err: %s", nvml.ErrorString(nvret))
func (cc ClusterManagerCollector) getDeviceCount(nvmllib nvml.Interface) (int, error) {
devnum, nvret := nvmllib.DeviceGetCount()
if !errors.Is(nvret, nvml.SUCCESS) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

does errors.Is(nvret, nvml.SUCCESS) behave any differently than nvret == nvml.SUCCESS here? why pick errors.Is?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

nvret is of type nvml.Return, which satisfies the standard Go error interface (Error() string). Using errors.Is(nvret, nvml.SUCCESS) follows the established convention across HAMi (e.g. pkg/device/nvidia/links.go:127,159), providing idiomatic Go error checking for types implementing error and supporting unwrapping.

@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.81159% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/vGPUmonitor/feedback.go 46.66% 8 Missing ⚠️
cmd/vGPUmonitor/metrics.go 89.79% 4 Missing and 1 partial ⚠️
cmd/vGPUmonitor/main.go 40.00% 3 Missing ⚠️
Flag Coverage Δ
unittests 63.46% <76.81%> (+1.01%) ⬆️

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

Files with missing lines Coverage Δ
cmd/vGPUmonitor/main.go 26.02% <40.00%> (+16.30%) ⬆️
cmd/vGPUmonitor/metrics.go 73.65% <89.79%> (+28.80%) ⬆️
cmd/vGPUmonitor/feedback.go 48.27% <46.66%> (+26.84%) ⬆️

... and 2 files with indirect coverage changes

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

@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch 5 times, most recently from f47146d to 5a900e3 Compare August 12, 2026 20:27
@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch 6 times, most recently from cd938ff to 80ec41b Compare August 12, 2026 21:14
@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch from 80ec41b to 6bae21b Compare August 12, 2026 21:20
@FouoF

FouoF commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Can you explain what is the key difference of nvml.Interface and NVML CGo and why we should refactor?

@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch from 6bae21b to a90b40a Compare August 13, 2026 05:46
…ics collection

This refactor decouples the vGPUmonitor metrics collector from package-level
NVML calls by accepting an nvml.Interface value through NewClusterManager and
propagating it through the internal collect* helpers.

Changes:
- cmd/vGPUmonitor/metrics.go: store nvml.Interface on ClusterManager; thread
  it through collectGPUInfo, initNVML, getDeviceCount, collectGPUDeviceMetrics,
  and collectGPUUtilizationMetrics; guard all collect helpers against nil
  ClusterManager / PodLister; wrap NVML returns with errors.Is for idiomatic
  error comparison; guard NewClusterManager informer setup behind a nil check.
- cmd/vGPUmonitor/main.go: pass nvml.New() to NewClusterManager and
  initMetrics so production code still uses the real library.
- cmd/vGPUmonitor/feedback.go: alias klog import for clarity; downgrade
  debug-only klog.V(5) calls to klog.Infof for visible feedback in logs.
- cmd/vGPUmonitor/metrics_test.go: add TestCollectGPUInfo_NilNVML,
  TestNewClusterManager, TestInitMetrics, TestCollectGPUInfo_Success,
  and TestCollectGPUInfo_ErrorPaths using nvml/mock.
- cmd/vGPUmonitor/feedback_test.go: add TestWatchAndFeedback_WithNVMLSuccess,
  TestWatchAndFeedback_WithNVMLError, TestWatchAndFeedback_MigLockSignal.

Signed-off-by: Kanika0306 <kanikakatare0306@gmail.com>
@Kanika0306
Kanika0306 force-pushed the refactor/vgpu-monitor-nvml-interface branch from a90b40a to 36ef0cc Compare August 13, 2026 07:10
@hami-robot hami-robot Bot added size/XL and removed size/L labels Aug 13, 2026
@Kanika0306

Copy link
Copy Markdown
Contributor Author

Can you explain what is the key difference of nvml.Interface and NVML CGo and why we should refactor?

Here's a version formatted to read naturally as a PR reply comment (less "generated report," more like an actual contributor explaining their reasoning):


Good question — happy to explain.

The core difference: the old code called NVML functions directly as package-level globals (nvml.Init(), nvml.DeviceGetCount(), etc.), which are backed by CGo bindings to libnvidia-ml.so. The refactor wraps these behind nvml.Interface, so the code calls nvmllib.Init() on an injected interface value instead. In production we still pass in the real thing via nvml.New() — behavior doesn't change. But now anything that needs to use NVML depends on an abstraction, not a hardcoded global.

Why that matters:

  1. Testability. Direct nvml.Init() calls require libnvidia-ml.so and an actual NVIDIA driver on the host. Without it you get ERROR_LIBRARY_NOT_FOUND or a panic — meaning none of this code could be unit tested in CI or on a dev machine without a GPU. With nvml.Interface, tests just pass in a mock from github.com/NVIDIA/go-nvml/pkg/nvml/mock, so I can deterministically test success paths, specific error codes (ERROR_UNKNOWN, ERROR_NOT_SUPPORTED, etc.), and the degraded-mode fallback — all without touching real hardware.

  2. Dev environment / tooling friction. Package-level CGo symbols cause gopls/IDEs on non-Linux or non-CGo setups to choke on unresolved symbols. Isolating the CGo dependency to a single nvml.New() call in main.go keeps the rest of the package clean to build, lint, and autocomplete on any OS.

  3. Resilience. If nvmllib is nil or Init() fails, vGPUmonitor now degrades gracefully — it skips physical GPU metric collection but keeps container observation and pod tracking running instead of crashing outright.

No functional change intended for the production path — nvml.New() still talks to the same driver the same way. This just makes the collection logic testable and decouples it from a hard CGo dependency at compile/test time, matching the pattern already used elsewhere in the codebase (e.g. pkg/device/nvidia).

@Kanika0306

Copy link
Copy Markdown
Contributor Author

/assign

@Kanika0306
Kanika0306 requested a review from mesutoezdil August 13, 2026 12:46
@mesutoezdil

Copy link
Copy Markdown
Contributor

This is being closed because it does not comply with the contribution guidelines.

@Kanika0306

Copy link
Copy Markdown
Contributor Author

This is being closed because it does not comply with the contribution guidelines.

could you let me know why it does not because all the test cases pass here

@mesutoezdil

Copy link
Copy Markdown
Contributor

This is being closed because it does not comply with the contribution guidelines.

could you let me know why it does not because all the test cases pass here

pls read the contributions rules.
we dont have time and energy for llm answers.
you SHOULD understand your codes and answer with your words.

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.

cmd/vGPUmonitor: Replace package-level NVML CGo calls with nvml.Interface

4 participants