未验证 提交 29494d70 编写于 作者: S ShenLiang 提交者: GitHub

fix remainder, floor_div (#26732)

* fix remainder, floordiv
上级 623a4c2e
...@@ -26,14 +26,34 @@ namespace operators { ...@@ -26,14 +26,34 @@ namespace operators {
template <typename T> template <typename T>
struct FloorDivFunctor { struct FloorDivFunctor {
inline HOSTDEVICE T operator()(T a, T b) const { inline HOSTDEVICE T operator()(T a, T b) const {
return static_cast<T>(floor(a / b)); #ifdef __CUDA_ARCH__
if (b == 0) {
printf("Error: Divide by zero encounter in floor_divide\n");
asm("trap;");
}
#else
if (b == 0)
PADDLE_THROW(platform::errors::InvalidArgument(
"Divide by zero encounter in floor_divide"));
#endif
return static_cast<T>(std::trunc(a / b));
} }
}; };
template <typename T> template <typename T>
struct InverseFloorDivFunctor { struct InverseFloorDivFunctor {
inline HOSTDEVICE T operator()(T a, T b) const { inline HOSTDEVICE T operator()(T a, T b) const {
return static_cast<T>(floor(b / a)); #ifdef __CUDA_ARCH__
if (a == 0) {
printf("Error: Divide by zero encounter in floor_divide\n");
asm("trap;");
}
#else
if (a == 0)
PADDLE_THROW(platform::errors::InvalidArgument(
"Divide by zero encounter in floor_divide"));
#endif
return static_cast<T>(std::trunc(b / a));
} }
}; };
......
...@@ -24,13 +24,19 @@ namespace operators { ...@@ -24,13 +24,19 @@ namespace operators {
template <typename T> template <typename T>
struct ModFunctor { struct ModFunctor {
inline HOSTDEVICE T operator()(T a, T b) const { return a % b; } inline HOSTDEVICE T operator()(T a, T b) const {
T res = a % b;
if ((res != 0) && ((res < 0) != (b < 0))) res += b;
return res;
}
}; };
template <typename T> template <typename T>
struct ModFunctorFP { struct ModFunctorFP {
inline HOSTDEVICE T operator()(T a, T b) const { inline HOSTDEVICE T operator()(T a, T b) const {
return fmod(b + fmod(a, b), b); T res = fmod(a, b);
if ((res != 0) && ((b < 0) != (res < 0))) res += b;
return res;
} }
}; };
......
...@@ -193,6 +193,27 @@ class TestFloorDivideAPI(unittest.TestCase): ...@@ -193,6 +193,27 @@ class TestFloorDivideAPI(unittest.TestCase):
z_expected = np.array([2., 0., 2.]) z_expected = np.array([2., 0., 2.])
self.assertEqual((z_expected == z.numpy()).all(), True) self.assertEqual((z_expected == z.numpy()).all(), True)
with fluid.dygraph.guard(fluid.CPUPlace()):
# divide by zero
np_x = np.array([2, 3, 4])
np_y = np.array([0])
x = paddle.to_tensor(np_x)
y = paddle.to_tensor(np_y)
try:
z = x // y
except Exception as e:
print("Error: Divide by zero encounter in floor_divide\n")
# divide by zero
np_x = np.array([2])
np_y = np.array([0, 0, 0])
x = paddle.to_tensor(np_x, dtype="int32")
y = paddle.to_tensor(np_y, dtype="int32")
try:
z = x // y
except Exception as e:
print("Error: Divide by zero encounter in floor_divide\n")
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -204,6 +204,22 @@ class TestRemainderAPI(unittest.TestCase): ...@@ -204,6 +204,22 @@ class TestRemainderAPI(unittest.TestCase):
z_expected = np.array([1., 0., 1., 1., 0., 1.]) z_expected = np.array([1., 0., 1., 1., 0., 1.])
self.assertEqual((z_expected == z.numpy()).all(), True) self.assertEqual((z_expected == z.numpy()).all(), True)
np_x = np.array([-3.3, 11.5, -2, 3.5])
np_y = np.array([-1.2, 2., 3.3, -2.3])
x = paddle.to_tensor(np_x)
y = paddle.to_tensor(np_y)
z = x % y
z_expected = np.array([-0.9, 1.5, 1.3, -1.1])
self.assertEqual(np.allclose(z_expected, z.numpy()), True)
np_x = np.array([-3, 11, -2, 3])
np_y = np.array([-1, 2, 3, -2])
x = paddle.to_tensor(np_x, dtype="int64")
y = paddle.to_tensor(np_y, dtype="int64")
z = x % y
z_expected = np.array([0, 1, 1, -1])
self.assertEqual(np.allclose(z_expected, z.numpy()), True)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册