Skip to content

[vulkan] Set BlockRegion initial usage_count to 1 on allocation#9237

Open
johningve wants to merge 1 commit into
halide:mainfrom
johningve:region-allocator-usage-count
Open

[vulkan] Set BlockRegion initial usage_count to 1 on allocation#9237
johningve wants to merge 1 commit into
halide:mainfrom
johningve:region-allocator-usage-count

Conversation

@johningve

Copy link
Copy Markdown
Contributor

BlockRegion has a usage_count that is incremented by RegionAllocator::retain and decremented by RegionAllocator::release. These methods are used in the runtime when a buffer is cropped, with the intent to ensure that the underlying memory region does not get deallocated until both the cropped buffer and original buffer are released.

The order of operations as seen by the RegionAllocator when allocating a buffer, then allocating a crop of that first buffer, then releasing both, is this:

  1. region = reserve(...)
  2. retain(region)
  3. release(region)
  4. release(region)

Note that after 3, but before 4, the region should still be allocated and the region allocator should not allocate any new region that overlaps it.

Testing this pattern found that the region allocator considers the region to be available after step 3. In practice, this causes Halide to give the same underlying memory to two live buffers simultaneously.

The cause of this issue is that RegionAllocator::alloc_block_region does not update the usage_count of the allocated block region from its default value of 0.

This commit fixes the issue by setting the usage count of the newly allocated block region to 1 in the same place where its status is updated, indicating that the newly allocated region will have one usage, which must be released before the memory can be reallocated to a new region.

This commit includes a regression test of retain/release with the exact same order of operations as was mentioned above.

Checklist

  • Tests added or updated (not required for docs, CI config, or typo fixes)
  • Documentation updated (if public API changed)
  • Python bindings updated (if public API changed)
  • Benchmarks are included here if the change is intended to affect performance.
  • Commits include AI attribution where applicable (see Code of Conduct)

BlockRegion has a usage_count that is incremented by
RegionAllocator::retain and decremented by RegionAllocator::release.
These methods are used in the runtime when a buffer is cropped, with the
intent to ensure that the underlying memory region does not get
deallocated until both the cropped buffer and original buffer are
released.

The order of operations as seen by the RegionAllocator when allocating a
buffer, then allocating a crop of that first buffer, then releasing
both, is this:

1. region = reserve(...)
2. retain(region)
3. release(region)
4. release(region)

Note that after 3, but before 4, the region should still be allocated
and the region allocator should not allocate any new region that
overlaps it.

Testing this pattern found that the region allocator considers the
region to be available after step 3. In practice, this causes Halide to
give the same underlying memory to two live buffers simultaneously.

The cause of this issue is that RegionAllocator::alloc_block_region does
not update the usage_count of the allocated block region from its
default value of 0.

This commit fixes the issue by setting the usage count of the newly
allocated block region to 1 in the same place where its status is
updated, indicating that the newly allocated region will have one usage,
which must be released before the memory can be reallocated to a new
region.

This commit includes a regression test of retain/release with the exact
same order of operations as was mentioned above.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@johningve
johningve force-pushed the region-allocator-usage-count branch from 3c38b94 to 0f1046c Compare July 24, 2026 13:05
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.10%. Comparing base (055bc89) to head (0f1046c).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9237      +/-   ##
==========================================
- Coverage   70.24%   70.10%   -0.15%     
==========================================
  Files         255      255              
  Lines       78929    78904      -25     
  Branches    18879    18866      -13     
==========================================
- Hits        55444    55313     -131     
- Misses      17872    17898      +26     
- Partials     5613     5693      +80     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

1 participant