-
Notifications
You must be signed in to change notification settings - Fork 5.9k
support vs2019 compilation in windows #38719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -174,6 +174,27 @@ struct FMaxFunctor<paddle::platform::float16> { | |
| } | ||
| }; | ||
|
|
||
| template <> | ||
| struct FMaxFunctor<int> { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. std::fmax 不能直接处理int类型的输入吗,还是说原本就有一个隐式的类型转换,在VS2019时必须变为显式? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 应该是在VS2019, int / int64_t不能隐式转换到float / double,导致CUDA找不到对应的函数声明,标准库的fmax没有这个问题。在CUDA10.2的机器上,使用VS2019编译,也存在这个问题。 |
||
| inline HOSTDEVICE int operator()(const int& a, const int& b) const { | ||
| float float_a = static_cast<float>(a); | ||
| float float_b = static_cast<float>(b); | ||
| auto result = std::fmax(float_a, float_b); | ||
| return std::lrint(result); | ||
| } | ||
| }; | ||
|
|
||
| template <> | ||
| struct FMaxFunctor<int64_t> { | ||
| inline HOSTDEVICE int64_t operator()(const int64_t& a, | ||
| const int64_t& b) const { | ||
| double double_a = static_cast<double>(a); | ||
| double double_b = static_cast<double>(b); | ||
| auto result = std::fmax(double_a, double_b); | ||
| return std::llrint(result); | ||
| } | ||
| }; | ||
|
|
||
| // Fmin | ||
| template <typename T> | ||
| struct FMinFunctor { | ||
|
|
@@ -194,6 +215,27 @@ struct FMinFunctor<paddle::platform::float16> { | |
| } | ||
| }; | ||
|
|
||
| template <> | ||
| struct FMinFunctor<int> { | ||
| inline HOSTDEVICE int operator()(const int& a, const int& b) const { | ||
| float float_a = static_cast<float>(a); | ||
| float float_b = static_cast<float>(b); | ||
| auto result = std::fmin(float_a, float_b); | ||
| return std::lrint(result); | ||
| } | ||
| }; | ||
|
|
||
| template <> | ||
| struct FMinFunctor<int64_t> { | ||
| inline HOSTDEVICE int64_t operator()(const int64_t& a, | ||
| const int64_t& b) const { | ||
| double double_a = static_cast<double>(a); | ||
| double double_b = static_cast<double>(b); | ||
| auto result = std::fmin(double_a, double_b); | ||
| return std::llrint(result); | ||
| } | ||
| }; | ||
|
|
||
| template <typename T> | ||
| struct MulGradFunctor { | ||
| inline HOSTDEVICE T operator()(const T& a, const T& b) const { return a * b; } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,8 @@ struct CudaPowFunctor< | |
| // when cast to int by default and it is wrong. | ||
| // Use llrint to cast it to the nearest integer, which is 3. | ||
| inline HOSTDEVICE T operator()(const T args[]) const { | ||
| return std::llrint(std::pow(args[0], args[1])); | ||
| return std::llrint( | ||
| std::pow(static_cast<double>(args[0]), static_cast<double>(args[1]))); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CUDA pow这里的计算是否会导致结果不同,这样的话会有不兼容风险 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这是只是将 int / int64_t 转换为 double类型后,进行pow运算,然后再用 llrint 函数取最接近的整数。因此不会导致结果不同,也就不会有非兼容性风险。 |
||
| } | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,8 @@ struct PowFunctor { | |
| // when cast to int by default and it is wrong. | ||
| // Use llrint to cast it to the nearest integer, which is 3. | ||
| if (std::is_integral<T>::value) { | ||
| return std::llrint(std::pow(a, b)); | ||
| return std::llrint( | ||
| std::pow(static_cast<double>(a), static_cast<double>(b))); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同上,这里加上显式转化是和以前一致吗 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这是只是将 int / int64_t 转换为 double类型后,进行pow运算,然后再用 llrint 函数取最接近的整数。因此不会导致结果不同,也就不会有非兼容性风险。 |
||
| } | ||
| #endif | ||
| return std::pow(a, b); | ||
|
|
@@ -60,17 +61,32 @@ class ElementwisePowKernel : public framework::OpKernel<T> { | |
| template <typename T> | ||
| struct PowGradDX { | ||
| HOSTDEVICE T operator()(T x, T y, T out, T dout) const { | ||
| #if defined(__CUDA_ARCH__) || defined(__HIPCC__) | ||
| if (std::is_integral<T>::value) { | ||
| return std::llrint(dout * y * std::pow(static_cast<double>(x), | ||
| static_cast<double>(y - 1))); | ||
| } | ||
| #endif | ||
| return dout * y * std::pow(x, y - 1); | ||
| } | ||
| }; | ||
|
|
||
| template <typename T> | ||
| template <typename T, typename Enable = void> | ||
| struct PowGradDY { | ||
| HOSTDEVICE T operator()(T x, T y, T out, T dout) const { | ||
| return dout * std::log(x) * std::pow(x, y); | ||
| } | ||
| }; | ||
|
|
||
| template <typename T> | ||
| struct PowGradDY<T, typename std::enable_if<std::is_integral<T>::value>::type> { | ||
|
||
| HOSTDEVICE T operator()(T x, T y, T out, T dout) const { | ||
| return std::llrint( | ||
| dout * std::log(static_cast<double>(x)) * | ||
| std::pow(static_cast<double>(x), static_cast<double>(y))); | ||
| } | ||
| }; | ||
|
|
||
| template <typename DeviceContext, typename T> | ||
| class ElementwisePowGradKernel : public ElemwiseGradKernel<T> { | ||
| public: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -156,11 +156,11 @@ def setUp(self): | |
| # dout = 1 | ||
| self.grad_res = np.asarray([1, 1, 1]) | ||
| # dx = dout * y * pow(x, y-1) | ||
| self.grad_x = self.grad_res * self.y * (self.x | ||
| **(self.y - 1)).astype("int") | ||
| self.grad_x = (np.rint(self.grad_res * self.y * self.x | ||
|
||
| **(self.y - 1))).astype("int") | ||
| # dy = dout * log(x) * pow(x, y) | ||
| self.grad_y = (self.grad_res * np.log(self.x) * | ||
| (self.x**self.y)).astype("int") | ||
| self.grad_y = (np.rint(self.grad_res * np.log(self.x) * | ||
| (self.x**self.y))).astype("int") | ||
| print(self.grad_res, self.grad_x, self.grad_y) | ||
|
|
||
| def test_grad(self): | ||
|
|
@@ -176,6 +176,7 @@ def test_grad(self): | |
| y.stop_gradient = False | ||
| res = x**y | ||
| res.backward() | ||
| print(res.gradient(), x.gradient(), y.gradient()) | ||
| self.assertTrue(np.array_equal(res.gradient(), self.grad_res)) | ||
| self.assertTrue(np.array_equal(x.gradient(), self.grad_x)) | ||
| self.assertTrue(np.array_equal(y.gradient(), self.grad_y)) | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
使用当前的tag编会有什么错误
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
与该issue一致,


新tag修复了该问题。