Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

vmem_chunked: `reuse()` rollback skips free-listed blocks, leaving the heap fragmented

Open
#586 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
Half a day
Newbie friendliness
58/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
python
Domain
backend

Research direction

Start with VMemChunkedAllocator.reuse() and collect(), and check how _released, bump and free_lists interact. Read test_chunked_churn_then_large_allocation_does_not_grow and run it with the keep_every=16 case. Done when the extended test frees all kept buffers, reclaims them, allocates most of the heap, and get_num_chunks() stays unchanged. Keep the free-list state identical on every rank.

Written by the indexing model from the issue text.

Description

iris python test

VMemChunkedAllocator.reuse() (added in #583) returns freed blocks at the top of the heap to the bump pointer, but it only considers blocks released in the current collect(). Blocks that went to a free list in an earlier round are never rolled back, even after the blocks above them are freed. The heap then stays split into small size-class blocks, and a later large allocation grows the heap even though the space below bump is free.

This behavior predates #583 (the allocator never merged free blocks), so it isn't a regression. It came up in review and was deferred to keep #583's scope: https://github.com/ROCm/iris/pull/583#discussion_r4275470909

How it happens

round k:    [ s1 ][ s2 ][ K ][ s3 ] <- bump      K = long-lived buffer, still in use
            s3 rolls back; s1 and s2 go to a free list (K blocks the rollback)

round k+1:  [ s1 ][ s2 ][ K ] <- bump            K is freed and rolls back
            the rollback stops: s2 ends at bump, but it's on a free list, not among this round's offsets

Bookkeeping model (agent-assisted; pure Python, no GPU): the shape of test_chunked_churn_then_large_allocation_does_not_grow with keep_every=16 at 4 KB granularity, then all kept buffers freed, then a 48 MB allocation in the 64 MB heap.

heap growths during the 48 MB allocation
before #583 1
after #583 1
with the change below 0

Proposed change

Treat free-listed blocks as rollback candidates in reuse():

with self.lock:
    self._bytes_since_collect = 0
    candidates = {offset: self._released.pop(offset) for offset in offsets}
    # Blocks freed in earlier rounds can reach the top once the blocks above them are freed
    for size_class, free in self.free_lists.items():
        candidates.update((offset, size_class) for offset in free)
        free.clear()
    # Blocks at the top of the bump region go back to the bump pointer, not a size class
    by_end = {offset + size: offset for offset, size in candidates.items()}
    while self.bump in by_end:
        self.bump = by_end.pop(self.bump)
        del candidates[self.bump]
    for offset in sorted(candidates):
        self.free_lists[candidates[offset]].append(offset)
  • Stays symmetric across ranks: both inputs, the intersection passed by collect() and free_lists, are identical on every rank.
  • Cost: O(F log F) per collect() for F free blocks, small next to the gc.collect() and device sync collect() already does.
  • Optional: append in descending order (sorted(candidates, reverse=True)) so pop() hands out the lowest offsets first, keeping blocks near the top free for later rollbacks.

Test

Extend test_chunked_churn_then_large_allocation_does_not_grow (keep_every=16 case): after the loop, kept.clear() and ctx.reclaim_freed(), then allocate most of the heap and assert get_num_chunks() is unchanged.

Dominant language
Python
Stars
202
Forks
52
Avg merge
5d 2h
Merged PRs (30d)
23

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from ROCm/iris

All issues in ROCm/iris

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.