diff --git a/paddle/phi/ops/yaml/python_api_info.yaml b/paddle/phi/ops/yaml/python_api_info.yaml index c6619d0fb96e41..f3530e0b29c98e 100644 --- a/paddle/phi/ops/yaml/python_api_info.yaml +++ b/paddle/phi/ops/yaml/python_api_info.yaml @@ -461,7 +461,7 @@ name : [paddle.poisson] args_alias : use_default_mapping : True - + - op : nextafter name : [paddle.nextafter, paddle.Tensor.nextafter] args_alias : diff --git a/python/paddle/tensor/math.py b/python/paddle/tensor/math.py index 119ff9d112cb4e..2eff7fd0d8380f 100644 --- a/python/paddle/tensor/math.py +++ b/python/paddle/tensor/math.py @@ -4249,14 +4249,26 @@ def multigammaln_(x: Tensor, p: int, name: str | None = None) -> Tensor: return x -def neg(x: Tensor, name: str | None = None) -> Tensor: +@param_one_alias(["x", "input"]) +def neg( + x: Tensor, + name: str | None = None, + *, + out: Tensor | None = None +) -> Tensor: """ This function computes the negative of the Tensor elementwisely. Args: - x (Tensor): Input of neg operator, an N-D Tensor, with data type bfloat16, float16, float32, float64, int8, int16, int32, - int64, uint8, complex64, complex128. - name (str|None, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`. + x (Tensor): Input of neg operator, an N-D Tensor, with data type bfloat16, + float16, float32, float64, int8, int16, int32, int64, uint8, + complex64, complex128. + Alias: ``input``. + name (str|None, optional): Name for the operation (optional, default is None). + For more information, please refer to :ref:`api_guide_Name`. + + Keyword args: + out (Tensor|None, optional): The output tensor. Default: None. Returns: out (Tensor): The negative of input Tensor. The shape and data type are the same with input Tensor. @@ -4265,7 +4277,6 @@ def neg(x: Tensor, name: str | None = None) -> Tensor: .. code-block:: pycon >>> import paddle - >>> x = paddle.to_tensor([-0.4, -0.2, 0.1, 0.3]) >>> out = paddle.neg(x) >>> out @@ -4273,10 +4284,21 @@ def neg(x: Tensor, name: str | None = None) -> Tensor: [ 0.40000001, 0.20000000, -0.10000000, -0.30000001]) """ - return scale( - x, scale=-1.0, bias=0.0, bias_after_scale=True, act=None, name=name + ret = scale( + x, + scale=-1.0, + bias=0.0, + bias_after_scale=True, + act=None, + name=name, ) + if out is not None: + paddle.assign(ret, out) + return out + + return ret + @inplace_apis_in_dygraph_only def neg_(x: Tensor, name: str | None = None) -> Tensor: @@ -6899,4 +6921,4 @@ def cartesian_prod(x: Sequence[Tensor], name: str | None = None) -> Tensor: return x[0] coordinates = paddle.stack(paddle.meshgrid(x), axis=-1) - return paddle.reshape(coordinates, [-1, len(x)]) + return paddle.reshape(coordinates, [-1, len(x)]) \ No newline at end of file diff --git a/test/legacy_test/test_api_compatibility.py b/test/legacy_test/test_api_compatibility.py index 6d25c9010f5008..f0293ddc3b2de5 100644 --- a/test/legacy_test/test_api_compatibility.py +++ b/test/legacy_test/test_api_compatibility.py @@ -3275,203 +3275,40 @@ def test_static_Compatibility(self): np.testing.assert_allclose(fetches[i + 1], ref_out[1]) -# Test hstack compatibility -class TestHstackAPI(unittest.TestCase): +# Test neg compatibility +class TestNeg(unittest.TestCase): def setUp(self): np.random.seed(2025) - self.shapes = [[2, 3], [2, 4]] + self.shape = [4] self.dtype = 'float32' - self.inputs = [] - for shape in self.shapes: - self.inputs.append(np.random.rand(*shape).astype(self.dtype)) - - def test_dygraph_Compatibility(self): - paddle.disable_static() - tensors = [paddle.to_tensor(inp) for inp in self.inputs] - - out1 = paddle.hstack(tuple(tensors)) - out2 = paddle.hstack(tensors) - out3 = paddle.hstack(x=tuple(tensors)) - out4 = paddle.hstack(x=tensors) - out5 = paddle.hstack(tensors=tuple(tensors)) - out6 = paddle.hstack(tensors=tensors) - - ref_out = np.hstack(tuple(inp for inp in self.inputs)) - for out in [out1, out2, out3, out4, out5, out6]: - np.testing.assert_allclose( - ref_out, out.numpy(), rtol=1e-5, atol=1e-8 - ) - - paddle.enable_static() - - def test_static_Compatibility(self): - paddle.enable_static() - main = paddle.static.Program() - startup = paddle.static.Program() - with paddle.base.program_guard(main, startup): - static_tensors = [] - feed_dict = {} - for i, (shape, inp) in enumerate(zip(self.shapes, self.inputs)): - static_tensor = paddle.static.data( - name=f"x{i}", shape=shape, dtype=self.dtype - ) - static_tensors.append(static_tensor) - feed_dict[f"x{i}"] = inp - - out1 = paddle.hstack(tuple(static_tensors)) - out2 = paddle.hstack(static_tensors) - out3 = paddle.hstack(x=tuple(static_tensors)) - out4 = paddle.hstack(tensors=tuple(static_tensors)) - - exe = paddle.base.Executor(paddle.CPUPlace()) - fetches = exe.run( - main, feed=feed_dict, fetch_list=[out1, out2, out3, out4] - ) - ref_out = np.hstack(tuple(inp for inp in self.inputs)) - for out in fetches: - np.testing.assert_allclose(out, ref_out, rtol=1e-5, atol=1e-8) - - -class TestVstackAPI(unittest.TestCase): - def setUp(self): - np.random.seed(2025) - self.shapes = [[2, 3], [3, 3]] - self.dtype = 'float32' - self.inputs = [] - for shape in self.shapes: - self.inputs.append(np.random.rand(*shape).astype(self.dtype)) - - def test_dygraph_Compatibility(self): - paddle.disable_static() - tensors = [paddle.to_tensor(inp) for inp in self.inputs] - out1 = paddle.vstack(tuple(tensors)) - out2 = paddle.vstack(tensors) - out3 = paddle.vstack(x=tuple(tensors)) - out4 = paddle.vstack(x=tensors) - out5 = paddle.vstack(tensors=tuple(tensors)) - out6 = paddle.vstack(tensors=tensors) - - ref_out = np.vstack(tuple(inp for inp in self.inputs)) - for out in [out1, out2, out3, out4, out5, out6]: - np.testing.assert_allclose( - ref_out, out.numpy(), rtol=1e-5, atol=1e-8 - ) - - paddle.enable_static() - - def test_static_Compatibility(self): - paddle.enable_static() - main = paddle.static.Program() - startup = paddle.static.Program() - with paddle.base.program_guard(main, startup): - static_tensors = [] - feed_dict = {} - for i, (shape, inp) in enumerate(zip(self.shapes, self.inputs)): - static_tensor = paddle.static.data( - name=f"x{i}", shape=shape, dtype=self.dtype - ) - static_tensors.append(static_tensor) - feed_dict[f"x{i}"] = inp - - out1 = paddle.vstack(tuple(static_tensors)) - out2 = paddle.vstack(static_tensors) - out3 = paddle.vstack(x=tuple(static_tensors)) - out4 = paddle.vstack(tensors=tuple(static_tensors)) - - exe = paddle.base.Executor(paddle.CPUPlace()) - fetches = exe.run( - main, feed=feed_dict, fetch_list=[out1, out2, out3, out4] - ) - - ref_out = np.vstack(tuple(inp for inp in self.inputs)) - for out in fetches: - np.testing.assert_allclose(out, ref_out, rtol=1e-5, atol=1e-8) - + self.init_data() -# Test dstack compatibility -class TestDstackAPI(unittest.TestCase): - def setUp(self): - np.random.seed(2025) - self.shapes = [[2, 3, 4], [2, 3, 4]] - self.dtype = 'float32' - self.inputs = [] - for shape in self.shapes: - self.inputs.append(np.random.rand(*shape).astype(self.dtype)) + def init_data(self): + self.np_x = np.random.rand(*self.shape).astype(self.dtype) def test_dygraph_Compatibility(self): paddle.disable_static() - tensors = [paddle.to_tensor(inp) for inp in self.inputs] - out1 = paddle.dstack(tuple(tensors)) - out2 = paddle.dstack(tensors) - out3 = paddle.dstack(x=tuple(tensors)) - out4 = paddle.dstack(x=tensors) - out5 = paddle.dstack(tensors=tuple(tensors)) - out6 = paddle.dstack(tensors=tensors) - - # Verify all outputs - ref_out = np.dstack(tuple(inp for inp in self.inputs)) - for out in [out1, out2, out3, out4, out5, out6]: - np.testing.assert_allclose( - ref_out, out.numpy(), rtol=1e-5, atol=1e-8 - ) - - paddle.enable_static() - - def test_static_Compatibility(self): - paddle.enable_static() - main = paddle.static.Program() - startup = paddle.static.Program() - with paddle.base.program_guard(main, startup): - static_tensors = [] - feed_dict = {} - for i, (shape, inp) in enumerate(zip(self.shapes, self.inputs)): - static_tensor = paddle.static.data( - name=f"x{i}", shape=shape, dtype=self.dtype - ) - static_tensors.append(static_tensor) - feed_dict[f"x{i}"] = inp - - out1 = paddle.dstack(tuple(static_tensors)) - out2 = paddle.dstack(static_tensors) - out3 = paddle.dstack(x=tuple(static_tensors)) - out4 = paddle.dstack(tensors=tuple(static_tensors)) - - exe = paddle.base.Executor(paddle.CPUPlace()) - fetches = exe.run( - main, feed=feed_dict, fetch_list=[out1, out2, out3, out4] - ) - - ref_out = np.dstack(tuple(inp for inp in self.inputs)) - for out in fetches: - np.testing.assert_allclose(out, ref_out, rtol=1e-5, atol=1e-8) - - -# Test column_stack compatibility -class TestColumnStackAPI(unittest.TestCase): - def setUp(self): - np.random.seed(2025) - self.shapes = [[3, 2], [3, 3]] - self.dtype = 'float32' - self.inputs = [] - for shape in self.shapes: - self.inputs.append(np.random.rand(*shape).astype(self.dtype)) + x = paddle.to_tensor(self.np_x) - def test_dygraph_Compatibility(self): - paddle.disable_static() - tensors = [paddle.to_tensor(inp) for inp in self.inputs] - out1 = paddle.column_stack(tuple(tensors)) - out2 = paddle.column_stack(tensors) - out3 = paddle.column_stack(x=tuple(tensors)) - out4 = paddle.column_stack(x=tensors) - out5 = paddle.column_stack(tensors=tuple(tensors)) - out6 = paddle.column_stack(tensors=tensors) + # 1. Paddle Positional arguments + out1 = paddle.neg(x) + # 2. Paddle keyword arguments + out2 = paddle.neg(x=x) + # 3. PyTorch keyword arguments (alias) + out3 = paddle.neg(input=x) + # 4. Mixed arguments + out4 = paddle.neg(x, name=None) + # 5. out parameter test + out5 = paddle.empty_like(x) + out6 = paddle.neg(x=x, out=out5) + # 6. Tensor method - args + out7 = x.neg() + # 7. Tensor method - kwargs + out8 = x.neg(name=None) # Verify all outputs - ref_out = np.column_stack(tuple(inp for inp in self.inputs)) - for out in [out1, out2, out3, out4, out5, out6]: - np.testing.assert_allclose( - ref_out, out.numpy(), rtol=1e-5, atol=1e-8 - ) + for out in [out1, out2, out3, out4, out5, out6, out7, out8]: + np.testing.assert_allclose(out.numpy(), -self.np_x, rtol=1e-6) paddle.enable_static() @@ -3479,91 +3316,27 @@ def test_static_Compatibility(self): paddle.enable_static() main = paddle.static.Program() startup = paddle.static.Program() - with paddle.base.program_guard(main, startup): - static_tensors = [] - feed_dict = {} - for i, (shape, inp) in enumerate(zip(self.shapes, self.inputs)): - static_tensor = paddle.static.data( - name=f"x{i}", shape=shape, dtype=self.dtype - ) - static_tensors.append(static_tensor) - feed_dict[f"x{i}"] = inp - - out1 = paddle.column_stack(tuple(static_tensors)) - out2 = paddle.column_stack(static_tensors) - out3 = paddle.column_stack(x=tuple(static_tensors)) - out4 = paddle.column_stack(tensors=tuple(static_tensors)) - - exe = paddle.base.Executor(paddle.CPUPlace()) - fetches = exe.run( - main, feed=feed_dict, fetch_list=[out1, out2, out3, out4] - ) - - ref_out = np.column_stack(tuple(inp for inp in self.inputs)) - for out in fetches: - np.testing.assert_allclose(out, ref_out, rtol=1e-5, atol=1e-8) - - -# Test row_stack compatibility -class TestRowStackAPI(unittest.TestCase): - def setUp(self): - np.random.seed(2025) - self.shapes = [[2, 3], [4, 3]] - self.dtype = 'float32' - self.inputs = [] - for shape in self.shapes: - self.inputs.append(np.random.rand(*shape).astype(self.dtype)) - - def test_dygraph_Compatibility(self): - paddle.disable_static() - tensors = [paddle.to_tensor(inp) for inp in self.inputs] - out1 = paddle.row_stack(tuple(tensors)) - out2 = paddle.row_stack(tensors) - out3 = paddle.row_stack(x=tuple(tensors)) - - out4 = paddle.row_stack(x=tensors) - - out5 = paddle.row_stack(tensors=tuple(tensors)) - - out6 = paddle.row_stack(tensors=tensors) - - # Verify all outputs - ref_out = np.vstack(tuple(inp for inp in self.inputs)) - for out in [out1, out2, out3, out4, out5, out6]: - np.testing.assert_allclose( - ref_out, out.numpy(), rtol=1e-5, atol=1e-8 - ) + with paddle.static.program_guard(main, startup): + x = paddle.static.data(name="x", shape=self.shape, dtype=self.dtype) - paddle.enable_static() + # 1. Paddle Positional arguments + out1 = paddle.neg(x) + # 2. Paddle keyword arguments + out2 = paddle.neg(x=x) + # 3. PyTorch keyword arguments (alias) + out3 = paddle.neg(input=x) - def test_static_Compatibility(self): - paddle.enable_static() - main = paddle.static.Program() - startup = paddle.static.Program() - with paddle.base.program_guard(main, startup): - static_tensors = [] - feed_dict = {} - for i, (shape, inp) in enumerate(zip(self.shapes, self.inputs)): - static_tensor = paddle.static.data( - name=f"x{i}", shape=shape, dtype=self.dtype - ) - static_tensors.append(static_tensor) - feed_dict[f"x{i}"] = inp - - out1 = paddle.row_stack(tuple(static_tensors)) - out2 = paddle.row_stack(static_tensors) - out3 = paddle.row_stack(x=tuple(static_tensors)) - out4 = paddle.row_stack(tensors=tuple(static_tensors)) - - exe = paddle.base.Executor(paddle.CPUPlace()) + exe = paddle.static.Executor() fetches = exe.run( - main, feed=feed_dict, fetch_list=[out1, out2, out3, out4] + main, + feed={"x": self.np_x}, + fetch_list=[out1, out2, out3], ) - ref_out = np.vstack(tuple(inp for inp in self.inputs)) + # Verify all outputs for out in fetches: - np.testing.assert_allclose(out, ref_out, rtol=1e-5, atol=1e-8) + np.testing.assert_allclose(out, -self.np_x, rtol=1e-6) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file