LCOV - code coverage report
Current view: top level - nntrainer/layers/loss - cross_entropy_softmax_loss_layer.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 82.8 % 29 24
Test Date: 2025-12-14 20:38:17 Functions: 100.0 % 2 2

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : /**
       3              :  * Copyright (C) 2021 Parichay Kapoor <pk.kapoor@samsung.com>
       4              :  *
       5              :  * @file   cross_entropy_Softmax_loss_layer.cpp
       6              :  * @date   24 June 2021
       7              :  * @brief  This is MSE Loss Layer Class of Neural Network
       8              :  * @see    https://github.com/nnstreamer/nntrainer
       9              :  * @author Parichay Kapoor <pk.kapoor@samsung.com>
      10              :  * @bug    No known bugs except for NYI items
      11              :  *
      12              :  */
      13              : 
      14              : #include <cmath>
      15              : 
      16              : #include <cross_entropy_softmax_loss_layer.h>
      17              : 
      18              : #include <acti_func.h>
      19              : #include <layer_context.h>
      20              : #include <lazy_tensor.h>
      21              : #include <util_func.h>
      22              : 
      23              : namespace nntrainer {
      24              : 
      25              : static constexpr size_t SINGLE_INOUT_IDX = 0;
      26              : 
      27          535 : void CrossEntropySoftmaxLossLayer::forwarding(RunLayerContext &context,
      28              :                                               bool training) {
      29          535 :   Tensor &hidden_ = context.getOutput(SINGLE_INOUT_IDX);
      30          535 :   Tensor &y = context.getInput(SINGLE_INOUT_IDX);
      31              : 
      32              :   // fill the output
      33          535 :   auto dataType = y.getDataType();
      34          535 :   if (dataType == ml::train::TensorDim::DataType::FP32) {
      35          535 :     hidden_ = y.apply(ActiFunc::softmax<float>, hidden_);
      36              : 
      37          535 :     if (context.isLabelAvailable(SINGLE_INOUT_IDX)) {
      38          442 :       Tensor &y2 = context.getLabel(SINGLE_INOUT_IDX);
      39          884 :       l = y2.multiply(hidden_.apply<float>(logFloat<float>))
      40          442 :             .sum_by_batch()
      41          884 :             .multiply(-1.0f);
      42              : 
      43              :       // update the loss value
      44          442 :       LossLayer::updateLoss(context, l);
      45              :     }
      46            0 :   } else if (dataType == ml::train::TensorDim::DataType::FP16) {
      47              : #ifdef ENABLE_FP16
      48              :     hidden_ = y.apply(ActiFunc::softmax<_FP16>, hidden_);
      49              : 
      50              :     if (context.isLabelAvailable(SINGLE_INOUT_IDX)) {
      51              :       Tensor &y2 = context.getLabel(SINGLE_INOUT_IDX);
      52              :       l = y2.multiply(hidden_.apply<_FP16>(logFloat<_FP16>))
      53              :             .sum_by_batch()
      54              :             .multiply(-1);
      55              : 
      56              :       // update the loss value
      57              :       LossLayer::updateLoss(context, l);
      58              :     }
      59              : #else
      60            0 :     throw std::invalid_argument("Error: enable-fp16 is not enabled");
      61              : #endif
      62              :   }
      63          535 : }
      64              : 
      65          344 : void CrossEntropySoftmaxLossLayer::calcDerivative(RunLayerContext &context) {
      66          344 :   Tensor &ret_derivative = context.getOutgoingDerivative(SINGLE_INOUT_IDX);
      67          344 :   const Tensor &y2 = context.getIncomingDerivative(SINGLE_INOUT_IDX);
      68          344 :   Tensor &y = context.getInput(SINGLE_INOUT_IDX);
      69              : 
      70          344 :   auto dataType = y.getDataType();
      71          344 :   Tensor ret = Tensor("ret", y.getFormat(), y.getDataType());
      72          344 :   if (dataType == ml::train::TensorDim::DataType::FP32) {
      73          688 :     y.apply(ActiFunc::softmax<float>, ret);
      74            0 :   } else if (dataType == ml::train::TensorDim::DataType::FP16) {
      75              : #ifdef ENABLE_FP16
      76              :     y.apply(ActiFunc::softmax<_FP16>, ret);
      77              : #else
      78            0 :     throw std::runtime_error("enable-fp16 is not enabled");
      79              : #endif
      80              :   }
      81              : 
      82              :   /// @note y and ret_derivative can be same here, so this has to be out-place
      83              :   /// operation
      84              :   // TODO: verify y and ret_derivative must not be same as loss layer is not
      85              :   // working in-place
      86          344 :   ret.subtract(y2, ret_derivative);
      87          344 :   if (ret_derivative.divide_i(ret.batch()) != ML_ERROR_NONE) {
      88              :     throw std::runtime_error("[CrossEntropySoftmaxLossLayer::calcDerivative] "
      89            0 :                              "Error when calculating loss");
      90              :   }
      91          344 : }
      92              : 
      93              : } // namespace nntrainer
        

Generated by: LCOV version 2.0-1