未验证 提交 2fbe9b09 编写于 作者: C Chen Weihang 提交者: GitHub

[CustomOp] Remove Eigen dependencies of float16 (#31669)

* remove eigen deps dof float16

* add cstdlib header

* replace stdlib header by cmath
上级 19592d2b
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "paddle/fluid/platform/bfloat16.h" #include "paddle/fluid/platform/bfloat16.h"
#include "paddle/fluid/platform/complex128.h" #include "paddle/fluid/platform/complex128.h"
#include "paddle/fluid/platform/complex64.h" #include "paddle/fluid/platform/complex64.h"
#include "paddle/fluid/platform/float16.h"
#include "paddle/fluid/platform/hostdevice.h" #include "paddle/fluid/platform/hostdevice.h"
#include "unsupported/Eigen/CXX11/Tensor" #include "unsupported/Eigen/CXX11/Tensor"
...@@ -26,6 +27,7 @@ namespace Eigen { ...@@ -26,6 +27,7 @@ namespace Eigen {
using bfloat16 = paddle::platform::bfloat16; using bfloat16 = paddle::platform::bfloat16;
using complex64 = paddle::platform::complex64; using complex64 = paddle::platform::complex64;
using complex128 = paddle::platform::complex128; using complex128 = paddle::platform::complex128;
using float16 = paddle::platform::float16;
template <typename T> template <typename T>
struct NumTraits; struct NumTraits;
...@@ -103,6 +105,33 @@ struct NumTraits<complex128> : GenericNumTraits<std::complex<double>> { ...@@ -103,6 +105,33 @@ struct NumTraits<complex128> : GenericNumTraits<std::complex<double>> {
static inline int digits10() { return NumTraits<Real>::digits10(); } static inline int digits10() { return NumTraits<Real>::digits10(); }
}; };
template <>
struct NumTraits<float16> : GenericNumTraits<float16> {
enum {
IsSigned = true,
IsInteger = false,
IsComplex = false,
RequireInitialization = false
};
HOSTDEVICE static inline float16 epsilon() {
return paddle::platform::raw_uint16_to_float16(0x0800);
}
HOSTDEVICE static inline float16 dummy_precision() { return float16(1e-2f); }
HOSTDEVICE static inline float16 highest() {
return paddle::platform::raw_uint16_to_float16(0x7bff);
}
HOSTDEVICE static inline float16 lowest() {
return paddle::platform::raw_uint16_to_float16(0xfbff);
}
HOSTDEVICE static inline float16 infinity() {
return paddle::platform::raw_uint16_to_float16(0x7c00);
}
HOSTDEVICE static inline float16 quiet_NaN() {
return paddle::platform::raw_uint16_to_float16(0x7c01);
}
};
namespace numext { namespace numext {
//////////// bfloat methods ///////////// //////////// bfloat methods /////////////
...@@ -302,5 +331,72 @@ HOSTDEVICE inline double abs(const complex128& a) { ...@@ -302,5 +331,72 @@ HOSTDEVICE inline double abs(const complex128& a) {
return paddle::platform::abs(a); return paddle::platform::abs(a);
} }
//////////// float16 methods /////////////
template <>
HOSTDEVICE inline bool(isnan)(const float16& a) {
return (paddle::platform::isnan)(a);
}
template <>
HOSTDEVICE inline bool(isinf)(const float16& a) {
return (paddle::platform::isinf)(a);
}
template <>
HOSTDEVICE inline bool(isfinite)(const float16& a) {
return (paddle::platform::isfinite)(a);
}
template <>
HOSTDEVICE inline float16 exp(const float16& a) {
return float16(::expf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 erf(const float16& a) {
return float16(::erff(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 log(const float16& a) {
return float16(::logf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 tanh(const float16& a) {
return float16(::tanhf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 sqrt(const float16& a) {
return float16(::sqrtf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 ceil(const float16& a) {
return float16(::ceilf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 floor(const float16& a) {
return float16(::floorf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 round(const float16& a) {
return float16(::roundf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 pow(const float16& a, const float16& b) {
return float16(::powf(static_cast<float>(a), static_cast<float>(b)));
}
template <>
HOSTDEVICE inline float16 abs(const float16& a) {
return float16(::fabs(static_cast<float>(a)));
}
} // namespace numext } // namespace numext
} // namespace Eigen } // namespace Eigen
...@@ -15,6 +15,9 @@ limitations under the License. */ ...@@ -15,6 +15,9 @@ limitations under the License. */
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <cmath>
#include <iostream>
#include <limits> #include <limits>
#ifdef PADDLE_WITH_CUDA #ifdef PADDLE_WITH_CUDA
...@@ -25,18 +28,6 @@ limitations under the License. */ ...@@ -25,18 +28,6 @@ limitations under the License. */
#include <hip/hip_runtime.h> #include <hip/hip_runtime.h>
#endif #endif
#ifdef __GNUC__
#define PADDLE_GNUC_VER (__GNUC__ * 10 + __GNUC_MINOR__)
#else
#define PADDLE_GNUC_VER 0
#endif // __GNUC__
#ifdef __clang__
#define PADDLE_CLANG_VER (__clang_major__ * 10 + __clang_minor__)
#else
#define PADDLE_CLANG_VER 0
#endif // __clang__
#if defined(__CUDACC__) && CUDA_VERSION >= 7050 #if defined(__CUDACC__) && CUDA_VERSION >= 7050
#define PADDLE_CUDA_FP16 #define PADDLE_CUDA_FP16
#include <cuda_fp16.h> #include <cuda_fp16.h>
...@@ -55,17 +46,15 @@ limitations under the License. */ ...@@ -55,17 +46,15 @@ limitations under the License. */
#define CUDA_ARCH_FP16_SUPPORTED(CUDA_ARCH) (CUDA_ARCH >= 600) #define CUDA_ARCH_FP16_SUPPORTED(CUDA_ARCH) (CUDA_ARCH >= 600)
namespace paddle { #if (defined(__CUDACC__) || defined(__HIPCC__))
namespace platform { #define HOSTDEVICE __host__ __device__
#define DEVICE __device__
// Forward declare float16 for eigen.h #define HOST __host__
struct float16; #else
#define HOSTDEVICE
} // namespace platform #define DEVICE
} // namespace paddle #define HOST
#endif
#include "paddle/fluid/platform/hostdevice.h"
#include "unsupported/Eigen/CXX11/Tensor"
namespace paddle { namespace paddle {
namespace platform { namespace platform {
...@@ -73,7 +62,7 @@ namespace platform { ...@@ -73,7 +62,7 @@ namespace platform {
// Use PADDLE_ALIGNED(2) to ensure that each float16 will be allocated // Use PADDLE_ALIGNED(2) to ensure that each float16 will be allocated
// and aligned at least on a 2-byte boundary, which leads to efficient // and aligned at least on a 2-byte boundary, which leads to efficient
// memory access of float16 struct and also makes float16 compatible // memory access of float16 struct and also makes float16 compatible
// with CUDA half, ARM float16_t, and Eigen::half data types. // with CUDA half, ARM float16_t data types.
struct PADDLE_ALIGN(2) float16 { struct PADDLE_ALIGN(2) float16 {
public: public:
uint16_t x; uint16_t x;
...@@ -100,8 +89,6 @@ struct PADDLE_ALIGN(2) float16 { ...@@ -100,8 +89,6 @@ struct PADDLE_ALIGN(2) float16 {
} }
#endif // PADDLE_CUDA_FP16 #endif // PADDLE_CUDA_FP16
HOSTDEVICE inline explicit float16(const Eigen::half& h) : x(h.x) {}
#ifdef PADDLE_WITH_NATIVE_FP16 #ifdef PADDLE_WITH_NATIVE_FP16
// __fp16 is a native half precision data type for arm cpu, // __fp16 is a native half precision data type for arm cpu,
// float16_t is an alias for __fp16 // float16_t is an alias for __fp16
...@@ -163,11 +150,6 @@ struct PADDLE_ALIGN(2) float16 { ...@@ -163,11 +150,6 @@ struct PADDLE_ALIGN(2) float16 {
} }
#endif #endif
HOSTDEVICE inline float16& operator=(const Eigen::half& rhs) {
x = rhs.x;
return *this;
}
#ifdef PADDLE_WITH_NATIVE_FP16 #ifdef PADDLE_WITH_NATIVE_FP16
HOSTDEVICE inline float16& operator=(const float16_t& rhs) { HOSTDEVICE inline float16& operator=(const float16_t& rhs) {
x = *reinterpret_cast<const uint16_t*>(&rhs); x = *reinterpret_cast<const uint16_t*>(&rhs);
...@@ -245,12 +227,6 @@ struct PADDLE_ALIGN(2) float16 { ...@@ -245,12 +227,6 @@ struct PADDLE_ALIGN(2) float16 {
} }
#endif // PADDLE_CUDA_FP16 #endif // PADDLE_CUDA_FP16
HOSTDEVICE inline explicit operator Eigen::half() const {
Eigen::half h;
h.x = x;
return h;
}
#ifdef PADDLE_WITH_NATIVE_FP16 #ifdef PADDLE_WITH_NATIVE_FP16
HOSTDEVICE inline explicit operator float16_t() const { HOSTDEVICE inline explicit operator float16_t() const {
return *reinterpret_cast<const float16_t*>(this); return *reinterpret_cast<const float16_t*>(this);
...@@ -1108,105 +1084,3 @@ HOSTDEVICE inline paddle::platform::float16 abs( ...@@ -1108,105 +1084,3 @@ HOSTDEVICE inline paddle::platform::float16 abs(
} }
} // namespace std } // namespace std
namespace Eigen {
using float16 = paddle::platform::float16;
template <>
struct NumTraits<float16> : GenericNumTraits<float16> {
enum {
IsSigned = true,
IsInteger = false,
IsComplex = false,
RequireInitialization = false
};
HOSTDEVICE static inline float16 epsilon() {
return paddle::platform::raw_uint16_to_float16(0x0800);
}
HOSTDEVICE static inline float16 dummy_precision() { return float16(1e-2f); }
HOSTDEVICE static inline float16 highest() {
return paddle::platform::raw_uint16_to_float16(0x7bff);
}
HOSTDEVICE static inline float16 lowest() {
return paddle::platform::raw_uint16_to_float16(0xfbff);
}
HOSTDEVICE static inline float16 infinity() {
return paddle::platform::raw_uint16_to_float16(0x7c00);
}
HOSTDEVICE static inline float16 quiet_NaN() {
return paddle::platform::raw_uint16_to_float16(0x7c01);
}
};
namespace numext {
template <>
HOSTDEVICE inline bool(isnan)(const float16& a) {
return (paddle::platform::isnan)(a);
}
template <>
HOSTDEVICE inline bool(isinf)(const float16& a) {
return (paddle::platform::isinf)(a);
}
template <>
HOSTDEVICE inline bool(isfinite)(const float16& a) {
return (paddle::platform::isfinite)(a);
}
template <>
HOSTDEVICE inline float16 exp(const float16& a) {
return float16(::expf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 erf(const float16& a) {
return float16(::erff(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 log(const float16& a) {
return float16(::logf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 tanh(const float16& a) {
return float16(::tanhf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 sqrt(const float16& a) {
return float16(::sqrtf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 ceil(const float16& a) {
return float16(::ceilf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 floor(const float16& a) {
return float16(::floorf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 round(const float16& a) {
return float16(::roundf(static_cast<float>(a)));
}
template <>
HOSTDEVICE inline float16 pow(const float16& a, const float16& b) {
return float16(::powf(static_cast<float>(a), static_cast<float>(b)));
}
template <>
HOSTDEVICE inline float16 abs(const float16& a) {
return float16(::fabs(static_cast<float>(a)));
}
} // namespace numext
} // namespace Eigen
...@@ -8,26 +8,19 @@ distributed under the License is distributed on an "AS IS" BASIS, ...@@ -8,26 +8,19 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include "paddle/fluid/platform/float16.h" #include "paddle/fluid/platform/float16.h"
#define GLOG_NO_ABBREVIATED_SEVERITIES // msvc conflict logging with windows.h #define GLOG_NO_ABBREVIATED_SEVERITIES // msvc conflict logging with windows.h
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/platform/eigen_ext.h"
#include "paddle/fluid/platform/enforce.h" #include "paddle/fluid/platform/enforce.h"
namespace paddle { namespace paddle {
namespace platform { namespace platform {
TEST(float16, conversion_cpu) { TEST(float16, conversion_cpu) {
// Explicit conversion from Eigen::half
EXPECT_EQ(float16(Eigen::half(1.0f)).x, 0x3c00);
EXPECT_EQ(float16(Eigen::half(0.5f)).x, 0x3800);
EXPECT_EQ(float16(Eigen::half(0.33333f)).x, 0x3555);
EXPECT_EQ(float16(Eigen::half(0.0f)).x, 0x0000);
EXPECT_EQ(float16(Eigen::half(-0.0f)).x, 0x8000);
EXPECT_EQ(float16(Eigen::half(65504.0f)).x, 0x7bff);
EXPECT_EQ(float16(Eigen::half(65536.0f)).x, 0x7c00);
// Conversion from float // Conversion from float
EXPECT_EQ(float16(1.0f).x, 0x3c00); EXPECT_EQ(float16(1.0f).x, 0x3c00);
EXPECT_EQ(float16(0.5f).x, 0x3800); EXPECT_EQ(float16(0.5f).x, 0x3800);
...@@ -61,8 +54,6 @@ TEST(float16, conversion_cpu) { ...@@ -61,8 +54,6 @@ TEST(float16, conversion_cpu) {
float16 v_assign; float16 v_assign;
v_assign = float16(0); v_assign = float16(0);
EXPECT_EQ(v_assign.x, 0x0000); EXPECT_EQ(v_assign.x, 0x0000);
v_assign = Eigen::half(1.0f);
EXPECT_EQ(v_assign.x, 0x3c00);
v_assign = 0.5f; v_assign = 0.5f;
EXPECT_EQ(v_assign.x, 0x3800); EXPECT_EQ(v_assign.x, 0x3800);
v_assign = 0.33333; v_assign = 0.33333;
...@@ -73,7 +64,6 @@ TEST(float16, conversion_cpu) { ...@@ -73,7 +64,6 @@ TEST(float16, conversion_cpu) {
EXPECT_EQ(v_assign.x, 0x3c00); EXPECT_EQ(v_assign.x, 0x3c00);
// Conversion operator // Conversion operator
EXPECT_EQ(Eigen::half(float16(1.0f)).x, 0x3c00);
EXPECT_EQ(static_cast<float>(float16(0.5f)), 0.5f); EXPECT_EQ(static_cast<float>(float16(0.5f)), 0.5f);
EXPECT_NEAR(static_cast<double>(float16(0.33333)), 0.33333, 0.0001); EXPECT_NEAR(static_cast<double>(float16(0.33333)), 0.33333, 0.0001);
EXPECT_EQ(static_cast<int>(float16(-1)), -1); EXPECT_EQ(static_cast<int>(float16(-1)), -1);
......
...@@ -19,6 +19,7 @@ limitations under the License. */ ...@@ -19,6 +19,7 @@ limitations under the License. */
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/tensor_util.h" #include "paddle/fluid/framework/tensor_util.h"
#include "paddle/fluid/platform/eigen_ext.h"
#include "paddle/fluid/platform/enforce.h" #include "paddle/fluid/platform/enforce.h"
#define ARITHMETIC_KERNEL(op_type, sign) \ #define ARITHMETIC_KERNEL(op_type, sign) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册