Skip to content

fix(scheduler): make NUMA sort opt-in for binpack/spread policies#1874

Open
mesutoezdil wants to merge 7 commits into
Project-HAMi:masterfrom
mesutoezdil:fix/numa-ignore-for-binpack-spread
Open

fix(scheduler): make NUMA sort opt-in for binpack/spread policies#1874
mesutoezdil wants to merge 7 commits into
Project-HAMi:masterfrom
mesutoezdil:fix/numa-ignore-for-binpack-spread

Conversation

@mesutoezdil

@mesutoezdil mesutoezdil commented May 15, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?
/kind bug

When spread or binpack policy is selected, Less() in pkg/scheduler/policy/gpu_policy.go uses NUMA as the primary sort key.
This overrides the policy intent: a busy NUMA node gets picked over an idle one on the other NUMA node.

Fix: add NumaIgnore bool to DeviceUsageList.
When the pod annotation hami.io/topology-aware-scoring: "false" is set, Less() sorts by Score only.
Default is unchanged (NUMA-first, backward compatible).

Which issue(s) this PR fixes: Fixes #1806

Does this PR introduce a user-facing change?
Yes. Users can now set hami.io/topology-aware-scoring: "false" on a pod to make spread/binpack sort by Score without NUMA grouping.

Summary by CodeRabbit

  • New Features
    • Added the hami.io/topology-aware-scoring annotation to control NUMA-aware GPU ordering per workload.
    • When set to "false", device ordering ignores NUMA locality and sorts by score only (direction depends on binpack vs spread); default ordering remains NUMA-first, using score only within the same NUMA node.
  • Tests
    • Updated NUMA sorting and scheduler behavior coverage to reflect the new NUMA-ignore flag.
    • Extended deep-copy and ordering fixtures, including additional cases for binpack and spread when NUMA is ignored.

@hami-robot hami-robot Bot added kind/bug Something isn't working dco-signoff: yes labels May 15, 2026
@hami-robot
hami-robot Bot requested review from archlitchi and wawa0210 May 15, 2026 11:39
@hami-robot hami-robot Bot added the size/M label May 15, 2026

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces the hami.io/topology-aware-scoring annotation, allowing users to disable NUMA-aware GPU scheduling. It also enhances error handling by ensuring that failures in decoding pod devices are logged and handled gracefully without stopping the monitoring or scheduling processes. Corresponding unit tests were added for these changes. Feedback was provided to optimize performance in the scheduler by moving loop-invariant calculations for GPU policy and NUMA settings outside of the node iteration loop.

Comment thread pkg/scheduler/scheduler.go Outdated
@codecov

codecov Bot commented May 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 61.16% <100.00%> (+0.01%) ⬆️

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

Files with missing lines Coverage Δ
pkg/scheduler/policy/gpu_policy.go 100.00% <100.00%> (ø)
pkg/scheduler/scheduler.go 67.39% <100.00%> (+0.09%) ⬆️
pkg/util/types.go 100.00% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wawa0210

wawa0210 commented Jun 4, 2026

Copy link
Copy Markdown
Member

Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑‍🤝‍🧑👫🧑🏿‍🤝‍🧑🏻👩🏾‍🤝‍👨🏿👬🏿


any news @archlitchi

@mesutoezdil
mesutoezdil force-pushed the fix/numa-ignore-for-binpack-spread branch from 206023b to ccde489 Compare June 4, 2026 13:14
@mesutoezdil
mesutoezdil force-pushed the fix/numa-ignore-for-binpack-spread branch from ccde489 to eedf4f3 Compare June 14, 2026 15:47
@mesutoezdil
mesutoezdil force-pushed the fix/numa-ignore-for-binpack-spread branch 2 times, most recently from cd18c31 to dddef02 Compare June 14, 2026 15:56
Same root cause as the other branches: upstream refactored inline
node-usage construction into buildNodeUsage(), this branch computed
NumaIgnore from the hami.io/topology-aware-scoring annotation at the
call site. Moved that computation into buildNodeUsage() so both are
kept.

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 13, 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

GPU device usage now defaults to NUMA-first sorting, with an annotation-controlled mode that orders solely by score. The new setting is copied across usage lists, wired from pod annotations, and covered by policy and NUMA selection tests.

Changes

GPU NUMA sorting

Layer / File(s) Summary
Device sorting and copy behavior
pkg/scheduler/policy/gpu_policy.go, pkg/scheduler/policy/gpu_policy_test.go
DeviceUsageList adds NumaIgnore; default ordering groups NUMA nodes and uses score within a node, while the ignore mode uses score alone for binpack or spread. Deep-copy and comparator tests cover both modes.
Annotation-driven scheduler wiring
pkg/util/types.go, pkg/scheduler/scheduler.go
Defines the topology-aware annotation key and sets NumaIgnore when the target pod annotation is "false".
NUMA selection validation
pkg/scheduler/numa_sort_test.go
Updates NUMA sorting scenarios and verifies that ignoring NUMA grouping permits score-based selection across NUMA nodes.

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

Sequence Diagram(s)

sequenceDiagram
  participant Pod
  participant buildNodeUsage
  participant DeviceUsageList
  participant Fit
  Pod->>buildNodeUsage: topology-aware annotation
  buildNodeUsage->>DeviceUsageList: set NumaIgnore
  DeviceUsageList->>DeviceUsageList: sort by score or NUMA
  Fit->>DeviceUsageList: select sorted devices
Loading

Possibly related issues

  • Project-HAMi/HAMi#2010 — Directly modifies the same GPU NUMA and score sorting behavior addressed here.

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: wawa0210, archlitchi

Poem

A rabbit tuned the GPU queue,
With NUMA groups in view.
When topology fades from sight,
Scores guide each device right.
Hop, binpack and spread take flight!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The issue required score-first ordering by default, but this PR keeps NUMA-first sorting unless the new annotation disables it. Make Score the primary sort key for binpack/spread by default, using NUMA only as a tiebreaker, and remove the annotation-gated NUMA-first path.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: making NUMA sorting opt-in for GPU binpack/spread policies.
Out of Scope Changes check ✅ Passed All code changes relate to the NUMA-sort fix, new annotation, and supporting tests.
✨ 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

🤖 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/scheduler/policy/gpu_policy_test.go`:
- Around line 124-129: Update the fully populated test case in
TestDeviceUsageListDeepCopy to set NumaIgnore: true in its input and expected
values, ensuring DeepCopy verifies propagation of the non-zero field while
preserving the existing assertions.
🪄 Autofix (Beta)

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: ea443c14-8257-4123-bdc0-5d6ee05a812c

📥 Commits

Reviewing files that changed from the base of the PR and between 69a89b6 and 546a917.

📒 Files selected for processing (4)
  • pkg/scheduler/policy/gpu_policy.go
  • pkg/scheduler/policy/gpu_policy_test.go
  • pkg/scheduler/scheduler.go
  • pkg/util/types.go

Comment thread pkg/scheduler/policy/gpu_policy_test.go
Fully populated case did not set NumaIgnore, so the deep copy check
could not catch a regression in that field.

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

@mesutoezdil Thanks for the clarification. I’ll review the current branch, including the deep-copy propagation and the NUMA-ignore score-ordering cases.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mesutoezdil

Copy link
Copy Markdown
Contributor Author

/assign @archlitchi

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
@hami-robot

hami-robot Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mesutoezdil
Once this PR has been reviewed and has the lgtm label, please ask for approval from archlitchi. 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

Per Project-HAMi#1806 discussion, the default stays NUMA-primary; hami.io/topology-aware-scoring: "false" opts out to pure Score ordering. NumaBind is kept for compatibility but no longer changes Less's behavior, since NUMA grouping is now unconditional.

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
@hami-robot hami-robot Bot added size/L and removed size/M labels Jul 20, 2026

@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 (1)
pkg/scheduler/policy/gpu_policy_test.go (1)

245-265: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add test cases for the NUMA tiebreaker.

If you implement the NUMA tiebreaker for equal scores in gpu_policy.go, consider adding the following test cases to ensure the tiebreaker behavior is explicitly verified and protected from future regressions.

🧪 Proposed test cases
 			},
 			expectedLess: false,
 		},
+		{
+			name:       "Binpack NumaIgnore score tiebreaker",
+			policy:     "binpack",
+			numaIgnore: true,
+			deviceLists: []*DeviceListsScore{
+				{Device: &device.DeviceUsage{Numa: 1}, Score: 10},
+				{Device: &device.DeviceUsage{Numa: 0}, Score: 10},
+			},
+			expectedLess: true,
+		},
+		{
+			name:       "Spread NumaIgnore score tiebreaker",
+			policy:     "spread",
+			numaIgnore: true,
+			deviceLists: []*DeviceListsScore{
+				{Device: &device.DeviceUsage{Numa: 0}, Score: 10},
+				{Device: &device.DeviceUsage{Numa: 1}, Score: 10},
+			},
+			expectedLess: true,
+		},
 	}
🤖 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/policy/gpu_policy_test.go` around lines 245 - 265, Add test
cases in the GPU policy comparison test table covering equal Score values with
differing NUMA nodes, verifying the NUMA tiebreaker for both binpack and spread
policies. Keep the existing NumaIgnore cases unchanged and assert the expected
ordering through expectedLess.
🤖 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/scheduler/policy/gpu_policy.go`:
- Around line 66-72: Update the NumaIgnore branch in the relevant score-ordering
comparator to use NUMA ordering when si and sj are equal, while preserving the
existing score-first behavior for unequal scores and the binpack direction.
Ensure equal-score comparisons return a deterministic NUMA-based result rather
than false.

---

Nitpick comments:
In `@pkg/scheduler/policy/gpu_policy_test.go`:
- Around line 245-265: Add test cases in the GPU policy comparison test table
covering equal Score values with differing NUMA nodes, verifying the NUMA
tiebreaker for both binpack and spread policies. Keep the existing NumaIgnore
cases unchanged and assert the expected ordering through expectedLess.
🪄 Autofix (Beta)

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: d0a98096-3b11-4c63-af69-409b4e6620fe

📥 Commits

Reviewing files that changed from the base of the PR and between bfc2683 and 47618a0.

📒 Files selected for processing (3)
  • pkg/scheduler/numa_sort_test.go
  • pkg/scheduler/policy/gpu_policy.go
  • pkg/scheduler/policy/gpu_policy_test.go

Comment thread pkg/scheduler/policy/gpu_policy.go Outdated
…sort

sort.Sort is not stable, so returning false for both Less(i,j) and
Less(j,i) on equal Score left device order for tied scores
nondeterministic across scheduling cycles.

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
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.

gpu scheduler policy sort bug

3 participants