Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
e29d727
Add CUDA support to bit functions
mborland Mar 26, 2026
b725ea1
Add CUDA testing of bit functions
mborland Mar 26, 2026
b394b47
Use CUDA provided functions when available
mborland Mar 26, 2026
613cb0f
Fix implementation for u128
mborland Mar 26, 2026
7c523e2
Add CUDA support to byte conversions functions
mborland Mar 26, 2026
398de51
Test byte conversions on CUDA
mborland Mar 26, 2026
9671ba9
Add CUDA support to charconv functions
mborland Mar 26, 2026
a8a7097
Add CUDA testing of charconv functions
mborland Mar 26, 2026
c6c150b
Add CUDA support to integer utilities
mborland Mar 26, 2026
2aaf8ad
Add CUDA testing of integer utilities
mborland Mar 26, 2026
9ad5573
Fix overflow in tests
mborland Mar 26, 2026
71e2f37
On CUDA move tables into functions
mborland Mar 26, 2026
0b8d781
Use CUDA bit functions when on device
mborland Mar 26, 2026
b09c97d
Add CUDA support for numeric functions
mborland Mar 26, 2026
e13f8d3
Add CUDA testing of numeric functions
mborland Mar 26, 2026
f15b9f1
Use cuda::std:: when compiling on device
mborland Mar 26, 2026
afa19ca
Add example of CUDA usage
mborland Mar 26, 2026
456ba65
Add example of failure and how to use error context
mborland Mar 26, 2026
c976532
Add examples to CUDA Jamfile
mborland Mar 26, 2026
c915375
Make the global a pointer because trap will destroy all managed memory
mborland Mar 26, 2026
4504f3e
Realloc after thrown exception
mborland Mar 26, 2026
a4582c7
Enforce allowing only a single error context at any time to avoid race
mborland Mar 26, 2026
d507b6a
Use local allocation instead of always global
mborland Mar 26, 2026
56832a0
Move from managed to device memory
mborland Mar 26, 2026
8ef8397
Print debugging
mborland Mar 26, 2026
03fe724
Change failure deallocation
mborland Mar 26, 2026
ea77528
Change recovery path
mborland Mar 26, 2026
f127714
Add a separate reset after error function
mborland Mar 26, 2026
f81d621
Try reset the runtime
mborland Mar 26, 2026
be61bd7
Reorder operations
mborland Mar 26, 2026
2868902
Do a harder reset
mborland Mar 26, 2026
b135e51
Need to link to driver to manipulate context
mborland Mar 26, 2026
732fe8f
Remove __trap as it causes an unrecoverable error for the process
mborland Mar 26, 2026
a55791e
Remove now unneeded print statements
mborland Mar 26, 2026
46a04da
Implement byteswap since only NVCC 13+ has it
mborland Mar 27, 2026
df77270
Add GPU markers to documentation pages where applicable
mborland Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions doc/modules/ROOT/pages/bit.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ For `u128`, the functions delegate to the `boost::int128` implementations.
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto has_single_bit(UnsignedInt x) noexcept -> bool;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto has_single_bit(UnsignedInt x) noexcept -> bool;
----

Returns `true` if `x` is a power of two.
Expand All @@ -37,7 +37,7 @@ See https://en.cppreference.com/w/cpp/numeric/has_single_bit.html[`std::has_sing
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto bit_ceil(UnsignedInt x) noexcept -> UnsignedInt;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto bit_ceil(UnsignedInt x) noexcept -> UnsignedInt;
----

Returns the smallest power of two not less than `x`.
Expand All @@ -49,7 +49,7 @@ See https://en.cppreference.com/w/cpp/numeric/bit_ceil.html[`std::bit_ceil`].
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto bit_floor(UnsignedInt x) noexcept -> UnsignedInt;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto bit_floor(UnsignedInt x) noexcept -> UnsignedInt;
----

Returns the largest power of two not greater than `x`.
Expand All @@ -61,7 +61,7 @@ See https://en.cppreference.com/w/cpp/numeric/bit_floor.html[`std::bit_floor`].
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto bit_width(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto bit_width(UnsignedInt x) noexcept -> int;
----

Returns the number of bits needed to represent `x` (i.e., 1 + floor(log2(x)) for x > 0, or 0 for x == 0).
Expand All @@ -74,7 +74,7 @@ See https://en.cppreference.com/w/cpp/numeric/bit_width.html[`std::bit_width`].
[source,c++]
----
template <non_bounded_unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto rotl(UnsignedInt x, int s) noexcept -> UnsignedInt;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto rotl(UnsignedInt x, int s) noexcept -> UnsignedInt;
----

Computes the result of bitwise left-rotating `x` by `s` positions.
Expand All @@ -87,7 +87,7 @@ NOTE: `rotl` is not available for `bounded_uint` types. Bit rotation can produce
[source,c++]
----
template <non_bounded_unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto rotr(UnsignedInt x, int s) noexcept -> UnsignedInt;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto rotr(UnsignedInt x, int s) noexcept -> UnsignedInt;
----

Computes the result of bitwise right-rotating `x` by `s` positions.
Expand All @@ -102,7 +102,7 @@ NOTE: `rotr` is not available for `bounded_uint` types. Bit rotation can produce
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto countl_zero(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto countl_zero(UnsignedInt x) noexcept -> int;
----

Returns the number of consecutive 0-bits starting from the most significant bit.
Expand All @@ -113,7 +113,7 @@ See https://en.cppreference.com/w/cpp/numeric/countl_zero.html[`std::countl_zero
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto countl_one(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto countl_one(UnsignedInt x) noexcept -> int;
----

Returns the number of consecutive 1-bits starting from the most significant bit.
Expand All @@ -124,7 +124,7 @@ See https://en.cppreference.com/w/cpp/numeric/countl_one.html[`std::countl_one`]
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto countr_zero(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto countr_zero(UnsignedInt x) noexcept -> int;
----

Returns the number of consecutive 0-bits starting from the least significant bit.
Expand All @@ -135,7 +135,7 @@ See https://en.cppreference.com/w/cpp/numeric/countr_zero.html[`std::countr_zero
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto countr_one(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto countr_one(UnsignedInt x) noexcept -> int;
----

Returns the number of consecutive 1-bits starting from the least significant bit.
Expand All @@ -146,7 +146,7 @@ See https://en.cppreference.com/w/cpp/numeric/countr_one.html[`std::countr_one`]
[source,c++]
----
template <unsigned_library_type UnsignedInt>
[[nodiscard]] constexpr auto popcount(UnsignedInt x) noexcept -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto popcount(UnsignedInt x) noexcept -> int;
----

Returns the number of 1-bits in `x`.
Expand All @@ -159,7 +159,7 @@ See https://en.cppreference.com/w/cpp/numeric/popcount.html[`std::popcount`].
[source,c++]
----
template <non_bounded_integral_library_type Int>
[[nodiscard]] constexpr auto byteswap(Int x) noexcept -> Int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto byteswap(Int x) noexcept -> Int;
----

Reverses the bytes of `x`.
Expand All @@ -172,7 +172,7 @@ NOTE: `byteswap` is not available for `bounded_uint` types. Byte reversal can pr
[source,c++]
----
template <non_bounded_integral_library_type Int>
[[nodiscard]] constexpr auto bitswap(Int x) noexcept -> Int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto bitswap(Int x) noexcept -> Int;
----

Reverses all bits of `x`.
Expand Down
12 changes: 6 additions & 6 deletions doc/modules/ROOT/pages/byte_conversions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ The value is first converted to big-endian byte order using `to_be`, then reinte
[source,c++]
----
template <non_bounded_integral_library_type T>
[[nodiscard]] constexpr auto to_be_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto to_be_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
----

=== Parameters
Expand Down Expand Up @@ -203,7 +203,7 @@ The bytes are reinterpreted as the underlying type and then converted from big-e
[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
[[nodiscard]] constexpr auto from_be_bytes(const std::span<const std::byte, N> bytes) -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto from_be_bytes(const std::span<const std::byte, N> bytes) -> T;
----

=== Parameters
Expand Down Expand Up @@ -251,7 +251,7 @@ The value is first converted to little-endian byte order using `to_le`, then rei
[source,c++]
----
template <non_bounded_integral_library_type T>
[[nodiscard]] constexpr auto to_le_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto to_le_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
----

=== Parameters
Expand Down Expand Up @@ -284,7 +284,7 @@ The bytes are reinterpreted as the underlying type and then converted from littl
[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
[[nodiscard]] constexpr auto from_le_bytes(const std::span<const std::byte, N> bytes) -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto from_le_bytes(const std::span<const std::byte, N> bytes) -> T;
----

=== Parameters
Expand Down Expand Up @@ -334,7 +334,7 @@ The result is equivalent to `std::bit_cast<std::array<std::byte, sizeof(T)>>(val
[source,c++]
----
template <non_bounded_integral_library_type T>
[[nodiscard]] constexpr auto to_ne_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto to_ne_bytes(const T value) noexcept -> std::array<std::byte, sizeof(T)>;
----

=== Parameters
Expand Down Expand Up @@ -368,7 +368,7 @@ Delegates to `from_le_bytes` on little-endian platforms and `from_be_bytes` on b
[source,c++]
----
template <non_bounded_integral_library_type T, std::size_t N>
[[nodiscard]] constexpr auto from_ne_bytes(const std::span<const std::byte, N> bytes) -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto from_ne_bytes(const std::span<const std::byte, N> bytes) -> T;
----

=== Parameters
Expand Down
9 changes: 9 additions & 0 deletions doc/modules/ROOT/pages/charconv.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ namespace boost::charconv {

// Convert safe integer to character string
template <safe_numbers::detail::library_type T>
BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr auto to_chars(char* first, char* last,
T value,
int base = 10) -> charconv::to_chars_result;

// Convert character string to safe integer
template <safe_numbers::detail::library_type T>
BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr auto from_chars(const char* first, const char* last,
T& value,
int base = 10) -> charconv::from_chars_result;
Expand All @@ -57,8 +59,10 @@ struct to_chars_result
char* ptr;
std::errc ec;

BOOST_SAFE_NUMBERS_HOST_DEVICE
friend constexpr bool operator==(const to_chars_result& lhs,
const to_chars_result& rhs) noexcept = default;
BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
};

Expand All @@ -83,8 +87,11 @@ struct from_chars_result
const char* ptr;
std::errc ec;

BOOST_SAFE_NUMBERS_HOST_DEVICE
friend constexpr bool operator==(const from_chars_result& lhs,
const from_chars_result& rhs) noexcept = default;

BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
};

Expand All @@ -103,6 +110,7 @@ struct from_chars_result
[source,c++]
----
template <safe_numbers::detail::library_type T>
BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr auto to_chars(char* first, char* last,
T value,
int base = 10) -> charconv::to_chars_result;
Expand Down Expand Up @@ -133,6 +141,7 @@ Returns `boost::charconv::to_chars_result` with:
[source,c++]
----
template <safe_numbers::detail::library_type T>
BOOST_SAFE_NUMBERS_HOST_DEVICE
constexpr auto from_chars(const char* first, const char* last,
T& value,
int base = 10) -> charconv::from_chars_result;
Expand Down
2 changes: 1 addition & 1 deletion doc/modules/ROOT/pages/cuda.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ Device error on thread 256 at /home/runner/work/safe_numbers/boost-root/libs/saf

The `device_error_context` will also attempt to `printf` the error into the terminal.
This works when compiling with verbose mode `-V`.
`printf` error messages will look the same as the message displayed by
`printf` error messages will look the same as the message displayed by the thrown exception

22 changes: 11 additions & 11 deletions doc/modules/ROOT/pages/integer_utilities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ These operate on the non-bounded unsigned types (`u8`, `u16`, `u32`, `u64`, `u12
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto isqrt(const T val) -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto isqrt(const T val) -> T;
----

Returns the integer square root of `val`, i.e., the largest integer `r` such that `r * r \<= val`.
Expand Down Expand Up @@ -74,7 +74,7 @@ struct remove_trailing_zeros_return
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto remove_trailing_zeros(const T n);
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto remove_trailing_zeros(const T n);
----

Removes all trailing decimal zeros from `n`.
Expand Down Expand Up @@ -141,7 +141,7 @@ Tests whether an unsigned integer value is an exact power of 10 (i.e., one of 1,
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto is_power_10(const T n) -> bool;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto is_power_10(const T n) -> bool;
----

=== Parameters
Expand Down Expand Up @@ -171,7 +171,7 @@ Returns the integer base-2 logarithm (floor of log~2~) of a value.
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto ilog2(const T n) -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto ilog2(const T n) -> int;
----

Computes `floor(log~2~(n))` using `bit_width(n) - 1`.
Expand Down Expand Up @@ -213,7 +213,7 @@ Uses an O(1) algorithm based on the most significant bit position to approximate
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto ilog10(const T n) -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto ilog10(const T n) -> int;
----

Computes `floor(log~10~(n))` using `num_digits(n) - 1`, where `num_digits` approximates the digit count via `log~10~(x) ~= log~2~(x) / log~2~(10)` and refines with at most two comparisons against a power-of-10 lookup table.
Expand Down Expand Up @@ -249,7 +249,7 @@ Returns the integer logarithm in an arbitrary base (floor of log~base~) of a val
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto ilog(const T n, const T base) -> int;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto ilog(const T n, const T base) -> int;
----

Computes `floor(log~base~(n))` by repeated division.
Expand Down Expand Up @@ -294,7 +294,7 @@ Integer exponentiation using the exponentiation-by-squaring algorithm.
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto ipow(const T a, const T b) noexcept -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto ipow(const T a, const T b) noexcept -> T;
----

Computes `a` raised to the power `b` using exponentiation by squaring.
Expand Down Expand Up @@ -339,7 +339,7 @@ Tests whether an unsigned integer value is an exact power of 2 (i.e., has exactl
[source,c++]
----
template <non_bounded_unsigned_library_type T>
[[nodiscard]] constexpr auto is_power_2(const T n) noexcept -> bool;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto is_power_2(const T n) noexcept -> bool;
----

=== Parameters
Expand Down Expand Up @@ -370,7 +370,7 @@ For unsigned types, naive subtraction `a - b` when `b > a` would underflow; `abs
[source,c++]
----
template <integral_library_type T>
[[nodiscard]] constexpr auto abs_diff(const T a, const T b) noexcept -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto abs_diff(const T a, const T b) noexcept -> T;
----

Returns `|a - b|`, computed as `a - b` if `a >= b`, or `b - a` otherwise.
Expand Down Expand Up @@ -411,7 +411,7 @@ For unsigned types, this is equivalent to `(a + b - 1) / b` but computed without
[source,c++]
----
template <integral_library_type T>
[[nodiscard]] constexpr auto div_ceil(const T a, const T b) noexcept -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto div_ceil(const T a, const T b) noexcept -> T;
----

Returns the ceiling of `a / b`.
Expand Down Expand Up @@ -454,7 +454,7 @@ This is useful for alignment calculations (e.g., aligning a size to a page bound
[source,c++]
----
template <integral_library_type T>
[[nodiscard]] constexpr auto next_multiple_of(const T a, const T b) noexcept -> T;
BOOST_SAFE_NUMBERS_HOST_DEVICE [[nodiscard]] constexpr auto next_multiple_of(const T a, const T b) noexcept -> T;
----

Returns the smallest value `m` such that `m >= a` and `m % b == 0`.
Expand Down
Loading
Loading