Skip to content

fix(ascend): honor nodeConfig.VDeviceCount in VDeviceCount()#100

Merged
hami-robot[bot] merged 2 commits into
Project-HAMi:mainfrom
Wangmin362:fix/vdevicecount-honor-nodeconfig
Jul 16, 2026
Merged

fix(ascend): honor nodeConfig.VDeviceCount in VDeviceCount()#100
hami-robot[bot] merged 2 commits into
Project-HAMi:mainfrom
Wangmin362:fix/vdevicecount-honor-nodeconfig

Conversation

@Wangmin362

@Wangmin362 Wangmin362 commented Jul 7, 2026

Copy link
Copy Markdown

What this PR does

VDeviceCount() always derived the per-card vDevice count from the global config (MemoryAllocatable / smallest template), ignoring the per-node override loaded into am.nodeConfig — even though the sibling method IsHamiVnpuCore() already prefers am.nodeConfig. As a result, setting vDeviceCount in the node config had no effect: every card kept advertising the global default slice count.

This PR makes VDeviceCount() prefer nodeConfig.VDeviceCount when present and positive, mirroring IsHamiVnpuCore(), and otherwise falls back to the existing global default.

func (am *AscendManager) VDeviceCount() int {
	if am.nodeConfig != nil && am.nodeConfig.VDeviceCount > 0 {
		return am.nodeConfig.VDeviceCount
	}
	if len(am.config.Templates) == 0 {
		return 1
	}
	return int(am.config.MemoryAllocatable / am.config.Templates[0].Memory)
}

Note: the per-node config is only loaded when the plugin is started with --node_config_file. The shipped ascend-device-plugin.yaml mounts the node-config but does not pass that flag; that is fixed separately in #99. This PR is the code side — it makes the loaded value actually take effect.

Unit test

Added a table-driven test TestVDeviceCount in internal/manager/manager_test.go covering: no node config (global default), VDeviceCount=0 (fallback), VDeviceCount>0 (honored + tracks value), and the no-template edge cases.

The test fails on the previous code and passes with this change — proving it pins the bug:

# against the OLD code (before this fix):
--- FAIL: TestVDeviceCount
    --- FAIL: TestVDeviceCount/node_config_VDeviceCount=8_->_honored_(the_fix)
        manager_test.go:96: VDeviceCount() = 4, want 8
    --- FAIL: TestVDeviceCount/node_config_VDeviceCount=2_->_honored,_tracks_the_value
        manager_test.go:96: VDeviceCount() = 4, want 2
    --- FAIL: TestVDeviceCount/no_templates_but_node_override_present_->_node_override_wins
        manager_test.go:96: VDeviceCount() = 1, want 5

# with this fix:
ok  	github.com/Project-HAMi/ascend-device-plugin/internal/manager	0.002s
--- PASS: TestVDeviceCount (0.00s)  [all 6 sub-cases PASS]

Real-hardware verification (8× Ascend 910B4)

Built this branch into an arm64 image and ran it on a real node with 8× Ascend 910B4 (driver 25.5.1, k8s v1.29.15, containerd 1.7.13). To avoid disturbing the node's existing device plugin, the test plugin used a distinct commonWord/resourceName (huawei.com/Ascend910B4-f2test) — a fully isolated, additive registration.

The 910B4 config has memoryAllocatable=32768 and smallest template 8192, so the global default is 32768/8192 = 4 vDevices/card. Evidence, per tier — the per-card count comes from the plugin's own HAMi node-register annotation, cross-checked against the kubelet-advertised resource capacity (8 cards):

node config plugin log per-card count (register annotation) node capacity (8 cards)
(vDeviceCount unset) matched node config … VDeviceCount:0 [4,4,4,4,4,4,4,4] 32
vDeviceCount: 8 matched node config … VDeviceCount:8 [8,8,8,8,8,8,8,8] 64
vDeviceCount: 2 matched node config … VDeviceCount:2 [2,2,2,2,2,2,2,2] 16
  • Unset → global default (4): unchanged behavior, no regression.
  • Set → honored and tracks the value (8→8, 2→2) on real hardware.

All test resources were removed after the run.

Scope / safety of the test

The real-hardware test ran as a fully isolated, additive deployment: a separate namespace, a distinct commonWord/resourceName (huawei.com/Ascend910B4-f2test) so it never collided with the production huawei.com/Ascend910B4 registration or its HAMi node annotations. All test resources were removed afterward and the node was restored to its exact prior state.


AI assistance disclosure (per the project's AI Assistance Notice): the underlying issue was diagnosed from my own testing on real Ascend 910B4 hardware. The one-function change and the unit test were drafted with AI assistance (Claude Code) and then reviewed, built, and verified by me on the hardware described above. I understand the change and stand behind it.

Summary by CodeRabbit

  • Bug Fixes

    • VDeviceCount() now honors a per-node vDevice override when a node configuration is present and the override is greater than zero.
    • When no valid override applies (including missing templates), it falls back to the computed default, using a safe value of 1 as needed.
  • Tests

    • Added unit test coverage for VDeviceCount() across default, node-overridden, zero-value override, and missing-template scenarios.

@coderabbitai

coderabbitai Bot commented Jul 7, 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: ed55cb60-b7eb-43d9-bfaa-bf9c94f47632

📥 Commits

Reviewing files that changed from the base of the PR and between 1ffd7f9 and 304cc80.

📒 Files selected for processing (2)
  • internal/manager/manager.go
  • internal/manager/manager_test.go
💤 Files with no reviewable changes (1)
  • internal/manager/manager.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/manager/manager_test.go

📝 Walkthrough

Walkthrough

Modified VDeviceCount() to return a positive per-node override from nodeConfig before falling back to the existing global config calculation. Added a table-driven unit test covering override and fallback cases.

Changes

VDeviceCount Override

Layer / File(s) Summary
Per-node override and fallback logic
internal/manager/manager.go, internal/manager/manager_test.go
VDeviceCount() now returns am.nodeConfig.VDeviceCount when set and positive, otherwise computes from global VNPUConfig data; the new test covers default, override, zero-fallback, and missing-template cases.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

I hopped to the node for a count so true,
If it’s set and positive, I’ll use that view.
Else back to the defaults, neat and small,
With tests in a row to catch them all. 🐇

🚥 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 states the main fix: VDeviceCount now honors nodeConfig.VDeviceCount.
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

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

Comment thread internal/manager/manager_test.go Outdated
VDeviceCount() always derived the per-card vDevice count from the global
config (MemoryAllocatable / smallest template), ignoring the per-node
override loaded into am.nodeConfig, even though the sibling method
IsHamiVnpuCore() already prefers am.nodeConfig. As a result, setting
vDeviceCount in the node config had no effect and each card kept
advertising the global default slice count.

Prefer nodeConfig.VDeviceCount when it is present and positive, mirroring
IsHamiVnpuCore(); otherwise fall back to the existing global default.

Add a table-driven unit test covering: no node config (global default),
VDeviceCount=0 (fallback), VDeviceCount>0 (honored and tracks the value),
and the no-template edge cases. The test fails on the previous code and
passes with this change.

Signed-off-by: wangmin <wangmin@riseunion.io>
@Wangmin362
Wangmin362 force-pushed the fix/vdevicecount-honor-nodeconfig branch from 0a3f264 to 1ffd7f9 Compare July 8, 2026 02:34

@DSFans2014 DSFans2014 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

Signed-off-by: wangmin <wangmin@riseunion.io>
@hami-robot hami-robot Bot added size/M and removed lgtm size/L labels Jul 8, 2026
@Wangmin362
Wangmin362 force-pushed the fix/vdevicecount-honor-nodeconfig branch from 304cc80 to ef52ad3 Compare July 8, 2026 09:47

@DSFans2014 DSFans2014 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@hami-robot hami-robot Bot added the lgtm label Jul 8, 2026

@archlitchi archlitchi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

@hami-robot

hami-robot Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: archlitchi, Wangmin362

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

The pull request process is described 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

@hami-robot hami-robot Bot added the approved label Jul 16, 2026
@hami-robot
hami-robot Bot merged commit f062939 into Project-HAMi:main Jul 16, 2026
11 checks passed
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.

3 participants