Repository navigation
Conversation
Add `__float128` overloads that use `__builtin_<fn>f128` on the host and `__nv_fp128_<fn>` on the device, with a portable bit-level fallback built on a shared truncation helper for hosts that provide neither. The float128 test driver only exercises these four functions, since the other rounding functions do not support `__float128` yet.
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Truncation fallback and overload libcudacxx/include/cuda/std/__cmath/rounding_functions.h |
Adds __trunc_fp128_impl and the trunc(__float128) overload, with builtin, device, and software fallback paths. |
Ceiling and floor overloads libcudacxx/include/cuda/std/__cmath/rounding_functions.h |
Adds ceil(__float128) and floor(__float128) overloads, including builtin detection and fallback paths. |
Round overload and tests libcudacxx/include/cuda/std/__cmath/rounding_functions.h, libcudacxx/test/libcudacxx/std/numerics/c.math/rounding.pass.cpp |
Adds round(__float128) and guarded tests for all four functions, including large fractional values, halfway rounding, signed zero, and NaN. |
Assessment against linked issues
| Objective | Addressed | Explanation |
|---|---|---|
Enable __float128 in cuda::std::ceil [9940] |
✅ | |
Enable __float128 in cuda::std::floor [9941] |
✅ | |
Enable __float128 in cuda::std::trunc [9942] |
✅ | |
Enable __float128 in cuda::std::round [9943] |
✅ |
Possibly related issues
- NVIDIA/cccl issue 10471: The PR adds
__float128overloads tocuda::stdrounding functions, which relates to extended floating-point support.
Suggested reviewers: miscco
Priority:
Change: Feature
Merge Risk: 
Minimal · up to d5dc4
-
The float128 rounding additions are mergeable; no actionable correctness or availability risk remains.
Comment @coderabbitai help to get the list of available commands.
| # if defined(_CCCL_BUILTIN_CEILF128) | ||
| return _CCCL_BUILTIN_CEILF128(__x); | ||
| # else // ^^^ _CCCL_BUILTIN_CEILF128 ^^^ / vvv !_CCCL_BUILTIN_CEILF128 vvv | ||
| NV_IF_TARGET(NV_IS_DEVICE, (return ::__nv_fp128_ceil(__x);)) |
There was a problem hiding this comment.
I believe this requires some NV_PROVIDES_SMXY
There was a problem hiding this comment.
Thanks! Switched all four __nv_fp128_* calls to NV_IF_TARGET(NV_PROVIDES_SM_100, ...), matching isnan/min_max, so older architectures fall through to the portable path. Fixed in 65ff009.
miscco
left a comment
There was a problem hiding this comment.
Looks good to me @davebayer can you also give it a look
|
/ok to test 65ff009 |
There was a problem hiding this comment.
🧹 Nitpick comments: 1
libcudacxx/test/libcudacxx/std/numerics/c.math/rounding.pass.cpp: 1
443-446:Trivial · Functional Correctness · Quick win suggestion: Cover all four overloads at the
2^111 + 0.5boundary.The test checks
truncandceilathuge, but notfloororround. A boundary regression in either changed overload can pass. Add the corresponding assertions.assert(eq(cuda::std::trunc(huge), huge - T(0.5))); + assert(eq(cuda::std::floor(huge), huge - T(0.5))); assert(eq(cuda::std::ceil(huge), huge + T(0.5))); + assert(eq(cuda::std::round(huge), huge + T(0.5)));

Review info
-
Run configuration-
- Source mode: Auto
- Repository: NVIDIA/cccl
- Branch: main
- File: .coderabbit.yaml
- Commit: 036ecd2
- Layers: Repository YAML
- Review profile: CHILL
- Plan: Enterprise
- Run ID:
4c63f65d-23de-4905-9bc8-976d54b51ba7
Files selected for processing: 1-
libcudacxx/include/cuda/std/__cmath/rounding_functions.h
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.
-
😬 CI Workflow Results🟥 Finished in 2h 09m: Pass: 99%/228 | Total: 6d 17h | Max: 2h 03m | Hits: 82%/863749See results here. AI failure analysis1. libcudacxx float128 rounding builtins undefined with NVCC/GCC 7 · 2 jobsExplanation: In both CTK 12.0 and CTK 12.9 builds, the failing SHA unconditionally enables the ceil, floor, round, and trunc float128 builtins for GCC, although GCC 7 does not provide them during NVCC host compilation; the device-only undef guards do not cover that pass. The supplied pr.diff contains the likely correction—removing the unconditional GCC fallback from all four capability checks—while the checked-out failing SHA still contains it. Evidence: Copy this prompt into a coding agentJobs: |
| const __storage_t __bits = ::cuda::std::__fp_get_storage(__x); | ||
| const int __exp = | ||
| static_cast<int>((__bits & __fp_exp_mask_of_v<__float128>) >> __mant_nbits) - __fp_exp_bias_v<__fmt>; |
There was a problem hiding this comment.
Can be just:
| const __storage_t __bits = ::cuda::std::__fp_get_storage(__x); | |
| const int __exp = | |
| static_cast<int>((__bits & __fp_exp_mask_of_v<__float128>) >> __mant_nbits) - __fp_exp_bias_v<__fmt>; | |
| const int __exp = ::cuda::std::__fp_get_exp(__x); |
|
/ok to test d5dc435 |
Description
closes #9940, closes #9941, closes #9942, closes #9943
Adds
__float128overloads forcuda::std::ceil,floor,truncandround, following the pattern from #9895 (fabs) and #9991 (copysign):__builtin_<fn>f128when available (_CCCL_CHECK_BUILTIN(...) || _CCCL_COMPILER(GCC)), undefined for the nvcc device pass.__nv_fp128_<fn>.__trunc_fp128_implclears the fractional mantissa bits using the existing__fp_*storage and mask helpers.floor,ceilandroundare derived from it.roundcomparesx - trunc(x), which is exact, against 0.5 instead of computingtrunc(x + 0.5), which avoids double rounding near the halfway point.The rounding functions are separate overloads rather than one
if constexprtemplate, so the new overloads sit next to the existing__halfand__nv_bfloat16ones inrounding_functions.h.Tests: the generic
test<T>()driver inrounding.pass.cppalso callsllrint,nextafterand the other functions, which don't support__float128yet. So, like #10014 did inlogarithms.pass.cpp, a separatetest_float128driver calls only these four. It also adds float128-specific cases: values beyond the 64-bit range (2^65 + 0.5 and 2^111 + 0.5), halfway cases, signed zeros and NaN.Verified locally (WSL Ubuntu 24.04, CUDA 13.3; no NVIDIA GPU, so device behavior is up to CI):
rounding.pass.cppprecompiles for sm_100 with a clang 18 host, where_CCCL_HAS_FLOAT128()is 1 on both host and device. It also precompiles with a gcc 13 host, where it is 0 because of__STRICT_ANSI__, as a regression check.ceilq/floorq/truncq/roundq) on special values, every exponent boundary from 2^-4 to 2^116, and 4M random inputs. It was built twice, once with the builtins and once with the builtin defines removed to force the fallback. Both runs had 0 mismatches.pre-commit runpasses on the changed files.Checklist