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