test_sparse_unary_op.py 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# 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
from typing import Union, Callable
import numpy as np
import paddle
20
import paddle.fluid as fluid
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
from paddle.fluid.framework import _test_eager_guard
from paddle import _C_ops


class TestSparseUnary(unittest.TestCase):
    def assert_raises_on_dense_tensor(self, sparse_func):
        with _test_eager_guard():
            dense_x = paddle.ones((2, 3))
            with self.assertRaises(ValueError):
                sparse_func(dense_x)

    def compare_with_dense(
            self,
            x,
            to_sparse: Callable[[paddle.Tensor], paddle.Tensor],
            dense_func: Callable[[paddle.Tensor], paddle.Tensor],
            sparse_func: Callable[[paddle.Tensor], paddle.Tensor],
            test_gradient: bool, ):
        def tensor_allclose(dense_tensor: paddle.Tensor,
                            sparse_tensor: paddle.Tensor):
            dense_numpy = dense_tensor.numpy()
            mask = ~np.isnan(dense_numpy)
            return np.allclose(dense_numpy[mask],
                               sparse_tensor.to_dense().numpy()[mask])

46
        fluid.set_flags({"FLAGS_retain_grad_for_all_tensor": True})
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
        with _test_eager_guard():
            dense_x = paddle.to_tensor(
                x, dtype="float32", stop_gradient=not test_gradient)

            sparse_x = to_sparse(dense_x)
            sparse_out = sparse_func(sparse_x)

            dense_x = paddle.to_tensor(
                x, dtype="float32", stop_gradient=not test_gradient)
            dense_out = dense_func(dense_x)

            assert tensor_allclose(dense_out, sparse_out)

            if test_gradient:
                dense_out.backward(dense_out)
                sparse_out.backward(sparse_out)
                assert tensor_allclose(dense_x.grad, sparse_x.grad)
64
        fluid.set_flags({"FLAGS_retain_grad_for_all_tensor": False})
65 66 67 68 69 70 71 72

    def test_sparse_relu(self):
        x = [[0, -1, 0, 2], [0, 0, -3, 0], [4, 5, 0, 0]]
        sparse_dim = 2
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_coo(sparse_dim),
            paddle.nn.ReLU(),
73
            paddle.incubate.sparse.nn.ReLU(),
74 75 76 77 78
            True, )
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_csr(),
            paddle.nn.ReLU(),
79
            paddle.incubate.sparse.nn.ReLU(),
80
            False, )
81
        self.assert_raises_on_dense_tensor(paddle.incubate.sparse.nn.ReLU())
82 83 84 85 86 87 88 89

    def test_sparse_sqrt(self):
        x = [[0, 16, 0, 0], [0, 0, 0, 0], [0, 4, 2, 0]]
        sparse_dim = 2
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_coo(sparse_dim),
            paddle.sqrt,
90
            paddle.incubate.sparse.sqrt,
91 92 93 94 95
            True, )
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_csr(),
            paddle.sqrt,
96
            paddle.incubate.sparse.sqrt,
97
            False, )
98
        self.assert_raises_on_dense_tensor(paddle.incubate.sparse.sqrt)
99 100 101 102 103 104 105 106

    def test_sparse_sin(self):
        x = [[0, 16, 0, 0], [0, 0, 0, 0], [0, 4, 2, 0]]
        sparse_dim = 2
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_coo(sparse_dim),
            paddle.sin,
107
            paddle.incubate.sparse.sin,
108 109 110 111 112
            True, )
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_csr(),
            paddle.sin,
113
            paddle.incubate.sparse.sin,
114
            False, )
115
        self.assert_raises_on_dense_tensor(paddle.incubate.sparse.sin)
116 117 118 119 120 121 122 123

    def test_sparse_tanh(self):
        x = [[0, 16, 0, 0], [0, 0, 0, 0], [0, -4, 2, 0]]
        sparse_dim = 2
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_coo(sparse_dim),
            paddle.tanh,
124
            paddle.incubate.sparse.tanh,
125 126 127 128 129
            True, )
        self.compare_with_dense(
            x,
            lambda x: x.to_sparse_csr(),
            paddle.tanh,
130
            paddle.incubate.sparse.tanh,
131
            False, )
132
        self.assert_raises_on_dense_tensor(paddle.incubate.sparse.tanh)
133 134 135 136


if __name__ == "__main__":
    unittest.main()