diff --git a/paddle/fluid/pybind/eager_method.cc b/paddle/fluid/pybind/eager_method.cc index b8f610f8c06dbc..b893d492456aa7 100644 --- a/paddle/fluid/pybind/eager_method.cc +++ b/paddle/fluid/pybind/eager_method.cc @@ -2883,6 +2883,7 @@ PyDoc_STRVAR(tensor_to_sparse_csr__doc__, // NOLINT Convert input Tensor to SparseCsrTensor. When input is SparseCooTensor, will convert `COO` to `CSR` . When input is DenseTensor, will convert `Dense` to `CSR` . +When input is SparseCsrTensor, the function will directly return the input itself without performing any conversion. Returns: SparseCsrTensor @@ -2909,6 +2910,10 @@ static PyObject* tensor_method_to_sparse_csr(TensorObject* self, PyObject* args, PyObject* kwargs) { EAGER_TRY + if (self->tensor.is_sparse_csr_tensor()) { + Py_INCREF(self); + return reinterpret_cast(self); + } auto csr_tensor = self->tensor.to_sparse_csr(); egr::EagerUtils::autograd_meta(&csr_tensor) ->SetStopGradient( diff --git a/python/paddle/base/dygraph/tensor_patch_methods.py b/python/paddle/base/dygraph/tensor_patch_methods.py index f9545777153f21..d6ef4b74ed0143 100644 --- a/python/paddle/base/dygraph/tensor_patch_methods.py +++ b/python/paddle/base/dygraph/tensor_patch_methods.py @@ -1256,7 +1256,9 @@ def to_sparse_coo(self: Tensor, sparse_dim: int) -> Tensor: **Notes**: **This API is ONLY available in Dygraph mode** - Convert the current DenseTensor to SparseTensor in COO format. + Convert the current DenseTensor to SparseTensor in COO format. When the input is already a SparseCooTensor, this function will directly return + the input itself without performing any conversion. + Returns: Tensor: A SparseCooTensor @@ -1274,6 +1276,8 @@ def to_sparse_coo(self: Tensor, sparse_dim: int) -> Tensor: [1, 3, 2, 3]], values=[1., 2., 3., 4.]) """ + if self.is_sparse_coo(): + return self return _C_ops.sparse_to_sparse_coo(self, sparse_dim) diff --git a/test/legacy_test/test_sparse_utils_op.py b/test/legacy_test/test_sparse_utils_op.py index b5d878d52c2499..e878cdce677ed4 100644 --- a/test/legacy_test/test_sparse_utils_op.py +++ b/test/legacy_test/test_sparse_utils_op.py @@ -180,6 +180,29 @@ def test_to_sparse_coo(self): dense_x.grad.numpy(), out_grad.to_dense().numpy() ) + def test_coo_to_coo(self): + indices = [[0, 0, 1, 2, 2], [1, 3, 2, 0, 1]] + values = [1.0, 2.0, 3.0, 4.0, 5.0] + sparse_x = paddle.sparse.sparse_coo_tensor( + paddle.to_tensor(indices), + paddle.to_tensor(values), + shape=[3, 4], + stop_gradient=False, + ) + sparse_x_ = sparse_x.to_sparse_coo(2) + assert sparse_x is sparse_x_ + + def test_csr_to_csr(self): + crows = [0, 2, 3, 5] + cols = [1, 3, 2, 0, 1] + values = [1.0, 2.0, 3.0, 4.0, 5.0] + crows = paddle.to_tensor(crows, dtype='int32') + cols = paddle.to_tensor(cols, dtype='int32') + values = paddle.to_tensor(values, dtype='float32') + sparse_x = paddle.sparse.sparse_csr_tensor(crows, cols, values) + sparse_x_ = sparse_x.to_sparse_csr() + assert sparse_x is sparse_x_ + def test_coo_to_dense(self): indices = [[0, 0, 1, 2, 2], [1, 3, 2, 0, 1]] values = [1.0, 2.0, 3.0, 4.0, 5.0]