Skip to content
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

support vs2019 compilation in windows #38719

Merged
merged 3 commits into from
Jan 11, 2022

Conversation

betterpig
Copy link
Contributor

@betterpig betterpig commented Jan 5, 2022

PR types

Bug fixes

PR changes

Others

Describe

fix vs2019 compilation problem in windows

  • protobuf.cmake
    change protobuf's tag to avoid building failure when building with vs2019 in windows.
  • pow, fmin, fmax, log
    cuda only support some combination of args list for these fuction, see this. so i use template specialization to transfer type to call cuda math api rightly when data type is int, int64_t.
    image
    image
  • PowGradDY
    It is not correct that return dout * std::log(x) * std::pow(x, y); when x and y is integer. Since log(int) may be decimal, the thus final result is decimal. While the return value will be floored to 2 and it is wrong. So I add llrint for both cpu and gpu code, and for test_elementwise_pow_op also.

@paddle-bot-old
Copy link

paddle-bot-old bot commented Jan 5, 2022

Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@betterpig betterpig changed the title support vs2019 compilation in windows(part 1) support vs2019 compilation in windows Jan 6, 2022
Copy link
Contributor

@zhwesky2010 zhwesky2010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

综合评估下pow fmin fmax这几个OP有没有不兼容风险,结果是否和之前一致

elseif(WIN32)
SET(PROTOBUF_REPOSITORY ${GIT_URL}/protocolbuffers/protobuf.git)
# Change the tag to support building with vs2019
SET(PROTOBUF_TAG 01a05a53f40ca2ac5f0af10c6cc0810bee39b792)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用当前的tag编会有什么错误

Copy link
Contributor Author

@betterpig betterpig Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

与该issue一致,
image
tag修复了该问题。
image

@@ -174,6 +174,27 @@ struct FMaxFunctor<paddle::platform::float16> {
}
};

template <>
struct FMaxFunctor<int> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::fmax 不能直接处理int类型的输入吗,还是说原本就有一个隐式的类型转换,在VS2019时必须变为显式?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

应该是在VS2019, int / int64_t不能隐式转换到float / double,导致CUDA找不到对应的函数声明,标准库的fmax没有这个问题。在CUDA10.2的机器上,使用VS2019编译,也存在这个问题。
此次修改针对int / int64_t类型,先将其精度提高,在调用fmax获得结果后,再通过lrint函数转换回原类型。
因为是整型,操作是不涉及到计算的比大小,再加上lrint能圆整回最接近的正数,因此不会影响结果。

@@ -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])));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CUDA pow这里的计算是否会导致结果不同,这样的话会有不兼容风险

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是只是将 int / int64_t 转换为 double类型后,进行pow运算,然后再用 llrint 函数取最接近的整数。因此不会导致结果不同,也就不会有非兼容性风险。

@@ -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)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上,这里加上显式转化是和以前一致吗

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这是只是将 int / int64_t 转换为 double类型后,进行pow运算,然后再用 llrint 函数取最接近的整数。因此不会导致结果不同,也就不会有非兼容性风险。

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> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

Copy link
Contributor Author

@betterpig betterpig Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对于PowGradDX和PowGradDY的修改,有两个方面:

  1. 将 int / int64_t 转换为 double类型,以调用CUDA的pow 函数
  2. 加上 llrint 做圆整,而不是使用隐式的类型转换 float -> int, double -> long long。因为隐式的类型转换默认是去尾法,显然是不合理的,应该用 llrint,取最接近的整数。举个例子,设x为6,y为1,则PowGradDY的实际结果为log(6)*6=10.75... 如果不用 llrint,PowGradDY的返回值为 10 ,使用 llrint 后,则为 11.

因此,第2个修改不是升级VS2019所必需的。若是考虑到兼容问题,可以去掉第2个修改。

@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看起来OP结果会改变 这样会有一些不兼容风险。如果要加很多 显式类型变换,要确保和以前的隐式变换一样

Copy link
Contributor Author

@betterpig betterpig Jan 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

单测的修改是为了和PowGradDY的第2个修改对应,具体说明见上一条。
astype("int")也是采用去尾法,需要先取最接近的整数,再转换为int。
image

Copy link
Contributor

@zhwesky2010 zhwesky2010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以先合进去,观察后面是否出现问题

@betterpig
Copy link
Contributor Author

可以先合进去,观察后面是否出现问题

好的

@zhwesky2010 zhwesky2010 merged commit 0ad363b into PaddlePaddle:develop Jan 11, 2022
@xinsuinizhuan
Copy link

咋样了,现在支持VS2019编译了没?

@betterpig
Copy link
Contributor Author

已支持VS2019编译

@xinsuinizhuan
Copy link

已支持VS2019编译

第三方库的支持问题,有解决吗?第三方库下载不下来,建议使用链接的方式,而不是直接git下载的方式

@betterpig
Copy link
Contributor Author

现在使用VS2019编译,不存在第三方库的支持问题。考虑到版权问题,第三方库尽量使用git clone方式获取源码。

@betterpig betterpig deleted the vs2019_part1 branch February 18, 2022 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants