From b45b89eb2095b20a021282679ca88d0e6fddee43 Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Fri, 19 Aug 2022 13:20:59 +0800 Subject: [PATCH 1/9] add remainder_ op --- .../elementwise/elementwise_mod_op.cc | 3 +- .../unittests/test_elementwise_mod_op.py | 38 +++++++++++++++++++ .../fluid/tests/unittests/test_inplace.py | 11 ++++++ python/paddle/tensor/__init__.py | 2 + python/paddle/tensor/math.py | 17 +++++++++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/paddle/fluid/operators/elementwise/elementwise_mod_op.cc b/paddle/fluid/operators/elementwise/elementwise_mod_op.cc index 55d6e214d6c12..4caeaf4180f29 100644 --- a/paddle/fluid/operators/elementwise/elementwise_mod_op.cc +++ b/paddle/fluid/operators/elementwise/elementwise_mod_op.cc @@ -56,7 +56,8 @@ class ElementwiseModOpMaker : public ElementwiseOpMaker { namespace ops = paddle::operators; REGISTER_OP_WITHOUT_GRADIENT(elementwise_mod, ops::ElementwiseOp, - ops::ElementwiseModOpMaker); + ops::ElementwiseModOpMaker, + ops::ElementwiseOpInplaceInferer); REGISTER_OP_VERSION(elementwise_mod) .AddCheckpoint( 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 f51d101224366..0f3d0b8464cbf 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -133,5 +133,43 @@ def test_dygraph(self): np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) +class TestRemainderInplaceOp(unittest.TestCase): + + def test_name(self): + with fluid.program_guard(fluid.Program()): + x = fluid.data(name="x", shape=[2, 3], dtype="int64") + y = fluid.data(name='y', shape=[2, 3], dtype='int64') + + y_1 = paddle.remainder_(x, y, name='div_res') + self.assertEqual(('div_res' in y_1.name), True) + + def test_dygraph(self): + with fluid.dygraph.guard(): + np_x = np.array([2, 3, 8, 7]).astype('int64') + np_y = np.array([1, 5, 3, 3]).astype('int64') + x = paddle.to_tensor(np_x) + y = paddle.to_tensor(np_y) + z = paddle.remainder_(x, y) + np_z = z.numpy() + z_expected = np.array([0, 3, 2, 1]) + self.assertEqual((np_z == z_expected).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]) + np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) + + 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]) + np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) + + if __name__ == '__main__': unittest.main() diff --git a/python/paddle/fluid/tests/unittests/test_inplace.py b/python/paddle/fluid/tests/unittests/test_inplace.py index 94e30a5e8a163..052109674ae0c 100644 --- a/python/paddle/fluid/tests/unittests/test_inplace.py +++ b/python/paddle/fluid/tests/unittests/test_inplace.py @@ -483,6 +483,17 @@ def inplace_api_processing(self, var): return var.subtract_(input_var_2) +class TestDygraphInplaceRemainder(TestDygraphInplaceAdd): + + def non_inplace_api_processing(self, var): + input_var_2 = paddle.to_tensor(self.input_var_numpy_2) + return var.remainder(input_var_2) + + def inplace_api_processing(self, var): + input_var_2 = paddle.to_tensor(self.input_var_numpy_2) + return var.remainder_(input_var_2) + + class TestLossIsInplaceVar(unittest.TestCase): def func_test_loss_is_inplace_var(self): diff --git a/python/paddle/tensor/__init__.py b/python/paddle/tensor/__init__.py index 42da4030dec4c..44091226e96ae 100755 --- a/python/paddle/tensor/__init__.py +++ b/python/paddle/tensor/__init__.py @@ -182,6 +182,7 @@ from .math import divide # noqa: F401 from .math import floor_divide # noqa: F401 from .math import remainder # noqa: F401 +from .math import remainder_ # noqa: F401 from .math import mod # noqa: F401 from .math import floor_mod # noqa: F401 from .math import multiply # noqa: F401 @@ -364,6 +365,7 @@ 'divide', 'floor_divide', 'remainder', + 'remainder_', 'mod', 'floor_mod', 'multiply', diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index 4d9f170d39ee4..f7390e9e49f7e 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -779,6 +779,23 @@ def remainder(x, y, name=None): return _elementwise_op(LayerHelper(op_type, **locals())) +def remainder_(x, y, name=None): + r""" + Inplace version of ``remainder`` API, the output Tensor will be inplaced with input ``x``. + Please refer to :ref:`api_tensor_remainder`. + """ + op_type = 'elementwise_mod_' + axis = -1 + + out_shape = broadcast_shape(x.shape, y.shape) + if out_shape != x.shape: + raise ValueError( + "The shape of broadcast output {} is different from that of inplace tensor {} in the Inplace operation.".format( + out_shape, x.shape)) + + return _elementwise_op_in_dygraph(x, y, axis=axis, op_name=op_type) + + mod = remainder # noqa: F841 floor_mod = remainder # noqa: F841 From c5bc2a822e3c92355b00e301afa521af718102af Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Fri, 19 Aug 2022 16:11:36 +0800 Subject: [PATCH 2/9] fix bug --- python/paddle/tensor/math.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index f7390e9e49f7e..e954b4f2aad4e 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -779,6 +779,7 @@ def remainder(x, y, name=None): return _elementwise_op(LayerHelper(op_type, **locals())) +@inplace_apis_in_dygraph_only def remainder_(x, y, name=None): r""" Inplace version of ``remainder`` API, the output Tensor will be inplaced with input ``x``. From db8a23351ec571a4c7ae3ca1fcd798300fc11f4e Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Fri, 19 Aug 2022 16:48:07 +0800 Subject: [PATCH 3/9] fix bug --- python/paddle/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index 6b99a91cdb307..a08df92390ee4 100755 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -236,6 +236,7 @@ from .tensor.math import divide # noqa: F401 from .tensor.math import floor_divide # noqa: F401 from .tensor.math import remainder # noqa: F401 +from .tensor.math import remainder_ # noqa: F401 from .tensor.math import mod # noqa: F401 from .tensor.math import floor_mod # noqa: F401 from .tensor.math import multiply # noqa: F401 From e932c68dfaa3217bef8aa72ed5f51f4c508f726c Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Fri, 19 Aug 2022 18:35:40 +0800 Subject: [PATCH 4/9] fix bug --- .../fluid/tests/unittests/test_inplace.py | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/python/paddle/fluid/tests/unittests/test_inplace.py b/python/paddle/fluid/tests/unittests/test_inplace.py index 052109674ae0c..399640ce6b1d2 100644 --- a/python/paddle/fluid/tests/unittests/test_inplace.py +++ b/python/paddle/fluid/tests/unittests/test_inplace.py @@ -483,7 +483,16 @@ def inplace_api_processing(self, var): return var.subtract_(input_var_2) -class TestDygraphInplaceRemainder(TestDygraphInplaceAdd): +class TestDygraphInplaceRemainder(unittest.TestCase): + + def setUp(self): + self.init_data() + self.set_np_compare_func() + + def init_data(self): + self.input_var_numpy = np.random.rand(2, 3, 4) + self.dtype = "float32" + self.input_var_numpy_2 = np.random.rand(2, 3, 4).astype(self.dtype) def non_inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2) @@ -493,6 +502,41 @@ def inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2) return var.remainder_(input_var_2) + def set_np_compare_func(self): + self.np_compare = np.array_equal + + def func_test_inplace_api(self): + var = paddle.to_tensor(self.input_var_numpy).astype(self.dtype) + inplace_var = self.inplace_api_processing(var) + self.assertTrue(id(var) == id(inplace_var)) + + inplace_var[0] = 2. + np.testing.assert_array_equal(var.numpy(), inplace_var.numpy()) + + def test_inplace_api(self): + with _test_eager_guard(): + self.func_test_inplace_api() + self.func_test_inplace_api() + + def func_test_forward_version(self): + with paddle.fluid.dygraph.guard(): + var = paddle.to_tensor(self.input_var_numpy).astype(self.dtype) + self.assertEqual(var.inplace_version, 0) + + inplace_var = self.inplace_api_processing(var) + self.assertEqual(var.inplace_version, 1) + + inplace_var[0] = 2. + self.assertEqual(var.inplace_version, 2) + + inplace_var = self.inplace_api_processing(inplace_var) + self.assertEqual(var.inplace_version, 3) + + def test_forward_version(self): + with _test_eager_guard(): + self.func_test_forward_version() + self.func_test_forward_version() + class TestLossIsInplaceVar(unittest.TestCase): From b999142c1f6d9c8136c46c005313f0c4a83a4a78 Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Tue, 23 Aug 2022 12:39:49 +0800 Subject: [PATCH 5/9] fix bug --- .../unittests/test_elementwise_mod_op.py | 68 ++++++++++--------- .../fluid/tests/unittests/test_inplace.py | 48 +++---------- 2 files changed, 44 insertions(+), 72 deletions(-) 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 0f3d0b8464cbf..d14974d61ea54 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -97,12 +97,15 @@ def init_dtype(self): class TestRemainderOp(unittest.TestCase): + def _executed_api(self, x, y, name=None): + return paddle.remainder(x, y, name) + def test_name(self): with fluid.program_guard(fluid.Program()): x = fluid.data(name="x", shape=[2, 3], dtype="int64") y = fluid.data(name='y', shape=[2, 3], dtype='int64') - y_1 = paddle.remainder(x, y, name='div_res') + y_1 = self._executed_api(x, y, name='div_res') self.assertEqual(('div_res' in y_1.name), True) def test_dygraph(self): @@ -111,7 +114,7 @@ def test_dygraph(self): np_y = np.array([1, 5, 3, 3]).astype('int64') x = paddle.to_tensor(np_x) y = paddle.to_tensor(np_y) - z = paddle.remainder(x, y) + z = self._executed_api(x, y) np_z = z.numpy() z_expected = np.array([0, 3, 2, 1]) self.assertEqual((np_z == z_expected).all(), True) @@ -135,40 +138,41 @@ def test_dygraph(self): class TestRemainderInplaceOp(unittest.TestCase): - def test_name(self): - with fluid.program_guard(fluid.Program()): - x = fluid.data(name="x", shape=[2, 3], dtype="int64") - y = fluid.data(name='y', shape=[2, 3], dtype='int64') + def _executed_api(self, x, y, name=None): + return x.subtract_(y, name) - y_1 = paddle.remainder_(x, y, name='div_res') - self.assertEqual(('div_res' in y_1.name), True) - def test_dygraph(self): - with fluid.dygraph.guard(): - np_x = np.array([2, 3, 8, 7]).astype('int64') - np_y = np.array([1, 5, 3, 3]).astype('int64') - x = paddle.to_tensor(np_x) - y = paddle.to_tensor(np_y) - z = paddle.remainder_(x, y) - np_z = z.numpy() - z_expected = np.array([0, 3, 2, 1]) - self.assertEqual((np_z == z_expected).all(), True) +class TestRemainderInplaceBroadcastSuccess(unittest.TestCase): - 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]) - np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) + def init_data(self): + self.x_numpy = np.random.rand(2, 3, 4).astype('float') + self.y_numpy = np.random.rand(3, 4).astype('float') - 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]) - np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) + def test_broadcast_success(self): + paddle.disable_static() + self.init_data() + x = paddle.to_tensor(self.x_numpy) + y = paddle.to_tensor(self.y_numpy) + inplace_result = x.remainder_(y) + numpy_result = self.x_numpy % self.y_numpy + self.assertEqual((inplace_result.numpy() == numpy_result).all(), True) + paddle.enable_static() + + +class TestRemainderInplaceBroadcastSuccess2(TestRemainderInplaceBroadcastSuccess + ): + + def init_data(self): + self.x_numpy = np.random.rand(1, 2, 3, 1).astype('float') + self.y_numpy = np.random.rand(3, 1).astype('float') + + +class TestRemainderInplaceBroadcastSuccess3(TestRemainderInplaceBroadcastSuccess + ): + + def init_data(self): + self.x_numpy = np.random.rand(2, 3, 1, 5).astype('float') + self.y_numpy = np.random.rand(1, 3, 1, 5).astype('float') if __name__ == '__main__': diff --git a/python/paddle/fluid/tests/unittests/test_inplace.py b/python/paddle/fluid/tests/unittests/test_inplace.py index 399640ce6b1d2..632759e17f06f 100644 --- a/python/paddle/fluid/tests/unittests/test_inplace.py +++ b/python/paddle/fluid/tests/unittests/test_inplace.py @@ -485,15 +485,6 @@ def inplace_api_processing(self, var): class TestDygraphInplaceRemainder(unittest.TestCase): - def setUp(self): - self.init_data() - self.set_np_compare_func() - - def init_data(self): - self.input_var_numpy = np.random.rand(2, 3, 4) - self.dtype = "float32" - self.input_var_numpy_2 = np.random.rand(2, 3, 4).astype(self.dtype) - def non_inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2) return var.remainder(input_var_2) @@ -502,40 +493,17 @@ def inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2) return var.remainder_(input_var_2) - def set_np_compare_func(self): - self.np_compare = np.array_equal - - def func_test_inplace_api(self): - var = paddle.to_tensor(self.input_var_numpy).astype(self.dtype) - inplace_var = self.inplace_api_processing(var) - self.assertTrue(id(var) == id(inplace_var)) - - inplace_var[0] = 2. - np.testing.assert_array_equal(var.numpy(), inplace_var.numpy()) - - def test_inplace_api(self): - with _test_eager_guard(): - self.func_test_inplace_api() - self.func_test_inplace_api() - - def func_test_forward_version(self): - with paddle.fluid.dygraph.guard(): - var = paddle.to_tensor(self.input_var_numpy).astype(self.dtype) - self.assertEqual(var.inplace_version, 0) - - inplace_var = self.inplace_api_processing(var) - self.assertEqual(var.inplace_version, 1) + def test_leaf_inplace_var_error(self): + pass - inplace_var[0] = 2. - self.assertEqual(var.inplace_version, 2) + def test_backward_error(self): + pass - inplace_var = self.inplace_api_processing(inplace_var) - self.assertEqual(var.inplace_version, 3) + def test_backward_success_1(self): + pass - def test_forward_version(self): - with _test_eager_guard(): - self.func_test_forward_version() - self.func_test_forward_version() + def test_backward_success_2(self): + pass class TestLossIsInplaceVar(unittest.TestCase): From d5b45e46abb677524fea4a384dfbfc539f54078e Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Fri, 26 Aug 2022 16:03:34 +0800 Subject: [PATCH 6/9] fix bug --- python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d14974d61ea54..dfe5743f7933e 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -139,7 +139,7 @@ def test_dygraph(self): class TestRemainderInplaceOp(unittest.TestCase): def _executed_api(self, x, y, name=None): - return x.subtract_(y, name) + return x.remainder_(y, name) class TestRemainderInplaceBroadcastSuccess(unittest.TestCase): From 72265b4a1191f4b6fc0883e223ad21b4723f5d42 Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Mon, 29 Aug 2022 22:54:14 +0800 Subject: [PATCH 7/9] fix bug --- .../paddle/fluid/tests/unittests/test_elementwise_mod_op.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 dfe5743f7933e..e186a164c4db2 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -136,13 +136,13 @@ def test_dygraph(self): np.testing.assert_allclose(z_expected, z.numpy(), rtol=1e-05) -class TestRemainderInplaceOp(unittest.TestCase): +class TestRemainderInplaceOp(TestRemainderOp): def _executed_api(self, x, y, name=None): return x.remainder_(y, name) -class TestRemainderInplaceBroadcastSuccess(unittest.TestCase): +class TestRemainderInplaceBroadcastSuccess(TestRemainderOp): def init_data(self): self.x_numpy = np.random.rand(2, 3, 4).astype('float') From 956ce7f250d6847a896d5864a86b7f61572db70c Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Tue, 30 Aug 2022 14:41:54 +0800 Subject: [PATCH 8/9] fix bug --- python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py | 2 +- python/paddle/fluid/tests/unittests/test_inplace.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 e186a164c4db2..eeccd8b976271 100644 --- a/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py +++ b/python/paddle/fluid/tests/unittests/test_elementwise_mod_op.py @@ -142,7 +142,7 @@ def _executed_api(self, x, y, name=None): return x.remainder_(y, name) -class TestRemainderInplaceBroadcastSuccess(TestRemainderOp): +class TestRemainderInplaceBroadcastSuccess(unittest.TestCase): def init_data(self): self.x_numpy = np.random.rand(2, 3, 4).astype('float') diff --git a/python/paddle/fluid/tests/unittests/test_inplace.py b/python/paddle/fluid/tests/unittests/test_inplace.py index 632759e17f06f..35acc810edc8a 100644 --- a/python/paddle/fluid/tests/unittests/test_inplace.py +++ b/python/paddle/fluid/tests/unittests/test_inplace.py @@ -483,7 +483,7 @@ def inplace_api_processing(self, var): return var.subtract_(input_var_2) -class TestDygraphInplaceRemainder(unittest.TestCase): +class TestDygraphInplaceRemainder(TestDygraphInplace): def non_inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2) From a5b8a5a888e78cfb2f2c8fa784a9fda96f94a176 Mon Sep 17 00:00:00 2001 From: zrr1999 <2742392377@qq.com> Date: Tue, 30 Aug 2022 15:49:23 +0800 Subject: [PATCH 9/9] fix bug --- python/paddle/fluid/tests/unittests/test_inplace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/fluid/tests/unittests/test_inplace.py b/python/paddle/fluid/tests/unittests/test_inplace.py index 35acc810edc8a..a96661a57f38a 100644 --- a/python/paddle/fluid/tests/unittests/test_inplace.py +++ b/python/paddle/fluid/tests/unittests/test_inplace.py @@ -483,7 +483,7 @@ def inplace_api_processing(self, var): return var.subtract_(input_var_2) -class TestDygraphInplaceRemainder(TestDygraphInplace): +class TestDygraphInplaceRemainder(TestDygraphInplaceAdd): def non_inplace_api_processing(self, var): input_var_2 = paddle.to_tensor(self.input_var_numpy_2)