1010
1111#include < stdint.h>
1212
13+ #include < type_traits>
14+
1315namespace raft {
1416namespace util {
1517
1618/* *
1719 * @brief Perform fast integer division and modulo using a known divisor
1820 * From Hacker's Delight, Second Edition, Chapter 10
1921 *
20- * @note This currently only supports 32b signed integers
22+ * @note 32b signed integer is supported.
23+ * @note 64b signed integers is supported for an input data up to 2^31
24+ * because gpu-non-native int128 is avoided for performance.
2125 * @todo Extend support for signed divisors
2226 */
27+ template <typename IntT>
2328struct FastIntDiv {
29+ static_assert (std::is_same_v<IntT, int32_t > || std::is_same_v<IntT, int64_t >,
30+ " FastIntDiv: IntT must be int32_t or int64_t" );
31+ using UIntT = std::make_unsigned_t <IntT>;
32+
2433 /* *
2534 * @defgroup HostMethods Ctor's that are accessible only from host
2635 * @{
2736 * @brief Host-only ctor's
2837 * @param _d the divisor
2938 */
30- FastIntDiv (int _d) : d(_d) { computeScalars (); }
31- FastIntDiv& operator =(int _d)
39+ FastIntDiv (IntT _d) : d(_d) { computeScalars (); }
40+ FastIntDiv& operator =(IntT _d)
3241 {
3342 d = _d;
3443 computeScalars ();
@@ -53,9 +62,9 @@ struct FastIntDiv {
5362 /* * @} */
5463
5564 /* * divisor */
56- int d;
65+ IntT d;
5766 /* * the term 'm' as found in the reference chapter */
58- unsigned m;
67+ UIntT m;
5968 /* * the term 'p' as found in the reference chapter */
6069 int p;
6170
@@ -90,10 +99,11 @@ struct FastIntDiv {
9099 * @param divisor the denominator
91100 * @return the quotient
92101 */
93- HDI int operator /(int n, const FastIntDiv& divisor)
102+ template <typename IntT>
103+ HDI IntT operator /(IntT n, const FastIntDiv<IntT>& divisor)
94104{
95105 if (divisor.d == 1 ) return n;
96- int ret = (int64_t (divisor.m ) * int64_t (n)) >> divisor.p ;
106+ IntT ret = (int64_t (divisor.m ) * int64_t (n)) >> divisor.p ;
97107 if (n < 0 ) ++ret;
98108 return ret;
99109}
@@ -105,10 +115,11 @@ HDI int operator/(int n, const FastIntDiv& divisor)
105115 * @param divisor the denominator
106116 * @return the remainder
107117 */
108- HDI int operator %(int n, const FastIntDiv& divisor)
118+ template <typename IntT>
119+ HDI IntT operator %(IntT n, const FastIntDiv<IntT>& divisor)
109120{
110- int quotient = n / divisor;
111- int remainder = n - quotient * divisor.d ;
121+ IntT quotient = n / divisor;
122+ IntT remainder = n - quotient * divisor.d ;
112123 return remainder;
113124}
114125
0 commit comments