Repository navigation
Add cuda::bit_ffs to <cuda/bit> - #9609
Conversation
Implements a type-safe find-first-set that returns 1 + the index of the least significant set bit, or 0 for a zero input, matching __builtin_ffs and CUDA's __ffs (unlike countr_zero). Adds tests and docs. Closes NVIDIA#6108 Signed-off-by: temujinkz <ttalkenov@gmail.com>
|
Thanks a lot for the PR, This already looks great, I have some nits |
Review feedback from @miscco and @fbusato on NVIDIA#9609: - route through __builtin_ffs / __builtin_ffsll on host and __ffs / __ffsll on device (constexpr fallback) so codegen matches __ffs / __ffsll - test: use assert instead of static_assert so the runtime path is exercised, mark the per-type helper void, [[maybe_unused]] the constant - test: add a concept check that bit_ffs rejects bool, signed, float, and enums - docs: add an all-bits-set example Signed-off-by: temujinkz <ttalkenov@gmail.com>
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds ChangesBit FFS API
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The PR adds the new bit_ffs API and documentation with no actionable merge-blocking risk remaining; the formatting and documentation follow-ups are non-blocking. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 8617fc92-34c6-45a3-b206-feac28bfbaf5
📒 Files selected for processing (5)
docs/libcudacxx/extended_api/bit.rstdocs/libcudacxx/extended_api/bit/bit_ffs.rstlibcudacxx/include/cuda/__bit/bit_ffs.hlibcudacxx/include/cuda/bitlibcudacxx/test/libcudacxx/cuda/bit/bit_ffs.pass.cpp
|
Thanks for the fast review, really appreciate it. Pushed an update that should cover everything:
Let me know if the codegen looks right on your side, happy to tweak anything. |
Pre-empt the same review feedback as bit_ffs (NVIDIA#9609): - implement bit_msb by forwarding to cuda::std::bit_width, which already lowers to the optimal clz based code - test: use assert instead of static_assert, per-type helper returns void, [[maybe_unused]] the constant, and add a concept check rejecting bool, signed, float, and enums - docs: add an all-bits-set example Signed-off-by: temujinkz <ttalkenov@gmail.com>
Per the IWYU coding guideline (and CodeRabbit), the test used numeric_limits and size_t through transitive includes. Add the direct headers. Signed-off-by: temujinkz <ttalkenov@gmail.com>
|
Good catch, fixed. Added |
temujinkz
left a comment
There was a problem hiding this comment.
went back through everything from the last round, should all be covered now. thanks for the thorough pass
- detect __builtin_ffs and __builtin_ffsll under separate conditions and drop the redundant clang/nvhpc checks; keep the gcc<10 fallback since gcc only gained __has_builtin in gcc 10, like the other bit headers - also undef the ffs builtins under nvrtc - rename __bit_ffs_impl_constexpr to __bit_ffs_impl_generic - take parameters by const value - drop the redundant intermediate casts and use cuda::std::uint32_t/uint64_t in the size dispatches - docs: bit_ffs ships in CUDA 13.5
Mark the signature __tile__ and include cuda_runtime_api.h in the example so it builds as written.
|
/ok to test 5698ecb |
This comment has been minimized.
This comment has been minimized.
Signed-off-by: temujinkz <ttalkenov@gmail.com>
griwes
left a comment
There was a problem hiding this comment.
This looks good, tests seem appropriate. Kinda wild we didn't have a native wrapper for __ffs yet.
|
/ok to test 8526d61 |
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
libcudacxx/include/cuda/__bit/bit_ffs.h (2)
35-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winsuggestion: Update both
#endifcomments to repeat their complete opening conditions. Lines 37 and 41 omit|| _CCCL_COMPILER(GCC, <, 10).Based on learnings, each annotated
#endifcomment must repeat the exact verbatim condition from its corresponding#if.Source: Learnings
119-124: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winsuggestion: Convert the
bit_ffsAPI comment to the required Doxygen form. Add//!@brief``,@param[in] __value, and `@return` documentation.As per coding guidelines, documented functions must include
//!@brief``, parameter documentation, and@returnfor non-void functions.Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: cff4a5f2-d179-45ba-a298-83a5e503f268
📒 Files selected for processing (5)
docs/libcudacxx/extended_api/bit.rstdocs/libcudacxx/extended_api/bit/bit_ffs.rstlibcudacxx/include/cuda/__bit/bit_ffs.hlibcudacxx/include/cuda/bitlibcudacxx/test/libcudacxx/cuda/bit/bit_ffs.pass.cpp
🚧 Files skipped from review as they are similar to previous changes (3)
- libcudacxx/include/cuda/bit
- docs/libcudacxx/extended_api/bit/bit_ffs.rst
- docs/libcudacxx/extended_api/bit.rst
⏱️ CCCL compile-time benchmark comparison: Public headers compile-time benchResult: 0 regression row(s), 1 improvement row(s) above threshold.
Artifacts: reports and traces Direct file processing
🟢 Direct file processing — Improvements
|
🥳 CI Workflow Results🟩 Finished in 1h 35m: Pass: 100%/117 | Total: 23h 27m | Max: 48m 03s | Hits: 98%/338174See results here. |
|
Thanks a lot for implementing this 🎉 Efficient bit fiddling is dear to my heart |
cuda::bit_ffs(x) returns the 1-based position of the lowest set bit, or 0 if x is zero. The body is x == 0 ? 0 : countr_zero(x) + 1. countr_zero counts trailing zeros, so adding 1 turns it into a 1-based index. The x == 0 guard is the one case countr_zero doesn't define cleanly, and handling it is the whole reason this wrapper exists. It matches __builtin_ffs and CUDA's __ffs. It's constrained to unsigned integers, works on all widths including 128-bit, and is constexpr plus host/device because it just forwards to countr_zero.