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

fix remainder, floor_div (#26732)

* fix remainder, floordiv
上级 623a4c2e
......@@ -26,14 +26,34 @@ namespace operators {
template <typename T>
struct FloorDivFunctor {
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>
struct InverseFloorDivFunctor {
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 {
template <typename T>
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>
struct ModFunctorFP {
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):
z_expected = np.array([2., 0., 2.])
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__':
unittest.main()
......@@ -204,6 +204,22 @@ class TestRemainderAPI(unittest.TestCase):
z_expected = np.array([1., 0., 1., 1., 0., 1.])
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__':
unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册