Skip to content

fix(align_up): assert power-of-2 and overflow invariants - #2469

Open
nethum529 wants to merge 8 commits into
rapidsai:mainfrom
nethum529:fix/align-up-invariants
Open

fix(align_up): assert power-of-2 and overflow invariants#2469
nethum529 wants to merge 8 commits into
rapidsai:mainfrom
nethum529:fix/align-up-invariants

Conversation

@nethum529

@nethum529 nethum529 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Problem

align_up's power-of-2 alignment precondition was only checked via a bare assert, and there was no overflow check at all. A value near SIZE_MAX silently wrapped to a small or zero result instead of being caught (observed while debugging #2002).

Fix

  • Add an overflow guard: assert(aligned_value >= value) catches wraparound in debug builds.
  • Document the alignment and non-overflow invariants on align_up (and the power-of-2 requirement on align_down).
  • align_up stays noexcept. Per review, it must remain callable from destructors, so the invariants are enforced with assert (debug-only) rather than by throwing. This keeps the release ABI and the destructor-safe contract intact.
  • align_down is unchanged: it only clears bits, so it cannot overflow.

Tests

New gtests in ALIGNED_TEST cover the overflow boundary (AlignUpJustBelowOverflowBoundarySucceeds, AlignUpAtOverflowBoundaryIsNoOp, AlignUpAlignmentOfOneIsNoOp) and a debug-only death test (AlignedDeathTest.AlignUpOverflowAborts) that exercises the overflow guard directly. Suite passes locally.

closes #2005

@nethum529
nethum529 requested a review from a team as a code owner July 6, 2026 21:19
@nethum529
nethum529 requested review from PointKernel and harrism July 6, 2026 21:19
@copy-pr-bot

copy-pr-bot Bot commented Jul 6, 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.

@PointKernel PointKernel added bug Something isn't working non-breaking Non-breaking change labels Jul 6, 2026
@PointKernel

Copy link
Copy Markdown
Member

/ok to test 5d83fc3

@PointKernel PointKernel added improvement Improvement / enhancement to an existing function and removed bug Something isn't working labels Jul 6, 2026
@coderabbitai

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

rmm::align_up now documents its alignment and overflow invariants, removes noexcept, checks for wraparound with an assertion, and adds boundary tests. align_down documentation also clarifies its power-of-two requirement.

Changes

align_up overflow assertion

Layer / File(s) Summary
Alignment contract and overflow guard
cpp/include/rmm/aligned.hpp, cpp/src/aligned.cpp
Documents alignment and non-overflow requirements, removes noexcept, and asserts that the aligned result remains greater than or equal to the input.
Boundary and no-op alignment tests
cpp/tests/mr/aligned_mr_tests.cpp
Tests overflow-edge values, the safe boundary, and alignment by one, including SIZE_MAX and a debug-only death test.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: harrism, pointkernel

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning [#2005] The PR only adds debug asserts for the invariant, so invalid inputs can still wrap in release builds instead of failing loudly. Add an always-on contract check such as RMM_EXPECTS for align_up's precondition and overflow guard, not just debug-only assert handling.
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
Out of Scope Changes check ✅ Passed The changes stay focused on align_up docs, implementation, and tests, with no obvious unrelated work.
Title check ✅ Passed The title matches the main change: hardening align_up with overflow and alignment invariant checks.
Description check ✅ Passed The description is clearly about the same align_up overflow and alignment fix, so it is related to the changeset.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@nethum529
nethum529 force-pushed the fix/align-up-invariants branch from 5d83fc3 to 7c80d0f Compare July 7, 2026 02:35
@PointKernel

Copy link
Copy Markdown
Member

/ok to test ad861de

@bdice bdice left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a helpful change. I have a couple of requests.

(I realize this is an agent's contribution, so if I don't hear back, I'll push a fix myself when time allows.)

Comment thread cpp/tests/mr/aligned_mr_tests.cpp Outdated
Comment thread cpp/tests/mr/aligned_mr_tests.cpp Outdated
@harrism

harrism commented Jul 15, 2026

Copy link
Copy Markdown
Member

Sorry for the drive-by, but I think alignup is probably noexcept for a reason: so it can be called from destructors.

@nethum529

Copy link
Copy Markdown
Contributor Author

Looking into the feedback now. Agreed on the noexcept point, align_up should stay noexcept so it can be called from destructors, so I'll keep it noexcept and use assert-based checks instead of throwing. Update coming shortly.

closes rapidsai#2005

`align_up`'s power-of-2 alignment precondition was only checked via a
bare `assert`, a no-op in release (NDEBUG) builds. Combined with no
overflow check, a value near `SIZE_MAX` silently wrapped to a small or
zero result instead of failing, observed while debugging rapidsai#2002.

Replace the assert with `RMM_EXPECTS` (always active, throws
`rmm::logic_error`) and add an overflow guard on the computed result.
`align_up` is no longer `noexcept` since it can now throw.

`align_down` is unchanged: it only clears bits, so it cannot overflow
and was out of scope for this issue.

Breaking change: any downstream code calling `align_up` from inside
its own `noexcept` function should be audited, since a throw escaping
a `noexcept` function now terminates instead of the old silent UB.
Within this repo, six `noexcept` call sites were audited and are safe
under contract-compliant use (matching bytes/alignment already
validated by a paired, non-noexcept `allocate()` call):
`stream_ordered_memory_resource.hpp` and
`arena_memory_resource_impl.cpp`, `limiting_resource_adaptor_impl.cpp`,
and `aligned_resource_adaptor_impl.cpp` deallocate paths (unconditional
in all build modes), plus `fixed_size_memory_resource_impl.cpp` and
`pool_memory_resource_impl.cpp` (gated behind `RMM_LOGGING_ASSERT`,
a no-op under NDEBUG).

Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
@nethum529
nethum529 force-pushed the fix/align-up-invariants branch from ad861de to 4589d01 Compare July 18, 2026 02:18

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

🧹 Nitpick comments (1)
cpp/tests/mr/aligned_mr_tests.cpp (1)

252-282: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider adding a test for the overflow failure case.

The three new tests cover the safe boundary and no-op cases well. There is no test for the case where overflow actually occurs (e.g., align_up(SIZE_MAX, 256)), which would trigger the new assert in debug builds. If death tests (EXPECT_DEATH) are acceptable in this codebase, adding one would close the coverage gap and directly validate the overflow guard.

🤖 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 `@cpp/tests/mr/aligned_mr_tests.cpp` around lines 252 - 282, Add a death test
in the AlignedTest suite covering
align_up(std::numeric_limits<std::size_t>::max(), 256) and assert that it
terminates due to the overflow guard. Follow the repository’s existing
death-test conventions, if available, and keep the current safe-boundary and
no-op tests unchanged.

Source: Learnings

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

Nitpick comments:
In `@cpp/tests/mr/aligned_mr_tests.cpp`:
- Around line 252-282: Add a death test in the AlignedTest suite covering
align_up(std::numeric_limits<std::size_t>::max(), 256) and assert that it
terminates due to the overflow guard. Follow the repository’s existing
death-test conventions, if available, and keep the current safe-boundary and
no-op tests unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ebfd1397-1999-4d51-828b-a990ae9a898b

📥 Commits

Reviewing files that changed from the base of the PR and between 7c80d0f and 4589d01.

📒 Files selected for processing (3)
  • cpp/include/rmm/aligned.hpp
  • cpp/src/aligned.cpp
  • cpp/tests/mr/aligned_mr_tests.cpp

…p doc comments

Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
@nethum529
nethum529 force-pushed the fix/align-up-invariants branch 2 times, most recently from ad0d329 to 92d6dfe Compare July 18, 2026 02:45
Covers align_up(SIZE_MAX, 256), which trips the debug assert(aligned_value
>= value) overflow guard and aborts. Guarded by NDEBUG since the guard is an
assert compiled out in release builds, matching the death-test convention in
cuda_stream_tests.cpp.

Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
@nethum529

Copy link
Copy Markdown
Contributor Author

Pushed the revision.

  • @harrism: align_up is back to noexcept so it stays callable from destructors. Invariants (power-of-2 alignment, non-overflow) are now enforced with assert in debug builds rather than throwing, so the release ABI and the destructor-safe contract are both preserved. Updated the doc comments and PR title/description to match.
  • CodeRabbit overflow-failure coverage: added AlignedDeathTest.AlignUpOverflowAborts (guarded by #ifndef NDEBUG, matching the existing death-test convention in cuda_stream_tests.cpp) which asserts align_up(SIZE_MAX, 256) aborts on the overflow guard.

@nethum529 nethum529 changed the title fix(align_up): assert invariants and remove noexcept fix(align_up): assert power-of-2 and overflow invariants Jul 18, 2026
@nethum529

Copy link
Copy Markdown
Contributor Author

Updated the branch against latest upstream main (including the new versioned ABI namespace from #2462, merged cleanly). Both review asks were addressed in the earlier push: the static_assert(noexcept(...)) is removed, and the vague happy-path test is replaced by purpose-named boundary tests plus a debug-only overflow death test. Built and ran the aligned tests locally after the merge.

@bdice bdice left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. Thanks for reworking this.

@bdice

bdice commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

/ok to test 0bf77ec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improvement / enhancement to an existing function non-breaking Non-breaking change

Projects

Status: Review

Development

Successfully merging this pull request may close these issues.

[FEA] Assert invariants in rmm::align_up

4 participants