From 03a43c35a26510bba3bdd9f6e4416a3b6d383b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Sun, 21 Apr 2024 23:36:40 +0800 Subject: [PATCH 01/22] add api --- python/paddle/nn/__init__.py | 7 ++ python/paddle/nn/layer/__init__.py | 5 + python/paddle/nn/layer/padding.py | 142 +++++++++++++++++++++++++++ python/paddle/tensor/manipulation.py | 28 ++++++ 4 files changed, 182 insertions(+) create mode 100644 python/paddle/nn/layer/padding.py diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index 7818c2398494d2..c9845bea6d0cd2 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -72,6 +72,11 @@ ZeroPad2D, ) +from .layer.padding import ( + ZeroPad1D, + ZeroPad3D, +) + # TODO: import all neural network related api under this directory, # including layers, linear, conv, rnn etc. from .layer.container import LayerDict, LayerList, ParameterList, Sequential @@ -298,4 +303,6 @@ 'Unflatten', 'FractionalMaxPool2D', 'FractionalMaxPool3D', + 'ZeroPad1D', + 'ZeroPad3D', ] diff --git a/python/paddle/nn/layer/__init__.py b/python/paddle/nn/layer/__init__.py index 6516c85bdefffb..e70bbd29bbb366 100644 --- a/python/paddle/nn/layer/__init__.py +++ b/python/paddle/nn/layer/__init__.py @@ -109,6 +109,11 @@ MaxUnPool2D, MaxUnPool3D, ) + +from .padding import ( # noqa: F401 + ZeroPad1D, + ZeroPad3D, +) from .vision import ChannelShuffle, PixelShuffle, PixelUnshuffle # noqa: F401 __all__ = [] diff --git a/python/paddle/nn/layer/padding.py b/python/paddle/nn/layer/padding.py new file mode 100644 index 00000000000000..f1fde220e12c95 --- /dev/null +++ b/python/paddle/nn/layer/padding.py @@ -0,0 +1,142 @@ +# Copyright (c) 2024 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. + +from .. import functional as F +from .common import _npairs +from .layers import Layer + + +class ZeroPad1D(Layer): + """ + This interface is used to construct a callable object of the ``ZeroPad1D`` class. + Pads the input tensor boundaries with zero. + + Parameters: + padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the + same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. + The pad has the form (pad_left, pad_right). + data_format (str): An string from: "NCL", "NCL". Specify the data format of the input data. + Default is "NCL" + name (str, optional) : The default value is None. Normally there is no need for + user to set this property. For more information, please refer to :ref:`api_guide_Name`. + + Shape: + - x(Tensor): The input tensor of zeropad1d operator, which is a 3-D tensor. + The data type can be float32, float64. + - output(Tensor): The output tensor of zeropad1d operator, which is a 3-D tensor. + The data type is same as input x. + + Examples: + + .. code-block:: python + + >>> import paddle + >>> import paddle.nn as nn + + >>> input_shape = (1, 2, 3) + >>> pad = [1, 2] + >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 + >>> my_pad = nn.ZeroPad1D(padding=pad) + >>> result = my_pad(data) + >>> print(result) + Tensor(shape=[1, 2, 6], dtype=float32, place=Place(cpu), stop_gradient=True, + [[[0., 1., 2., 3., 0., 0.], + [0., 4., 5., 6., 0., 0.]]]) + """ + + def __init__(self, padding, data_format="NCL", name=None): + super().__init__() + self._pad = _npairs(padding, 1) + self._mode = 'constant' + self._value = 0.0 + self._data_format = data_format + self._name = name + + def forward(self, x): + return F.pad( + x, + pad=self._pad, + mode=self._mode, + value=self._value, + data_format=self._data_format, + name=self._name, + ) + + def extra_repr(self): + name_str = f', name={self._name}' if self._name else '' + return f'padding={self._pad}, data_format={self._data_format}{name_str}' + + +class ZeroPad3D(Layer): + """ + This interface is used to construct a callable object of the ``ZeroPad3D`` class. + Pads the input tensor boundaries with zero. + + Parameters: + padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the + same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. + The pad has the form (pad_left, pad_right, pad_top, pad_bottom, pad_front, pad_back). + data_format (str): An string from: "NCDHW", "NCDHW". Specify the data format of the input data. + Default is "NCDHW" + name (str, optional) : The default value is None. Normally there is no need for + user to set this property. For more information, please refer to :ref:`api_guide_Name`. + + Shape: + - x(Tensor): The input tensor of zeropad3d operator, which is a 5-D tensor. + The data type can be float32, float64. + - output(Tensor): The output tensor of zeropad3d operator, which is a 5-D tensor. + The data type is same as input x. + + Examples: + + .. code-block:: python + + >>> import paddle + >>> import paddle.nn as nn + + >>> input_shape = (1, 1, 1, 2, 3) + >>> pad = [1, 0, 1, 2, 0, 0] + >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 + >>> my_pad = nn.ZeroPad3D(padding=pad) + >>> result = my_pad(data) + >>> print(result) + Tensor(shape=[1, 1, 1, 5, 4], dtype=float32, place=Place(cpu), stop_gradient=True, + [[[[[0., 0., 0., 0.], + [0., 1., 2., 3.], + [0., 4., 5., 6.], + [0., 0., 0., 0.], + [0., 0., 0., 0.]]]]]) + """ + + def __init__(self, padding, data_format="NCDHW", name=None): + super().__init__() + self._pad = _npairs(padding, 3) + self._mode = 'constant' + self._value = 0.0 + self._data_format = data_format + self._name = name + + def forward(self, x): + return F.pad( + x, + pad=self._pad, + mode=self._mode, + value=self._value, + data_format=self._data_format, + name=self._name, + ) + + def extra_repr(self): + name_str = f', name={self._name}' if self._name else '' + return f'padding={self._pad}, data_format={self._data_format}{name_str}' diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 70bcfd1c8291b9..1dd80c219d86fa 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6836,3 +6836,31 @@ def slice_scatter(x, value, axes, starts, ends, strides, name=None): ) return output + +def block_diag(*inputs, name=None): + def to_col_block(arys, i, a): + return [ + a if idx == i else paddle.zeros([ary.shape[0], a.shape[1]], dtype=a.dtype) + for idx, ary in enumerate(arys) + ] + + def to_2d(ary): + if not isinstance(ary, paddle.Tensor): + raise TypeError( + f"For 'block_diag', each element of 'inputs' must be a tensor, but got {type(ary)}" + ) + if ary.ndim == 0: + return ary.unsqueeze(axis=0).unsqueeze(axis=0) + if ary.ndim == 1: + return ary.unsqueeze(axis=0) + if ary.ndim == 2: + return ary + raise ValueError( + "For 'block_diag', the dimension of each elements in 'inputs' must be 0, 1, or 2, but got " + f"{ary.ndim}" + ) + + arys = [to_2d(ary) for ary in inputs] + + matrix = [paddle.concat(to_col_block(arys, idx, ary), axis=0) for idx, ary in enumerate(arys)] + return paddle.concat(matrix, axis=1) \ No newline at end of file From 05e60500bf065c9249c8830ca2059dbc9d637e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 22 Apr 2024 10:34:33 +0800 Subject: [PATCH 02/22] update zeropad1 test --- test/legacy_test/test_ZeroPad1d.py | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 test/legacy_test/test_ZeroPad1d.py diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py new file mode 100644 index 00000000000000..56410e89abe064 --- /dev/null +++ b/test/legacy_test/test_ZeroPad1d.py @@ -0,0 +1,92 @@ +# Copyright (c) 2024 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. + +import unittest + +import numpy as np + +from paddle import to_tensor +from paddle.nn import ZeroPad1D + +class TestZeroPad1dAPIError(unittest.TestCase): + + def setUp(self): + self.shape = [4, 224, 224] + self.unsupport_dtypes = ['bool', 'int8'] + + def test_unsupport_dtypes(self): + for dtype in self.unsupport_dtypes: + pad = 2 + x = np.random.randint(-255, 255, size=self.shape) + zeropad1d = ZeroPad1D(padding=pad) + x_tensor = to_tensor(x).astype(dtype) + self.assertRaises(TypeError, zeropad1d, x=x_tensor) + +class TestZeroPad1dAPI(unittest.TestCase): + + def setUp(self): + self.shape = [4, 224, 224] + self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] + + def test_support_dtypes(self): + for dtype in self.support_dtypes: + pad = 2 + x = np.random.randint(-255, 255, size=self.shape).astype(dtype) + expect_res = np.pad(x, [[0, 0], [0, 0], [pad, pad]], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x).astype(dtype) + zeropad1d = ZeroPad1D(padding=[pad, pad]) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad2(self): + pad = [1, 2] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], pad], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x) + zeropad1d = ZeroPad1D(padding=pad) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad3(self): + pad = (1, 2) + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + zeropad1d = ZeroPad1D(padding=pad) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad4(self): + pad = [1, 2] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + pad_tensor = to_tensor(pad, dtype='int32') + zeropad1d = ZeroPad1D(padding=pad_tensor) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From ab0762c521b50d9a41843ae43bde247214331b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 22 Apr 2024 11:00:01 +0800 Subject: [PATCH 03/22] test --- test/legacy_test/test_ZeroPad1d.py | 2 +- test/legacy_test/test_ZeroPad3d.py | 92 ++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/legacy_test/test_ZeroPad3d.py diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index 56410e89abe064..ac3753bf657287 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -47,7 +47,7 @@ def test_support_dtypes(self): ) x_tensor = to_tensor(x).astype(dtype) - zeropad1d = ZeroPad1D(padding=[pad, pad]) + zeropad1d = ZeroPad1D(padding=pad) ret_res = zeropad1d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py new file mode 100644 index 00000000000000..6004691ede9dd1 --- /dev/null +++ b/test/legacy_test/test_ZeroPad3d.py @@ -0,0 +1,92 @@ +# Copyright (c) 2024 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. + +import unittest + +import numpy as np + +from paddle import to_tensor +from paddle.nn import ZeroPad3D + +class TestZeroPad3DAPIError(unittest.TestCase): + + def setUp(self): + self.shape = [4, 3, 244, 224, 224] + self.unsupport_dtypes = ['bool', 'int8'] + + def test_unsupport_dtypes(self): + for dtype in self.unsupport_dtypes: + pad = 2 + x = np.random.randint(-255, 255, size=self.shape) + zeropad3d = ZeroPad3D(padding=pad) + x_tensor = to_tensor(x).astype(dtype) + self.assertRaises(TypeError, zeropad3d, x=x_tensor) + +class TestZeroPad3DAPI(unittest.TestCase): + + def setUp(self): + self.shape = [4, 3, 244, 224, 224] + self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] + + def test_support_dtypes(self): + for dtype in self.support_dtypes: + pad = 2 + x = np.random.randint(-255, 255, size=self.shape).astype(dtype) + expect_res = np.pad(x, [[0, 0], [0, 0], [pad, pad], [pad, pad], [pad, pad]], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x).astype(dtype) + zeropad3d = ZeroPad3D(padding=pad) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad2(self): + pad = [1, 2, 3, 4, 5, 6] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x) + zeropad3d = ZeroPad3D(padding=pad) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad3(self): + pad = (1, 2, 3, 4, 5, 6) + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + zeropad3d = ZeroPad3D(padding=pad) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad4(self): + pad = [1, 2, 3, 4, 5, 6] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + pad_tensor = to_tensor(pad, dtype='int32') + zeropad3d = ZeroPad3D(padding=pad_tensor) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 5088dbe90dcf9609fa178d5c5681e0aacfe5063f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 22 Apr 2024 15:05:31 +0800 Subject: [PATCH 04/22] update block_diag example --- python/paddle/__init__.py | 2 ++ python/paddle/tensor/__init__.py | 2 ++ python/paddle/tensor/manipulation.py | 32 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index ccf9d97c008c10..ceb516470eef30 100644 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -258,6 +258,7 @@ not_equal_, # noqa: F401 ) from .tensor.manipulation import ( + block_diag, as_complex, as_real, as_strided, @@ -946,6 +947,7 @@ 'asinh', 'acosh', 'atanh', + 'block_diag', 'as_complex', 'as_real', 'diff', diff --git a/python/paddle/tensor/__init__.py b/python/paddle/tensor/__init__.py index 936edb9c428fb9..53396035df62ad 100644 --- a/python/paddle/tensor/__init__.py +++ b/python/paddle/tensor/__init__.py @@ -135,6 +135,7 @@ not_equal_, ) from .manipulation import ( # noqa: F401 + block_diag, as_complex, as_real, as_strided, @@ -816,6 +817,7 @@ 'masked_scatter_', "combinations", 'signbit', + 'block_diag', ] # this list used in math_op_patch.py for magic_method bind diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 1dd80c219d86fa..529755444b32da 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6838,6 +6838,38 @@ def slice_scatter(x, value, axes, starts, ends, strides, name=None): return output def block_diag(*inputs, name=None): + """ + Create a block diagonal matrix from provided tensors. + + Args: + *input (Tensor): One or more tensors with 0, 1, or 2 dimensions. + name (str, optional): Name for the operation (optional, default is None). + + Returns: + Tensor, A ``Tensor``. The data type is same as ``input``. + + Examples: + .. code-block:: python + + >>> import paddle + + >>> A = paddle.to_tensor([[0, 1], [1, 0]]) + >>> B = paddle.to_tensor([[3, 4, 5], [6, 7, 8]]) + >>> C = paddle.to_tensor(7) + >>> D = paddle.to_tensor([1, 2, 3]) + >>> E = paddle.to_tensor([[4], [5], [6]]) + >>> out = paddle.block_diag(A, B, C, D, E) + >>> print(out) + [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 3, 4, 5, 0, 0, 0, 0, 0], + [0, 0, 6, 7, 8, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 7, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 1, 2, 3, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 4], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 5], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 6]] + """ def to_col_block(arys, i, a): return [ a if idx == i else paddle.zeros([ary.shape[0], a.shape[1]], dtype=a.dtype) From 7854d915e39efefc061b9410c8fca1e175108a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 22 Apr 2024 16:25:35 +0800 Subject: [PATCH 05/22] update test --- test/legacy_test/test_ZeroPad1d.py | 96 ++++++++++++++--------------- test/legacy_test/test_ZeroPad3d.py | 96 ++++++++++++++--------------- test/legacy_test/test_block_diag.py | 44 +++++++++++++ 3 files changed, 140 insertions(+), 96 deletions(-) create mode 100644 test/legacy_test/test_block_diag.py diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index ac3753bf657287..3bb28a63e3b4c9 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -19,24 +19,24 @@ from paddle import to_tensor from paddle.nn import ZeroPad1D -class TestZeroPad1dAPIError(unittest.TestCase): +# class TestZeroPad1dAPIError(unittest.TestCase): - def setUp(self): - self.shape = [4, 224, 224] - self.unsupport_dtypes = ['bool', 'int8'] +# def setUp(self): +# self.shape = [4, 6, 6] +# self.unsupport_dtypes = ['bool', 'int8'] - def test_unsupport_dtypes(self): - for dtype in self.unsupport_dtypes: - pad = 2 - x = np.random.randint(-255, 255, size=self.shape) - zeropad1d = ZeroPad1D(padding=pad) - x_tensor = to_tensor(x).astype(dtype) - self.assertRaises(TypeError, zeropad1d, x=x_tensor) +# def test_unsupport_dtypes(self): +# for dtype in self.unsupport_dtypes: +# pad = 2 +# x = np.random.randint(-255, 255, size=self.shape) +# zeropad1d = ZeroPad1D(padding=pad) +# x_tensor = to_tensor(x).astype(dtype) +# self.assertRaises(TypeError, zeropad1d, x=x_tensor) class TestZeroPad1dAPI(unittest.TestCase): def setUp(self): - self.shape = [4, 224, 224] + self.shape = [4, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] def test_support_dtypes(self): @@ -51,42 +51,42 @@ def test_support_dtypes(self): ret_res = zeropad1d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - def test_support_pad2(self): - pad = [1, 2] - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], pad], mode='constant', constant_values=0 - ) - - x_tensor = to_tensor(x) - zeropad1d = ZeroPad1D(padding=pad) - ret_res = zeropad1d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - def test_support_pad3(self): - pad = (1, 2) - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[0], pad[1]]] - ) - - x_tensor = to_tensor(x) - zeropad1d = ZeroPad1D(padding=pad) - ret_res = zeropad1d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - def test_support_pad4(self): - pad = [1, 2] - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[0], pad[1]]] - ) - - x_tensor = to_tensor(x) - pad_tensor = to_tensor(pad, dtype='int32') - zeropad1d = ZeroPad1D(padding=pad_tensor) - ret_res = zeropad1d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + # def test_support_pad2(self): + # pad = [1, 2] + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], pad], mode='constant', constant_values=0 + # ) + + # x_tensor = to_tensor(x) + # zeropad1d = ZeroPad1D(padding=pad) + # ret_res = zeropad1d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + # def test_support_pad3(self): + # pad = (1, 2) + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], [pad[0], pad[1]]] + # ) + + # x_tensor = to_tensor(x) + # zeropad1d = ZeroPad1D(padding=pad) + # ret_res = zeropad1d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + # def test_support_pad4(self): + # pad = [1, 2] + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], [pad[0], pad[1]]] + # ) + + # x_tensor = to_tensor(x) + # pad_tensor = to_tensor(pad, dtype='int32') + # zeropad1d = ZeroPad1D(padding=pad_tensor) + # ret_res = zeropad1d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index 6004691ede9dd1..57db1b8896351c 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -19,24 +19,24 @@ from paddle import to_tensor from paddle.nn import ZeroPad3D -class TestZeroPad3DAPIError(unittest.TestCase): +# class TestZeroPad3DAPIError(unittest.TestCase): - def setUp(self): - self.shape = [4, 3, 244, 224, 224] - self.unsupport_dtypes = ['bool', 'int8'] +# def setUp(self): +# self.shape = [4, 3, 6, 6, 6] +# self.unsupport_dtypes = ['bool', 'int8'] - def test_unsupport_dtypes(self): - for dtype in self.unsupport_dtypes: - pad = 2 - x = np.random.randint(-255, 255, size=self.shape) - zeropad3d = ZeroPad3D(padding=pad) - x_tensor = to_tensor(x).astype(dtype) - self.assertRaises(TypeError, zeropad3d, x=x_tensor) +# def test_unsupport_dtypes(self): +# for dtype in self.unsupport_dtypes: +# pad = 2 +# x = np.random.randint(-255, 255, size=self.shape) +# zeropad3d = ZeroPad3D(padding=pad) +# x_tensor = to_tensor(x).astype(dtype) +# self.assertRaises(TypeError, zeropad3d, x=x_tensor) class TestZeroPad3DAPI(unittest.TestCase): def setUp(self): - self.shape = [4, 3, 244, 224, 224] + self.shape = [4, 3, 6, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] def test_support_dtypes(self): @@ -51,42 +51,42 @@ def test_support_dtypes(self): ret_res = zeropad3d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - def test_support_pad2(self): - pad = [1, 2, 3, 4, 5, 6] - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 - ) - - x_tensor = to_tensor(x) - zeropad3d = ZeroPad3D(padding=pad) - ret_res = zeropad3d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - def test_support_pad3(self): - pad = (1, 2, 3, 4, 5, 6) - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] - ) - - x_tensor = to_tensor(x) - zeropad3d = ZeroPad3D(padding=pad) - ret_res = zeropad3d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - def test_support_pad4(self): - pad = [1, 2, 3, 4, 5, 6] - x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] - ) - - x_tensor = to_tensor(x) - pad_tensor = to_tensor(pad, dtype='int32') - zeropad3d = ZeroPad3D(padding=pad_tensor) - ret_res = zeropad3d(x_tensor).numpy() - np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + # def test_support_pad2(self): + # pad = [1, 2, 3, 4, 5, 6] + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 + # ) + + # x_tensor = to_tensor(x) + # zeropad3d = ZeroPad3D(padding=pad) + # ret_res = zeropad3d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + # def test_support_pad3(self): + # pad = (1, 2, 3, 4, 5, 6) + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + # ) + + # x_tensor = to_tensor(x) + # zeropad3d = ZeroPad3D(padding=pad) + # ret_res = zeropad3d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + # def test_support_pad4(self): + # pad = [1, 2, 3, 4, 5, 6] + # x = np.random.randint(-255, 255, size=self.shape) + # expect_res = np.pad( + # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + # ) + + # x_tensor = to_tensor(x) + # pad_tensor = to_tensor(pad, dtype='int32') + # zeropad3d = ZeroPad3D(padding=pad_tensor) + # ret_res = zeropad3d(x_tensor).numpy() + # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py new file mode 100644 index 00000000000000..437791f81a2aed --- /dev/null +++ b/test/legacy_test/test_block_diag.py @@ -0,0 +1,44 @@ +# Copyright (c) 2024 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. + +import unittest + +import numpy as np + +import paddle +from paddle import base + +class TestBlockDiagError(unittest.TestCase): + def test_errors(self): + def test_type_error(): + A = np.array([[1, 2], [3, 4]]) + B = np.array([[5, 6], [7, 8]]) + C = np.array([[9, 10], [11, 12]]) + with paddle.static.program_guard(base.Program()): + out = paddle.block_diag(A, B ,C) + + self.assertRaises(TypeError, test_type_error) + + def test_dime_error(): + A = paddle.to_tensor([[[1, 2], [3, 4]]]) + B = paddle.to_tensor([[[5, 6], [7, 8]]]) + C = paddle.to_tensor([[[9, 10], [11, 12]]]) + with paddle.static.program_guard(base.Program()): + out = block_diag(A, B ,C) + + self.assertRaises(ValueError, test_dime_error) + + +if __name__ == '__main__': + unittest.main() From cbf4594a4ecdeae19c297a68f95ae7c9a4a134b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 22 Apr 2024 18:17:15 +0800 Subject: [PATCH 06/22] test --- test/legacy_test/test_block_diag.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py index 437791f81a2aed..ef64c669dc80ec 100644 --- a/test/legacy_test/test_block_diag.py +++ b/test/legacy_test/test_block_diag.py @@ -35,7 +35,7 @@ def test_dime_error(): B = paddle.to_tensor([[[5, 6], [7, 8]]]) C = paddle.to_tensor([[[9, 10], [11, 12]]]) with paddle.static.program_guard(base.Program()): - out = block_diag(A, B ,C) + out = paddle.block_diag(A, B ,C) self.assertRaises(ValueError, test_dime_error) From edae11d3aafe4fb32d8cdd1af96d097b5846dbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Tue, 23 Apr 2024 10:12:27 +0800 Subject: [PATCH 07/22] update --- python/paddle/__init__.py | 2 - python/paddle/tensor/__init__.py | 2 - python/paddle/tensor/manipulation.py | 59 ---------------------------- test/legacy_test/test_block_diag.py | 44 --------------------- 4 files changed, 107 deletions(-) delete mode 100644 test/legacy_test/test_block_diag.py diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index ceb516470eef30..ccf9d97c008c10 100644 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -258,7 +258,6 @@ not_equal_, # noqa: F401 ) from .tensor.manipulation import ( - block_diag, as_complex, as_real, as_strided, @@ -947,7 +946,6 @@ 'asinh', 'acosh', 'atanh', - 'block_diag', 'as_complex', 'as_real', 'diff', diff --git a/python/paddle/tensor/__init__.py b/python/paddle/tensor/__init__.py index 53396035df62ad..936edb9c428fb9 100644 --- a/python/paddle/tensor/__init__.py +++ b/python/paddle/tensor/__init__.py @@ -135,7 +135,6 @@ not_equal_, ) from .manipulation import ( # noqa: F401 - block_diag, as_complex, as_real, as_strided, @@ -817,7 +816,6 @@ 'masked_scatter_', "combinations", 'signbit', - 'block_diag', ] # this list used in math_op_patch.py for magic_method bind diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 529755444b32da..5fb7c5c1c7fd1a 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6837,62 +6837,3 @@ def slice_scatter(x, value, axes, starts, ends, strides, name=None): return output -def block_diag(*inputs, name=None): - """ - Create a block diagonal matrix from provided tensors. - - Args: - *input (Tensor): One or more tensors with 0, 1, or 2 dimensions. - name (str, optional): Name for the operation (optional, default is None). - - Returns: - Tensor, A ``Tensor``. The data type is same as ``input``. - - Examples: - .. code-block:: python - - >>> import paddle - - >>> A = paddle.to_tensor([[0, 1], [1, 0]]) - >>> B = paddle.to_tensor([[3, 4, 5], [6, 7, 8]]) - >>> C = paddle.to_tensor(7) - >>> D = paddle.to_tensor([1, 2, 3]) - >>> E = paddle.to_tensor([[4], [5], [6]]) - >>> out = paddle.block_diag(A, B, C, D, E) - >>> print(out) - [[0, 1, 0, 0, 0, 0, 0, 0, 0, 0], - [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 3, 4, 5, 0, 0, 0, 0, 0], - [0, 0, 6, 7, 8, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 7, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 1, 2, 3, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 4], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 5], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 6]] - """ - def to_col_block(arys, i, a): - return [ - a if idx == i else paddle.zeros([ary.shape[0], a.shape[1]], dtype=a.dtype) - for idx, ary in enumerate(arys) - ] - - def to_2d(ary): - if not isinstance(ary, paddle.Tensor): - raise TypeError( - f"For 'block_diag', each element of 'inputs' must be a tensor, but got {type(ary)}" - ) - if ary.ndim == 0: - return ary.unsqueeze(axis=0).unsqueeze(axis=0) - if ary.ndim == 1: - return ary.unsqueeze(axis=0) - if ary.ndim == 2: - return ary - raise ValueError( - "For 'block_diag', the dimension of each elements in 'inputs' must be 0, 1, or 2, but got " - f"{ary.ndim}" - ) - - arys = [to_2d(ary) for ary in inputs] - - matrix = [paddle.concat(to_col_block(arys, idx, ary), axis=0) for idx, ary in enumerate(arys)] - return paddle.concat(matrix, axis=1) \ No newline at end of file diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py deleted file mode 100644 index ef64c669dc80ec..00000000000000 --- a/test/legacy_test/test_block_diag.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2024 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. - -import unittest - -import numpy as np - -import paddle -from paddle import base - -class TestBlockDiagError(unittest.TestCase): - def test_errors(self): - def test_type_error(): - A = np.array([[1, 2], [3, 4]]) - B = np.array([[5, 6], [7, 8]]) - C = np.array([[9, 10], [11, 12]]) - with paddle.static.program_guard(base.Program()): - out = paddle.block_diag(A, B ,C) - - self.assertRaises(TypeError, test_type_error) - - def test_dime_error(): - A = paddle.to_tensor([[[1, 2], [3, 4]]]) - B = paddle.to_tensor([[[5, 6], [7, 8]]]) - C = paddle.to_tensor([[[9, 10], [11, 12]]]) - with paddle.static.program_guard(base.Program()): - out = paddle.block_diag(A, B ,C) - - self.assertRaises(ValueError, test_dime_error) - - -if __name__ == '__main__': - unittest.main() From 319e0c5daca95ef0aed0deb0cedfc854f485e755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Tue, 23 Apr 2024 13:53:23 +0800 Subject: [PATCH 08/22] add block_diag --- python/paddle/__init__.py | 2 + python/paddle/nn/__init__.py | 9 ++- python/paddle/nn/layer/__init__.py | 9 ++- python/paddle/tensor/__init__.py | 2 + python/paddle/tensor/manipulation.py | 63 +++++++++++++++++++ test/legacy_test/test_ZeroPad1d.py | 11 +++- test/legacy_test/test_ZeroPad3d.py | 11 +++- test/legacy_test/test_block_diag.py | 94 ++++++++++++++++++++++++++++ 8 files changed, 185 insertions(+), 16 deletions(-) create mode 100644 test/legacy_test/test_block_diag.py diff --git a/python/paddle/__init__.py b/python/paddle/__init__.py index ccf9d97c008c10..f63fc1a97cada5 100644 --- a/python/paddle/__init__.py +++ b/python/paddle/__init__.py @@ -264,6 +264,7 @@ atleast_1d, atleast_2d, atleast_3d, + block_diag, broadcast_tensors, broadcast_to, cast, @@ -603,6 +604,7 @@ ir_guard._switch_to_pir() __all__ = [ + 'block_diag', 'iinfo', 'finfo', 'dtype', diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index c9845bea6d0cd2..9f6e26a5d63161 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -72,11 +72,6 @@ ZeroPad2D, ) -from .layer.padding import ( - ZeroPad1D, - ZeroPad3D, -) - # TODO: import all neural network related api under this directory, # including layers, linear, conv, rnn etc. from .layer.container import LayerDict, LayerList, ParameterList, Sequential @@ -127,6 +122,10 @@ SpectralNorm, SyncBatchNorm, ) +from .layer.padding import ( + ZeroPad1D, + ZeroPad3D, +) from .layer.pooling import ( AdaptiveAvgPool1D, AdaptiveAvgPool2D, diff --git a/python/paddle/nn/layer/__init__.py b/python/paddle/nn/layer/__init__.py index e70bbd29bbb366..7bd733efad5a7b 100644 --- a/python/paddle/nn/layer/__init__.py +++ b/python/paddle/nn/layer/__init__.py @@ -90,6 +90,10 @@ SpectralNorm, SyncBatchNorm, ) +from .padding import ( # noqa: F401 + ZeroPad1D, + ZeroPad3D, +) from .pooling import ( # noqa: F401 AdaptiveAvgPool1D, AdaptiveAvgPool2D, @@ -109,11 +113,6 @@ MaxUnPool2D, MaxUnPool3D, ) - -from .padding import ( # noqa: F401 - ZeroPad1D, - ZeroPad3D, -) from .vision import ChannelShuffle, PixelShuffle, PixelUnshuffle # noqa: F401 __all__ = [] diff --git a/python/paddle/tensor/__init__.py b/python/paddle/tensor/__init__.py index 936edb9c428fb9..c72cfa68c45f23 100644 --- a/python/paddle/tensor/__init__.py +++ b/python/paddle/tensor/__init__.py @@ -141,6 +141,7 @@ atleast_1d, atleast_2d, atleast_3d, + block_diag, broadcast_tensors, broadcast_to, cast, @@ -535,6 +536,7 @@ 'hypot_', 'nansum', 'nanmean', + 'block_diag', 'count_nonzero', 'tanh', 'tanh_', diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 5fb7c5c1c7fd1a..26fa41bff3fcd6 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6837,3 +6837,66 @@ def slice_scatter(x, value, axes, starts, ends, strides, name=None): return output + +def block_diag(*inputs, name=None): + """ + Create a block diagonal matrix from provided tensors. + + Args: + *input (Tensor): One or more tensors with 0, 1, or 2 dimensions. + name (str, optional): Name for the operation (optional, default is None). + + Returns: + Tensor, A ``Tensor``. The data type is same as ``input``. + + Examples: + .. code-block:: python + + >>> import paddle + + >>> A = paddle.to_tensor([[4], [3], [2]]) + >>> B = paddle.to_tensor([7, 6, 5]) + >>> C = paddle.to_tensor(1) + >>> D = paddle.to_tensor([[5, 4, 3], [2, 1, 0]]) + >>> E = paddle.to_tensor([[8, 7], [7, 8]]) + >>> out = paddle.block_diag(A, B, C, D, E) + >>> print(out) + Tensor(shape=[9, 10], dtype=int64, place=Place(gpu:0), stop_gradient=True, + [[4, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [2, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 7, 6, 5, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 5, 4, 3, 0, 0], + [0, 0, 0, 0, 0, 2, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 8, 7], + [0, 0, 0, 0, 0, 0, 0, 0, 7, 8]]) + """ + + def to_col_block(arys, i, a): + return [ + a + if idx == i + else paddle.zeros([ary.shape[0], a.shape[1]], dtype=a.dtype) + for idx, ary in enumerate(arys) + ] + + def to_2d(ary): + if ary.ndim == 0: + return ary.unsqueeze(axis=0).unsqueeze(axis=0) + if ary.ndim == 1: + return ary.unsqueeze(axis=0) + if ary.ndim == 2: + return ary + raise ValueError( + "For 'block_diag', the dimension of each elements in 'inputs' must be 0, 1, or 2, but got " + f"{ary.ndim}" + ) + + arys = [to_2d(ary) for ary in inputs] + + matrix = [ + paddle.concat(to_col_block(arys, idx, ary), axis=0) + for idx, ary in enumerate(arys) + ] + return paddle.concat(matrix, axis=1) diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index 3bb28a63e3b4c9..26d15aea24fc35 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -33,8 +33,8 @@ # x_tensor = to_tensor(x).astype(dtype) # self.assertRaises(TypeError, zeropad1d, x=x_tensor) -class TestZeroPad1dAPI(unittest.TestCase): +class TestZeroPad1dAPI(unittest.TestCase): def setUp(self): self.shape = [4, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] @@ -43,7 +43,11 @@ def test_support_dtypes(self): for dtype in self.support_dtypes: pad = 2 x = np.random.randint(-255, 255, size=self.shape).astype(dtype) - expect_res = np.pad(x, [[0, 0], [0, 0], [pad, pad]], mode='constant', constant_values=0 + expect_res = np.pad( + x, + [[0, 0], [0, 0], [pad, pad]], + mode='constant', + constant_values=0, ) x_tensor = to_tensor(x).astype(dtype) @@ -88,5 +92,6 @@ def test_support_dtypes(self): # ret_res = zeropad1d(x_tensor).numpy() # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index 57db1b8896351c..0ab28bfc3b7aa9 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -33,8 +33,8 @@ # x_tensor = to_tensor(x).astype(dtype) # self.assertRaises(TypeError, zeropad3d, x=x_tensor) -class TestZeroPad3DAPI(unittest.TestCase): +class TestZeroPad3DAPI(unittest.TestCase): def setUp(self): self.shape = [4, 3, 6, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] @@ -43,7 +43,11 @@ def test_support_dtypes(self): for dtype in self.support_dtypes: pad = 2 x = np.random.randint(-255, 255, size=self.shape).astype(dtype) - expect_res = np.pad(x, [[0, 0], [0, 0], [pad, pad], [pad, pad], [pad, pad]], mode='constant', constant_values=0 + expect_res = np.pad( + x, + [[0, 0], [0, 0], [pad, pad], [pad, pad], [pad, pad]], + mode='constant', + constant_values=0, ) x_tensor = to_tensor(x).astype(dtype) @@ -88,5 +92,6 @@ def test_support_dtypes(self): # ret_res = zeropad3d(x_tensor).numpy() # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py new file mode 100644 index 00000000000000..b4df230dee47be --- /dev/null +++ b/test/legacy_test/test_block_diag.py @@ -0,0 +1,94 @@ +# Copyright (c) 2024 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. + +import unittest + +import numpy as np +import scipy + +import paddle +from paddle import base + + +class TestBlockDiagError(unittest.TestCase): + def test_errors(self): + def test_type_error(): + A = np.array([[1, 2], [3, 4]]) + B = np.array([[5, 6], [7, 8]]) + C = np.array([[9, 10], [11, 12]]) + with paddle.static.program_guard(base.Program()): + out = paddle.block_diag(A, B, C) + + self.assertRaises(TypeError, test_type_error) + + def test_dime_error(): + A = paddle.to_tensor([[[1, 2], [3, 4]]]) + B = paddle.to_tensor([[[5, 6], [7, 8]]]) + C = paddle.to_tensor([[[9, 10], [11, 12]]]) + with paddle.static.program_guard(base.Program()): + out = paddle.block_diag(A, B, C) + + self.assertRaises(ValueError, test_dime_error) + + +class TestBlockDiag(unittest.TestCase): + def setUp(self): + self.type_list = ['int32', 'int64', 'float32', 'float64'] + self.place = [('cpu', paddle.CPUPlace())] + ( + [('gpu', paddle.CUDAPlace(0))] + if paddle.is_compiled_with_cuda() + else [] + ) + + def test_dygraph(self): + paddle.disable_static() + for device, place in self.place: + paddle.set_device(device) + for i in self.type_list: + A = np.random.randn(2, 3).astype(i) + B = np.random.randn(2).astype(i) + C = np.random.randn(4, 1).astype(i) + s_out = scipy.linalg.block_diag(A, B, C) + + A_tensor = paddle.to_tensor(A) + B_tensor = paddle.to_tensor(B) + C_tensor = paddle.to_tensor(C) + out = paddle.block_diag(A_tensor, B_tensor, C_tensor) + np.testing.assert_allclose(out.numpy(), s_out) + + def test_static(self): + paddle.enable_static() + for device, place in self.place: + paddle.set_device(device) + for i in self.type_list: + A = np.random.randn(2, 3).astype(i) + B = np.random.randn(2).astype(i) + C = np.random.randn(4, 1).astype(i) + s_out = scipy.linalg.block_diag(A, B, C) + + with paddle.static.program_guard(paddle.static.Program()): + A_tensor = paddle.static.data('A', [2, 3], i) + B_tensor = paddle.static.data('B', [2], i) + C_tensor = paddle.static.data('C', [4, 1], i) + out = paddle.block_diag(A_tensor, B_tensor, C_tensor) + exe = paddle.static.Executor(place) + res = exe.run( + feed={'A': A, 'B': B, 'C': C}, + fetch_list=[out], + ) + np.testing.assert_allclose(res[0], s_out) + + +if __name__ == '__main__': + unittest.main() From e7a7625f07163b0c3fc5e0591d964fb7421c2cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Wed, 24 Apr 2024 15:30:31 +0800 Subject: [PATCH 09/22] update --- test/legacy_test/test_block_diag.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py index b4df230dee47be..691474f001a380 100644 --- a/test/legacy_test/test_block_diag.py +++ b/test/legacy_test/test_block_diag.py @@ -44,6 +44,7 @@ def test_dime_error(): class TestBlockDiag(unittest.TestCase): def setUp(self): + paddle.seed(2024) self.type_list = ['int32', 'int64', 'float32', 'float64'] self.place = [('cpu', paddle.CPUPlace())] + ( [('gpu', paddle.CUDAPlace(0))] From 28e80b743c67c5a604d68a49dc0c8111c2156274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Fri, 26 Apr 2024 10:01:55 +0800 Subject: [PATCH 10/22] Zeropad --- test/legacy_test/test_ZeroPad1d.py | 98 ++++++++++++++++-------------- test/legacy_test/test_ZeroPad3d.py | 98 ++++++++++++++++-------------- 2 files changed, 102 insertions(+), 94 deletions(-) diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index 26d15aea24fc35..f92a01b0f603c7 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -19,19 +19,18 @@ from paddle import to_tensor from paddle.nn import ZeroPad1D -# class TestZeroPad1dAPIError(unittest.TestCase): +class TestZeroPad1dAPIError(unittest.TestCase): -# def setUp(self): -# self.shape = [4, 6, 6] -# self.unsupport_dtypes = ['bool', 'int8'] + def setUp(self): + self.shape = [4, 6, 6] + self.unsupport_dtypes = 'int8' -# def test_unsupport_dtypes(self): -# for dtype in self.unsupport_dtypes: -# pad = 2 -# x = np.random.randint(-255, 255, size=self.shape) -# zeropad1d = ZeroPad1D(padding=pad) -# x_tensor = to_tensor(x).astype(dtype) -# self.assertRaises(TypeError, zeropad1d, x=x_tensor) + def test_unsupport_dtypes(self): + pad = 2 + x = np.random.randint(-255, 255, size=self.shape) + zeropad1d = ZeroPad1D(padding=pad) + x_tensor = to_tensor(x).astype(self.unsupport_dtypes) + self.assertRaises(TypeError, zeropad1d, x=x_tensor) class TestZeroPad1dAPI(unittest.TestCase): @@ -55,42 +54,47 @@ def test_support_dtypes(self): ret_res = zeropad1d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - # def test_support_pad2(self): - # pad = [1, 2] - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], pad], mode='constant', constant_values=0 - # ) - - # x_tensor = to_tensor(x) - # zeropad1d = ZeroPad1D(padding=pad) - # ret_res = zeropad1d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - # def test_support_pad3(self): - # pad = (1, 2) - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], [pad[0], pad[1]]] - # ) - - # x_tensor = to_tensor(x) - # zeropad1d = ZeroPad1D(padding=pad) - # ret_res = zeropad1d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - # def test_support_pad4(self): - # pad = [1, 2] - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], [pad[0], pad[1]]] - # ) - - # x_tensor = to_tensor(x) - # pad_tensor = to_tensor(pad, dtype='int32') - # zeropad1d = ZeroPad1D(padding=pad_tensor) - # ret_res = zeropad1d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + def test_support_pad2(self): + pad = [1, 2] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], pad], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x) + zeropad1d = ZeroPad1D(padding=pad) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad3(self): + pad = (1, 2) + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + zeropad1d = ZeroPad1D(padding=pad) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad4(self): + pad = [1, 2] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + pad_tensor = to_tensor(pad, dtype='int32') + zeropad1d = ZeroPad1D(padding=pad_tensor) + ret_res = zeropad1d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_repr(self): + pad = [1, 2] + zeropad1d = ZeroPad1D(padding=pad) + zeropad1d.extra_repr() if __name__ == '__main__': diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index 0ab28bfc3b7aa9..1bf1606f87c9a7 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -19,19 +19,18 @@ from paddle import to_tensor from paddle.nn import ZeroPad3D -# class TestZeroPad3DAPIError(unittest.TestCase): +class TestZeroPad3DAPIError(unittest.TestCase): -# def setUp(self): -# self.shape = [4, 3, 6, 6, 6] -# self.unsupport_dtypes = ['bool', 'int8'] + def setUp(self): + self.shape = [4, 3, 6, 6, 6] + self.unsupport_dtypes = 'int8' -# def test_unsupport_dtypes(self): -# for dtype in self.unsupport_dtypes: -# pad = 2 -# x = np.random.randint(-255, 255, size=self.shape) -# zeropad3d = ZeroPad3D(padding=pad) -# x_tensor = to_tensor(x).astype(dtype) -# self.assertRaises(TypeError, zeropad3d, x=x_tensor) + def test_unsupport_dtypes(self): + pad = 2 + x = np.random.randint(-255, 255, size=self.shape) + zeropad3d = ZeroPad3D(padding=pad) + x_tensor = to_tensor(x).astype(self.unsupport_dtypes) + self.assertRaises(TypeError, zeropad3d, x=x_tensor) class TestZeroPad3DAPI(unittest.TestCase): @@ -55,42 +54,47 @@ def test_support_dtypes(self): ret_res = zeropad3d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - # def test_support_pad2(self): - # pad = [1, 2, 3, 4, 5, 6] - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 - # ) - - # x_tensor = to_tensor(x) - # zeropad3d = ZeroPad3D(padding=pad) - # ret_res = zeropad3d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - # def test_support_pad3(self): - # pad = (1, 2, 3, 4, 5, 6) - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] - # ) - - # x_tensor = to_tensor(x) - # zeropad3d = ZeroPad3D(padding=pad) - # ret_res = zeropad3d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - - # def test_support_pad4(self): - # pad = [1, 2, 3, 4, 5, 6] - # x = np.random.randint(-255, 255, size=self.shape) - # expect_res = np.pad( - # x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] - # ) - - # x_tensor = to_tensor(x) - # pad_tensor = to_tensor(pad, dtype='int32') - # zeropad3d = ZeroPad3D(padding=pad_tensor) - # ret_res = zeropad3d(x_tensor).numpy() - # np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + def test_support_pad2(self): + pad = [1, 2, 3, 4, 5, 6] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 + ) + + x_tensor = to_tensor(x) + zeropad3d = ZeroPad3D(padding=pad) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad3(self): + pad = (1, 2, 3, 4, 5, 6) + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + zeropad3d = ZeroPad3D(padding=pad) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_support_pad4(self): + pad = [1, 2, 3, 4, 5, 6] + x = np.random.randint(-255, 255, size=self.shape) + expect_res = np.pad( + x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + ) + + x_tensor = to_tensor(x) + pad_tensor = to_tensor(pad, dtype='int32') + zeropad3d = ZeroPad3D(padding=pad_tensor) + ret_res = zeropad3d(x_tensor).numpy() + np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) + + def test_repr(self): + pad = pad = [1, 2, 3, 4, 5, 6] + zeropad3d = ZeroPad3D(padding=pad) + zeropad3d.extra_repr() if __name__ == '__main__': From d9fccd4df8c28a9b21cf740e4e3f12cf0c6b9eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Sat, 27 Apr 2024 18:35:34 +0800 Subject: [PATCH 11/22] finish --- test/legacy_test/test_ZeroPad1d.py | 13 ------------- test/legacy_test/test_ZeroPad3d.py | 21 +++++---------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index f92a01b0f603c7..2ca075c4fc47db 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -19,19 +19,6 @@ from paddle import to_tensor from paddle.nn import ZeroPad1D -class TestZeroPad1dAPIError(unittest.TestCase): - - def setUp(self): - self.shape = [4, 6, 6] - self.unsupport_dtypes = 'int8' - - def test_unsupport_dtypes(self): - pad = 2 - x = np.random.randint(-255, 255, size=self.shape) - zeropad1d = ZeroPad1D(padding=pad) - x_tensor = to_tensor(x).astype(self.unsupport_dtypes) - self.assertRaises(TypeError, zeropad1d, x=x_tensor) - class TestZeroPad1dAPI(unittest.TestCase): def setUp(self): diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index 1bf1606f87c9a7..4ba64024ae2cc8 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -19,19 +19,6 @@ from paddle import to_tensor from paddle.nn import ZeroPad3D -class TestZeroPad3DAPIError(unittest.TestCase): - - def setUp(self): - self.shape = [4, 3, 6, 6, 6] - self.unsupport_dtypes = 'int8' - - def test_unsupport_dtypes(self): - pad = 2 - x = np.random.randint(-255, 255, size=self.shape) - zeropad3d = ZeroPad3D(padding=pad) - x_tensor = to_tensor(x).astype(self.unsupport_dtypes) - self.assertRaises(TypeError, zeropad3d, x=x_tensor) - class TestZeroPad3DAPI(unittest.TestCase): def setUp(self): @@ -70,7 +57,8 @@ def test_support_pad3(self): pad = (1, 2, 3, 4, 5, 6) x = np.random.randint(-255, 255, size=self.shape) expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + x, [[0, 0], [0, 0], [pad[4], pad[5]], [ + pad[2], pad[3]], [pad[0], pad[1]]] ) x_tensor = to_tensor(x) @@ -82,7 +70,8 @@ def test_support_pad4(self): pad = [1, 2, 3, 4, 5, 6] x = np.random.randint(-255, 255, size=self.shape) expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]] + x, [[0, 0], [0, 0], [pad[4], pad[5]], [ + pad[2], pad[3]], [pad[0], pad[1]]] ) x_tensor = to_tensor(x) @@ -90,7 +79,7 @@ def test_support_pad4(self): zeropad3d = ZeroPad3D(padding=pad_tensor) ret_res = zeropad3d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - + def test_repr(self): pad = pad = [1, 2, 3, 4, 5, 6] zeropad3d = ZeroPad3D(padding=pad) From 7bd3ffe12ffee43e90ba9d59c4b506dc9cab4afd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 29 Apr 2024 14:43:53 +0800 Subject: [PATCH 12/22] update test --- test/legacy_test/test_ZeroPad1d.py | 13 +++++------- test/legacy_test/test_ZeroPad3d.py | 34 ++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index 2ca075c4fc47db..2f839016b116ce 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -56,9 +56,7 @@ def test_support_pad2(self): def test_support_pad3(self): pad = (1, 2) x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[0], pad[1]]] - ) + expect_res = np.pad(x, [[0, 0], [0, 0], [pad[0], pad[1]]]) x_tensor = to_tensor(x) zeropad1d = ZeroPad1D(padding=pad) @@ -68,20 +66,19 @@ def test_support_pad3(self): def test_support_pad4(self): pad = [1, 2] x = np.random.randint(-255, 255, size=self.shape) - expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[0], pad[1]]] - ) + expect_res = np.pad(x, [[0, 0], [0, 0], [pad[0], pad[1]]]) x_tensor = to_tensor(x) pad_tensor = to_tensor(pad, dtype='int32') zeropad1d = ZeroPad1D(padding=pad_tensor) ret_res = zeropad1d(x_tensor).numpy() np.testing.assert_allclose(expect_res, ret_res, rtol=1e-05) - + def test_repr(self): pad = [1, 2] zeropad1d = ZeroPad1D(padding=pad) - zeropad1d.extra_repr() + name_str = zeropad1d.extra_repr() + assert name_str == 'padding=[1, 2], data_format=NCL' if __name__ == '__main__': diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index 4ba64024ae2cc8..c666009684a6ad 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -45,7 +45,16 @@ def test_support_pad2(self): pad = [1, 2, 3, 4, 5, 6] x = np.random.randint(-255, 255, size=self.shape) expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [pad[2], pad[3]], [pad[0], pad[1]]], mode='constant', constant_values=0 + x, + [ + [0, 0], + [0, 0], + [pad[4], pad[5]], + [pad[2], pad[3]], + [pad[0], pad[1]], + ], + mode='constant', + constant_values=0, ) x_tensor = to_tensor(x) @@ -57,8 +66,14 @@ def test_support_pad3(self): pad = (1, 2, 3, 4, 5, 6) x = np.random.randint(-255, 255, size=self.shape) expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [ - pad[2], pad[3]], [pad[0], pad[1]]] + x, + [ + [0, 0], + [0, 0], + [pad[4], pad[5]], + [pad[2], pad[3]], + [pad[0], pad[1]], + ], ) x_tensor = to_tensor(x) @@ -70,8 +85,14 @@ def test_support_pad4(self): pad = [1, 2, 3, 4, 5, 6] x = np.random.randint(-255, 255, size=self.shape) expect_res = np.pad( - x, [[0, 0], [0, 0], [pad[4], pad[5]], [ - pad[2], pad[3]], [pad[0], pad[1]]] + x, + [ + [0, 0], + [0, 0], + [pad[4], pad[5]], + [pad[2], pad[3]], + [pad[0], pad[1]], + ], ) x_tensor = to_tensor(x) @@ -83,7 +104,8 @@ def test_support_pad4(self): def test_repr(self): pad = pad = [1, 2, 3, 4, 5, 6] zeropad3d = ZeroPad3D(padding=pad) - zeropad3d.extra_repr() + name_str = zeropad3d.extra_repr() + assert name_str == 'padding=[1, 2, 3, 4, 5, 6], data_format=NCDHW' if __name__ == '__main__': From cda4dcada48286296acb6bcee0baf79559193101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Thu, 9 May 2024 16:13:28 +0800 Subject: [PATCH 13/22] update cpu/gpu --- test/legacy_test/test_ZeroPad1d.py | 5 +++++ test/legacy_test/test_ZeroPad3d.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/test/legacy_test/test_ZeroPad1d.py b/test/legacy_test/test_ZeroPad1d.py index 2f839016b116ce..31baf6a7cf2468 100644 --- a/test/legacy_test/test_ZeroPad1d.py +++ b/test/legacy_test/test_ZeroPad1d.py @@ -16,12 +16,17 @@ import numpy as np +import paddle from paddle import to_tensor from paddle.nn import ZeroPad1D class TestZeroPad1dAPI(unittest.TestCase): def setUp(self): + if paddle.is_compiled_with_cuda(): + paddle.device.set_device('gpu:0') + else: + paddle.device.set_device('cpu') self.shape = [4, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index c666009684a6ad..edac3865657f49 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -22,6 +22,10 @@ class TestZeroPad3DAPI(unittest.TestCase): def setUp(self): + if paddle.is_compiled_with_cuda(): + paddle.device.set_device('gpu:0') + else: + paddle.device.set_device('cpu') self.shape = [4, 3, 6, 6, 6] self.support_dtypes = ['float32', 'float64', 'int32', 'int64'] From b382c5e89074932c4fdbd8b85a3134ca57de02b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Thu, 9 May 2024 20:01:44 +0800 Subject: [PATCH 14/22] update --- test/legacy_test/test_ZeroPad3d.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/legacy_test/test_ZeroPad3d.py b/test/legacy_test/test_ZeroPad3d.py index edac3865657f49..8cc7a45c959df8 100644 --- a/test/legacy_test/test_ZeroPad3d.py +++ b/test/legacy_test/test_ZeroPad3d.py @@ -16,6 +16,7 @@ import numpy as np +import paddle from paddle import to_tensor from paddle.nn import ZeroPad3D From 9dddaa5a9b2caeead8c8d1deaf476c8f8a03ff0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 20 May 2024 15:55:06 +0800 Subject: [PATCH 15/22] update file --- python/paddle/nn/__init__.py | 6 +- python/paddle/nn/layer/common.py | 125 ++++++++++++++++++++++++++ python/paddle/nn/layer/padding.py | 142 ------------------------------ 3 files changed, 127 insertions(+), 146 deletions(-) delete mode 100644 python/paddle/nn/layer/padding.py diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index 9f6e26a5d63161..e3451e3222c617 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -70,6 +70,8 @@ UpsamplingBilinear2D, UpsamplingNearest2D, ZeroPad2D, + ZeroPad1D, + ZeroPad3D, ) # TODO: import all neural network related api under this directory, @@ -122,10 +124,6 @@ SpectralNorm, SyncBatchNorm, ) -from .layer.padding import ( - ZeroPad1D, - ZeroPad3D, -) from .layer.pooling import ( AdaptiveAvgPool1D, AdaptiveAvgPool2D, diff --git a/python/paddle/nn/layer/common.py b/python/paddle/nn/layer/common.py index 6faf07bb6eb19d..7f979ffb530ab6 100644 --- a/python/paddle/nn/layer/common.py +++ b/python/paddle/nn/layer/common.py @@ -1077,6 +1077,67 @@ def extra_repr(self): return f'padding={self._pad}, mode={self._mode}, value={self._value}, data_format={self._data_format}{name_str}' +class ZeroPad1D(Layer): + """ + This interface is used to construct a callable object of the ``ZeroPad1D`` class. + Pads the input tensor boundaries with zero. + + Parameters: + padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the + same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. + The pad has the form (pad_left, pad_right). + data_format (str): An string from: "NCL", "NCL". Specify the data format of the input data. + Default is "NCL" + name (str, optional) : The default value is None. Normally there is no need for + user to set this property. For more information, please refer to :ref:`api_guide_Name`. + + Shape: + - x(Tensor): The input tensor of zeropad1d operator, which is a 3-D tensor. + The data type can be float32, float64. + - output(Tensor): The output tensor of zeropad1d operator, which is a 3-D tensor. + The data type is same as input x. + + Examples: + + .. code-block:: python + + >>> import paddle + >>> import paddle.nn as nn + + >>> input_shape = (1, 2, 3) + >>> pad = [1, 2] + >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 + >>> my_pad = nn.ZeroPad1D(padding=pad) + >>> result = my_pad(data) + >>> print(result) + Tensor(shape=[1, 2, 6], dtype=float32, place=Place(cpu), stop_gradient=True, + [[[0., 1., 2., 3., 0., 0.], + [0., 4., 5., 6., 0., 0.]]]) + """ + + def __init__(self, padding, data_format="NCL", name=None): + super().__init__() + self._pad = _npairs(padding, 1) + self._mode = 'constant' + self._value = 0.0 + self._data_format = data_format + self._name = name + + def forward(self, x): + return F.pad( + x, + pad=self._pad, + mode=self._mode, + value=self._value, + data_format=self._data_format, + name=self._name, + ) + + def extra_repr(self): + name_str = f', name={self._name}' if self._name else '' + return f'padding={self._pad}, data_format={self._data_format}{name_str}' + + class Pad2D(Layer): """ This interface is used to construct a callable object of the ``Pad2D`` class. @@ -1290,6 +1351,70 @@ def extra_repr(self): return f'padding={self._pad}, mode={self._mode}, value={self._value}, data_format={self._data_format}{name_str}' +class ZeroPad3D(Layer): + """ + This interface is used to construct a callable object of the ``ZeroPad3D`` class. + Pads the input tensor boundaries with zero. + + Parameters: + padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the + same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. + The pad has the form (pad_left, pad_right, pad_top, pad_bottom, pad_front, pad_back). + data_format (str): An string from: "NCDHW", "NCDHW". Specify the data format of the input data. + Default is "NCDHW" + name (str, optional) : The default value is None. Normally there is no need for + user to set this property. For more information, please refer to :ref:`api_guide_Name`. + + Shape: + - x(Tensor): The input tensor of zeropad3d operator, which is a 5-D tensor. + The data type can be float32, float64. + - output(Tensor): The output tensor of zeropad3d operator, which is a 5-D tensor. + The data type is same as input x. + + Examples: + + .. code-block:: python + + >>> import paddle + >>> import paddle.nn as nn + + >>> input_shape = (1, 1, 1, 2, 3) + >>> pad = [1, 0, 1, 2, 0, 0] + >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 + >>> my_pad = nn.ZeroPad3D(padding=pad) + >>> result = my_pad(data) + >>> print(result) + Tensor(shape=[1, 1, 1, 5, 4], dtype=float32, place=Place(cpu), stop_gradient=True, + [[[[[0., 0., 0., 0.], + [0., 1., 2., 3.], + [0., 4., 5., 6.], + [0., 0., 0., 0.], + [0., 0., 0., 0.]]]]]) + """ + + def __init__(self, padding, data_format="NCDHW", name=None): + super().__init__() + self._pad = _npairs(padding, 3) + self._mode = 'constant' + self._value = 0.0 + self._data_format = data_format + self._name = name + + def forward(self, x): + return F.pad( + x, + pad=self._pad, + mode=self._mode, + value=self._value, + data_format=self._data_format, + name=self._name, + ) + + def extra_repr(self): + name_str = f', name={self._name}' if self._name else '' + return f'padding={self._pad}, data_format={self._data_format}{name_str}' + + class CosineSimilarity(Layer): """ This interface is used to compute cosine similarity between x1 and x2 along axis. diff --git a/python/paddle/nn/layer/padding.py b/python/paddle/nn/layer/padding.py deleted file mode 100644 index f1fde220e12c95..00000000000000 --- a/python/paddle/nn/layer/padding.py +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright (c) 2024 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. - -from .. import functional as F -from .common import _npairs -from .layers import Layer - - -class ZeroPad1D(Layer): - """ - This interface is used to construct a callable object of the ``ZeroPad1D`` class. - Pads the input tensor boundaries with zero. - - Parameters: - padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the - same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. - The pad has the form (pad_left, pad_right). - data_format (str): An string from: "NCL", "NCL". Specify the data format of the input data. - Default is "NCL" - name (str, optional) : The default value is None. Normally there is no need for - user to set this property. For more information, please refer to :ref:`api_guide_Name`. - - Shape: - - x(Tensor): The input tensor of zeropad1d operator, which is a 3-D tensor. - The data type can be float32, float64. - - output(Tensor): The output tensor of zeropad1d operator, which is a 3-D tensor. - The data type is same as input x. - - Examples: - - .. code-block:: python - - >>> import paddle - >>> import paddle.nn as nn - - >>> input_shape = (1, 2, 3) - >>> pad = [1, 2] - >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 - >>> my_pad = nn.ZeroPad1D(padding=pad) - >>> result = my_pad(data) - >>> print(result) - Tensor(shape=[1, 2, 6], dtype=float32, place=Place(cpu), stop_gradient=True, - [[[0., 1., 2., 3., 0., 0.], - [0., 4., 5., 6., 0., 0.]]]) - """ - - def __init__(self, padding, data_format="NCL", name=None): - super().__init__() - self._pad = _npairs(padding, 1) - self._mode = 'constant' - self._value = 0.0 - self._data_format = data_format - self._name = name - - def forward(self, x): - return F.pad( - x, - pad=self._pad, - mode=self._mode, - value=self._value, - data_format=self._data_format, - name=self._name, - ) - - def extra_repr(self): - name_str = f', name={self._name}' if self._name else '' - return f'padding={self._pad}, data_format={self._data_format}{name_str}' - - -class ZeroPad3D(Layer): - """ - This interface is used to construct a callable object of the ``ZeroPad3D`` class. - Pads the input tensor boundaries with zero. - - Parameters: - padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the - same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. - The pad has the form (pad_left, pad_right, pad_top, pad_bottom, pad_front, pad_back). - data_format (str): An string from: "NCDHW", "NCDHW". Specify the data format of the input data. - Default is "NCDHW" - name (str, optional) : The default value is None. Normally there is no need for - user to set this property. For more information, please refer to :ref:`api_guide_Name`. - - Shape: - - x(Tensor): The input tensor of zeropad3d operator, which is a 5-D tensor. - The data type can be float32, float64. - - output(Tensor): The output tensor of zeropad3d operator, which is a 5-D tensor. - The data type is same as input x. - - Examples: - - .. code-block:: python - - >>> import paddle - >>> import paddle.nn as nn - - >>> input_shape = (1, 1, 1, 2, 3) - >>> pad = [1, 0, 1, 2, 0, 0] - >>> data = paddle.arange(paddle.prod(paddle.to_tensor(input_shape)), dtype="float32").reshape(input_shape) + 1 - >>> my_pad = nn.ZeroPad3D(padding=pad) - >>> result = my_pad(data) - >>> print(result) - Tensor(shape=[1, 1, 1, 5, 4], dtype=float32, place=Place(cpu), stop_gradient=True, - [[[[[0., 0., 0., 0.], - [0., 1., 2., 3.], - [0., 4., 5., 6.], - [0., 0., 0., 0.], - [0., 0., 0., 0.]]]]]) - """ - - def __init__(self, padding, data_format="NCDHW", name=None): - super().__init__() - self._pad = _npairs(padding, 3) - self._mode = 'constant' - self._value = 0.0 - self._data_format = data_format - self._name = name - - def forward(self, x): - return F.pad( - x, - pad=self._pad, - mode=self._mode, - value=self._value, - data_format=self._data_format, - name=self._name, - ) - - def extra_repr(self): - name_str = f', name={self._name}' if self._name else '' - return f'padding={self._pad}, data_format={self._data_format}{name_str}' From 940d3659d88464036cf47a9150ada08c571306da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 20 May 2024 16:45:49 +0800 Subject: [PATCH 16/22] update --- python/paddle/nn/layer/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python/paddle/nn/layer/__init__.py b/python/paddle/nn/layer/__init__.py index 7bd733efad5a7b..6516c85bdefffb 100644 --- a/python/paddle/nn/layer/__init__.py +++ b/python/paddle/nn/layer/__init__.py @@ -90,10 +90,6 @@ SpectralNorm, SyncBatchNorm, ) -from .padding import ( # noqa: F401 - ZeroPad1D, - ZeroPad3D, -) from .pooling import ( # noqa: F401 AdaptiveAvgPool1D, AdaptiveAvgPool2D, From 832059ff17e8b42a5e03e88940e0aa343a820b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Mon, 20 May 2024 20:34:20 +0800 Subject: [PATCH 17/22] update --- python/paddle/nn/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/nn/__init__.py b/python/paddle/nn/__init__.py index e3451e3222c617..6a7cf78d55b024 100644 --- a/python/paddle/nn/__init__.py +++ b/python/paddle/nn/__init__.py @@ -69,8 +69,8 @@ Upsample, UpsamplingBilinear2D, UpsamplingNearest2D, - ZeroPad2D, ZeroPad1D, + ZeroPad2D, ZeroPad3D, ) From 333f225ca0ca0e28a87df2fb1cdd38683919a371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Wed, 22 May 2024 12:41:22 +0800 Subject: [PATCH 18/22] update --- python/paddle/tensor/manipulation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index 78f581b7c2be73..63b489eb660e86 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6845,12 +6845,12 @@ def slice_scatter(x, value, axes, starts, ends, strides, name=None): return output -def block_diag(*inputs, name=None): +def block_diag(inputs, name=None): """ Create a block diagonal matrix from provided tensors. Args: - *input (Tensor): One or more tensors with 0, 1, or 2 dimensions. + input (list|tuple): ``input`` is a Tensor list or Tensor tuple, one or more tensors with 0, 1, or 2 dimensions. name (str, optional): Name for the operation (optional, default is None). Returns: From 8fd3aebe3c320f9b3e89e814e94b30ebaf2a5cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Wed, 22 May 2024 19:54:02 +0800 Subject: [PATCH 19/22] update --- python/paddle/tensor/manipulation.py | 2 +- test/legacy_test/test_block_diag.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index c8aaaf8a05cfac..ef2a88c7f78354 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6884,7 +6884,7 @@ def block_diag(inputs, name=None): >>> C = paddle.to_tensor(1) >>> D = paddle.to_tensor([[5, 4, 3], [2, 1, 0]]) >>> E = paddle.to_tensor([[8, 7], [7, 8]]) - >>> out = paddle.block_diag(A, B, C, D, E) + >>> out = paddle.block_diag([A, B, C, D, E]) >>> print(out) Tensor(shape=[9, 10], dtype=int64, place=Place(gpu:0), stop_gradient=True, [[4, 0, 0, 0, 0, 0, 0, 0, 0, 0], diff --git a/test/legacy_test/test_block_diag.py b/test/legacy_test/test_block_diag.py index 691474f001a380..842f360f33c4b7 100644 --- a/test/legacy_test/test_block_diag.py +++ b/test/legacy_test/test_block_diag.py @@ -28,7 +28,7 @@ def test_type_error(): B = np.array([[5, 6], [7, 8]]) C = np.array([[9, 10], [11, 12]]) with paddle.static.program_guard(base.Program()): - out = paddle.block_diag(A, B, C) + out = paddle.block_diag([A, B, C]) self.assertRaises(TypeError, test_type_error) @@ -37,7 +37,7 @@ def test_dime_error(): B = paddle.to_tensor([[[5, 6], [7, 8]]]) C = paddle.to_tensor([[[9, 10], [11, 12]]]) with paddle.static.program_guard(base.Program()): - out = paddle.block_diag(A, B, C) + out = paddle.block_diag([A, B, C]) self.assertRaises(ValueError, test_dime_error) @@ -65,7 +65,7 @@ def test_dygraph(self): A_tensor = paddle.to_tensor(A) B_tensor = paddle.to_tensor(B) C_tensor = paddle.to_tensor(C) - out = paddle.block_diag(A_tensor, B_tensor, C_tensor) + out = paddle.block_diag([A_tensor, B_tensor, C_tensor]) np.testing.assert_allclose(out.numpy(), s_out) def test_static(self): @@ -82,7 +82,7 @@ def test_static(self): A_tensor = paddle.static.data('A', [2, 3], i) B_tensor = paddle.static.data('B', [2], i) C_tensor = paddle.static.data('C', [4, 1], i) - out = paddle.block_diag(A_tensor, B_tensor, C_tensor) + out = paddle.block_diag([A_tensor, B_tensor, C_tensor]) exe = paddle.static.Executor(place) res = exe.run( feed={'A': A, 'B': B, 'C': C}, From 97bfa5f1f888db4d9efa1d45f42de792560d9edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Thu, 23 May 2024 12:48:18 +0800 Subject: [PATCH 20/22] update --- python/paddle/nn/layer/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/nn/layer/common.py b/python/paddle/nn/layer/common.py index 7f979ffb530ab6..bbce96a7ede143 100644 --- a/python/paddle/nn/layer/common.py +++ b/python/paddle/nn/layer/common.py @@ -1086,7 +1086,7 @@ class ZeroPad1D(Layer): padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. The pad has the form (pad_left, pad_right). - data_format (str): An string from: "NCL", "NCL". Specify the data format of the input data. + data_format (str): An string from: "NCL", "NLC". Specify the data format of the input data. Default is "NCL" name (str, optional) : The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. From c8b7a846aedcc45578975040e9e335dd920b3fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Thu, 23 May 2024 12:48:52 +0800 Subject: [PATCH 21/22] finish --- python/paddle/nn/layer/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/nn/layer/common.py b/python/paddle/nn/layer/common.py index bbce96a7ede143..6b34c9fa90f6bf 100644 --- a/python/paddle/nn/layer/common.py +++ b/python/paddle/nn/layer/common.py @@ -1360,7 +1360,7 @@ class ZeroPad3D(Layer): padding (Tensor | List[int] | int): The padding size with data type int. If is int, use the same padding in all dimensions. Else [len(padding)/2] dimensions of input will be padded. The pad has the form (pad_left, pad_right, pad_top, pad_bottom, pad_front, pad_back). - data_format (str): An string from: "NCDHW", "NCDHW". Specify the data format of the input data. + data_format (str): An string from: "NCDHW", "NDHWC". Specify the data format of the input data. Default is "NCDHW" name (str, optional) : The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. From d05dd19b31a5533945a917f46e5a7c41b8129fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=A7?= <2085127827@qq.com> Date: Thu, 23 May 2024 13:00:58 +0800 Subject: [PATCH 22/22] update --- python/paddle/tensor/manipulation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/tensor/manipulation.py b/python/paddle/tensor/manipulation.py index ef2a88c7f78354..dc26bc13537293 100644 --- a/python/paddle/tensor/manipulation.py +++ b/python/paddle/tensor/manipulation.py @@ -6868,11 +6868,11 @@ def block_diag(inputs, name=None): Create a block diagonal matrix from provided tensors. Args: - input (list|tuple): ``input`` is a Tensor list or Tensor tuple, one or more tensors with 0, 1, or 2 dimensions. + inputs (list|tuple): ``inputs`` is a Tensor list or Tensor tuple, one or more tensors with 0, 1, or 2 dimensions. name (str, optional): Name for the operation (optional, default is None). Returns: - Tensor, A ``Tensor``. The data type is same as ``input``. + Tensor, A ``Tensor``. The data type is same as ``inputs``. Examples: .. code-block:: python