From 3c7b55033780a172703a832a5256a2250d4328a0 Mon Sep 17 00:00:00 2001 From: AyaseNana <13659110308@163.com> Date: Fri, 13 Jun 2025 21:25:31 +0800 Subject: [PATCH] mean accuracy fix --- paddle/phi/kernels/reduce_mean_kernel.cc | 20 +++++++- test/legacy_test/test_mean_op.py | 58 ++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/paddle/phi/kernels/reduce_mean_kernel.cc b/paddle/phi/kernels/reduce_mean_kernel.cc index a657e7ba8c01d..f1d2ed756cff4 100644 --- a/paddle/phi/kernels/reduce_mean_kernel.cc +++ b/paddle/phi/kernels/reduce_mean_kernel.cc @@ -16,6 +16,7 @@ #include "paddle/phi/backends/all_context.h" #include "paddle/phi/core/kernel_registry.h" +#include "paddle/phi/kernels/cast_kernel.h" #include "paddle/phi/kernels/reduce_kernel_impl.h" namespace phi { @@ -27,7 +28,24 @@ void MeanKernel(const Context& dev_ctx, bool keep_dim, DenseTensor* out) { bool reduce_all = recompute_reduce_all(x, dims); - MeanRawKernel(dev_ctx, x, dims, keep_dim, reduce_all, out); + if (std::is_same::value || std::is_same::value || + std::is_same::value) { + using Type = + typename std::conditional::value || + std::is_same::value || + std::is_same::value, + float, + T>::type; + DenseTensor x_float = + phi::Cast(dev_ctx, x, phi::DataType::FLOAT32); + DenseTensor* out_float = new DenseTensor(); + out_float->Resize(out->dims()); + MeanRawKernel( + dev_ctx, x_float, dims, keep_dim, reduce_all, out_float); + phi::CastKernel(dev_ctx, *out_float, x.dtype(), out); + } else { + MeanRawKernel(dev_ctx, x, dims, keep_dim, reduce_all, out); + } } } // namespace phi diff --git a/test/legacy_test/test_mean_op.py b/test/legacy_test/test_mean_op.py index f063de460ab89..449398b21cbbf 100644 --- a/test/legacy_test/test_mean_op.py +++ b/test/legacy_test/test_mean_op.py @@ -806,6 +806,64 @@ def test_errors(self): ) +class TestMeanAPIInt32(unittest.TestCase): + def setUp(self): + self.x_shape = [2, 3, 4, 5] + self.dtype = "int32" + self.x_np = np.random.randint(-1, 10000, self.x_shape).astype( + self.dtype + ) + self.places = [paddle.CPUPlace()] + if core.is_compiled_with_cuda(): + self.places.append(paddle.CUDAPlace(0)) + + def test_dygraph(self): + for place in self.places: + with base.dygraph.guard(place): + x = paddle.to_tensor(self.x_np) + out = paddle.mean(x=x) + np.testing.assert_equal( + out.numpy(), + np.mean(self.x_np.astype("float32")).astype(self.dtype), + ) + + def test_static(self): + paddle.enable_static() + for place in self.places: + with base.program_guard(base.Program(), base.Program()): + x = paddle.static.data( + "x", shape=self.x_shape, dtype=self.dtype + ) + out = paddle.mean(x=x) + exe = base.Executor(place) + res = exe.run(feed={"x": self.x_np}, fetch_list=[out]) + np.testing.assert_equal( + res[0], np.mean(self.x_np.astype("float32")).astype(self.dtype) + ) + + +class TestMeanAPIInt64(TestMeanAPIInt32): + def setUp(self): + self.x_shape = [2, 3, 4, 5] + self.dtype = "int64" + self.x_np = np.random.randint(-1, 10000, self.x_shape).astype( + self.dtype + ) + self.places = [paddle.CPUPlace()] + if core.is_compiled_with_cuda(): + self.places.append(paddle.CUDAPlace(0)) + + +class TestMeanAPIBool(TestMeanAPIInt32): + def setUp(self): + self.x_shape = [2, 3, 4, 5] + self.dtype = "bool" + self.x_np = np.random.uniform(-1, 1, self.x_shape).astype(self.dtype) + self.places = [paddle.CPUPlace()] + if core.is_compiled_with_cuda(): + self.places.append(paddle.CUDAPlace(0)) + + class TestMeanWithTensorAxis1(TestReduceOPTensorAxisBase): def init_data(self): self.pd_api = paddle.mean