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

Support for MOD, PMOD and PYMOD for decimal32/64/128 #10179

Merged
merged 13 commits into from
Feb 3, 2022
25 changes: 25 additions & 0 deletions cpp/include/cudf/fixed_point/fixed_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,21 @@ class fixed_point {
CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator/(
fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);

/**
* @brief operator % (for modulo-ing two `fixed_point` numbers)
codereport marked this conversation as resolved.
Show resolved Hide resolved
*
* If `_scale`s are equal, `_value`s are modulo-ed <br>
* If `_scale`s are not equal, number with smaller `_scale` is shifted to the
* greater `_scale`, and then `_value`s are modulo-ed
codereport marked this conversation as resolved.
Show resolved Hide resolved
*
* @tparam Rep1 Representation type of number being modulo-ed to `this`
* @tparam Rad1 Radix (base) type of number being modulo-ed to `this`
* @return The resulting `fixed_point` number
*/
template <typename Rep1, Radix Rad1>
bdice marked this conversation as resolved.
Show resolved Hide resolved
CUDF_HOST_DEVICE inline friend fixed_point<Rep1, Rad1> operator%(
fixed_point<Rep1, Rad1> const& lhs, fixed_point<Rep1, Rad1> const& rhs);

/**
* @brief operator == (for comparing two `fixed_point` numbers)
*
Expand Down Expand Up @@ -750,6 +765,16 @@ CUDF_HOST_DEVICE inline bool operator>(fixed_point<Rep1, Rad1> const& lhs,
return lhs.rescaled(scale)._value > rhs.rescaled(scale)._value;
}

// MODULUS OPERATION
codereport marked this conversation as resolved.
Show resolved Hide resolved
template <typename Rep1, Radix Rad1>
CUDF_HOST_DEVICE inline fixed_point<Rep1, Rad1> operator%(fixed_point<Rep1, Rad1> const& lhs,
fixed_point<Rep1, Rad1> const& rhs)
{
auto const scale = std::min(lhs._scale, rhs._scale);
auto const remainder = lhs.rescaled(scale)._value % rhs.rescaled(scale)._value;
return fixed_point<Rep1, Rad1>{scaled_integer<Rep1>{remainder, scale}};
}

using decimal32 = fixed_point<int32_t, Radix::BASE_10>;
using decimal64 = fixed_point<int64_t, Radix::BASE_10>;
using decimal128 = fixed_point<__int128_t, Radix::BASE_10>;
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/binaryop/binaryop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ bool is_comparison_binop(binary_operator op)
*/
bool is_supported_fixed_point_binop(binary_operator op)
{
return is_basic_arithmetic_binop(op) or is_comparison_binop(op);
return is_basic_arithmetic_binop(op) or is_comparison_binop(op) or //
codereport marked this conversation as resolved.
Show resolved Hide resolved
op == binary_operator::MOD or //
codereport marked this conversation as resolved.
Show resolved Hide resolved
op == binary_operator::PMOD;
codereport marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
10 changes: 10 additions & 0 deletions cpp/src/binaryop/compiled/operation.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ struct PMod {
if (rem < 0) rem = std::fmod(rem + yconv, yconv);
return rem;
}

template <typename TypeLhs,
typename TypeRhs,
std::enable_if_t<cudf::is_fixed_point<TypeLhs>() and
std::is_same_v<TypeLhs, TypeRhs>>* = nullptr>
codereport marked this conversation as resolved.
Show resolved Hide resolved
__device__ inline auto operator()(TypeLhs x, TypeRhs y)
codereport marked this conversation as resolved.
Show resolved Hide resolved
{
auto const remainder = x % y;
return remainder.value() < 0 ? (remainder + y) % y : remainder;
}
};

struct PyMod {
Expand Down
Loading