From 423dda377c507f8c84a6604f0e117f2ec78d0672 Mon Sep 17 00:00:00 2001 From: lijin23 <41257772+lj970926@users.noreply.github.com> Date: Mon, 22 May 2023 14:22:37 +0800 Subject: [PATCH] [XPU][PHI Kernels] fix errors when numel is zero for xpu (#54010) * fix empty bugs for xpu * fix empty bugs for xpu --- paddle/phi/kernels/xpu/cast_kernel.cc | 100 +++++++++--------------- paddle/phi/kernels/xpu/gather_kernel.cc | 2 +- paddle/phi/kernels/xpu/scale_kernel.cc | 7 +- test/xpu/test_cast_op_xpu.py | 12 +++ test/xpu/test_gather_op_xpu.py | 12 +++ test/xpu/test_scale_op_xpu.py | 11 +++ 6 files changed, 77 insertions(+), 67 deletions(-) diff --git a/paddle/phi/kernels/xpu/cast_kernel.cc b/paddle/phi/kernels/xpu/cast_kernel.cc index 74e2a622dba..c5fd2d02e33 100644 --- a/paddle/phi/kernels/xpu/cast_kernel.cc +++ b/paddle/phi/kernels/xpu/cast_kernel.cc @@ -15,90 +15,66 @@ #include "paddle/phi/kernels/cast_kernel.h" #include "paddle/phi/backends/xpu/enforce_xpu.h" -#include "paddle/phi/backends/xpu/xpu_context.h" -#include "paddle/phi/backends/xpu/xpu_header.h" -#include "paddle/phi/common/float16.h" -#include "paddle/phi/core/enforce.h" #include "paddle/phi/core/kernel_registry.h" namespace phi { +template +void CastXPUKernelImpl(const Context& dev_ctx, + const DenseTensor& x, + DenseTensor* out) { + using XPUInT = typename XPUTypeTrait::Type; + using XPUOutT = typename XPUTypeTrait::Type; + + const auto* in_data = x.data(); + auto* out_data = dev_ctx.template Alloc(out); + auto numel = x.numel(); + + if (numel == 0) { + return; + } + + int r = xpu::cast(dev_ctx.x_context(), + reinterpret_cast(in_data), + reinterpret_cast(out_data), + numel); + + PADDLE_ENFORCE_XDNN_SUCCESS(r, "cast"); +} template void CastKernel(const Context& dev_ctx, const DenseTensor& x, DataType out_dtype, DenseTensor* out) { - using XPUInTDType = typename XPUTypeTrait::Type; - using XPUTypeFP16 = typename XPUTypeTrait::Type; - - auto* in_data = x.data(); - auto numel = x.numel(); - - int r = -1; switch (out_dtype) { - case phi::DataType::FLOAT32: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::INT32: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::FLOAT16: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - reinterpret_cast( - dev_ctx.template Alloc(out)), - numel); + case DataType::FLOAT32: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::INT64: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::FLOAT16: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::INT32: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::INT64: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::BOOL: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::BOOL: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::INT8: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::INT8: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::UINT8: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::UINT8: + CastXPUKernelImpl(dev_ctx, x, out); break; - case phi::DataType::FLOAT64: - r = xpu::cast( - dev_ctx.x_context(), - reinterpret_cast(in_data), - dev_ctx.template Alloc(out), - numel); + case DataType::FLOAT64: + CastXPUKernelImpl(dev_ctx, x, out); break; default: PADDLE_THROW(phi::errors::Unavailable( "Not supported cast %d -> %d", x.dtype(), out_dtype)); } - - PADDLE_ENFORCE_XDNN_SUCCESS(r, "cast"); } } // namespace phi diff --git a/paddle/phi/kernels/xpu/gather_kernel.cc b/paddle/phi/kernels/xpu/gather_kernel.cc index 658999c5289..bcbd859cd4d 100644 --- a/paddle/phi/kernels/xpu/gather_kernel.cc +++ b/paddle/phi/kernels/xpu/gather_kernel.cc @@ -29,7 +29,7 @@ void GatherKernel(const Context& dev_ctx, const auto& index_type = index.dtype(); dev_ctx.template Alloc(out); - if (x.numel() == 0) return; + if (x.numel() == 0 || index.numel() == 0) return; const auto index_dims = index.dims(); if (index_dims.size() == 2) { diff --git a/paddle/phi/kernels/xpu/scale_kernel.cc b/paddle/phi/kernels/xpu/scale_kernel.cc index cc8bdf6165e..4d84e186062 100644 --- a/paddle/phi/kernels/xpu/scale_kernel.cc +++ b/paddle/phi/kernels/xpu/scale_kernel.cc @@ -15,10 +15,6 @@ #include "paddle/phi/kernels/scale_kernel.h" #include "paddle/phi/backends/xpu/enforce_xpu.h" -#include "paddle/phi/backends/xpu/xpu_context.h" -#include "paddle/phi/common/data_type.h" -#include "paddle/phi/common/float16.h" -#include "paddle/phi/core/compat/convert_utils.h" #include "paddle/phi/core/kernel_registry.h" namespace phi { @@ -39,6 +35,9 @@ void ScaleKernel(const Context& dev_ctx, " expected %s, but got %s.", x.dims().to_str().c_str(), out->dims().to_str().c_str())); + if (x.numel() == 0 || !x.IsInitialized()) { + return; + } using XPUType = typename XPUTypeTrait::Type; int r = xpu::scale(dev_ctx.x_context(), reinterpret_cast(x.data()), diff --git a/test/xpu/test_cast_op_xpu.py b/test/xpu/test_cast_op_xpu.py index baf814e08de..fbfe6e979e7 100644 --- a/test/xpu/test_cast_op_xpu.py +++ b/test/xpu/test_cast_op_xpu.py @@ -99,6 +99,18 @@ class TestCastOpError(unittest.TestCase): self.assertRaises(TypeError, paddle.cast, x1, 'int32') +class TestCastOpEmpty(unittest.TestCase): + def test_cast_op_empty(self): + if paddle.is_compiled_with_xpu(): + paddle.set_device('xpu') + paddle.disable_static() + data = paddle.ones([0, 10], dtype='float32') + out = paddle.cast(data, 'int32') + self.assertEqual(out.shape, data.shape) + self.assertEqual(out.dtype, paddle.int32) + paddle.enable_static() + + if __name__ == '__main__': paddle.enable_static() unittest.main() diff --git a/test/xpu/test_gather_op_xpu.py b/test/xpu/test_gather_op_xpu.py index 0d132e7185e..bef509edae7 100644 --- a/test/xpu/test_gather_op_xpu.py +++ b/test/xpu/test_gather_op_xpu.py @@ -112,6 +112,18 @@ class XPUTestGather(XPUOpTestWrapper): self.index_type = np.int64 +class TestGatherOpEmpty(unittest.TestCase): + def test_gather_empty_index(self): + if paddle.is_compiled_with_xpu(): + paddle.set_device('xpu') + paddle.disable_static() + data = paddle.ones([10], dtype='int32') + index = paddle.ones([], dtype='int32') + out = paddle.gather(data, index) + self.assertEqual(out.shape, index.shape) + paddle.enable_static() + + support_types = get_xpu_op_support_types('gather') for stype in support_types: create_test_class(globals(), XPUTestGather, stype) diff --git a/test/xpu/test_scale_op_xpu.py b/test/xpu/test_scale_op_xpu.py index fbc3b7f8208..8ad7800fe23 100644 --- a/test/xpu/test_scale_op_xpu.py +++ b/test/xpu/test_scale_op_xpu.py @@ -136,6 +136,17 @@ class TestScaleInplaceApiDygraph(TestScaleApiDygraph): return x.scale_(scale, bias) +class TestScaleOpZeroNumelVariable(unittest.TestCase): + def test_check_zero_numel_xpu(self): + if paddle.is_compiled_with_xpu(): + paddle.disable_static() + paddle.set_device('xpu') + data = paddle.ones([0, 1]) + out = paddle.scale(data, 2) + self.assertEqual(out.shape, data.shape) + paddle.enable_static() + + support_types = get_xpu_op_support_types('scale') for stype in support_types: create_test_class(globals(), XPUTestScaleOp, stype) -- GitLab