Commit 4d783429 authored by Hamdi Sahloul's avatar Hamdi Sahloul

Closes #12281 - a bug in cuda::pow with negative base values

parent 6700fdb8
...@@ -278,20 +278,12 @@ namespace ...@@ -278,20 +278,12 @@ namespace
{ {
template<typename T, bool Signed = numeric_limits<T>::is_signed> struct PowOp : unary_function<T, T> template<typename T, bool Signed = numeric_limits<T>::is_signed> struct PowOp : unary_function<T, T>
{ {
float power; typedef typename LargerType<T, float>::type LargerType;
LargerType power;
__device__ __forceinline__ T operator()(T e) const __device__ __forceinline__ T operator()(T e) const
{ {
return cudev::saturate_cast<T>(__powf((float)e, power)); T res = cudev::saturate_cast<T>(__powf(e < 0 ? -e : e, power));
}
};
template<typename T> struct PowOp<T, true> : unary_function<T, T>
{
float power;
__device__ __forceinline__ T operator()(T e) const
{
T res = cudev::saturate_cast<T>(__powf((float)e, power));
if ((e < 0) && (1 & static_cast<int>(power))) if ((e < 0) && (1 & static_cast<int>(power)))
res *= -1; res *= -1;
...@@ -299,22 +291,15 @@ namespace ...@@ -299,22 +291,15 @@ namespace
return res; return res;
} }
}; };
template<> struct PowOp<float> : unary_function<float, float>
{
float power;
__device__ __forceinline__ float operator()(float e) const template<typename T> struct PowOp<T, false> : unary_function<T, T>
{
return __powf(::fabs(e), power);
}
};
template<> struct PowOp<double> : unary_function<double, double>
{ {
double power; typedef typename LargerType<T, float>::type LargerType;
LargerType power;
__device__ __forceinline__ double operator()(double e) const __device__ __forceinline__ T operator()(T e) const
{ {
return ::pow(::fabs(e), power); return cudev::saturate_cast<T>(__powf(e, power));
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment