Skip to content

Commit 602eef1

Browse files
committed
pow no longer uses std::pow for integers
- Not portable to devices without 64-bit precision
1 parent 55caa04 commit 602eef1

File tree

1 file changed

+25
-2
lines changed
  • dpctl/tensor/libtensor/include/kernels/elementwise_functions

1 file changed

+25
-2
lines changed

dpctl/tensor/libtensor/include/kernels/elementwise_functions/pow.hpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <CL/sycl.hpp>
2828
#include <cstddef>
2929
#include <cstdint>
30+
#include <limits>
3031
#include <type_traits>
3132

3233
#include "utils/offset_utils.hpp"
@@ -60,9 +61,31 @@ template <typename argT1, typename argT2, typename resT> struct PowFunctor
6061
std::is_integral<argT1>,
6162
std::is_integral<argT2>>>;
6263

63-
resT operator()(const argT1 &in1, const argT2 &in2)
64+
resT operator()(argT1 in1, argT2 in2)
6465
{
65-
return std::pow(in1, in2);
66+
if constexpr (std::is_integral_v<argT1> || std::is_integral_v<argT2>) {
67+
if constexpr (std::is_signed_v<argT2>) {
68+
if (in2 < 0) {
69+
// invalid; return 0
70+
return resT(0);
71+
}
72+
}
73+
resT res = 1;
74+
if (in1 == 1 || in2 == 0) {
75+
return res;
76+
}
77+
while (in2 > 0) {
78+
if (in2 & 1) {
79+
res *= in1;
80+
}
81+
in2 >>= 1;
82+
in1 *= in1;
83+
}
84+
return res;
85+
}
86+
else {
87+
return std::pow(in1, in2);
88+
}
6689
}
6790

6891
template <int vec_sz>

0 commit comments

Comments
 (0)