Skip to content

[rocsparse] Add null/zero-size guards to memstat allocation functions#6597

Merged
kliegeois merged 2 commits intoROCm:developfrom
kliegeois:fix/memstat-null-zero-guards
Apr 21, 2026
Merged

[rocsparse] Add null/zero-size guards to memstat allocation functions#6597
kliegeois merged 2 commits intoROCm:developfrom
kliegeois:fix/memstat-null-zero-guards

Conversation

@kliegeois
Copy link
Copy Markdown
Contributor

What changed and why

The memstat-enabled variants of rocsparse_free, rocsparse_free_async, rocsparse_malloc, and rocsparse_malloc_async in rocsparse_memstat.cpp lack defensive guards for null pointers and zero-size allocations.

  • Calling rocsparse_free(nullptr) falls through to the HIP allocator and memstat bookkeeping unnecessarily.
  • Calling rocsparse_malloc(&p, 0) issues a zero-size allocation to HIP, whose behavior is implementation-defined.

The non-memstat build path already handles these cases (e.g., the rocsparse_hipFreeAsync macro has a null check), but the memstat path did not, creating an inconsistency.

This PR adds early-return guards:

  • rocsparse_free / rocsparse_free_async: return hipSuccess for nullptr without entering the allocator or memstat tracking.
  • rocsparse_malloc / rocsparse_malloc_async: set output to nullptr and return hipSuccess for zero-size requests.

API changes / backward compatibility

None. These are internal allocation wrappers, not part of the public API. The guards make behavior consistent with the non-memstat path.

Performance impact

None. The guards add a single branch at function entry, avoiding unnecessary work for no-op calls.

Testing

The existing test suite exercises these paths implicitly through normal library usage. The guards handle edge cases that previously produced undefined or unnecessary behavior. A memstat-enabled build can be used to verify correct bookkeeping.

Areas needing review attention

  • Confirm that returning hipSuccess without calling memstat::remove is correct for the null-pointer free case (it is, since a null pointer was never tracked by memstat::add).
  • Confirm that zero-size allocations returning nullptr is the expected contract for all callers.

rocsparse_free/rocsparse_free_async now return hipSuccess for nullptr.
rocsparse_malloc/rocsparse_malloc_async now return hipSuccess with a
nullptr output for zero-size allocations.
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

❌ Your project status has failed because the head coverage (47.50%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #6597      +/-   ##
===========================================
+ Coverage    66.79%   66.82%   +0.03%     
===========================================
  Files         2255     2255              
  Lines       325081   324953     -128     
  Branches     41532    41506      -26     
===========================================
  Hits        217132   217132              
+ Misses       93289    93161     -128     
  Partials     14660    14660              
Flag Coverage Δ *Carryforward flag
hipBLAS 90.65% <ø> (ø) Carriedforward from 9163a22
hipBLASLt 40.00% <ø> (ø) Carriedforward from 9163a22
hipCUB 82.21% <ø> (ø) Carriedforward from 9163a22
hipDNN 82.40% <ø> (ø) Carriedforward from 9163a22
hipFFT 55.00% <ø> (ø) Carriedforward from 9163a22
hipRAND 76.12% <ø> (ø) Carriedforward from 9163a22
hipSPARSE 84.70% <ø> (ø) Carriedforward from 9163a22
rocBLAS 48.11% <ø> (ø) Carriedforward from 9163a22
rocFFT 47.50% <ø> (ø) Carriedforward from 9163a22
rocPRIM 38.96% <ø> (ø) Carriedforward from 9163a22
rocRAND 57.09% <ø> (ø) Carriedforward from 9163a22
rocSPARSE 71.65% <ø> (+0.12%) ⬆️
rocThrust 91.37% <ø> (ø) Carriedforward from 9163a22

*This pull request uses carry forward flags. Click here to find out more.
see 8 files with indirect coverage changes

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

@kliegeois kliegeois merged commit 152e338 into ROCm:develop Apr 21, 2026
18 of 20 checks passed
@kliegeois kliegeois deleted the fix/memstat-null-zero-guards branch April 21, 2026 12:43
assistant-librarian Bot pushed a commit to ROCm/rocSPARSE that referenced this pull request Apr 21, 2026
[rocsparse] Add null/zero-size guards to memstat allocation
 functions (#6597)

## What changed and why

The memstat-enabled variants of `rocsparse_free`,
`rocsparse_free_async`, `rocsparse_malloc`, and `rocsparse_malloc_async`
in `rocsparse_memstat.cpp` lack defensive guards for null pointers and
zero-size allocations.

- Calling `rocsparse_free(nullptr)` falls through to the HIP allocator
and memstat bookkeeping unnecessarily.
- Calling `rocsparse_malloc(&p, 0)` issues a zero-size allocation to
HIP, whose behavior is implementation-defined.

The non-memstat build path already handles these cases (e.g., the
`rocsparse_hipFreeAsync` macro has a null check), but the memstat path
did not, creating an inconsistency.

This PR adds early-return guards:
- `rocsparse_free` / `rocsparse_free_async`: return `hipSuccess` for
`nullptr` without entering the allocator or memstat tracking.
- `rocsparse_malloc` / `rocsparse_malloc_async`: set output to `nullptr`
and return `hipSuccess` for zero-size requests.

## API changes / backward compatibility

None. These are internal allocation wrappers, not part of the public
API. The guards make behavior consistent with the non-memstat path.

## Performance impact

None. The guards add a single branch at function entry, avoiding
unnecessary work for no-op calls.

## Testing

The existing test suite exercises these paths implicitly through normal
library usage. The guards handle edge cases that previously produced
undefined or unnecessary behavior. A memstat-enabled build can be used
to verify correct bookkeeping.

## Areas needing review attention

- Confirm that returning `hipSuccess` without calling `memstat::remove`
is correct for the null-pointer free case (it is, since a null pointer
was never tracked by `memstat::add`).
- Confirm that zero-size allocations returning `nullptr` is the expected
contract for all callers.
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.

4 participants