Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roll back ipow changes due to register pressure. #15242

Merged
merged 1 commit into from
Mar 11, 2024
Merged
Changes from all commits
Commits
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
60 changes: 16 additions & 44 deletions cpp/include/cudf/fixed_point/fixed_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,41 +85,7 @@ constexpr inline auto is_supported_construction_value_type()
namespace detail {

/**
* @brief Recursively computes integer exponentiation
*
* @note This is intended to be run at compile time
*
* @tparam Rep Representation type for return type
* @tparam Base The base to be exponentiated
* @param exp The exponent to be used for exponentiation
* @return Result of `Base` to the power of `exponent` of type `Rep`
*/
template <typename Rep, int32_t Base>
CUDF_HOST_DEVICE inline constexpr Rep get_power(int32_t exp)
{
// Compute power recursively
return (exp > 0) ? Rep(Base) * get_power<Rep, Base>(exp - 1) : 1;
}

/**
* @brief Implementation of integer exponentiation by array lookup
*
* @tparam Rep Representation type for return type
* @tparam Base The base to be exponentiated
* @tparam Exponents The exponents for the array entries
* @param exponent The exponent to be used for exponentiation
* @return Result of `Base` to the power of `exponent` of type `Rep`
*/
template <typename Rep, int32_t Base, std::size_t... Exponents>
CUDF_HOST_DEVICE inline Rep ipow_impl(int32_t exponent, cuda::std::index_sequence<Exponents...>)
{
// Compute powers at compile time, storing into array
static constexpr Rep powers[] = {get_power<Rep, Base>(Exponents)...};
return powers[exponent];
}

/**
* @brief A function for integer exponentiation by array lookup
* @brief A function for integer exponentiation by squaring.
*
* @tparam Rep Representation type for return type
* @tparam Base The base to be exponentiated
Expand All @@ -134,16 +100,22 @@ template <typename Rep,
CUDF_HOST_DEVICE inline Rep ipow(T exponent)
{
cudf_assert(exponent >= 0 && "integer exponentiation with negative exponent is not possible.");
if constexpr (Base == numeric::Radix::BASE_2) {
return static_cast<Rep>(1) << exponent;
} else { // BASE_10
// Build index sequence for building power array at compile time
static constexpr auto max_exp = cuda::std::numeric_limits<Rep>::digits10;
static constexpr auto exponents = cuda::std::make_index_sequence<max_exp + 1>{};

// Get compile-time result
return ipow_impl<Rep, static_cast<int32_t>(Base)>(exponent, exponents);

if constexpr (Base == numeric::Radix::BASE_2) { return static_cast<Rep>(1) << exponent; }

// Note: Including an array here introduces too much register pressure
// https://simple.wikipedia.org/wiki/Exponentiation_by_squaring
// This is the iterative equivalent of the recursive definition (faster)
// Quick-bench for squaring: http://quick-bench.com/Wg7o7HYQC9FW5M0CO0wQAjSwP_Y
if (exponent == 0) { return static_cast<Rep>(1); }
auto extra = static_cast<Rep>(1);
auto square = static_cast<Rep>(Base);
while (exponent > 1) {
if (exponent & 1) { extra *= square; }
exponent >>= 1;
square *= square;
}
return square * extra;
}

/** @brief Function that performs a `right shift` scale "times" on the `val`
Expand Down
Loading