• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15
16import numpy as np
17import pytest
18import mindspore.ops.operations._rl_inner_ops as rl_ops
19import mindspore.ops.operations._grad_ops as grad_ops
20from mindspore import context, Tensor
21from mindspore.common.parameter import ParameterTuple
22import mindspore as ms
23import mindspore.nn as nn
24from mindspore.ops import composite as c
25
26
27@pytest.mark.level2
28@pytest.mark.platform_x86_cpu
29@pytest.mark.platform_arm_cpu
30@pytest.mark.env_onecard
31@pytest.mark.parametrize("mode", [context.GRAPH_MODE, context.PYNATIVE_MODE])
32def test_gru_grad(mode):
33    """
34    Feature: test gru_grad cpu operation.
35    Description: test gru_grad cpu operation.
36    Expectation: no exception.
37    """
38    input_size = 10
39    hidden_size = 2
40    num_layers = 1
41    max_seq_len = 5
42    batch_size = 2
43
44    context.set_context(mode=mode)
45    net = rl_ops.GRUV2(input_size, hidden_size, num_layers, True, False, 0.0)
46    input_tensor = Tensor(
47        np.ones([max_seq_len, batch_size, input_size]).astype(np.float32))
48    h0 = Tensor(
49        np.ones([num_layers, batch_size, hidden_size]).astype(np.float32))
50    w = Tensor(np.ones([84, 1, 1]).astype(np.float32))
51    seq_lengths = Tensor(np.array([4, 3]).astype(np.int32))
52    output, hn, out1, _ = net(input_tensor, h0, w, seq_lengths)
53    grad_net = grad_ops.GRUV2Grad(
54        input_size, hidden_size, num_layers, True, False, 0.0)
55    dx, dh, dw = grad_net(input_tensor, h0, w, seq_lengths,
56                          output, hn, output, hn, out1)
57    print("dx:", dx)
58    print("dh:", dh)
59    print("dw:", dw)
60
61
62class GradOfAllInputsAndParams(nn.Cell):
63    def __init__(self, network, sens_param):
64        super().__init__()
65        self.grad = c.GradOperation(
66            get_all=True, get_by_list=True, sens_param=sens_param)
67        self.network = network
68        self.params = ParameterTuple(self.network.trainable_params())
69
70    def construct(self, *inputs):
71        gout = self.grad(self.network, self.params)(*inputs)
72        return gout
73
74
75class NetGruV2(nn.Cell):
76    def __init__(self, input_size, hidden_size, num_layers, has_bias, weights, is_train):
77        super(NetGruV2, self).__init__()
78        self.gruv2 = rl_ops.GRUV2(
79            input_size, hidden_size, num_layers, has_bias, False, 0.0, is_train)
80        self.weights = weights
81
82    def construct(self, x, h_0, seq_len):
83        return self.gruv2(
84            x, h_0, self.weights.astype(x.dtype), seq_len)
85
86
87@pytest.mark.level1
88@pytest.mark.platform_x86_cpu
89@pytest.mark.platform_arm_cpu
90@pytest.mark.env_onecard
91@pytest.mark.parametrize("has_bias", [True, False])
92@pytest.mark.parametrize("is_train", [True, False])
93def test_gru_backward(has_bias, is_train):
94    """
95    Feature: test GRUV2 backward.
96    Description: test gru_grad cpu operation.
97    Expectation: no exception.
98    """
99    batch_size = 3
100    max_seq_length = 5
101    input_size = 10
102    hidden_size = 3
103    num_layers = 1
104    num_directions = 1
105    seq_lengths = Tensor([5, 3, 2], ms.int32)
106    dtype = ms.float32
107
108    x = Tensor(np.random.normal(
109        0.0, 1.0, (max_seq_length, batch_size, input_size)), dtype)
110    h0 = Tensor(np.random.normal(
111        0.0, 1.0, (num_layers * num_directions, batch_size, hidden_size)), dtype)
112    weight_size = 135 if has_bias else 117
113    weights = Tensor(np.ones([weight_size, 1, 1]).astype(np.float32))
114
115    # graph mode
116    context.set_context(mode=context.GRAPH_MODE)
117    gru_v2_net = NetGruV2(input_size, hidden_size,
118                          num_layers, has_bias, weights, is_train)
119    grad_net_inp = GradOfAllInputsAndParams(gru_v2_net, sens_param=False)
120    grad_net_inp.set_train()
121    out_grad, _ = grad_net_inp(x, h0, seq_lengths)
122    # pynative mode
123    context.set_context(mode=context.PYNATIVE_MODE)
124    pynative_gru_v2_net = NetGruV2(input_size, hidden_size,
125                                   num_layers, has_bias, weights, is_train)
126    pynative_grad_net_inp = GradOfAllInputsAndParams(
127        pynative_gru_v2_net, sens_param=False)
128    pynative_grad_net_inp.set_train()
129    py_native_out_grad, _ = pynative_grad_net_inp(x, h0, seq_lengths)
130
131    assert np.allclose(out_grad[0].asnumpy(),
132                       py_native_out_grad[0].asnumpy(), 0.001, 0.001)
133    assert np.allclose(out_grad[1].asnumpy(),
134                       py_native_out_grad[1].asnumpy(), 0.001, 0.001)
135