test_kron_op.py 7.6 KB
Newer Older
F
Feiyu Chan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# Copyright (c) 2020 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 numpy as np
from op_test import OpTest

import paddle
import paddle.fluid as fluid
import paddle.fluid.dygraph as dg
24
from paddle.fluid.framework import _test_eager_guard
F
Feiyu Chan 已提交
25 26 27


class TestKronOp(OpTest):
28

F
Feiyu Chan 已提交
29 30
    def setUp(self):
        self.op_type = "kron"
31
        self.python_api = paddle.kron
F
Feiyu Chan 已提交
32 33 34 35 36 37 38 39 40 41 42
        self.dtype = self._init_dtype()
        x = np.random.uniform(size=(10, 10)).astype(self.dtype)
        y = np.random.uniform(size=(10, 10)).astype(self.dtype)
        out_ref = np.kron(x, y)
        self.inputs = {'X': x, 'Y': y}
        self.outputs = {'Out': out_ref}

    def _init_dtype(self):
        return "float64"

    def test_check_output(self):
43
        self.check_output(check_eager=True)
F
Feiyu Chan 已提交
44 45

    def test_check_grad(self):
46
        self.check_grad(['X', 'Y'], 'Out', check_eager=True)
F
Feiyu Chan 已提交
47

48
    def test_check_grad_ignore_x(self):
49
        self.check_grad(['Y'], 'Out', no_grad_set=set('X'), check_eager=True)
50 51

    def test_check_grad_ignore_y(self):
52
        self.check_grad(['X'], 'Out', no_grad_set=set('Y'), check_eager=True)
53

F
Feiyu Chan 已提交
54 55

class TestKronOp2(TestKronOp):
56

F
Feiyu Chan 已提交
57 58
    def setUp(self):
        self.op_type = "kron"
59
        self.python_api = paddle.kron
F
Feiyu Chan 已提交
60 61 62 63 64 65 66 67 68
        self.dtype = self._init_dtype()
        x = np.random.uniform(size=(5, 5, 4)).astype(self.dtype)
        y = np.random.uniform(size=(10, 10)).astype(self.dtype)
        out_ref = np.kron(x, y)
        self.inputs = {'X': x, 'Y': y}
        self.outputs = {'Out': out_ref}


class TestKronOp3(TestKronOp):
69

F
Feiyu Chan 已提交
70 71
    def setUp(self):
        self.op_type = "kron"
72
        self.python_api = paddle.kron
F
Feiyu Chan 已提交
73 74 75 76 77 78 79 80 81
        self.dtype = self._init_dtype()
        x = np.random.uniform(size=(10, 10)).astype(self.dtype)
        y = np.random.uniform(size=(5, 5, 4)).astype(self.dtype)
        out_ref = np.kron(x, y)
        self.inputs = {'X': x, 'Y': y}
        self.outputs = {'Out': out_ref}


class TestKronLayer(unittest.TestCase):
82

F
Feiyu Chan 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    def test_case(self):
        a = np.random.randn(10, 10).astype(np.float64)
        b = np.random.randn(10, 10).astype(np.float64)

        place = fluid.CPUPlace()
        with dg.guard(place):
            a_var = dg.to_variable(a)
            b_var = dg.to_variable(b)
            c_var = paddle.kron(a_var, b_var)
            np.testing.assert_allclose(c_var.numpy(), np.kron(a, b))

    def test_case_with_output(self):
        a = np.random.randn(10, 10).astype(np.float64)
        b = np.random.randn(10, 10).astype(np.float64)

        main = fluid.Program()
        start = fluid.Program()
        with fluid.unique_name.guard():
            with fluid.program_guard(main, start):
                a_var = fluid.data("a", [-1, -1], dtype="float64")
                b_var = fluid.data("b", [-1, -1], dtype="float64")
W
WuHaobo 已提交
104
                out_var = paddle.kron(a_var, b_var)
F
Feiyu Chan 已提交
105 106 107 108 109 110 111

        place = fluid.CPUPlace()
        exe = fluid.Executor(place)
        exe.run(start)
        c, = exe.run(main, feed={'a': a, 'b': b}, fetch_list=[out_var])
        np.testing.assert_allclose(c, np.kron(a, b))

112 113 114 115 116
    def test_api_eager_dygraph(self):
        with _test_eager_guard():
            self.test_case()
            self.test_case_with_output()

F
Feiyu Chan 已提交
117

118
class TestComplexKronOp(OpTest):
119

120 121
    def setUp(self):
        self.op_type = "kron"
122
        self.python_api = paddle.kron
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
        self.x_shape = np.array([10, 10])
        self.y_shape = np.array([3, 35])
        self.out_shape = self.x_shape * self.y_shape
        self.init_base_dtype()
        self.init_input_output()
        self.init_grad_input_output()

        self.inputs = {
            'X': OpTest.np_dtype_to_fluid_dtype(self.x),
            'Y': OpTest.np_dtype_to_fluid_dtype(self.y)
        }
        self.attrs = {'axis': -1, 'use_mkldnn': False}
        self.outputs = {'Out': self.out}

    def init_base_dtype(self):
        self.dtype = np.float64

    def init_input_output(self):
        self.x = np.random.random(self.x_shape).astype(
            self.dtype) + 1J * np.random.random(self.x_shape).astype(self.dtype)
        self.y = np.random.random(self.y_shape).astype(
            self.dtype) + 1J * np.random.random(self.y_shape).astype(self.dtype)
        self.out = np.kron(self.x, self.y)

    def init_grad_input_output(self):
        self.grad_out = np.ones(self.out_shape, self.dtype) + 1J * np.ones(
            self.out_shape, self.dtype)
        self.grad_x = self.get_grad_x_by_numpy()
        self.grad_y = self.get_grad_y_by_numpy()

    def get_grad_x_by_numpy(self):
        grad_x = np.zeros(self.x_shape, np.complex)
        for x_i in range(self.x_shape[0]):
            for x_j in range(self.x_shape[1]):
                for i in range(self.y_shape[0]):
                    for j in range(self.y_shape[1]):
                        idx_i = x_i * self.y_shape[0] + i
                        idx_j = x_j * self.y_shape[1] + j
                        grad_x[x_i][x_j] += self.grad_out[idx_i][
                            idx_j] * np.conj(self.y[i][j])
        return grad_x

    def get_grad_y_by_numpy(self):
        grad_y = np.zeros(self.y_shape, np.complex)
        for y_i in range(self.y_shape[0]):
            for y_j in range(self.y_shape[1]):
                for x_i in range(self.x_shape[0]):
                    for x_j in range(self.x_shape[1]):
                        idx_i = x_i * self.y_shape[0] + y_i
                        idx_j = x_j * self.y_shape[1] + y_j
                        grad_y[y_i][y_j] += self.grad_out[idx_i][
                            idx_j] * np.conj(self.x[x_i][x_j])
        return grad_y

    def test_check_output(self):
178
        self.check_output(check_eager=True)
179 180

    def test_check_grad_normal(self):
181 182 183 184 185
        self.check_grad(['X', 'Y'],
                        'Out',
                        user_defined_grads=[self.grad_x, self.grad_y],
                        user_defined_grad_outputs=[self.grad_out],
                        check_eager=True)
186 187

    def test_check_grad_ingore_x(self):
188 189 190 191 192 193
        self.check_grad(['Y'],
                        'Out',
                        no_grad_set=set("X"),
                        user_defined_grads=[self.grad_y],
                        user_defined_grad_outputs=[self.grad_out],
                        check_eager=True)
194 195

    def test_check_grad_ingore_y(self):
196 197 198 199 200 201
        self.check_grad(['X'],
                        'Out',
                        no_grad_set=set('Y'),
                        user_defined_grads=[self.grad_x],
                        user_defined_grad_outputs=[self.grad_out],
                        check_eager=True)
202 203


C
chentianyu03 已提交
204
class TestKronOpTypePromotion(TestComplexKronOp):
205

C
chentianyu03 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218
    def init_input_output(self):
        self.x = np.random.random(self.x_shape).astype(self.dtype)
        self.y = np.random.random(self.y_shape).astype(
            self.dtype) + 1J * np.random.random(self.y_shape).astype(self.dtype)
        self.out = np.kron(self.x, self.y)

    def init_grad_input_output(self):
        self.grad_out = np.ones(self.out_shape, self.dtype) + 1J * np.ones(
            self.out_shape, self.dtype)
        self.grad_x = self.get_grad_x_by_numpy().real
        self.grad_y = self.get_grad_y_by_numpy()


F
Feiyu Chan 已提交
219
if __name__ == '__main__':
220
    paddle.enable_static()
F
Feiyu Chan 已提交
221
    unittest.main()