Skip to content

refactor(MIG): support MIG instance dynamic allocation/deallocation - #2378

Merged
archlitchi merged 11 commits into
Project-HAMi:masterfrom
FouoF:feat/mig-dynamic-deallocate
Aug 10, 2026
Merged

refactor(MIG): support MIG instance dynamic allocation/deallocation#2378
archlitchi merged 11 commits into
Project-HAMi:masterfrom
FouoF:feat/mig-dynamic-deallocate

Conversation

@FouoF

@FouoF FouoF commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

/kind feature

What this PR does / why we need it:

NVIDIA MIG manager and current dynamic MIG can only apply by node scope, whether it is the former or latter. So changing MIG instances requires drain and cordon the node.

Which issue(s) this PR fixes:

HAMi RoadMap v2.10 Flexible MIG

Special notes for your reviewer:

Added e2e script and already passed on A100-40G * 1 instance.

Known limits:

  1. Current scheduling strategy is prone to resource fragmentation.
  2. There is a regression that CDI in MIG mode is not support now, but it will be implemented soon later.
  3. Multi device cases is still lack support and test, this is the same with current implementation.

Does this PR introduce a user-facing change?:

Only introduce internal API changes, dynamic MIG can use as usual.
MIG related metrics label changed for better match DCGM style.

Summary by CodeRabbit

  • New Features

    • Added dynamic NVIDIA MIG allocation using profile allowlists and topology-aware placement.
    • Preserved MIG reservations and runtime identities across restarts and device-plugin recovery.
    • Added safer startup handling to avoid resetting GPUs with active workloads.
    • Added detailed MIG metrics, including UUIDs, profiles, instance IDs, and placement coordinates.
    • Added clearer scheduling errors for infeasible MIG topologies.
  • Documentation

    • Added guidance for reservation-first Dynamic MIG operations and recovery.
  • Testing

    • Expanded coverage for allocation persistence, topology placement, metrics, container handling, and end-to-end MIG scenarios.

@coderabbitai

coderabbitai Bot commented Aug 5, 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
📝 Walkthrough

Walkthrough

This PR replaces legacy MIG geometry and nvidia-mig-parted workflows with dynamic profile discovery, topology-aware reservations, native GI/CI management, runtime allocation metadata, reconciliation, updated metrics, and fixed-MIG end-to-end validation.

Changes

Dynamic MIG allocation

Layer / File(s) Summary
MIG contracts and topology
pkg/device/..., pkg/device/nvidia/..., pkg/scheduler/..., charts/hami/...
MIG profiles, placements, reservations, annotations, topology checks, scheduler accounting, and topology-specific failure reasons now replace legacy geometry state.
MIG discovery and runtime realization
pkg/device-plugin/nvidiadevice/nvinternal/plugin/...
The device plugin discovers profiles through NVML, manages GI/CI instances, adopts active allocations, reconciles stale state, and records runtime identities in Pod annotations.
Runtime MIG metrics
cmd/scheduler/..., cmd/vGPUmonitor/...
Metrics now expose MIG UUIDs, profiles, instance IDs, placement coordinates, readiness, and container mapping.
Integration and deployment validation
hack/hami-mig-e2e.sh, docs/develop/..., docker/*, go.mod
Added fixed-MIG scenarios, Dynamic MIG architecture documentation, configurable image building, and removal of nvidia-mig-parted image steps.

Estimated code review effort: 5 (Critical) | ~90+ minutes

Possibly related PRs

Suggested reviewers: archlitchi

Poem

A rabbit hops through MIG’s new maze,
Profiles bloom in balanced arrays.
GI and CI dance in place,
UUIDs leave a trace.
Pods remember where they’ve been—
Metrics sparkle; tests begin.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.32% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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 PR's primary change: support for dynamic NVIDIA MIG instance allocation and deallocation.
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.

@github-actions github-actions Bot added kind/enhancement New feature or request and removed kind/feature new function labels Aug 5, 2026
@hami-robot hami-robot Bot added the size/XXL label Aug 5, 2026
@FouoF
FouoF force-pushed the feat/mig-dynamic-deallocate branch from c9e65ab to ffa8ab3 Compare August 5, 2026 11:46
@FouoF FouoF mentioned this pull request Aug 5, 2026
28 tasks
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.07293% with 730 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ce-plugin/nvidiadevice/nvinternal/plugin/migmgr.go 0.00% 323 Missing ⚠️
...ce-plugin/nvidiadevice/nvinternal/plugin/server.go 2.53% 152 Missing and 2 partials ⚠️
...ugin/nvidiadevice/nvinternal/plugin/mig_startup.go 18.47% 74 Missing and 1 partial ⚠️
...vice-plugin/nvidiadevice/nvinternal/plugin/util.go 10.90% 49 Missing ⚠️
...-plugin/nvidiadevice/nvinternal/plugin/register.go 0.00% 45 Missing ⚠️
cmd/vGPUmonitor/metrics.go 28.12% 23 Missing ⚠️
pkg/device/devices.go 71.42% 11 Missing and 1 partial ⚠️
pkg/scheduler/scheduler.go 79.24% 8 Missing and 3 partials ⚠️
cmd/scheduler/metrics.go 68.75% 8 Missing and 2 partials ⚠️
pkg/device/nvidia/mig_allocations.go 78.72% 5 Missing and 5 partials ⚠️
... and 3 more
Flag Coverage Δ
unittests 62.05% <27.07%> (-2.58%) ⬇️

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

Files with missing lines Coverage Δ
pkg/device/common/common.go 50.00% <ø> (ø)
pkg/device/pods.go 86.58% <100.00%> (+0.24%) ⬆️
pkg/device/nvidia/mig_profiles.go 77.77% <77.77%> (ø)
pkg/device/nvidia/device.go 95.23% <80.95%> (-2.50%) ⬇️
pkg/device/nvidia/mig_topology.go 88.23% <88.23%> (ø)
cmd/scheduler/metrics.go 76.22% <68.75%> (+1.31%) ⬆️
pkg/device/nvidia/mig_allocations.go 78.72% <78.72%> (ø)
pkg/scheduler/scheduler.go 68.04% <79.24%> (-0.64%) ⬇️
pkg/device/devices.go 88.95% <71.42%> (-2.43%) ⬇️
cmd/vGPUmonitor/metrics.go 45.03% <28.12%> (+1.53%) ⬆️
... and 5 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@FouoF
FouoF force-pushed the feat/mig-dynamic-deallocate branch from 04ff0b5 to e004b39 Compare August 6, 2026 07:13
@FouoF
FouoF force-pushed the feat/mig-dynamic-deallocate branch from e004b39 to 5c04cbd Compare August 7, 2026 01:54
@FouoF
FouoF force-pushed the feat/mig-dynamic-deallocate branch from 5c04cbd to 5786b1a Compare August 7, 2026 01:56
@FouoF

FouoF commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

As this feature correctness depends on NVML driver behavior. UT can not cover it very well. So I added an e2e test script instead. I think we can ignore the codecov check.

@FouoF
FouoF marked this pull request as ready for review August 7, 2026 02:01
@hami-robot
hami-robot Bot requested a review from DSFans2014 August 7, 2026 02:01
@coderabbitai
coderabbitai Bot requested a review from mesutoezdil August 7, 2026 02:03

@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: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/scheduler/scheduler.go (1)

662-711: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fail closed for unconsumed MIG allocation reservations.

Lines 687-706 consume one reservation per cached ContainerDevice but discard remaining entries in allocationsByGPU.

If hami.io/vgpu-mig-allocations contains an extra valid reservation for a parent GPU, scheduler state omits its placement. The scheduler can then allocate capacity that the runtime reservation already occupies.

After processing the Pod, account for every remaining reservation or mark the matching MIG device unhealthy. Add a test where the annotation has more reservations than PodDevices entries.

🤖 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/scheduler/scheduler.go` around lines 662 - 711, Ensure the
resource-rebuild logic around allocationsByGPU accounts for every unconsumed MIG
reservation after processing each Pod. For any remaining reservation associated
with a parent GPU, add its placement to the matching device’s
MigAllocationsInUse when possible, or mark that MIG device unhealthy to fail
closed; do not silently discard leftovers. Add a test covering an annotation
with more reservations than cached ContainerDevice entries.
🧹 Nitpick comments (10)
cmd/scheduler/metrics.go (1)

195-228: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for allocations that are not runtime-ready.

The current test only verifies RuntimeReady: true. Add a RuntimeReady: false allocation and assert that hami_node_gpu_mig_instance_info does not expose it. This protects the readiness filter from regression.

🤖 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/scheduler/metrics.go` around lines 195 - 228, Extend the test covering
MIG instance metrics to include an allocation with RuntimeReady set to false,
alongside the existing ready allocation. Assert that
hami_node_gpu_mig_instance_info excludes the non-ready allocation while
retaining the ready allocation’s metric, covering the filter in the MIG
allocation iteration.
cmd/vGPUmonitor/metrics.go (1)

515-545: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a collector-level MIG metric test.

metrics_mig_test.go only tests migAllocationContainerName. Add a test that supplies pod annotations and verifies the emitted hami_mig_device_info labels. Include an allocation without complete runtime identity and assert that collection skips it.

🤖 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/metrics.go` around lines 515 - 545, Add a collector-level
test covering the MIG allocation loop that provides pod annotations with valid
and incomplete allocations, then verifies the emitted hami_mig_device_info
metric labels for the valid allocation. Assert that an allocation missing
MigUUID, GPUInstanceID, or ComputeInstanceID is skipped, using the existing
metrics collection entry point and test helpers in metrics_mig_test.go.
pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go (2)

591-609: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Return an error for an unknown GI profile ID instead of defaulting to 1 slice.

profileIDToCIProfileID returns COMPUTE_INSTANCE_PROFILE_1_SLICE for any unrecognized input. Callers then query the wrong compute-instance profile and silently skip real compute instances. Return a second boolean result, and let callers reject unknown profiles.

🤖 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/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go` around lines 591
- 609, Update profileIDToCIProfileID to return the mapped compute-instance
profile plus a boolean indicating whether giProfileID was recognized; remove the
default 1-slice fallback and mark unknown inputs false. Update every caller to
handle the boolean and reject or propagate unknown GI profiles before querying
compute-instance profiles.

531-566: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove unused MIG placement helpers.

pickFreePlacement, placementCandidates, giProfileIDToSliceKey, chooseFreePlacement, and preferHighPlacement are only defined or referenced from tests in Go files. Remove them from migmgr.go so placement selection has one authority.

🤖 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/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go` around lines 531
- 566, Remove the unused placement helpers pickFreePlacement,
placementCandidates, giProfileIDToSliceKey, chooseFreePlacement, and
preferHighPlacement from migmgr.go, along with any imports used only by them.
Leave the active placement-selection implementation unchanged so it has a single
authority.
pkg/device/nvidia/device.go (1)

752-762: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Update the comment to the new profile/placement model.

The comment refers to "the device's current template" and to resharding. This PR removed MIG templates and geometry. Describe the condition as "no allowed MIG profile has a free placement on this device" so the comment matches CustomFilterRule.

🤖 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/device/nvidia/device.go` around lines 752 - 762, The comment in the
dev.Mode == MigMode branch should reflect the profile/placement model: replace
references to the device’s current template, topology, and resharding with
wording that explains no allowed MIG profile has a free placement on the device.
Keep the behavior and logging unchanged.
pkg/device/nvidia/device_test.go (1)

1226-1236: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the MIG failure path of AddResourceUsage.

This test now covers only the non-MIG path. pkg/device/nvidia/mig_capability_test.go covers the successful MIG path. No test covers the new error return "MIG profile and placement allocation failed". Add a case with Mode: MigMode and no free placement, and assert that AddResourceUsage returns an error and leaves n.Used, n.Usedmem, and n.Usedcores unchanged.

🤖 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/device/nvidia/device_test.go` around lines 1226 - 1236, Extend
TestDevices_AddResourceUsage with a MIG-mode case using Mode: MigMode and no
available placement, then assert AddResourceUsage returns the “MIG profile and
placement allocation failed” error. Verify the usage fields Used, Usedmem, and
Usedcores remain unchanged after the failure.
pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup.go (2)

141-153: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Verify the MIG-mode branch condition.

Line 148 tests ret == nvml.ERROR_NOT_SUPPORTED and then ret != nvml.SUCCESS. The second test already covers the first. Also confirm that GetMaxMigDeviceCount returning a count larger than the number of live MIG devices is expected here; the loop relies on GetMigDeviceHandleByIndex returning a non-SUCCESS code for empty slots and continues silently in that case.

🤖 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/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup.go` around lines
141 - 153, Simplify the MIG-mode condition in the loop around GetMigMode by
removing the redundant ret == nvml.ERROR_NOT_SUPPORTED check and retaining the
general ret != nvml.SUCCESS or disabled-mode handling. Verify that the count
from GetMaxMigDeviceCount is intentionally used as the loop bound, with
GetMigDeviceHandleByIndex failures for empty slots continuing silently.

116-126: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Initialize NVML once for MIG UUID lookups.

GetContainerDeviceStrArray calls gpuUUIDToIndex(reservation.GPUUUID) for every MIG reservation on Allocate, and active-pod/runtime-info paths also call it. NVML reference-counts initialization, while the current helpers each call nvml.Init() without nvml.Shutdown. Move a single nvml.Init() into plugin startup and make these helpers assume NVML is initialized.

🤖 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/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup.go` around lines
116 - 126, Initialize NVML once during plugin startup, before any MIG UUID
lookup paths can run, and handle startup failure consistently. Update
gpuUUIDToIndex and related lookup helpers to assume NVML is already initialized
by removing their per-call nvml.Init invocation; keep UUID handle and index
error handling unchanged.
pkg/device/nvidia/mig_capability_test.go (1)

51-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a case with a non-empty toAllocate.

Both cases pass nil for toAllocate, so the queued-request branch of CustomFilterRule is untested. Add a case that passes container devices already selected for this GPU and for a different GPU. That case pins the device-identity behavior discussed in pkg/device/nvidia/device.go Lines 581-593. Add a case where the request exceeds every profile, to cover the false return of selectMigCandidate.

🤖 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/device/nvidia/mig_capability_test.go` around lines 51 - 67, Extend
TestCustomFilterUsesReportedPlacementCapacity with non-empty toAllocate cases
containing devices selected for the same GPU and for a different GPU, verifying
only matching device identities affect CustomFilterRule’s queued-request path.
Also add a request whose memory exceeds every MIG profile and assert
CustomFilterRule returns false through selectMigCandidate.
pkg/device/nvidia/mig_allocations.go (1)

48-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Silent skip can produce a partial annotation.

EncodeMigAllocations skips any device whose CustomInfo lacks a valid profile or placement, and still returns true if at least one device produced an entry. The device plugin then rejects the Pod at Allocate time, because GetContainerDeviceStrArray requires one reservation per requested device (pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go, Line 305). Add a log line for each skipped MIG device so the cause is visible in the scheduler logs.

🤖 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/device/nvidia/mig_allocations.go` around lines 48 - 77, Update
EncodeMigAllocations to log each MIG device skipped because CustomInfo is
missing or its profile/placement is invalid, including the device identifiers
and skip reason, while preserving the existing filtering and return behavior.
🤖 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 `@hack/hami-mig-e2e.sh`:
- Around line 35-44: Scope the MIG test to one explicitly selected target node:
add a preflight topology check if single-node operation is required, bind Pods
created by create_pod to that node, and run mig_count/profile_count against its
GPU. Update the device-plugin restart logic to delete or restart only the plugin
Pod on the target node rather than rolling out the DaemonSet cluster-wide.
- Around line 26-33: Register the defined cleanup function with an EXIT trap
immediately after its definition so it runs on every script exit path, including
failed assertions. Preserve the existing cleanup behavior and avoid relying
solely on the final explicit cleanup call.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup_test.go`:
- Around line 13-21: Reorder the imports in the test so standard-library
packages remain first, k8s.io dependencies form the external group, and the
github.com/Project-HAMi/HAMi/pkg/device/nvidia import is placed in its own
trailing local group. Apply the repository’s goimports grouping convention
without changing code behavior.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go`:
- Around line 236-271: Update destroyAllMigInstances to enumerate and destroy
every compute-instance profile available for each gi, rather than only the
single profile returned by profileIDToCIProfileID(giProfileID). Complete all
successful GetComputeInstances results and propagate Destroy errors before
calling gi.Destroy(), preserving the existing GPU-instance destruction order.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/register.go`:
- Around line 186-194: The MIG registration flow in the isMigMode branch must
handle an empty result from discoverMigProfiles before appending the device: log
a clear warning identifying the model and missing profiles, or skip registration
of the zero-capacity device. Preserve the existing Count calculation when
profiles are discovered.
- Around line 203-236: Update the core-percentage calculation in the MIG profile
discovery flow to use the device’s physical SM count from
GetAttributes().MultiprocessorCount, matching Devcore = 100. Retain
fullGPUMultiprocessors as a fallback only when the device attribute value is
unavailable, and use the selected device capacity when computing profile.Core.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go`:
- Around line 307-335: Move NewMigInstanceManager initialization for
plugin.migMgr to the plugin setup path before plugin.Serve and plugin.Register,
ensuring Allocate requests always see an initialized manager. Remove the later
assignment from the MIG startup block, leaving only GPU reset, annotation
adoption, and reconciliation work there; preserve non-MIG behavior and ensure
initialization is not concurrently written after serving begins.
- Around line 283-296: Update the deviceSupportMig initialization and validation
in the MIG capability check so an empty deviceNames result is treated as
unsupported. Ensure MIG is enabled only when at least one device name exists and
every name matches an entry in plugin.schedulerConfig.MigProfileAllowlist, while
preserving the existing unsupported behavior for unmatched models.
- Around line 794-800: In the refresh path within the request allocation flow,
update the Pod fetch around current so Get assigns to a temporary Pod variable
first; check the error before replacing current, and pass the still-valid
current Pod to PodAllocationFailed on failure. Only update current after a
successful fetch.
- Around line 362-394: Update annotateMigRuntimeInfo to patch annotations with
optimistic concurrency using the Pod’s current resourceVersion, ensuring
concurrent updates to hami.io/vgpu-mig-allocations cannot be overwritten; use
the Kubernetes patch options precondition rather than the unconditional
PatchPodAnnotations path, while preserving the existing runtime-field updates.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go`:
- Around line 311-326: Update deviceAllocateFromAnnotation to track MIG UUIDs
returned by EnsureAllocation and release all already-created allocations through
nv.migMgr.Release when a later reservation or allocation step fails. Ensure
cleanup occurs before returning the error, including failures from reservation
validation, gpuUUIDToIndex, or EnsureAllocation, while preserving the existing
successful output behavior.

In `@pkg/device/nvidia/device.go`:
- Around line 619-624: The MIG selection path must use the same effective memory
value as accounting: update Fit and its CustomFilterRule invocation to resolve
percentage-based requests into the derived memory amount before filtering, or
otherwise pass that effective value instead of the unmodified request.Memreq.
Ensure the value used to select the MIG profile matches ContainerDevice.Usedmem
consumed by AddResourceUsage.
- Around line 581-593: In CustomFilterRule, filter toAllocate entries by
devusage.ID before calling selectMigCandidate, so only allocations queued for
the GPU currently being evaluated reserve MIG placements. Preserve the existing
occupied-placement accumulation and final request check, while excluding entries
belonging to other GPU UUIDs and preventing duplicate reservations when the same
device is revisited.

---

Outside diff comments:
In `@pkg/scheduler/scheduler.go`:
- Around line 662-711: Ensure the resource-rebuild logic around allocationsByGPU
accounts for every unconsumed MIG reservation after processing each Pod. For any
remaining reservation associated with a parent GPU, add its placement to the
matching device’s MigAllocationsInUse when possible, or mark that MIG device
unhealthy to fail closed; do not silently discard leftovers. Add a test covering
an annotation with more reservations than cached ContainerDevice entries.

---

Nitpick comments:
In `@cmd/scheduler/metrics.go`:
- Around line 195-228: Extend the test covering MIG instance metrics to include
an allocation with RuntimeReady set to false, alongside the existing ready
allocation. Assert that hami_node_gpu_mig_instance_info excludes the non-ready
allocation while retaining the ready allocation’s metric, covering the filter in
the MIG allocation iteration.

In `@cmd/vGPUmonitor/metrics.go`:
- Around line 515-545: Add a collector-level test covering the MIG allocation
loop that provides pod annotations with valid and incomplete allocations, then
verifies the emitted hami_mig_device_info metric labels for the valid
allocation. Assert that an allocation missing MigUUID, GPUInstanceID, or
ComputeInstanceID is skipped, using the existing metrics collection entry point
and test helpers in metrics_mig_test.go.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup.go`:
- Around line 141-153: Simplify the MIG-mode condition in the loop around
GetMigMode by removing the redundant ret == nvml.ERROR_NOT_SUPPORTED check and
retaining the general ret != nvml.SUCCESS or disabled-mode handling. Verify that
the count from GetMaxMigDeviceCount is intentionally used as the loop bound,
with GetMigDeviceHandleByIndex failures for empty slots continuing silently.
- Around line 116-126: Initialize NVML once during plugin startup, before any
MIG UUID lookup paths can run, and handle startup failure consistently. Update
gpuUUIDToIndex and related lookup helpers to assume NVML is already initialized
by removing their per-call nvml.Init invocation; keep UUID handle and index
error handling unchanged.

In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go`:
- Around line 591-609: Update profileIDToCIProfileID to return the mapped
compute-instance profile plus a boolean indicating whether giProfileID was
recognized; remove the default 1-slice fallback and mark unknown inputs false.
Update every caller to handle the boolean and reject or propagate unknown GI
profiles before querying compute-instance profiles.
- Around line 531-566: Remove the unused placement helpers pickFreePlacement,
placementCandidates, giProfileIDToSliceKey, chooseFreePlacement, and
preferHighPlacement from migmgr.go, along with any imports used only by them.
Leave the active placement-selection implementation unchanged so it has a single
authority.

In `@pkg/device/nvidia/device_test.go`:
- Around line 1226-1236: Extend TestDevices_AddResourceUsage with a MIG-mode
case using Mode: MigMode and no available placement, then assert
AddResourceUsage returns the “MIG profile and placement allocation failed”
error. Verify the usage fields Used, Usedmem, and Usedcores remain unchanged
after the failure.

In `@pkg/device/nvidia/device.go`:
- Around line 752-762: The comment in the dev.Mode == MigMode branch should
reflect the profile/placement model: replace references to the device’s current
template, topology, and resharding with wording that explains no allowed MIG
profile has a free placement on the device. Keep the behavior and logging
unchanged.

In `@pkg/device/nvidia/mig_allocations.go`:
- Around line 48-77: Update EncodeMigAllocations to log each MIG device skipped
because CustomInfo is missing or its profile/placement is invalid, including the
device identifiers and skip reason, while preserving the existing filtering and
return behavior.

In `@pkg/device/nvidia/mig_capability_test.go`:
- Around line 51-67: Extend TestCustomFilterUsesReportedPlacementCapacity with
non-empty toAllocate cases containing devices selected for the same GPU and for
a different GPU, verifying only matching device identities affect
CustomFilterRule’s queued-request path. Also add a request whose memory exceeds
every MIG profile and assert CustomFilterRule returns false through
selectMigCandidate.
🪄 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: 9f19bdbd-92bf-48fd-bba5-317cf834ffa0

📥 Commits

Reviewing files that changed from the base of the PR and between 87d9795 and 5786b1a.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (40)
  • charts/hami/templates/scheduler/device-configmap.yaml
  • cmd/scheduler/metrics.go
  • cmd/scheduler/metrics_test.go
  • cmd/vGPUmonitor/metrics.go
  • cmd/vGPUmonitor/metrics_mig_test.go
  • docker/Dockerfile
  • docker/Dockerfile.hamimaster
  • docker/Dockerfile.no-core-test
  • docker/Dockerfile.withlib
  • docs/develop/mig-dynamic-deallocate.md
  • go.mod
  • hack/hami-mig-e2e.sh
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr_placement_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/register.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/register_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/server_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/util_test.go
  • pkg/device/common/common.go
  • pkg/device/devices.go
  • pkg/device/devices_test.go
  • pkg/device/nvidia/device.go
  • pkg/device/nvidia/device_test.go
  • pkg/device/nvidia/mig_allocations.go
  • pkg/device/nvidia/mig_capability_test.go
  • pkg/device/nvidia/mig_profiles.go
  • pkg/device/nvidia/mig_profiles_test.go
  • pkg/device/nvidia/mig_topology.go
  • pkg/device/nvidia/mig_topology_test.go
  • pkg/device/pod_test.go
  • pkg/device/pods.go
  • pkg/scheduler/mig_allocation_test.go
  • pkg/scheduler/scheduler.go
  • pkg/scheduler/scheduler_test.go
  • pkg/scheduler/score_test.go
  • pkg/scheduler/webhook_test.go
💤 Files with no reviewable changes (6)
  • docker/Dockerfile.hamimaster
  • docker/Dockerfile
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/register_test.go
  • docker/Dockerfile.withlib
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/util_test.go
  • pkg/scheduler/scheduler_test.go

Comment thread hack/hami-mig-e2e.sh
Comment thread hack/hami-mig-e2e.sh
Comment thread pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go
Comment thread pkg/device-plugin/nvidiadevice/nvinternal/plugin/register.go
Comment thread pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go
Comment thread pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go Outdated
Comment thread pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
Comment thread pkg/device/nvidia/device.go
Comment thread pkg/device/nvidia/device.go

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go (1)

313-325: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Complete MIG startup before plugin registration.

Start serves and registers before collecting active MIG allocations, destroying idle instances, and adopting annotations. An Allocate call can then call EnsureAllocation and create a GI/CI after the snapshot while ResetIdleGPUs is still deleting instances on GPUs not found in that snapshot. Do registration after reset and annotation adoption complete, or protect startup work and allocation under a common gate.

🤖 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/device-plugin/nvidiadevice/nvinternal/plugin/server.go` around lines 313
- 325, Update the plugin.Start startup sequence so MIG allocation detection,
ResetIdleGPUs, and annotation adoption finish before serving or registering the
plugin. Ensure Allocate/EnsureAllocation cannot run concurrently with this
initialization, either by moving registration after startup work or guarding
both paths with a shared initialization gate.
🤖 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.

Outside diff comments:
In `@pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go`:
- Around line 313-325: Update the plugin.Start startup sequence so MIG
allocation detection, ResetIdleGPUs, and annotation adoption finish before
serving or registering the plugin. Ensure Allocate/EnsureAllocation cannot run
concurrently with this initialization, either by moving registration after
startup work or guarding both paths with a shared initialization gate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02450ca8-a892-4675-8863-bdbf737649e7

📥 Commits

Reviewing files that changed from the base of the PR and between 5786b1a and 9178019.

📒 Files selected for processing (8)
  • hack/hami-mig-e2e.sh
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/migmgr.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/register.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/server.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
  • pkg/device/nvidia/device.go
  • pkg/device/nvidia/mig_capability_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/mig_startup_test.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/register.go
  • pkg/device-plugin/nvidiadevice/nvinternal/plugin/util.go
  • pkg/device/nvidia/device.go

FouoF added 3 commits August 10, 2026 14:46
Signed-off-by: Jifei Wang <jifei.wang@dynamia.ai>
Signed-off-by: Jifei Wang <jifei.wang@dynamia.ai>
Signed-off-by: Jifei Wang <jifei.wang@dynamia.ai>
@FouoF
FouoF force-pushed the feat/mig-dynamic-deallocate branch from 6142cd9 to 9c5464e Compare August 10, 2026 06:48

@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 Aug 10, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

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

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

@archlitchi
archlitchi merged commit 0ce9ff8 into Project-HAMi:master Aug 10, 2026
16 of 18 checks passed
@archlitchi
archlitchi deleted the feat/mig-dynamic-deallocate branch August 10, 2026 07:20
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