From 5df774d8c7fac43a818a050228cbabec4658de44 Mon Sep 17 00:00:00 2001 From: co63oc Date: Tue, 20 May 2025 17:06:23 +0800 Subject: [PATCH 1/2] Fix --- paddle/phi/kernels/cpu/cum_kernel.cc | 4 +++ paddle/phi/kernels/gpu/cum_kernel.cu | 4 +++ .../phi/kernels/impl/logcumsumexp_grad_impl.h | 4 +++ paddle/phi/kernels/xpu/cum_kernel.cc | 4 +++ test/legacy_test/test_cumsum_op.py | 33 ++++++++++++++++++ test/legacy_test/test_logcumsumexp_op.py | 34 +++++++++++++++++++ 6 files changed, 83 insertions(+) diff --git a/paddle/phi/kernels/cpu/cum_kernel.cc b/paddle/phi/kernels/cpu/cum_kernel.cc index b4d48e38004da..69578a27cff31 100644 --- a/paddle/phi/kernels/cpu/cum_kernel.cc +++ b/paddle/phi/kernels/cpu/cum_kernel.cc @@ -57,6 +57,10 @@ void ScanKernel(const Context& dev_ctx, bool reverse, Reducer reducer, DenseTensor* out) { + if (out && out->numel() == 0) { + dev_ctx.template Alloc(out); + return; + } dev_ctx.template Alloc(out); if (x.numel() == 1) { diff --git a/paddle/phi/kernels/gpu/cum_kernel.cu b/paddle/phi/kernels/gpu/cum_kernel.cu index fdff5b9384359..84ee158344aa0 100644 --- a/paddle/phi/kernels/gpu/cum_kernel.cu +++ b/paddle/phi/kernels/gpu/cum_kernel.cu @@ -274,6 +274,10 @@ void ScanKernel(const Context& dev_ctx, bool reverse, Op op, DenseTensor* out) { + if (out && out->numel() == 0) { + dev_ctx.template Alloc(out); + return; + } T* out_data = dev_ctx.template Alloc(out); // For 0D Tensor diff --git a/paddle/phi/kernels/impl/logcumsumexp_grad_impl.h b/paddle/phi/kernels/impl/logcumsumexp_grad_impl.h index 0eeae849bcfed..3c28bf2b4769c 100644 --- a/paddle/phi/kernels/impl/logcumsumexp_grad_impl.h +++ b/paddle/phi/kernels/impl/logcumsumexp_grad_impl.h @@ -50,6 +50,10 @@ void LogcumsumexpGradKernel(const Context& dev_ctx, bool exclusive, bool reverse, DenseTensor* d_x) { + if (d_x && d_x->numel() == 0) { + dev_ctx.template Alloc(d_x); + return; + } reverse = !reverse; dev_ctx.template Alloc(d_x); diff --git a/paddle/phi/kernels/xpu/cum_kernel.cc b/paddle/phi/kernels/xpu/cum_kernel.cc index 29f7614ee83f8..aed6a64903ff7 100644 --- a/paddle/phi/kernels/xpu/cum_kernel.cc +++ b/paddle/phi/kernels/xpu/cum_kernel.cc @@ -28,6 +28,10 @@ void CumsumKernel(const Context& dev_ctx, bool reverse, DenseTensor* out) { using XPUType = typename XPUTypeTrait::Type; + if (out && out->numel() == 0) { + dev_ctx.template Alloc(out); + return; + } dev_ctx.template Alloc(out); if (x.numel() == 1) { diff --git a/test/legacy_test/test_cumsum_op.py b/test/legacy_test/test_cumsum_op.py index 6b88fe323f88a..0b66a96a3ac8b 100644 --- a/test/legacy_test/test_cumsum_op.py +++ b/test/legacy_test/test_cumsum_op.py @@ -747,5 +747,38 @@ def test_fp16(self): paddle.disable_static() +def create_test_class(op_type, dtype, shape, axis): + class Cls(unittest.TestCase): + def test_zero_size(self): + numpy_tensor_1 = np.random.rand(*shape).astype(dtype) + paddle_x = paddle.to_tensor(numpy_tensor_1) + paddle_x.stop_gradient = False + + paddle_api = eval(f"paddle.{op_type}") + paddle_out = paddle_api(paddle_x, axis=axis) + numpy_api = eval(f"np.{op_type}") + numpy_out = numpy_api(numpy_tensor_1, axis=axis) + + np.testing.assert_allclose( + paddle_out.numpy(), + numpy_out, + 1e-2, + 1e-2, + ) + np.testing.assert_allclose( + paddle_out.shape, + numpy_out.shape, + ) + + cls_name = f"{op_type}{dtype}_0SizeTest" + Cls.__name__ = cls_name + globals()[cls_name] = Cls + + +create_test_class("cumsum", "float32", [3, 4, 0], 0) +create_test_class("cumsum", "float64", [3, 4, 0, 3, 4], -2) +create_test_class("cumsum", "int32", [3, 4, 0], 0) +create_test_class("cumsum", "int64", [3, 4, 0, 3, 4], -1) + if __name__ == '__main__': unittest.main() diff --git a/test/legacy_test/test_logcumsumexp_op.py b/test/legacy_test/test_logcumsumexp_op.py index 5d7e3dcdf54d9..25173ba87df1f 100644 --- a/test/legacy_test/test_logcumsumexp_op.py +++ b/test/legacy_test/test_logcumsumexp_op.py @@ -375,5 +375,39 @@ def test_check_grad(self): ) +def create_test_class(op_type, dtype, shape, axis): + class Cls(unittest.TestCase): + def test_zero_size(self): + numpy_tensor_1 = np.random.rand(*shape).astype(dtype) + paddle_x = paddle.to_tensor(numpy_tensor_1) + paddle_x.stop_gradient = False + + paddle_api = eval(f"paddle.{op_type}") + paddle_out = paddle_api(paddle_x, axis=axis) + numpy_out = np.log( + np.cumsum(np.exp(numpy_tensor_1), axis=axis) + ) # Numpy does not have logcumsumexp + + np.testing.assert_allclose( + paddle_out.numpy(), + numpy_out, + 1e-2, + 1e-2, + ) + np.testing.assert_allclose( + paddle_out.shape, + numpy_out.shape, + ) + + cls_name = f"{op_type}{dtype}_0SizeTest" + Cls.__name__ = cls_name + globals()[cls_name] = Cls + + +create_test_class("logcumsumexp", "float32", [3, 4, 0], 0) +create_test_class("logcumsumexp", "float64", [3, 4, 0, 3, 4], -2) +create_test_class("logcumsumexp", "int32", [3, 4, 0], 0) +create_test_class("logcumsumexp", "int64", [3, 4, 0, 3, 4], -1) + if __name__ == '__main__': unittest.main() From aa9fc46162ab0d86dfb25e83a315e5c92f3702f3 Mon Sep 17 00:00:00 2001 From: co63oc Date: Tue, 20 May 2025 21:18:15 +0800 Subject: [PATCH 2/2] Fix --- test/legacy_test/test_cumsum_op.py | 1 + test/legacy_test/test_logcumsumexp_op.py | 1 + 2 files changed, 2 insertions(+) diff --git a/test/legacy_test/test_cumsum_op.py b/test/legacy_test/test_cumsum_op.py index 0b66a96a3ac8b..ef9bbaee1fd06 100644 --- a/test/legacy_test/test_cumsum_op.py +++ b/test/legacy_test/test_cumsum_op.py @@ -750,6 +750,7 @@ def test_fp16(self): def create_test_class(op_type, dtype, shape, axis): class Cls(unittest.TestCase): def test_zero_size(self): + paddle.disable_static() numpy_tensor_1 = np.random.rand(*shape).astype(dtype) paddle_x = paddle.to_tensor(numpy_tensor_1) paddle_x.stop_gradient = False diff --git a/test/legacy_test/test_logcumsumexp_op.py b/test/legacy_test/test_logcumsumexp_op.py index 25173ba87df1f..85e89d2b06f7f 100644 --- a/test/legacy_test/test_logcumsumexp_op.py +++ b/test/legacy_test/test_logcumsumexp_op.py @@ -378,6 +378,7 @@ def test_check_grad(self): def create_test_class(op_type, dtype, shape, axis): class Cls(unittest.TestCase): def test_zero_size(self): + paddle.disable_static() numpy_tensor_1 = np.random.rand(*shape).astype(dtype) paddle_x = paddle.to_tensor(numpy_tensor_1) paddle_x.stop_gradient = False