diff --git a/paddle/fluid/operators/elementwise/elementwise_floordiv_op.h b/paddle/fluid/operators/elementwise/elementwise_floordiv_op.h index a5909aad99a82529a0739cd28b1b72a146524f76..8afe2133c0488bbe04ec4803aac5dce6573f634d 100644 --- a/paddle/fluid/operators/elementwise/elementwise_floordiv_op.h +++ b/paddle/fluid/operators/elementwise/elementwise_floordiv_op.h @@ -26,14 +26,34 @@ namespace operators { template struct FloorDivFunctor { inline HOSTDEVICE T operator()(T a, T b) const { - return static_cast(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(std::trunc(a / b)); } }; template struct InverseFloorDivFunctor { inline HOSTDEVICE T operator()(T a, T b) const { - return static_cast(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(std::trunc(b / a)); } }; diff --git a/paddle/fluid/operators/elementwise/elementwise_mod_op.h b/paddle/fluid/operators/elementwise/elementwise_mod_op.h index 4306a471b76c5bd4f0a5284052d7d39aa5fbc279..47bd6af0b95ace2b9b753e38cfc5f191bc1bb942 100644 --- a/paddle/fluid/operators/elementwise/elementwise_mod_op.h +++ b/paddle/fluid/operators/elementwise/elementwise_mod_op.h @@ -24,13 +24,19 @@ namespace operators { template 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 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; } }; diff --git a/python/paddle/fluid/tests/unittests/test_elementwise_floordiv_op.py b/python/paddle/fluid/tests/unittests/test_elementwise_floordiv_op.py index 4fe085ce854726676bc1b1bef650419b3ebbfc86..0b6acc7615395ed99a484e0e56f9c62447a1f345 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_floordiv_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_floordiv_op.py @@ -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() diff --git a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py index 25769a42aa261c0b5ae9fe2795a337c668580a99..f5d8b4f704da8acd97475444346522f63d3724fd 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -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()