From e6bf0bf32d4a6cceefedfcb5e44cf3aa59289264 Mon Sep 17 00:00:00 2001 From: gsq7474741 <38883252+gsq7474741@users.noreply.github.com> Date: Thu, 11 Aug 2022 20:31:42 +0800 Subject: [PATCH 1/5] add paddle.incubate.sparse.is_same_shape --- paddle/fluid/pybind/eager_method.cc | 13 ++ .../tests/unittests/test_sparse_multiary.py | 125 ++++++++++++++++++ python/paddle/incubate/sparse/__init__.py | 2 + python/paddle/incubate/sparse/multiary.py | 31 +++++ 4 files changed, 171 insertions(+) create mode 100644 python/paddle/fluid/tests/unittests/test_sparse_multiary.py diff --git a/paddle/fluid/pybind/eager_method.cc b/paddle/fluid/pybind/eager_method.cc index e7978b8e23ac4..d1ba1696a03b9 100644 --- a/paddle/fluid/pybind/eager_method.cc +++ b/paddle/fluid/pybind/eager_method.cc @@ -1543,6 +1543,15 @@ static PyObject* tensor_method_to_sparse_csr(TensorObject* self, EAGER_CATCH_AND_THROW_RETURN_NULL } +static PyObject* tensor_method_is_same_shape(TensorObject* self, + PyObject* args, + PyObject* kwargs) { + EAGER_TRY + auto other = CastPyArg2Tensor(PyTuple_GET_ITEM(args, 0), 0); + return ToPyObject(self->tensor.shape() == other.shape()); + EAGER_CATCH_AND_THROW_RETURN_NULL +} + static PyObject* tensor__inplace_version(TensorObject* self, PyObject* args, PyObject* kwargs) { @@ -1934,6 +1943,10 @@ PyMethodDef variable_methods[] = { (PyCFunction)(void (*)(void))tensor_method_is_sparse_csr, METH_VARARGS | METH_KEYWORDS, NULL}, + {"is_same_shape", + (PyCFunction)(void (*)(void))tensor_method_is_same_shape, + METH_VARARGS | METH_KEYWORDS, + NULL}, {"to_sparse_csr", (PyCFunction)(void (*)(void))tensor_method_to_sparse_csr, METH_VARARGS | METH_KEYWORDS, diff --git a/python/paddle/fluid/tests/unittests/test_sparse_multiary.py b/python/paddle/fluid/tests/unittests/test_sparse_multiary.py new file mode 100644 index 0000000000000..835ac4c6e507b --- /dev/null +++ b/python/paddle/fluid/tests/unittests/test_sparse_multiary.py @@ -0,0 +1,125 @@ +# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function +import unittest + +import paddle +from paddle.incubate.sparse.multiary import is_same_shape + + +class TestSparseMultiaryAPI(unittest.TestCase): + """ + test paddle.incubate.sparse.is_same_shape + """ + + def setUp(self): + self.shapes = [[2, 5, 8], [3, 4]] + self.tensors = [ + paddle.rand(self.shapes[0]), + paddle.rand(self.shapes[0]), + paddle.rand(self.shapes[1]) + ] + self.sparse_dim = 2 + + def test_dense_dense(self): + self.assertTrue(is_same_shape(self.tensors[0], self.tensors[1])) + self.assertFalse(is_same_shape(self.tensors[0], self.tensors[2])) + self.assertFalse(is_same_shape(self.tensors[1], self.tensors[2])) + + def test_dense_csr(self): + self.assertTrue( + is_same_shape(self.tensors[0], self.tensors[1].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[0], self.tensors[2].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[1], self.tensors[2].to_sparse_csr())) + + def test_dense_coo(self): + self.assertTrue( + is_same_shape(self.tensors[0], + self.tensors[1].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[0], + self.tensors[2].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[1], + self.tensors[2].to_sparse_coo(self.sparse_dim))) + + def test_csr_dense(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_csr(), self.tensors[1])) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_csr(), self.tensors[2])) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_csr(), self.tensors[2])) + + def test_csr_csr(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_csr(), + self.tensors[1].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_csr(), + self.tensors[2].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_csr(), + self.tensors[2].to_sparse_csr())) + + def test_csr_coo(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_csr(), + self.tensors[1].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_csr(), + self.tensors[2].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_csr(), + self.tensors[2].to_sparse_coo(self.sparse_dim))) + + def test_coo_dense(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[1])) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[2])) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_coo(self.sparse_dim), + self.tensors[2])) + + def test_coo_csr(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[1].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[2].to_sparse_csr())) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_coo(self.sparse_dim), + self.tensors[2].to_sparse_csr())) + + def test_coo_coo(self): + self.assertTrue( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[1].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[0].to_sparse_coo(self.sparse_dim), + self.tensors[2].to_sparse_coo(self.sparse_dim))) + self.assertFalse( + is_same_shape(self.tensors[1].to_sparse_coo(self.sparse_dim), + self.tensors[2].to_sparse_coo(self.sparse_dim))) + + +if __name__ == "__main__": + unittest.main() diff --git a/python/paddle/incubate/sparse/__init__.py b/python/paddle/incubate/sparse/__init__.py index 8408c3ca27730..d3c41a9c45f1b 100644 --- a/python/paddle/incubate/sparse/__init__.py +++ b/python/paddle/incubate/sparse/__init__.py @@ -44,6 +44,7 @@ from .binary import subtract from .multiary import addmm +from .multiary import is_same_shape from . import nn @@ -77,4 +78,5 @@ 'multiply', 'divide', 'coalesce', + 'is_same_shape', ] diff --git a/python/paddle/incubate/sparse/multiary.py b/python/paddle/incubate/sparse/multiary.py index 17cf75fdc3903..0b014b8c57b65 100644 --- a/python/paddle/incubate/sparse/multiary.py +++ b/python/paddle/incubate/sparse/multiary.py @@ -79,3 +79,34 @@ def addmm(input, x, y, beta=1.0, alpha=1.0, name=None): """ return _C_ops.final_state_sparse_addmm(input, x, y, alpha, beta) + + +@dygraph_only +def is_same_shape(x, y): + """ + Check whether x.shape equal to y.shape. + + Args: + x (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. + y (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. + + Returns: + bool: True for same shape and False for different shape. + + Examples: + + .. code-block:: python + + import paddle + + x = paddle.rand([2, 3, 8]) + y = paddle.rand([2, 3, 8]) + z = paddle.rand([2, 5]) + + paddle.incubate.sparse.is_same_shape(x, y) + # True + paddle.incubate.sparse.is_same_shape(x, z) + # False + + """ + return x.is_same_shape(y) From c4c6db08c295364ee224eaf80d76c106cae4d11b Mon Sep 17 00:00:00 2001 From: gsq7474741 <38883252+gsq7474741@users.noreply.github.com> Date: Tue, 16 Aug 2022 13:13:10 +0800 Subject: [PATCH 2/5] add paddle.incubate.sparse.is_same_shape --- ...ltiary.py => test_sparse_is_same_shape.py} | 4 +-- python/paddle/incubate/sparse/__init__.py | 2 +- python/paddle/incubate/sparse/binary.py | 32 +++++++++++++++++++ python/paddle/incubate/sparse/multiary.py | 31 ------------------ 4 files changed, 35 insertions(+), 34 deletions(-) rename python/paddle/fluid/tests/unittests/{test_sparse_multiary.py => test_sparse_is_same_shape.py} (97%) diff --git a/python/paddle/fluid/tests/unittests/test_sparse_multiary.py b/python/paddle/fluid/tests/unittests/test_sparse_is_same_shape.py similarity index 97% rename from python/paddle/fluid/tests/unittests/test_sparse_multiary.py rename to python/paddle/fluid/tests/unittests/test_sparse_is_same_shape.py index 835ac4c6e507b..aac5d04a76338 100644 --- a/python/paddle/fluid/tests/unittests/test_sparse_multiary.py +++ b/python/paddle/fluid/tests/unittests/test_sparse_is_same_shape.py @@ -16,10 +16,10 @@ import unittest import paddle -from paddle.incubate.sparse.multiary import is_same_shape +from paddle.incubate.sparse.binary import is_same_shape -class TestSparseMultiaryAPI(unittest.TestCase): +class TestSparseIsSameShapeAPI(unittest.TestCase): """ test paddle.incubate.sparse.is_same_shape """ diff --git a/python/paddle/incubate/sparse/__init__.py b/python/paddle/incubate/sparse/__init__.py index d3c41a9c45f1b..de89f46438a35 100644 --- a/python/paddle/incubate/sparse/__init__.py +++ b/python/paddle/incubate/sparse/__init__.py @@ -42,9 +42,9 @@ from .binary import divide from .binary import multiply from .binary import subtract +from .binary import is_same_shape from .multiary import addmm -from .multiary import is_same_shape from . import nn diff --git a/python/paddle/incubate/sparse/binary.py b/python/paddle/incubate/sparse/binary.py index 7a7861f7b20e7..0330bd7f471ef 100644 --- a/python/paddle/incubate/sparse/binary.py +++ b/python/paddle/incubate/sparse/binary.py @@ -399,3 +399,35 @@ def divide(x, y, name=None): if y.dtype != x.dtype: y = _C_ops.final_state_sparse_cast(y, None, x.dtype) return _C_ops.final_state_sparse_divide(x, y) + + +@dygraph_only +def is_same_shape(x, y): + """ + Check whether x.shape equal to y.shape. + + Args: + x (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. + y (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. + + Returns: + bool: True for same shape and False for different shape. + + Examples: + + .. code-block:: python + + import paddle + + x = paddle.rand([2, 3, 8]) + y = paddle.rand([2, 3, 8]) + y = y.to_sparse_csr() + z = paddle.rand([2, 5]) + + paddle.incubate.sparse.is_same_shape(x, y) + # True + paddle.incubate.sparse.is_same_shape(x, z) + # False + + """ + return x.is_same_shape(y) \ No newline at end of file diff --git a/python/paddle/incubate/sparse/multiary.py b/python/paddle/incubate/sparse/multiary.py index 0b014b8c57b65..17cf75fdc3903 100644 --- a/python/paddle/incubate/sparse/multiary.py +++ b/python/paddle/incubate/sparse/multiary.py @@ -79,34 +79,3 @@ def addmm(input, x, y, beta=1.0, alpha=1.0, name=None): """ return _C_ops.final_state_sparse_addmm(input, x, y, alpha, beta) - - -@dygraph_only -def is_same_shape(x, y): - """ - Check whether x.shape equal to y.shape. - - Args: - x (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. - y (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor. - - Returns: - bool: True for same shape and False for different shape. - - Examples: - - .. code-block:: python - - import paddle - - x = paddle.rand([2, 3, 8]) - y = paddle.rand([2, 3, 8]) - z = paddle.rand([2, 5]) - - paddle.incubate.sparse.is_same_shape(x, y) - # True - paddle.incubate.sparse.is_same_shape(x, z) - # False - - """ - return x.is_same_shape(y) From d16e02dd132e6e27ca3f17c1bc761a9184b5ac6a Mon Sep 17 00:00:00 2001 From: gsq7474741 <38883252+gsq7474741@users.noreply.github.com> Date: Mon, 22 Aug 2022 15:18:08 +0800 Subject: [PATCH 3/5] add paddle.incubate.sparse.is_same_shape --- python/paddle/incubate/sparse/binary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/paddle/incubate/sparse/binary.py b/python/paddle/incubate/sparse/binary.py index 0330bd7f471ef..267343afb0813 100644 --- a/python/paddle/incubate/sparse/binary.py +++ b/python/paddle/incubate/sparse/binary.py @@ -430,4 +430,4 @@ def is_same_shape(x, y): # False """ - return x.is_same_shape(y) \ No newline at end of file + return x.is_same_shape(y) From 33b09c9ff64d1038e27d6ea4df65b03d630c9bce Mon Sep 17 00:00:00 2001 From: gsq7474741 <38883252+gsq7474741@users.noreply.github.com> Date: Tue, 6 Sep 2022 18:56:43 +0800 Subject: [PATCH 4/5] add paddle.incubate.sparse.is_same_shape --- python/paddle/incubate/sparse/binary.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/paddle/incubate/sparse/binary.py b/python/paddle/incubate/sparse/binary.py index cbb603a708657..6b207187080ef 100644 --- a/python/paddle/incubate/sparse/binary.py +++ b/python/paddle/incubate/sparse/binary.py @@ -431,4 +431,3 @@ def is_same_shape(x, y): """ return x.is_same_shape(y) - From 86aaa2e869156f8f751d0784cc49d3ae21c6e54b Mon Sep 17 00:00:00 2001 From: gsq7474741 <38883252+gsq7474741@users.noreply.github.com> Date: Thu, 8 Sep 2022 19:33:38 +0800 Subject: [PATCH 5/5] fix doc --- python/paddle/incubate/sparse/binary.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/paddle/incubate/sparse/binary.py b/python/paddle/incubate/sparse/binary.py index 6b207187080ef..6c78628d27037 100644 --- a/python/paddle/incubate/sparse/binary.py +++ b/python/paddle/incubate/sparse/binary.py @@ -404,7 +404,8 @@ def divide(x, y, name=None): @dygraph_only def is_same_shape(x, y): """ - Check whether x.shape equal to y.shape. + Return the results of shape comparison between two Tensors, check whether x.shape equal to y.shape. + Any two type Tensor among DenseTensor/SparseCooTensor/SparseCsrTensor are supported. Args: x (Tensor): The input tensor. It can be DenseTensor/SparseCooTensor/SparseCsrTensor.