From ad015185de10421f39b2b3967e23af596fb4d91c Mon Sep 17 00:00:00 2001 From: enkilee Date: Thu, 29 May 2025 17:00:50 +0800 Subject: [PATCH 1/7] fix --- paddle/phi/kernels/impl/nextafter_kernel_impl.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/paddle/phi/kernels/impl/nextafter_kernel_impl.h b/paddle/phi/kernels/impl/nextafter_kernel_impl.h index e4ed11a6be5c66..d8fbd3746bcc9b 100644 --- a/paddle/phi/kernels/impl/nextafter_kernel_impl.h +++ b/paddle/phi/kernels/impl/nextafter_kernel_impl.h @@ -71,6 +71,11 @@ void NextafterKernel(const Context& ctx, const DenseTensor& x, const DenseTensor& y, DenseTensor* out) { + if (x.numel() == 0 || y.numel() == 0) { + ctx.template Alloc::type>(out); + return; + } + auto* out_data = ctx.template Alloc(out); auto x_data = x.data(); auto y_data = y.data(); From 5daf7d99a79a52ceb42f19971463ef7e369e1b5e Mon Sep 17 00:00:00 2001 From: enkilee Date: Thu, 29 May 2025 17:14:16 +0800 Subject: [PATCH 2/7] add test --- test/legacy_test/test_nextafter_op.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/legacy_test/test_nextafter_op.py b/test/legacy_test/test_nextafter_op.py index 872ff56304bbb7..b651eb083ed43f 100644 --- a/test/legacy_test/test_nextafter_op.py +++ b/test/legacy_test/test_nextafter_op.py @@ -114,5 +114,31 @@ def init_dtype(self): self.dtype = np.float32 +class TestNextafterOPZeroDim1(TestNextafterOP): + def setUp(self): + self.op_type = "nextafter" + self.python_api = paddle.nextafter + self.init_dtype() + + x = np.random.rand(0, 3, 2).astype(self.dtype) + y = np.random.rand(0, 3, 2).astype(self.dtype) + out = np.nextafter(x, y) + self.inputs = {'x': x, 'y': y} + self.outputs = {'out': out} + + +class TestNextafterOPZeroDim2(TestNextafterOP): + def setUp(self): + self.op_type = "nextafter" + self.python_api = paddle.nextafter + self.init_dtype() + + x = np.random.rand(4, 0, 2).astype(self.dtype) + y = np.random.rand(4, 0, 2).astype(self.dtype) + out = np.nextafter(x, y) + self.inputs = {'x': x, 'y': y} + self.outputs = {'out': out} + + if __name__ == "__main__": unittest.main() From 950c05c8e69d1f16de05f184ff378a605035212e Mon Sep 17 00:00:00 2001 From: enkilee Date: Tue, 3 Jun 2025 14:52:42 +0800 Subject: [PATCH 3/7] fix --- paddle/phi/kernels/impl/nextafter_kernel_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/phi/kernels/impl/nextafter_kernel_impl.h b/paddle/phi/kernels/impl/nextafter_kernel_impl.h index d8fbd3746bcc9b..30c2b409677290 100644 --- a/paddle/phi/kernels/impl/nextafter_kernel_impl.h +++ b/paddle/phi/kernels/impl/nextafter_kernel_impl.h @@ -72,7 +72,7 @@ void NextafterKernel(const Context& ctx, const DenseTensor& y, DenseTensor* out) { if (x.numel() == 0 || y.numel() == 0) { - ctx.template Alloc::type>(out); + ctx.template Alloc(out); return; } From 8cd54e8532abacf3772fc338bcf67e5b1ef8a98c Mon Sep 17 00:00:00 2001 From: enkilee Date: Fri, 6 Jun 2025 08:39:13 +0800 Subject: [PATCH 4/7] merge and fix --- paddle/phi/kernels/cpu/elementwise_kernel.cc | 24 +++++ paddle/phi/kernels/cpu/nextafter_kernel.cc | 22 ----- .../phi/kernels/funcs/elementwise_functor.h | 51 ++++++++++ paddle/phi/kernels/gpu/nextafter_kernel.cu | 22 ----- .../phi/kernels/impl/nextafter_kernel_impl.h | 98 ------------------- paddle/phi/kernels/kps/elementwise_kernel.cu | 20 ++++ paddle/phi/kernels/nextafter_kernel.h | 28 ------ test/legacy_test/test_nextafter_op.py | 39 +++++++- 8 files changed, 132 insertions(+), 172 deletions(-) delete mode 100644 paddle/phi/kernels/cpu/nextafter_kernel.cc delete mode 100644 paddle/phi/kernels/gpu/nextafter_kernel.cu delete mode 100644 paddle/phi/kernels/impl/nextafter_kernel_impl.h delete mode 100644 paddle/phi/kernels/nextafter_kernel.h diff --git a/paddle/phi/kernels/cpu/elementwise_kernel.cc b/paddle/phi/kernels/cpu/elementwise_kernel.cc index 0605b4846ae390..1c0a3ff737dded 100644 --- a/paddle/phi/kernels/cpu/elementwise_kernel.cc +++ b/paddle/phi/kernels/cpu/elementwise_kernel.cc @@ -106,6 +106,27 @@ void CopySignKernel(const Context& dev_ctx, } } +template +void NextafterKernel(const Context& dev_ctx, + const DenseTensor& x, + const DenseTensor& y, + DenseTensor* out) { + if (x.numel() == 0 || y.numel() == 0) { + ctx.template Alloc(out); + return; + } + dev_ctx.template Alloc(out); + auto x_dims = x.dims(); + auto y_dims = y.dims(); + if (x_dims.size() >= y_dims.size()) { + funcs::ElementwiseCompute, T>( + dev_ctx, x, y, funcs ::NextafterFunctor(), out); + } else { + funcs::ElementwiseCompute, T>( + dev_ctx, x, y, funcs::InverseNextafterFunctor(), out); + } +} + } // namespace phi using complex64 = ::phi::dtype::complex; @@ -193,3 +214,6 @@ PD_REGISTER_KERNEL(copysign, double, phi::dtype::float16, phi::dtype::bfloat16) {} + +PD_REGISTER_KERNEL( + nextafter, CPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} diff --git a/paddle/phi/kernels/cpu/nextafter_kernel.cc b/paddle/phi/kernels/cpu/nextafter_kernel.cc deleted file mode 100644 index ac4ab00a4d3fe9..00000000000000 --- a/paddle/phi/kernels/cpu/nextafter_kernel.cc +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "paddle/phi/kernels/nextafter_kernel.h" - -#include "paddle/phi/backends/cpu/cpu_context.h" -#include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/nextafter_kernel_impl.h" - -PD_REGISTER_KERNEL( - nextafter, CPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} diff --git a/paddle/phi/kernels/funcs/elementwise_functor.h b/paddle/phi/kernels/funcs/elementwise_functor.h index 37ce9ca44d1244..2373d38925e474 100644 --- a/paddle/phi/kernels/funcs/elementwise_functor.h +++ b/paddle/phi/kernels/funcs/elementwise_functor.h @@ -1174,5 +1174,56 @@ struct InverseCopySignFunctor { } }; +template +struct NextafterFunctor { + inline HOSTDEVICE T operator()(const T x, const T y) const { + return static_cast( + std::nextafter(static_cast(x), static_cast(y))); + } +}; + +template +struct NextafterFunctor< + T, + typename std::enable_if_t::value>> { + inline HOSTDEVICE T operator()(const T x, const T y) const { + return std::nextafter(x, y); + } +}; + +template +struct NextafterFunctor::value>> { + inline HOSTDEVICE double operator()(const T x, const T y) const { + return std::nextafter(static_cast(x), static_cast(y)); + } +}; + +template +struct InverseNextafterFunctor { + inline HOSTDEVICE T operator()(const T x, const T y) const { + return static_cast( + std::nextafter(static_cast(y), static_cast(x))); + } +}; + +template +struct InverseNextafterFunctor< + T, + typename std::enable_if_t::value>> { + inline HOSTDEVICE T operator()(const T x, const T y) const { + return std::nextafter(y, x); + } +}; + +template +struct InverseNextafterFunctor< + T, + typename std::enable_if_t::value>> { + inline HOSTDEVICE double operator()(const T x, const T y) const { + return std::nextafter(static_cast(y), static_cast(x)); + } +}; + } // namespace funcs } // namespace phi diff --git a/paddle/phi/kernels/gpu/nextafter_kernel.cu b/paddle/phi/kernels/gpu/nextafter_kernel.cu deleted file mode 100644 index e0ac8212853c98..00000000000000 --- a/paddle/phi/kernels/gpu/nextafter_kernel.cu +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "paddle/phi/kernels/nextafter_kernel.h" - -#include "paddle/phi/backends/gpu/gpu_context.h" -#include "paddle/phi/core/kernel_registry.h" -#include "paddle/phi/kernels/impl/nextafter_kernel_impl.h" - -PD_REGISTER_KERNEL( - nextafter, GPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} diff --git a/paddle/phi/kernels/impl/nextafter_kernel_impl.h b/paddle/phi/kernels/impl/nextafter_kernel_impl.h deleted file mode 100644 index 30c2b409677290..00000000000000 --- a/paddle/phi/kernels/impl/nextafter_kernel_impl.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -#pragma once -#include -#include "paddle/phi/core/dense_tensor.h" -#include "paddle/phi/core/device_context.h" -#include "paddle/phi/kernels/funcs/for_range.h" -#include "paddle/phi/kernels/funcs/math.h" -#include "paddle/phi/kernels/nextafter_kernel.h" -namespace phi { -template -struct NextafterOut { - using type = T; -}; - -template <> -struct NextafterOut { - using type = double; -}; - -template <> -struct NextafterOut { - using type = double; -}; -template -struct NextafterFunctor { - NextafterFunctor(const T* x, - const T* y, - typename NextafterOut::type* out, - int64_t numel) - : x_(x), y_(y), out_(out), numel_(numel) {} - - HOSTDEVICE void operator()(int64_t idx) const { - out_[idx] = static_cast::type>(std::nextafter( - static_cast(x_[idx]), static_cast(y_[idx]))); - } - const T* x_; - const T* y_; - typename NextafterOut::type* out_; - int64_t numel_; -}; -template <> -struct NextafterFunctor { - NextafterFunctor(const double* x, const double* y, double* out, int64_t numel) - : x_(x), y_(y), out_(out), numel_(numel) {} - - HOSTDEVICE void operator()(int64_t idx) const { - out_[idx] = std::nextafter(x_[idx], y_[idx]); - } - - const double* x_; - const double* y_; - double* out_; - int64_t numel_; -}; - -template -void NextafterKernel(const Context& ctx, - const DenseTensor& x, - const DenseTensor& y, - DenseTensor* out) { - if (x.numel() == 0 || y.numel() == 0) { - ctx.template Alloc(out); - return; - } - - auto* out_data = ctx.template Alloc(out); - auto x_data = x.data(); - auto y_data = y.data(); - auto x_numel = x.numel(); - - if (x.dims().size() != 0 && y.dims().size() != 0) { - PADDLE_ENFORCE_EQ( - x.dims(), - y.dims(), - errors::InvalidArgument( - "x and y must have same shape, but x.shape = %s, y.shape = %s.", - x.dims(), - y.dims())); - } - phi::funcs::ForRange for_range(ctx, x_numel); - phi::NextafterFunctor functor(x_data, y_data, out_data, x_numel); - for_range(functor); -} - -} // namespace phi diff --git a/paddle/phi/kernels/kps/elementwise_kernel.cu b/paddle/phi/kernels/kps/elementwise_kernel.cu index 1cebd45023ece3..9fafca5dbc69b5 100644 --- a/paddle/phi/kernels/kps/elementwise_kernel.cu +++ b/paddle/phi/kernels/kps/elementwise_kernel.cu @@ -199,6 +199,23 @@ void CopySignKernel(const Context& dev_ctx, dev_ctx, inputs, &outputs, funcs::CopySignFunctor()); } +template +void NextafterKernel(const Context& dev_ctx, + const DenseTensor& x, + const DenseTensor& y, + DenseTensor* out) { + if (x.numel() == 0 || y.numel() == 0) { + ctx.template Alloc(out); + return; + } + std::vector inputs = {&x, &y}; + std::vector outputs = {out}; + + dev_ctx.template Alloc(out); + funcs::BroadcastKernel( + dev_ctx, inputs, &outputs, funcs::NextafterFunctor()); +} + } // namespace phi #if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP) @@ -273,6 +290,9 @@ PD_REGISTER_KERNEL(copysign, phi::dtype::float16, phi::dtype::bfloat16) {} +PD_REGISTER_KERNEL( + nextafter, GPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} + #endif #ifdef PADDLE_WITH_XPU_KP diff --git a/paddle/phi/kernels/nextafter_kernel.h b/paddle/phi/kernels/nextafter_kernel.h deleted file mode 100644 index 3a185e39bd9407..00000000000000 --- a/paddle/phi/kernels/nextafter_kernel.h +++ /dev/null @@ -1,28 +0,0 @@ - -// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "paddle/phi/core/dense_tensor.h" - -namespace phi { - -template -void NextafterKernel(const Context& dev_ctx, - const DenseTensor& x, - const DenseTensor& y, - DenseTensor* out); - -} // namespace phi diff --git a/test/legacy_test/test_nextafter_op.py b/test/legacy_test/test_nextafter_op.py index b651eb083ed43f..daacd63cef820f 100644 --- a/test/legacy_test/test_nextafter_op.py +++ b/test/legacy_test/test_nextafter_op.py @@ -95,9 +95,10 @@ def setUp(self): self.op_type = "nextafter" self.python_api = paddle.nextafter self.init_dtype() + self.init_shape() - x = np.array([1, 2]).astype(self.dtype) - y = np.array([2, 1]).astype(self.dtype) + x = np.random.rand(*self.x_shape).astype(self.dtype) + y = np.random.rand(*self.y_shape).astype(self.dtype) out = np.nextafter(x, y) self.inputs = {'x': x, 'y': y} self.outputs = {'out': out} @@ -108,12 +109,46 @@ def test_check_output(self): def init_dtype(self): self.dtype = np.float64 + def init_shape(self): + self.x_shape = (2,) + self.y_shape = (2,) + class TestNextafterOPFP32(TestNextafterOP): def init_dtype(self): self.dtype = np.float32 +class TestNextafterOPFP32Case1(TestNextafterOP): + def init_dtype(self): + self.dtype = np.float32 + + def init_shape(self): + self.x_shape = (5,) + self.y_shape = (2, 3, 4, 5) + + +class TestNextafterOPFP32Case2(TestNextafterOP): + def init_dtype(self): + self.dtype = np.float32 + + def init_shape(self): + self.x_shape = (2, 3, 4, 5) + self.y_shape = (1,) + + +class TestNextafterOPCase1(TestNextafterOP): + def init_shape(self): + self.x_shape = (5,) + self.y_shape = (2, 3, 4, 5) + + +class TestNextafterOPCase2(TestNextafterOP): + def init_shape(self): + self.x_shape = (2, 3, 4, 5) + self.y_shape = (1,) + + class TestNextafterOPZeroDim1(TestNextafterOP): def setUp(self): self.op_type = "nextafter" From e0a32aa9d6a775ad512ddb2feeece77cb36fad53 Mon Sep 17 00:00:00 2001 From: enkilee Date: Fri, 6 Jun 2025 09:16:45 +0800 Subject: [PATCH 5/7] fix error --- paddle/phi/kernels/cpu/elementwise_kernel.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/phi/kernels/cpu/elementwise_kernel.cc b/paddle/phi/kernels/cpu/elementwise_kernel.cc index 1c0a3ff737dded..dbffe04a1d5367 100644 --- a/paddle/phi/kernels/cpu/elementwise_kernel.cc +++ b/paddle/phi/kernels/cpu/elementwise_kernel.cc @@ -112,7 +112,7 @@ void NextafterKernel(const Context& dev_ctx, const DenseTensor& y, DenseTensor* out) { if (x.numel() == 0 || y.numel() == 0) { - ctx.template Alloc(out); + dev_ctx.template Alloc(out); return; } dev_ctx.template Alloc(out); From 847fef598f48184db8710088373906a1f1ae331c Mon Sep 17 00:00:00 2001 From: enkilee Date: Fri, 6 Jun 2025 09:40:10 +0800 Subject: [PATCH 6/7] fix error --- paddle/phi/kernels/kps/elementwise_kernel.cu | 3 --- 1 file changed, 3 deletions(-) diff --git a/paddle/phi/kernels/kps/elementwise_kernel.cu b/paddle/phi/kernels/kps/elementwise_kernel.cu index af788adc4b89bf..93e680f07e0263 100644 --- a/paddle/phi/kernels/kps/elementwise_kernel.cu +++ b/paddle/phi/kernels/kps/elementwise_kernel.cu @@ -288,9 +288,6 @@ PD_REGISTER_KERNEL(copysign, PD_REGISTER_KERNEL( nextafter, GPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} -PD_REGISTER_KERNEL( - nextafter, GPU, ALL_LAYOUT, phi::NextafterKernel, float, double) {} - #endif #ifdef PADDLE_WITH_XPU_KP From 8a159bf748460f23e39f592883ea52d6c935f861 Mon Sep 17 00:00:00 2001 From: enkilee Date: Fri, 6 Jun 2025 11:34:08 +0800 Subject: [PATCH 7/7] fix error --- paddle/phi/kernels/kps/elementwise_kernel.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paddle/phi/kernels/kps/elementwise_kernel.cu b/paddle/phi/kernels/kps/elementwise_kernel.cu index 93e680f07e0263..94033f1fa1015a 100644 --- a/paddle/phi/kernels/kps/elementwise_kernel.cu +++ b/paddle/phi/kernels/kps/elementwise_kernel.cu @@ -202,7 +202,7 @@ void NextafterKernel(const Context& dev_ctx, const DenseTensor& y, DenseTensor* out) { if (x.numel() == 0 || y.numel() == 0) { - ctx.template Alloc(out); + dev_ctx.template Alloc(out); return; } std::vector inputs = {&x, &y};