Skip to content

perf(rm): replace per-iteration sort in distributedAlloc with a min-heap - #1826

Open
jonathan-meiri wants to merge 1 commit into
NVIDIA:mainfrom
jonathan-meiri:optimize-distributedalloc-heap
Open

perf(rm): replace per-iteration sort in distributedAlloc with a min-heap#1826
jonathan-meiri wants to merge 1 commit into
NVIDIA:mainfrom
jonathan-meiri:optimize-distributedalloc-heap

Conversation

@jonathan-meiri

Copy link
Copy Markdown

Summary

Follow-up optimization stacked on #1788. Until #1788 lands, this PR's cumulative diff includes that commit too — the new work here is in the second commit (the heap refactor). Not for review until #1788 lands.

Replaces the per-iteration sort.Slice in distributedAlloc with a min-heap keyed by (used, pickedFrom). Brings the loop from O(n² log n) to O(n log m) where n is replicas requested and m is the number of physical GPUs touched in this allocation. Same correctness as #1788; same tests pass.

Practically, n and m are small in real configurations and the wall-clock impact is invisible — this is structural cleanliness, not a hot-path speedup.

Opened as draft so it doesn't enter the review queue alongside #1788. Happy to mark it ready as a separate follow-up after #1788 lands, or fold the change into #1788 if that's preferred.

Contributed by @Meiri28 on behalf of @runatom-ai.

@copy-pr-bot

copy-pr-bot Bot commented Jun 2, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch from 82b1b23 to b9da143 Compare June 2, 2026 08:16
@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch from b9da143 to 21cd040 Compare June 30, 2026 15:35
@jonathan-meiri
jonathan-meiri marked this pull request as ready for review June 30, 2026 19:10
@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch 3 times, most recently from 8333b12 to 5efcd18 Compare July 1, 2026 11:02
@jonathan-meiri

Copy link
Copy Markdown
Author

Hi @rajatchopra — following up on your comment in #1788 ("Lets attack the loop optimization in #1826 next"). This PR is out of draft and ready for review: a single commit with the heap-based O(n log m) refactor of distributedAlloc. Would appreciate your thoughts when you have a moment.

@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch from 5efcd18 to 2319fe5 Compare July 14, 2026 12:50
@rajatchopra

Copy link
Copy Markdown
Contributor

Heap logic looks good. Though this PR must wait for #1621 first. Will need a rebase after that.

@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch from 2319fe5 to 6848b06 Compare July 22, 2026 08:24
@jonathan-meiri

Copy link
Copy Markdown
Author

Rebased on top of #1621 (now merged). The heap now sits on top of the new greedyAlloc / replicaComparator structure — both distributed and packed policies get the O(n log m) improvement. Existing tests pass unchanged.

Ready for another look when you have a moment, @rajatchopra.

Follow-up on top of NVIDIA#1621, which introduced the shared greedyAlloc loop
with a pluggable replicaComparator (distributed vs packed). The loop
still sorts the full candidate slice inside the allocation loop, paying
O(n log n) per iteration for n iterations and giving O(n² log n) overall.

Since all annotated replicas from the same underlying physical device
share the same sort key, sorting at the replica granularity is wasted
work — only m (the number of distinct physical devices contributing
candidates) needs to be reordered.

Refactor greedyAlloc to bucket candidates by their underlying physical
device into a small gpuAllocState per device, holding a shared
*replicaCount, the pickedFrom counter, and the remaining candidate IDs.
A gpuPriorityQueue defers to the caller-supplied replicaComparator on
allocated() for primary ordering and to pickedFrom for the tie-break
(unchanged semantics). Each iteration pops the best device, takes one
of its remaining replicas, updates counters, and pushes it back if any
remain.

Total cost drops to O(n log m). Both allocation policies (distributed
and packed) benefit; no behavior change — the existing test suite
(TestDistributedAlloc, TestPackedAlloc, TestPackedVsDistributedContrast,
TestDistributedAlloc_PartiallyAllocated_DistributesAcrossDistinctGPUs,
etc.) passes unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: runatom-ai <258621014+runatom-ai@users.noreply.github.com>
Signed-off-by: Jonathan Meiri <33288957+Meiri28@users.noreply.github.com>
@jonathan-meiri
jonathan-meiri force-pushed the optimize-distributedalloc-heap branch from 06c33eb to 36e7ad1 Compare July 28, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants