1# Copyright 2021 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 18 19import mindspore.context as context 20import mindspore.nn as nn 21from mindspore import Tensor 22from mindspore.ops.operations import _grad_ops as G 23from mindspore.ops import operations as P 24 25 26class Net(nn.Cell): 27 def __init__(self, reduction): 28 super(Net, self).__init__() 29 self.loss = P.NLLLoss(reduction=reduction) 30 31 def construct(self, predict, target, weight): 32 return self.loss(predict, target, weight) 33 34 35class NLLLossGradNet(nn.Cell): 36 def __init__(self, reduction): 37 super(NLLLossGradNet, self).__init__() 38 self.grad = G.NLLLossGrad(reduction=reduction) 39 40 def construct(self, x, dout_x, target, weight, total_weight): 41 gout = self.grad(x, dout_x, target, weight, total_weight) 42 return gout 43 44 45def nll_loss_template(nptype_input, nptype_weight, reduction): 46 context.set_context(mode=context.GRAPH_MODE, device_target="GPU") 47 48 nll_loss_net = Net(reduction) 49 50 predict = Tensor( 51 np.array([[0.53, 0.74, -2.12], [1.29, -0.34, -1.13]]).astype(nptype_input)) 52 53 target = Tensor(np.array([0, 1]).astype(np.int32)) 54 55 weight = Tensor(np.array([0.45, -0.32, 1.21]).astype(nptype_weight)) 56 57 loss, total_weight = nll_loss_net(predict, target, weight) 58 59 loss_np = loss.asnumpy() 60 total_weight_np = total_weight.asnumpy() 61 62 expected_tot_weight = np.array(0.129999995) 63 64 if reduction == 'none': 65 expected_loss = np.array([-0.238499984, -0.108800001]) 66 elif reduction == 'mean': 67 expected_loss = np.array(-2.67153859) 68 elif reduction == 'sum': 69 expected_loss = np.array(-0.347299993) 70 71 if nptype_input == np.float32 and nptype_weight == np.float32: 72 ertol_loss = 1e-06 73 elif nptype_input == np.float16 or nptype_weight == np.float16: 74 ertol_loss = 1e-03 75 76 if nptype_weight == np.float32: 77 ertol_weight = 1e-06 78 elif nptype_weight == np.float16: 79 ertol_weight = 1e-03 80 81 np.testing.assert_allclose(loss_np, expected_loss, ertol_loss) 82 np.testing.assert_allclose( 83 total_weight_np, expected_tot_weight, ertol_weight) 84 85 86def nll_loss_grad_template(nptype_input, nptype_weight, reduction): 87 context.set_context(mode=context.GRAPH_MODE, device_target="GPU") 88 89 nll_loss_grad_net = NLLLossGradNet(reduction) 90 91 x = Tensor( 92 np.array([[0.53, 0.74, -2.12], [1.29, -0.34, -1.13]]).astype(nptype_input)) 93 94 if reduction == "none": 95 dloss = Tensor( 96 np.array([3.24, -2.13]).astype(nptype_input)) 97 else: 98 dloss = Tensor(np.array(1.23).astype(nptype_input)) 99 100 target = Tensor(np.array([0, 1]).astype(np.int32)) 101 weight = Tensor(np.array([0.45, -0.32, 1.21]).astype(nptype_weight)) 102 103 total_weight = Tensor(np.array(0.13).astype(nptype_weight)) 104 105 dx = nll_loss_grad_net(x, dloss, target, weight, total_weight) 106 107 dx_np = dx.asnumpy() 108 109 print(dx) 110 111 if reduction == "none": 112 dx_expected = np.array([[-1.45799994, 0, 0], [0, -0.681600034, 0]]) 113 elif reduction == "mean": 114 dx_expected = np.array([[-4.25769234, 0, 0], [0, 3.02769232, 0]]) 115 else: 116 dx_expected = np.array([[-0.553499997, 0, 0], [0, 0.393599987, 0]]) 117 118 if nptype_input == np.float32 and nptype_weight == np.float32: 119 ertol_loss = 1e-06 120 else: 121 ertol_loss = 1e-02 122 123 np.testing.assert_allclose(dx_np, dx_expected, ertol_loss) 124 125 126@pytest.mark.level0 127@pytest.mark.platform_x86_gpu_training 128@pytest.mark.env_onecard 129def test_nll_loss_no_reduction(): 130 # Four combinations of fp32 and fp16 inputs and weights 131 nll_loss_template(np.float32, np.float32, "none") 132 nll_loss_template(np.float32, np.float16, "none") 133 nll_loss_template(np.float16, np.float32, "none") 134 nll_loss_template(np.float16, np.float16, "none") 135 136 137@pytest.mark.level0 138@pytest.mark.platform_x86_gpu_training 139@pytest.mark.env_onecard 140def test_nll_loss_mean_reduction(): 141 # Four combinations of fp32 and fp16 inputs and weights 142 nll_loss_template(np.float32, np.float32, "mean") 143 nll_loss_template(np.float32, np.float16, "mean") 144 nll_loss_template(np.float16, np.float32, "mean") 145 nll_loss_template(np.float16, np.float16, "mean") 146 147 148@pytest.mark.level0 149@pytest.mark.platform_x86_gpu_training 150@pytest.mark.env_onecard 151def test_nll_loss_sum_reduction(): 152 # Four combinations of fp32 and fp16 inputs and weights 153 nll_loss_template(np.float32, np.float32, "sum") 154 nll_loss_template(np.float32, np.float16, "sum") 155 nll_loss_template(np.float16, np.float32, "sum") 156 nll_loss_template(np.float16, np.float16, "sum") 157 158 159@pytest.mark.level0 160@pytest.mark.platform_x86_gpu_training 161@pytest.mark.env_onecard 162def test_nll_loss_grad_mean_reduction(): 163 # Four combinations of fp32 and fp16 inputs and weights 164 nll_loss_grad_template(np.float32, np.float32, "mean") 165 nll_loss_grad_template(np.float32, np.float16, "mean") 166 nll_loss_grad_template(np.float16, np.float32, "mean") 167 nll_loss_grad_template(np.float16, np.float16, "mean") 168 169 170@pytest.mark.level0 171@pytest.mark.platform_x86_gpu_training 172@pytest.mark.env_onecard 173def test_nll_loss_grad_sum_reduction(): 174 # Four combinations of fp32 and fp16 inputs and weights 175 nll_loss_grad_template(np.float32, np.float32, "sum") 176 nll_loss_grad_template(np.float32, np.float16, "sum") 177 nll_loss_grad_template(np.float16, np.float32, "sum") 178 nll_loss_grad_template(np.float16, np.float16, "sum") 179 180 181@pytest.mark.level0 182@pytest.mark.platform_x86_gpu_training 183@pytest.mark.env_onecard 184def test_nll_loss_grad_no_reduction(): 185 # Four combinations of fp32 and fp16 inputs and weights 186 nll_loss_grad_template(np.float32, np.float32, "none") 187 nll_loss_grad_template(np.float32, np.float16, "none") 188 nll_loss_grad_template(np.float16, np.float32, "none") 189 nll_loss_grad_template(np.float16, np.float16, "none") 190