diff --git a/paddle/phi/kernels/xpu/log_softmax_grad_kernel.cc b/paddle/phi/kernels/xpu/log_softmax_grad_kernel.cc index 946daf5d7104a5..949e40474c7351 100644 --- a/paddle/phi/kernels/xpu/log_softmax_grad_kernel.cc +++ b/paddle/phi/kernels/xpu/log_softmax_grad_kernel.cc @@ -33,6 +33,7 @@ void LogSoftmaxGradKernel(const Context& dev_ctx, // For 0D Tensor if (rank == 0) { + dev_ctx.template Alloc(x_grad); phi::funcs::set_constant(dev_ctx, x_grad, 0.0); return; } diff --git a/paddle/phi/kernels/xpu/log_softmax_kernel.cc b/paddle/phi/kernels/xpu/log_softmax_kernel.cc index 059157db63a314..2ee093dbad44c5 100644 --- a/paddle/phi/kernels/xpu/log_softmax_kernel.cc +++ b/paddle/phi/kernels/xpu/log_softmax_kernel.cc @@ -32,6 +32,7 @@ void LogSoftmaxKernel(const Context& dev_ctx, // For 0D Tensor if (rank == 0) { + dev_ctx.template Alloc(out); phi::funcs::set_constant(dev_ctx, out, 0.0); return; } diff --git a/paddle/phi/kernels/xpu/prelu_grad_kernel.cc b/paddle/phi/kernels/xpu/prelu_grad_kernel.cc index b786b13b3db84e..fa43c908837664 100644 --- a/paddle/phi/kernels/xpu/prelu_grad_kernel.cc +++ b/paddle/phi/kernels/xpu/prelu_grad_kernel.cc @@ -40,16 +40,24 @@ void PReluGradKernel(const Context& dev_ctx, auto x_rank = x_dim.size(); std::vector x_shape(x_rank); - for (int i = 0; i < x_rank; i++) { - x_shape[i] = x_dim[i]; + if (x_rank == 0) { + x_shape = std::vector({1}); + } else { + for (int i = 0; i < x_rank; i++) { + x_shape[i] = x_dim[i]; + } } auto alpha_dim = alpha.dims(); auto alpha_rank = alpha_dim.size(); std::vector alpha_shape(alpha_rank); - for (int i = 0; i < x_rank; i++) { - alpha_shape[i] = alpha_dim[i]; + if (alpha_rank == 0) { + alpha_shape = std::vector({1}); + } else { + for (int i = 0; i < x_rank; i++) { + alpha_shape[i] = alpha_dim[i]; + } } // mode = 0: channel_nchw, slope_shape = {c}, default. meanwhile, xhsape = {n, diff --git a/paddle/phi/kernels/xpu/prelu_kernel.cc b/paddle/phi/kernels/xpu/prelu_kernel.cc index 9a72cd79da38a6..4d6835896ab911 100644 --- a/paddle/phi/kernels/xpu/prelu_kernel.cc +++ b/paddle/phi/kernels/xpu/prelu_kernel.cc @@ -34,20 +34,26 @@ void PReluKernel(const Context& dev_ctx, auto x_dim = x.dims(); auto x_rank = x_dim.size(); - std::vector x_shape(x_rank); - for (int i = 0; i < x_rank; i++) { - x_shape[i] = x_dim[i]; + if (x_rank == 0) { + x_shape = std::vector({1}); + } else { + for (int i = 0; i < x_rank; i++) { + x_shape[i] = x_dim[i]; + } } auto alpha_dim = alpha.dims(); auto alpha_rank = alpha_dim.size(); - std::vector alpha_shape(x_rank, 1); // same size with x_shape - for (int i = 0; i < alpha_rank; i++) { - alpha_shape[i] = alpha_dim[i]; + if (x_rank == 0) { + alpha_shape = std::vector({1}); + } else { + for (int i = 0; i < alpha_rank; i++) { + alpha_shape[i] = alpha_dim[i]; + } } int r = xpu::prelu(dev_ctx.x_context(), diff --git a/paddle/phi/kernels/xpu/softmax_grad_kernel.cc b/paddle/phi/kernels/xpu/softmax_grad_kernel.cc index 8d5d855e52aa94..809534b8d96f10 100644 --- a/paddle/phi/kernels/xpu/softmax_grad_kernel.cc +++ b/paddle/phi/kernels/xpu/softmax_grad_kernel.cc @@ -16,6 +16,7 @@ limitations under the License. */ #include "paddle/phi/backends/xpu/enforce_xpu.h" #include "paddle/phi/core/kernel_registry.h" #include "paddle/phi/kernels/funcs/axis_utils.h" +#include "paddle/phi/kernels/funcs/math_function.h" namespace phi { @@ -35,6 +36,12 @@ void SoftmaxGradKernel(const Context& dev_ctx, return; } + // For 0D Tensor + if (rank == 0) { + phi::funcs::set_constant(dev_ctx, x_grad, 0.0); + return; + } + std::vector x_dims; for (int i = 0; i < rank; i++) { x_dims.push_back(x_grad->dims()[i]); diff --git a/python/paddle/fluid/tests/unittests/test_zero_dim_tensor.py b/python/paddle/fluid/tests/unittests/test_zero_dim_tensor.py index 64881c08fb6373..c87f55fb3980d8 100644 --- a/python/paddle/fluid/tests/unittests/test_zero_dim_tensor.py +++ b/python/paddle/fluid/tests/unittests/test_zero_dim_tensor.py @@ -1628,24 +1628,29 @@ def test_t(self): self.assertEqual(x.grad.shape, []) def test_prelu(self): - x = paddle.full([], 1.0, 'float32') - x.stop_gradient = False - - w1 = paddle.to_tensor([0.25], dtype='float32') - out1 = paddle.nn.functional.prelu(x, w1) + x1 = paddle.full([], 1.0, 'float32') + x1.stop_gradient = False + w1 = paddle.full([], 0.25, dtype='float32') + out1 = paddle.nn.functional.prelu(x1, w1) out1.retain_grads() out1.backward() self.assertEqual(out1.shape, []) + self.assertEqual(out1.numpy(), 1.0) self.assertEqual(out1.grad.shape, []) - self.assertEqual(x.grad.shape, []) + self.assertEqual(x1.grad.shape, []) + self.assertEqual(x1.grad.numpy(), 1.0) + x2 = paddle.full([], -1.0, 'float32') + x2.stop_gradient = False w2 = paddle.full([], 0.25, dtype='float32') - out2 = paddle.nn.functional.prelu(x, w2) + out2 = paddle.nn.functional.prelu(x2, w2) out2.retain_grads() out2.backward() self.assertEqual(out2.shape, []) + self.assertEqual(out2.numpy(), -0.25) self.assertEqual(out2.grad.shape, []) - self.assertEqual(x.grad.shape, []) + self.assertEqual(x2.grad.shape, []) + self.assertEqual(x2.grad.numpy(), 0.25) def test_while_loop(self): def cond(i, x): diff --git a/python/paddle/fluid/tests/unittests/xpu/test_zero_dim_tensor_xpu.py b/python/paddle/fluid/tests/unittests/xpu/test_zero_dim_tensor_xpu.py index 518b1c1488e17a..ea54f5b26388e6 100644 --- a/python/paddle/fluid/tests/unittests/xpu/test_zero_dim_tensor_xpu.py +++ b/python/paddle/fluid/tests/unittests/xpu/test_zero_dim_tensor_xpu.py @@ -84,6 +84,8 @@ paddle.lgamma, paddle.poisson, paddle.bernoulli, + paddle.nn.functional.softmax, + paddle.nn.functional.log_softmax, ] inplace_api_list = [ @@ -1033,6 +1035,33 @@ def test_unsqueeze(self): out2.backward() self.assertEqual(out2.shape, [1]) + def test_prelu(self): + x1 = paddle.full([], 1.0, 'float32') + x1.stop_gradient = False + w1 = paddle.full([], 0.25, dtype='float32') + w1.stop_gradient = False + out1 = paddle.nn.functional.prelu(x1, w1) + out1.retain_grads() + out1.backward() + self.assertEqual(out1.shape, []) + self.assertEqual(out1.numpy(), 1.0) + self.assertEqual(out1.grad.shape, []) + self.assertEqual(x1.grad.shape, []) + self.assertEqual(x1.grad.numpy(), 1.0) + + x2 = paddle.full([], -1.0, 'float32') + x2.stop_gradient = False + w2 = paddle.full([], 0.25, dtype='float32') + w2.stop_gradient = False + out2 = paddle.nn.functional.prelu(x2, w2) + out2.retain_grads() + out2.backward() + self.assertEqual(out2.shape, []) + self.assertEqual(out2.numpy(), -0.25) + self.assertEqual(out2.grad.shape, []) + self.assertEqual(x2.grad.shape, []) + self.assertEqual(x2.grad.numpy(), 0.25) + # Use to test API whose zero-dim input tensors don't have grad and not need to test backward in OpTest. class TestNoBackwardAPI(unittest.TestCase):