You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
1.9 KiB
75 lines
1.9 KiB
#if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|
|
#pragma once
|
|
|
|
#include <ATen/native/DispatchStub.h>
|
|
|
|
namespace c10 {
|
|
class Scalar;
|
|
}
|
|
|
|
namespace at {
|
|
|
|
struct TensorIterator;
|
|
struct TensorIteratorBase;
|
|
|
|
namespace native {
|
|
|
|
#if defined(__CUDACC__) || defined(__HIPCC__)
|
|
#define HOST_DEVICE __host__ __device__
|
|
#else
|
|
#define HOST_DEVICE
|
|
#endif
|
|
|
|
// integral power in pytorch allows for negative exponents, giving truncated integral results.
|
|
// e.g. since 2**-1==0.5, the truncated integral result is zero. 1**negative_exponent is the
|
|
// only non-zero result.
|
|
template <class T,
|
|
std::enable_if_t<std::is_integral_v<T>, T>* = nullptr>
|
|
inline HOST_DEVICE __ubsan_ignore_signed_int_overflow__ T powi_impl(T a, T b) {
|
|
T result = 1;
|
|
while (b) {
|
|
if (b & 1) {
|
|
result *= a;
|
|
}
|
|
b /= 2;
|
|
a *= a;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template <class T,
|
|
std::enable_if_t<std::is_integral_v<T> && !std::is_signed_v<T>, T>* = nullptr>
|
|
inline HOST_DEVICE T powi(T a, T b) {
|
|
return powi_impl(a, b);
|
|
}
|
|
|
|
template <class T,
|
|
std::enable_if_t<std::is_integral_v<T> && std::is_signed_v<T>, T>* = nullptr>
|
|
inline HOST_DEVICE T powi(T a, T b) {
|
|
if ( b < 0 ) {
|
|
if ( a == 1 ) {
|
|
return 1;
|
|
} else if ( a == -1 ) {
|
|
auto negative = (-b) % static_cast<T>(2);
|
|
return negative ? -1 : 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
return powi_impl(a, b);
|
|
}
|
|
|
|
using pow_tensor_tensor_fn = void (*)(TensorIteratorBase&);
|
|
using pow_tensor_scalar_fn = void (*)(TensorIteratorBase&, const c10::Scalar&);
|
|
|
|
DECLARE_DISPATCH(pow_tensor_tensor_fn, pow_tensor_tensor_stub)
|
|
DECLARE_DISPATCH(pow_tensor_scalar_fn, pow_tensor_scalar_stub)
|
|
|
|
} // namespace native
|
|
|
|
} // namespace at
|
|
|
|
#else
|
|
#error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
|
|
#endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
|