fix(align_up): assert power-of-2 and overflow invariants - #2469
fix(align_up): assert power-of-2 and overflow invariants#2469nethum529 wants to merge 8 commits into
Conversation
|
/ok to test 5d83fc3 |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough
Changesalign_up overflow assertion
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
5d83fc3 to
7c80d0f
Compare
|
/ok to test ad861de |
bdice
left a comment
There was a problem hiding this comment.
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.)
|
Sorry for the drive-by, but I think alignup is probably |
|
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>
ad861de to
4589d01
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cpp/tests/mr/aligned_mr_tests.cpp (1)
252-282: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider 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 newassertin 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
📒 Files selected for processing (3)
cpp/include/rmm/aligned.hppcpp/src/aligned.cppcpp/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>
ad0d329 to
92d6dfe
Compare
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>
|
Pushed the revision.
|
|
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 |
bdice
left a comment
There was a problem hiding this comment.
Great. Thanks for reworking this.
|
/ok to test 0bf77ec |
Problem
align_up's power-of-2 alignment precondition was only checked via a bareassert, and there was no overflow check at all. A value nearSIZE_MAXsilently wrapped to a small or zero result instead of being caught (observed while debugging #2002).Fix
assert(aligned_value >= value)catches wraparound in debug builds.align_up(and the power-of-2 requirement onalign_down).align_upstaysnoexcept. Per review, it must remain callable from destructors, so the invariants are enforced withassert(debug-only) rather than by throwing. This keeps the release ABI and the destructor-safe contract intact.align_downis unchanged: it only clears bits, so it cannot overflow.Tests
New gtests in
ALIGNED_TESTcover 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