From cbe76d5d0e895992aee6e22eb6b7789b9a44652e Mon Sep 17 00:00:00 2001 From: RedContritio Date: Sun, 22 Jan 2023 18:05:47 +0000 Subject: [PATCH 1/7] support 0 dim tensor in HandleLargeDim --- paddle/fluid/operators/reduce_ops/reduce_op.h | 13 ++++++++++++- paddle/phi/kernels/funcs/reduce_function.h | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/paddle/fluid/operators/reduce_ops/reduce_op.h b/paddle/fluid/operators/reduce_ops/reduce_op.h index ecf8119ed2a19..2f36f9d6e2fa6 100644 --- a/paddle/fluid/operators/reduce_ops/reduce_op.h +++ b/paddle/fluid/operators/reduce_ops/reduce_op.h @@ -141,8 +141,19 @@ void HandleLargeDim(const framework::ExecutionContext& context, // transpose to 2D tensor whose shape is {unreduced, reduced}. const int64_t unreduced = output->numel(); - const int64_t reduced = shuffled_input.numel() / unreduced; + const int64_t input_numel = shuffled_input.numel(); + + // this enforce will always pass if the memory is functioning normally + PADDLE_ENFORCE_NE(unreduced == 0 && input_numel != 0, + true, + phi::errors::InvalidArgument( + "An error occurred in HandleLargeDim, which means a " + "tensor has at least a 0 dimension but is not empty.")); + + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = unreduced != 0 ? (input_numel / unreduced) : 0; shuffled_input.Resize({unreduced, reduced}); + DDim output_dim = output->dims(); output->Resize({unreduced}); paddle::operators::ReduceFunctor( diff --git a/paddle/phi/kernels/funcs/reduce_function.h b/paddle/phi/kernels/funcs/reduce_function.h index b48f2eb4cdf2b..958c5008a8b5b 100644 --- a/paddle/phi/kernels/funcs/reduce_function.h +++ b/paddle/phi/kernels/funcs/reduce_function.h @@ -1228,8 +1228,19 @@ void HandleLargeDim(const DeviceContext& dev_ctx, // transpose to 2D tensor whose shape is {unreduced, reduced}. const int64_t unreduced = output->numel(); - const int64_t reduced = shuffled_input.numel() / unreduced; + const int64_t input_numel = shuffled_input.numel(); + + // this enforce will always pass if the memory is functioning normally + PADDLE_ENFORCE_NE(unreduced == 0 && input_numel != 0, + true, + phi::errors::InvalidArgument( + "An error occurred in HandleLargeDim, which means a " + "tensor has at least a 0 dimension but is not empty.")); + + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = unreduced != 0 ? (input_numel / unreduced) : 0; shuffled_input.ResizeAndAllocate({unreduced, reduced}); + DDim output_dim = output->dims(); output->ResizeAndAllocate({unreduced}); ReduceFunctor( From f09ad6fe155dbd1983505e137c675874a91878dd Mon Sep 17 00:00:00 2001 From: RedContritio Date: Sun, 22 Jan 2023 18:13:51 +0000 Subject: [PATCH 2/7] support 0 dim tensor in HandleLargeDimGrad --- paddle/fluid/operators/reduce_ops/reduce_op.h | 14 +++++++++++++- paddle/phi/kernels/funcs/reduce_grad_functions.h | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/paddle/fluid/operators/reduce_ops/reduce_op.h b/paddle/fluid/operators/reduce_ops/reduce_op.h index 2f36f9d6e2fa6..1504a0d4e4bc2 100644 --- a/paddle/fluid/operators/reduce_ops/reduce_op.h +++ b/paddle/fluid/operators/reduce_ops/reduce_op.h @@ -174,7 +174,19 @@ void HandleLargeDimGrad(const framework::ExecutionContext& context, Functor functor, const std::vector& dims) { const int64_t unreduced = out->numel(); - const int64_t reduced = x->numel() / unreduced; + const int64_t x_numel = x->numel(); + + // this enforce will always pass if the memory is functioning normally + PADDLE_ENFORCE_NE( + unreduced == 0 && x_numel != 0, + true, + phi::errors::InvalidArgument( + "An error occurred in HandleLargeDimGrad, which means a " + "tensor has at least a 0 dimension but is not empty.")); + + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = unreduced != 0 ? (x_numel / unreduced) : 0; + DDim out_dim(out->dims()); DDim x_dim(x->dims()); // transpose and reshape X diff --git a/paddle/phi/kernels/funcs/reduce_grad_functions.h b/paddle/phi/kernels/funcs/reduce_grad_functions.h index 3ab7618adec48..ad63cb464fc93 100644 --- a/paddle/phi/kernels/funcs/reduce_grad_functions.h +++ b/paddle/phi/kernels/funcs/reduce_grad_functions.h @@ -87,7 +87,19 @@ void HandleLargeDimGrad(const Context& dev_ctx, Functor functor, const std::vector& dims) { const int64_t unreduced = out->numel(); - const int64_t reduced = x->numel() / unreduced; + const int64_t x_numel = x->numel(); + + // this enforce will always pass if the memory is functioning normally + PADDLE_ENFORCE_NE( + unreduced == 0 && x_numel != 0, + true, + phi::errors::InvalidArgument( + "An error occurred in HandleLargeDimGrad, which means a " + "tensor has at least a 0 dimension but is not empty.")); + + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = unreduced != 0 ? (x_numel / unreduced) : 0; + DDim out_dim(out->dims()); DDim x_dim(x->dims()); // transpose and reshape X From 14b4bed5e3246c9e4cf8158238c06d3aeca191ae Mon Sep 17 00:00:00 2001 From: RedContritio Date: Sun, 22 Jan 2023 18:39:47 +0000 Subject: [PATCH 3/7] better enforce with EQ --- paddle/fluid/operators/reduce_ops/reduce_op.h | 21 ++++++++----------- paddle/phi/kernels/funcs/reduce_function.h | 9 ++++---- .../phi/kernels/funcs/reduce_grad_functions.h | 12 +++++------ 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/paddle/fluid/operators/reduce_ops/reduce_op.h b/paddle/fluid/operators/reduce_ops/reduce_op.h index 1504a0d4e4bc2..d4a367e3412bf 100644 --- a/paddle/fluid/operators/reduce_ops/reduce_op.h +++ b/paddle/fluid/operators/reduce_ops/reduce_op.h @@ -142,16 +142,15 @@ void HandleLargeDim(const framework::ExecutionContext& context, // transpose to 2D tensor whose shape is {unreduced, reduced}. const int64_t unreduced = output->numel(); const int64_t input_numel = shuffled_input.numel(); + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = (unreduced != 0) ? (input_numel / unreduced) : 0; - // this enforce will always pass if the memory is functioning normally - PADDLE_ENFORCE_NE(unreduced == 0 && input_numel != 0, - true, + PADDLE_ENFORCE_EQ(unreduced * reduced, + input_numel, phi::errors::InvalidArgument( "An error occurred in HandleLargeDim, which means a " "tensor has at least a 0 dimension but is not empty.")); - // assume: 0 / 0 == 0, which allow process 0 dim tensor - const int64_t reduced = unreduced != 0 ? (input_numel / unreduced) : 0; shuffled_input.Resize({unreduced, reduced}); DDim output_dim = output->dims(); @@ -175,18 +174,16 @@ void HandleLargeDimGrad(const framework::ExecutionContext& context, const std::vector& dims) { const int64_t unreduced = out->numel(); const int64_t x_numel = x->numel(); + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = (unreduced != 0) ? (x_numel / unreduced) : 0; - // this enforce will always pass if the memory is functioning normally - PADDLE_ENFORCE_NE( - unreduced == 0 && x_numel != 0, - true, + PADDLE_ENFORCE_EQ( + unreduced * reduced, + x_numel, phi::errors::InvalidArgument( "An error occurred in HandleLargeDimGrad, which means a " "tensor has at least a 0 dimension but is not empty.")); - // assume: 0 / 0 == 0, which allow process 0 dim tensor - const int64_t reduced = unreduced != 0 ? (x_numel / unreduced) : 0; - DDim out_dim(out->dims()); DDim x_dim(x->dims()); // transpose and reshape X diff --git a/paddle/phi/kernels/funcs/reduce_function.h b/paddle/phi/kernels/funcs/reduce_function.h index 958c5008a8b5b..b5a77710914ca 100644 --- a/paddle/phi/kernels/funcs/reduce_function.h +++ b/paddle/phi/kernels/funcs/reduce_function.h @@ -1229,16 +1229,15 @@ void HandleLargeDim(const DeviceContext& dev_ctx, // transpose to 2D tensor whose shape is {unreduced, reduced}. const int64_t unreduced = output->numel(); const int64_t input_numel = shuffled_input.numel(); + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = (unreduced != 0) ? (input_numel / unreduced) : 0; - // this enforce will always pass if the memory is functioning normally - PADDLE_ENFORCE_NE(unreduced == 0 && input_numel != 0, - true, + PADDLE_ENFORCE_EQ(unreduced * reduced, + input_numel, phi::errors::InvalidArgument( "An error occurred in HandleLargeDim, which means a " "tensor has at least a 0 dimension but is not empty.")); - // assume: 0 / 0 == 0, which allow process 0 dim tensor - const int64_t reduced = unreduced != 0 ? (input_numel / unreduced) : 0; shuffled_input.ResizeAndAllocate({unreduced, reduced}); DDim output_dim = output->dims(); diff --git a/paddle/phi/kernels/funcs/reduce_grad_functions.h b/paddle/phi/kernels/funcs/reduce_grad_functions.h index ad63cb464fc93..daca8c3d8dfad 100644 --- a/paddle/phi/kernels/funcs/reduce_grad_functions.h +++ b/paddle/phi/kernels/funcs/reduce_grad_functions.h @@ -88,18 +88,16 @@ void HandleLargeDimGrad(const Context& dev_ctx, const std::vector& dims) { const int64_t unreduced = out->numel(); const int64_t x_numel = x->numel(); + // assume: 0 / 0 == 0, which allow process 0 dim tensor + const int64_t reduced = (unreduced != 0) ? (x_numel / unreduced) : 0; - // this enforce will always pass if the memory is functioning normally - PADDLE_ENFORCE_NE( - unreduced == 0 && x_numel != 0, - true, + PADDLE_ENFORCE_EQ( + unreduced * reduced, + x_numel, phi::errors::InvalidArgument( "An error occurred in HandleLargeDimGrad, which means a " "tensor has at least a 0 dimension but is not empty.")); - // assume: 0 / 0 == 0, which allow process 0 dim tensor - const int64_t reduced = unreduced != 0 ? (x_numel / unreduced) : 0; - DDim out_dim(out->dims()); DDim x_dim(x->dims()); // transpose and reshape X From a1312e437324d10801d80d579c187a1e3da2c9d9 Mon Sep 17 00:00:00 2001 From: RedContritio Date: Sun, 22 Jan 2023 19:14:11 +0000 Subject: [PATCH 4/7] better error message --- paddle/fluid/operators/reduce_ops/reduce_op.h | 21 ++++++++++++------- paddle/phi/kernels/funcs/reduce_function.h | 14 ++++++++----- .../phi/kernels/funcs/reduce_grad_functions.h | 7 +++++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/paddle/fluid/operators/reduce_ops/reduce_op.h b/paddle/fluid/operators/reduce_ops/reduce_op.h index d4a367e3412bf..1f1ea5c005db7 100644 --- a/paddle/fluid/operators/reduce_ops/reduce_op.h +++ b/paddle/fluid/operators/reduce_ops/reduce_op.h @@ -145,11 +145,15 @@ void HandleLargeDim(const framework::ExecutionContext& context, // assume: 0 / 0 == 0, which allow process 0 dim tensor const int64_t reduced = (unreduced != 0) ? (input_numel / unreduced) : 0; - PADDLE_ENFORCE_EQ(unreduced * reduced, - input_numel, - phi::errors::InvalidArgument( - "An error occurred in HandleLargeDim, which means a " - "tensor has at least a 0 dimension but is not empty.")); + PADDLE_ENFORCE_EQ( + unreduced * reduced, + input_numel, + phi::errors::InvalidArgument( + "Reducing failed in HandleLargeDim, when try to transpose (%d) " + "operands into 2D tensor with shape (%d, %d).", + input_numel, + unreduced, + reduced)); shuffled_input.Resize({unreduced, reduced}); @@ -181,8 +185,11 @@ void HandleLargeDimGrad(const framework::ExecutionContext& context, unreduced * reduced, x_numel, phi::errors::InvalidArgument( - "An error occurred in HandleLargeDimGrad, which means a " - "tensor has at least a 0 dimension but is not empty.")); + "Reducing failed in HandleLargeDimGrad, when try to transpose (%d) " + "operands into 2D tensor with shape (%d, %d).", + x_numel, + unreduced, + reduced)); DDim out_dim(out->dims()); DDim x_dim(x->dims()); diff --git a/paddle/phi/kernels/funcs/reduce_function.h b/paddle/phi/kernels/funcs/reduce_function.h index b5a77710914ca..0b9b852a7585d 100644 --- a/paddle/phi/kernels/funcs/reduce_function.h +++ b/paddle/phi/kernels/funcs/reduce_function.h @@ -1232,11 +1232,15 @@ void HandleLargeDim(const DeviceContext& dev_ctx, // assume: 0 / 0 == 0, which allow process 0 dim tensor const int64_t reduced = (unreduced != 0) ? (input_numel / unreduced) : 0; - PADDLE_ENFORCE_EQ(unreduced * reduced, - input_numel, - phi::errors::InvalidArgument( - "An error occurred in HandleLargeDim, which means a " - "tensor has at least a 0 dimension but is not empty.")); + PADDLE_ENFORCE_EQ( + unreduced * reduced, + input_numel, + phi::errors::InvalidArgument( + "Reducing failed in HandleLargeDim, when try to transpose (%d) " + "operands into 2D tensor with shape (%d, %d).", + input_numel, + unreduced, + reduced)); shuffled_input.ResizeAndAllocate({unreduced, reduced}); diff --git a/paddle/phi/kernels/funcs/reduce_grad_functions.h b/paddle/phi/kernels/funcs/reduce_grad_functions.h index daca8c3d8dfad..1b0f34b943d5a 100644 --- a/paddle/phi/kernels/funcs/reduce_grad_functions.h +++ b/paddle/phi/kernels/funcs/reduce_grad_functions.h @@ -95,8 +95,11 @@ void HandleLargeDimGrad(const Context& dev_ctx, unreduced * reduced, x_numel, phi::errors::InvalidArgument( - "An error occurred in HandleLargeDimGrad, which means a " - "tensor has at least a 0 dimension but is not empty.")); + "Reducing failed in HandleLargeDimGrad, when try to transpose (%d) " + "operands into 2D tensor with shape (%d, %d).", + x_numel, + unreduced, + reduced)); DDim out_dim(out->dims()); DDim x_dim(x->dims()); From 0d5b3bda646f42e9c71801b0458b2a7a902e861c Mon Sep 17 00:00:00 2001 From: RedContritio Date: Tue, 31 Jan 2023 11:00:15 +0000 Subject: [PATCH 5/7] add unittest --- python/paddle/fluid/tests/unittests/test_min_op.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/python/paddle/fluid/tests/unittests/test_min_op.py b/python/paddle/fluid/tests/unittests/test_min_op.py index c0e9803b140f0..e4acbfe5f3dc8 100644 --- a/python/paddle/fluid/tests/unittests/test_min_op.py +++ b/python/paddle/fluid/tests/unittests/test_min_op.py @@ -117,5 +117,17 @@ def init_data(self): self.keepdim = True +class TestMinWithEmptyTensor(TestReduceOPTensorAxisBase): + def init_data(self): + self.pd_api = paddle.min + self.np_api = np.min + data = np.array([], dtype=np.float32) + self.x = paddle.to_tensor( + np.reshape(data, [0, 0, 0, 0, 0, 0, 0]), dtype='float64' + ) + self.np_axis = 0 + self.tensor_axis = 0 + + if __name__ == '__main__': unittest.main() From 246763938eb1795590c24f749f9d4b4108671047 Mon Sep 17 00:00:00 2001 From: RedContritio Date: Wed, 1 Feb 2023 16:55:33 +0000 Subject: [PATCH 6/7] force run CI From e266b5f8f37b0e2b1b10f9971cc79c1b5f2e7d7b Mon Sep 17 00:00:00 2001 From: RedContritio Date: Wed, 1 Feb 2023 18:30:44 +0000 Subject: [PATCH 7/7] enforce x.numel() > 0 in minOp --- paddle/phi/kernels/reduce_min_kernel.cc | 5 +++++ .../fluid/tests/unittests/test_min_op.py | 22 ++++++++++--------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/paddle/phi/kernels/reduce_min_kernel.cc b/paddle/phi/kernels/reduce_min_kernel.cc index 660d3b753e97e..c4c58c8342e60 100644 --- a/paddle/phi/kernels/reduce_min_kernel.cc +++ b/paddle/phi/kernels/reduce_min_kernel.cc @@ -26,6 +26,11 @@ void MinKernel(const Context& dev_ctx, bool keep_dim, DenseTensor* out) { bool reduce_all = recompute_reduce_all(x, dims); + PADDLE_ENFORCE_GT( + x.numel(), + 0, + errors::InvalidArgument("Zero-size tensor to reduction operation minimum " + "which has no identity.")); MinRawKernel(dev_ctx, x, dims, keep_dim, reduce_all, out); } diff --git a/python/paddle/fluid/tests/unittests/test_min_op.py b/python/paddle/fluid/tests/unittests/test_min_op.py index e4acbfe5f3dc8..70d41e1132169 100644 --- a/python/paddle/fluid/tests/unittests/test_min_op.py +++ b/python/paddle/fluid/tests/unittests/test_min_op.py @@ -20,6 +20,7 @@ import paddle import paddle.fluid.core as core +from paddle import fluid class ApiMinTest(unittest.TestCase): @@ -117,16 +118,17 @@ def init_data(self): self.keepdim = True -class TestMinWithEmptyTensor(TestReduceOPTensorAxisBase): - def init_data(self): - self.pd_api = paddle.min - self.np_api = np.min - data = np.array([], dtype=np.float32) - self.x = paddle.to_tensor( - np.reshape(data, [0, 0, 0, 0, 0, 0, 0]), dtype='float64' - ) - self.np_axis = 0 - self.tensor_axis = 0 +class TestMinAPIWithEmptyTensor(unittest.TestCase): + def test_empty_tensor(self): + with fluid.dygraph.guard(): + with self.assertRaises(ValueError): + data = np.array([], dtype=np.float32) + data = np.reshape(data, [0, 0, 0, 0, 0, 0, 0]) + x = paddle.to_tensor(data, dtype='float64') + np_axis = np.array([0], dtype='int64') + tensor_axis = paddle.to_tensor(np_axis, dtype='int64') + + out = paddle.min(x, tensor_axis) if __name__ == '__main__':