LCOV - code coverage report
Current view: top level - ut/compiler/engines/nn_engine/optimizer/adapter/tbe_adapter/kernel_launch - l2_cache_kernel_launch.cc Coverage Total Hit
Test: CHG Lines: 100.0 % 2 2
Test Date: 2026-08-27 17:40:36
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "adapter/tbe_adapter/kernel_launch/l2_cache_kernel_launch.h"
      12              : #include <memory>
      13              : #include <vector>
      14              : #include "common/fe_log.h"
      15              : #include "common/configuration.h"
      16              : #include "common/fe_type_utils.h"
      17              : #include "graph/utils/anchor_utils.h"
      18              : #include "graph/utils/attr_utils.h"
      19              : #include "graph/utils/node_utils.h"
      20              : 
      21              : namespace fe {
      22              : namespace {
      23              : const std::string ATTR_NAME_L2CACHE_GRAPH_READ_MODE = "_fe_l2cache_graph_read_mode";
      24              : const std::set<std::string> LIFECYCLE_IS_END_OPS = {DATA, AIPPDATA, ANN_DATA, CONSTANT, CONSTANTOP};
      25              : const std::set<std::string> LIFECYCLE_IS_NOT_END_OPS = {VARIABLE};
      26              : }  // namespace
      27           27 : size_t L2CacheKernelLaunch::GetAppendArgsSizeOf() const {
      28              :   return sizeof(uint64_t);  // uinit64_t: 8
      29              : }
      30              : 
      31           45 : size_t L2CacheKernelLaunch::GetAppendArgsNum() const {
      32              :   return input_num_;
      33              : }
      34              : 
      35              : Status L2CacheKernelLaunch::AddAppendArgs(const ge::Node &node, void *all_args_buff, const uint32_t &args_size) {
      36              :   auto op_desc_ptr = node.GetOpDesc();
      37              :   auto op_name = node.GetName();
      38              :   auto op_type = node.GetType();
      39              : 
      40              :   // 1. generate read mode
      41              :   vector<uint64_t> read_modes;
      42              :   if (GenerateReadModes(node, read_modes) != SUCCESS) {
      43              :     REPORT_FE_ERROR("[GenTask][AddAppendArgs][Op %s,type %s] failed to generate the read mode.", op_name.c_str(),
      44              :                     op_type.c_str());
      45              :     return FAILED;
      46              :   }
      47              : 
      48              :   if (read_modes.size() != GetAppendArgsNum()) {
      49              :     REPORT_FE_ERROR("[GenTask][AddAppendArgs] Node[%s, %s]: append_args_num %zu is not equal to read_modes_size %zu.",
      50              :                     op_name.c_str(), op_type.c_str(), GetAppendArgsNum(), read_modes.size());
      51              :     return FAILED;
      52              :   }
      53              : 
      54              :   // 2. add append args
      55              :   size_t each_append_arg_size = GetAppendArgsSizeOf();
      56              :   size_t left_append_arg_size = each_append_arg_size * GetAppendArgsNum();
      57              :   uint64_t cur_ptr = ge::PtrToValue(all_args_buff) + args_size;
      58              :   for (uint64_t &read_mode : read_modes) {
      59              :     errno_t ret = memcpy_s(reinterpret_cast<void *>(cur_ptr), left_append_arg_size,
      60              :                            reinterpret_cast<void *>(&read_mode), each_append_arg_size);
      61              :     if (ret != EOK) {
      62              :       return FAILED;
      63              :     }
      64              :     left_append_arg_size -= each_append_arg_size;
      65              :     cur_ptr += each_append_arg_size;
      66              :   }
      67              :   return SUCCESS;
      68              : }
      69              : 
      70              : Status L2CacheKernelLaunch::GenerateReadModes(const ge::Node &node, vector<uint64_t> &read_modes) const {
      71              :   auto op_desc_ptr = node.GetOpDesc();
      72              :   auto op_name = op_desc_ptr->GetName();
      73              :   auto op_type = op_desc_ptr->GetType();
      74              :   bool is_enable_reuse_mem = Configuration::Instance(AI_CORE_NAME).IsEnableReuseMemory();
      75              : 
      76              :   for (const auto &in_data_anchor : node.GetAllInDataAnchors()) {
      77              :     if (in_data_anchor == nullptr) {
      78              :       continue;
      79              :     }
      80              :     auto peer_out_anchor = in_data_anchor->GetPeerOutAnchor();
      81              :     if (peer_out_anchor == nullptr) {
      82              :       continue;
      83              :     }
      84              : 
      85              :     auto idx = in_data_anchor->GetIdx();
      86              :     auto input_desc = op_desc_ptr->MutableInputDesc(idx);
      87              :     if (input_desc == nullptr) {
      88              :       continue;
      89              :     }
      90              :     // 1. get the src node of the input
      91              :     auto src_node = peer_out_anchor->GetOwnerNode();
      92              :     FE_CHECK_NOTNULL(src_node);
      93              :     auto read_mode = GenRmForSpecialInputOps(src_node, is_enable_reuse_mem);
      94              :     if (read_mode == L2CacheReadMode::RM_NONE) {
      95              :       // 2. get the life cycle of the input desc
      96              :       auto is_life_cycle_end = IsLifeCycleEnd(node, input_desc, idx);
      97              :       // 3. generate rm by life cycle and read distance
      98              :       read_mode = GenerateReadMode(node, input_desc, idx, is_life_cycle_end);
      99              :     }
     100              :     // 4. set the attr
     101              :     (void)ge::AttrUtils::SetInt(input_desc, ATTR_NAME_L2CACHE_GRAPH_READ_MODE, static_cast<int64_t>(read_mode));
     102              : 
     103              :     read_modes.emplace_back(static_cast<uint64_t>(read_mode));
     104              :     FE_LOGD("Op[name=%s,type=%s,input=%d]: the graph read_mode=[%s].", op_name.c_str(), op_type.c_str(), idx,
     105              :             L2CacheReadMode2Str(read_mode).c_str());
     106              :   }
     107              : 
     108              :   return SUCCESS;
     109              : }
     110              : 
     111              : L2CacheReadMode L2CacheKernelLaunch::GenRmForSpecialInputOps(const ge::NodePtr &src_node,
     112              :                                                              bool is_enable_reuse_mem) const {
     113              :   auto src_node_type = ge::NodeUtils::GetInConstNodeTypeCrossSubgraph(src_node);
     114              :   // Const/Data
     115              :   if (LIFECYCLE_IS_END_OPS.count(src_node_type) != 0) {
     116              :     return is_enable_reuse_mem ? L2CacheReadMode::NOT_NEED_WRITEBACK : L2CacheReadMode::READ_LAST;
     117              :   }
     118              : 
     119              :   // Variable
     120              :   if (LIFECYCLE_IS_NOT_END_OPS.count(src_node_type) != 0) {
     121              :     return L2CacheReadMode::READ_LAST;
     122              :   }
     123              :   return L2CacheReadMode::RM_NONE;
     124              : }
     125              : 
     126              : bool L2CacheKernelLaunch::IsLifeCycleEnd(const ge::Node &node, const ge::GeTensorDescPtr &input_desc,
     127              :                                          int input_idx) const {
     128              :   auto op_desc = node.GetOpDesc();
     129              :   auto op_name = op_desc->GetName();
     130              :   auto op_type = op_desc->GetType();
     131              : 
     132              :   bool is_life_cycle_end = false;
     133              :   if (ge::AttrUtils::HasAttr(input_desc, ge::ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE)) {
     134              :     (void)ge::AttrUtils::GetBool(input_desc, ge::ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE, is_life_cycle_end);
     135              :     FE_LOGD("Op[name=%s,type=%s,input=%d]: has attr %s, the life_cycle is %s.", op_name.c_str(), op_type.c_str(),
     136              :             input_idx, ge::ATTR_NAME_IS_END_OF_INPUTMEM_LIFECYCLE.c_str(), is_life_cycle_end ? "end" : "not end");
     137              :     return is_life_cycle_end;
     138              :   }
     139              :   return is_life_cycle_end;
     140              : }
     141              : 
     142              : L2CacheReadMode L2CacheKernelLaunch::GenerateReadMode(const ge::Node &node, const ge::GeTensorDescPtr &input_desc,
     143              :                                                       int input_idx, bool is_life_cycle_end) const {
     144              :   auto op_desc = node.GetOpDesc();
     145              :   auto op_name = op_desc->GetName();
     146              :   auto op_type = op_desc->GetType();
     147              : 
     148              :   // 1. no read distance on the input desc
     149              :   if (!ge::AttrUtils::HasAttr(input_desc, ge::ATTR_NAME_DATA_VISIT_DISTANCE)) {
     150              :     FE_LOGD("Op[name=%s,type=%s,input=%d]: no attr %s.", op_name.c_str(), op_type.c_str(), input_idx,
     151              :             ge::ATTR_NAME_DATA_VISIT_DISTANCE.c_str());
     152              :     return is_life_cycle_end ? L2CacheReadMode::NOT_NEED_WRITEBACK : L2CacheReadMode::READ_LAST;
     153              :   }
     154              : 
     155              :   // 2. there is the read distance on the input desc
     156              :   vector<int32_t> data_visit_dist_vec;
     157              :   (void)ge::AttrUtils::GetListInt(input_desc, ge::ATTR_NAME_DATA_VISIT_DISTANCE, data_visit_dist_vec);
     158              :   auto data_visit_dist_size = data_visit_dist_vec.size();
     159              : 
     160              :   // 3. life cycle is end
     161              :   if (is_life_cycle_end) {
     162              :     int32_t data_visit_dist_from_pre_node = 0;
     163              :     if (data_visit_dist_size == 0) {
     164              :       FE_LOGD(
     165              :           "Op[name=%s,type=%s,input=%d]: no read distance from previous node, set data_visit_dist_from_pre_node to be "
     166              :           "-1.",
     167              :           op_name.c_str(), op_type.c_str(), input_idx);
     168              :       data_visit_dist_from_pre_node = -1;
     169              :     } else {
     170              :       data_visit_dist_from_pre_node = data_visit_dist_vec[0];
     171              :     }
     172              : 
     173              :     FE_LOGD("Op[name=%s,type=%s,input=%d]: data_visit_dist_from_pre_node=[%d], data_visit_dist_threshold=[%d].",
     174              :             op_name.c_str(), op_type.c_str(), input_idx, data_visit_dist_from_pre_node, kDataVisitDistThreshold);
     175              :     return L2CacheReadMode::READ_INVALID;
     176              :   }
     177              : 
     178              :   // 4. life cycle is not end
     179              :   int32_t data_visit_dist_to_next_node = 0;
     180              :   if (data_visit_dist_size < 2) {
     181              :     FE_LOGW("Op[name=%s,type=%s,input=%d]: no read distance to next node, set data_visit_dist_to_next_node to be -1.",
     182              :             op_name.c_str(), op_type.c_str(), input_idx);
     183              :     data_visit_dist_to_next_node = -1;
     184              :   } else {
     185              :     data_visit_dist_to_next_node = data_visit_dist_vec[1];
     186              :   }
     187              :   FE_LOGD("Op[name=%s,type=%s,input=%d]: data_visit_dist_to_next_node=[%d], data_visit_dist_threshold=[%d].",
     188              :           op_name.c_str(), op_type.c_str(), input_idx, data_visit_dist_to_next_node, kDataVisitDistThreshold);
     189              :   return data_visit_dist_to_next_node <= kDataVisitDistThreshold ? L2CacheReadMode::READ_LAST
     190              :                                                                  : L2CacheReadMode::READ_INVALID;
     191              : }
     192              : }  // namespace fe
        

Generated by: LCOV version 2.3.2-1