LCOV - code coverage report
Current view: top level - aicpu_processer - ae_kernel_lib_aicpu_kfc.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.4 % 109 104
Test Date: 2026-08-12 11:05:02 Functions: 100.0 % 11 11

            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 "ae_kernel_lib_aicpu_kfc.h"
      12              : #include <sstream>
      13              : #include <string>
      14              : #include <memory>
      15              : #include <dlfcn.h>
      16              : #include "securec.h"
      17              : #include "aicpu_event_struct.h"
      18              : #ifdef AICPU_PROFILING
      19              : #include "aicpu_prof/profiling_adp.h"
      20              : #endif
      21              : namespace cce {
      22              : AIKernelsLibAiCpuKFC* AIKernelsLibAiCpuKFC::instance_ = nullptr;
      23              : 
      24              : // SINGLETON object get interface
      25            9 : AIKernelsLibAiCpuKFC* AIKernelsLibAiCpuKFC::GetInstance()
      26              : {
      27              :     static std::once_flag flag;
      28            9 :     std::call_once(flag, []() {
      29            1 :         instance_ = new (std::nothrow) AIKernelsLibAiCpuKFC();
      30            1 :         if ((instance_ != nullptr) && (instance_->Init() != AE_STATUS_SUCCESS)) {
      31            0 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "AIKernelsLibAiCpuKFC init failed.");
      32            0 :             delete instance_;
      33            0 :             instance_ = nullptr;
      34              :         }
      35            1 :         AE_RUN_INFO_LOG(AE_MODULE_ID, "AIKernelsLibAiCpuKFC init finish.");
      36            1 :     });
      37            9 :     return instance_;
      38              : }
      39              : 
      40            1 : aeStatus_t AIKernelsLibAiCpuKFC::Init()
      41              : {
      42            1 :     apiCacher_.clear();
      43            1 :     return AIKernelsLibBase::Init();
      44              : }
      45              : 
      46              : // SINGLETON object destroy interface
      47            5 : void AIKernelsLibAiCpuKFC::DestroyInstance()
      48              : {
      49            5 :     if (instance_ == nullptr) {
      50            4 :         return;
      51              :     }
      52            1 :     delete instance_;
      53            1 :     instance_ = nullptr;
      54              : }
      55              : 
      56           12 : aeStatus_t AIKernelsLibAiCpuKFC::GetKernelName(char_t*& kernelName, const aicpu::HwtsCceKernel* cceKernelBase) const
      57              : {
      58           12 :     kernelName = PtrToPtr<void, char_t>(ValueToPtr(cceKernelBase->kernelName));
      59           12 :     if (static_cast<bool>(unlikely(kernelName == nullptr))) {
      60            1 :         AE_ERR_LOG(AE_MODULE_ID, "Input param kernelName is null.");
      61            1 :         return AE_STATUS_BAD_PARAM;
      62              :     }
      63           11 :     uint32_t len = strnlen(kernelName, AE_MAX_KERNEL_NAME + 1);
      64           11 :     if (static_cast<bool>(unlikely(len > AE_MAX_KERNEL_NAME))) {
      65            1 :         AE_ERR_LOG(AE_MODULE_ID, "KernelName length is not supported, len=%d.", len);
      66            1 :         kernelName = nullptr;
      67            1 :         return AE_STATUS_INNER_ERROR;
      68              :     }
      69           10 :     return AE_STATUS_SUCCESS;
      70              : }
      71              : 
      72            8 : int32_t AIKernelsLibAiCpuKFC::GetApiGlobal(AicpuKFCOpFuncPtr& opFuncPtr, const char_t* kernelName) const
      73              : {
      74            8 :     opFuncPtr = PtrToFunctionPtr<void, AicpuKFCOpFuncPtr>(dlsym(RTLD_DEFAULT, kernelName));
      75            8 :     if (static_cast<bool>(unlikely(opFuncPtr == nullptr))) {
      76            7 :         AE_ERR_LOG(
      77              :             AE_MODULE_ID, "Get KFC api by global failed, func is nullptr, kernelName[%s], dlerror[%s]", kernelName,
      78              :             dlerror());
      79            7 :         return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
      80              :     }
      81            1 :     return AE_STATUS_SUCCESS;
      82              : }
      83              : 
      84            7 : int32_t AIKernelsLibAiCpuKFC::GetApiWhenSonameNotEmpty(
      85              :     const aicpu::KernelType kernelType, const uint32_t soNameLen, const char_t* kernelSoName, const char_t* kernelName,
      86              :     void*& funcAddr)
      87              : {
      88            7 :     if (static_cast<bool>(unlikely(soNameLen > AE_MAX_SO_NAME))) {
      89            2 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "kernelSoName length is not supported, len=%d.", soNameLen);
      90            2 :         return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
      91              :     }
      92              : 
      93            5 :     const auto ret = soMngr_.GetApi(kernelType, kernelSoName, kernelName, &funcAddr);
      94            5 :     if (static_cast<bool>(unlikely(ret != AE_STATUS_SUCCESS))) {
      95            3 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Get %s api from %s unsuccessfully.", kernelName, kernelSoName);
      96            3 :         return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
      97              :     }
      98              : 
      99            2 :     if (static_cast<bool>(unlikely(funcAddr == nullptr))) {
     100            1 :         AE_RUN_WARN_LOG(AE_MODULE_ID, "Get %s api from %s success, but func is nullptr", kernelName, kernelSoName);
     101            1 :         return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
     102              :     }
     103              : 
     104            1 :     return AE_STATUS_SUCCESS;
     105              : }
     106              : 
     107            9 : int32_t AIKernelsLibAiCpuKFC::GetApiBySoname(
     108              :     const aicpu::KernelType kernelType, const char_t* kernelSoName, AicpuKFCOpFuncPtr& opFuncPtr,
     109              :     const char_t* kernelName)
     110              : {
     111            9 :     const uint32_t soNameLen = strnlen(kernelSoName, AE_MAX_SO_NAME + 1);
     112            9 :     if (soNameLen == 0) {
     113            2 :         if (GetApiGlobal(opFuncPtr, kernelName) != AE_STATUS_SUCCESS) {
     114            1 :             AE_ERR_LOG(
     115              :                 AE_MODULE_ID, "Get KFC api by global failed, kernelSoName[%s], soNameLen[%u], kernelName[%s].",
     116              :                 kernelSoName, soNameLen, kernelName);
     117            1 :             return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
     118              :         }
     119              :     } else {
     120            7 :         void* funcAddr = nullptr;
     121            7 :         if (GetApiWhenSonameNotEmpty(kernelType, soNameLen, kernelSoName, kernelName, funcAddr) == AE_STATUS_SUCCESS) {
     122            1 :             opFuncPtr = PtrToFunctionPtr<void, AicpuKFCOpFuncPtr>(funcAddr);
     123              :         } else {
     124            6 :             if (GetApiGlobal(opFuncPtr, kernelName) != AE_STATUS_SUCCESS) {
     125            6 :                 AE_ERR_LOG(
     126              :                     AE_MODULE_ID,
     127              :                     "Get KFC api by soname and global both failed, kernelSoName[%s], soNameLen[%u], kernelName[%s].",
     128              :                     kernelSoName, soNameLen, kernelName);
     129            6 :                 return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
     130              :             }
     131              :         }
     132              :     }
     133              : 
     134            2 :     return AE_STATUS_SUCCESS;
     135              : }
     136              : 
     137              : // Implement call a aicpu op kernel interface
     138           12 : int32_t AIKernelsLibAiCpuKFC::CallKernelApi(const aicpu::KernelType kernelType, const void* const kernelBase)
     139              : {
     140              :     (void)kernelType;
     141           12 :     const aicpu::HwtsCceKernel* cceKernelBase = static_cast<const aicpu::HwtsCceKernel*>(kernelBase);
     142           12 :     if (static_cast<bool>(unlikely(cceKernelBase == nullptr))) {
     143            1 :         AE_ERR_LOG(AE_MODULE_ID, "Input param KFC kernelBase is nullptr.");
     144            1 :         return static_cast<int32_t>(AE_STATUS_BAD_PARAM);
     145              :     }
     146              : 
     147           11 :     char_t* kernelName = nullptr;
     148           11 :     aeStatus_t ret = GetKernelName(kernelName, cceKernelBase);
     149           11 :     if (static_cast<bool>(unlikely((ret != AE_STATUS_SUCCESS)))) {
     150            1 :         AE_ERR_LOG(AE_MODULE_ID, "get KFC kernelName failed, ret=%u.", ret);
     151            1 :         return static_cast<int32_t>(ret);
     152              :     }
     153           10 :     AicpuKFCOpFuncPtr opFuncPtr = nullptr;
     154           10 :     AE_RW_LOCK_RD_LOCK(&rwLock_);
     155           20 :     auto apiIter = apiCacher_.find(kernelName);
     156           10 :     if (apiIter != apiCacher_.end()) {
     157            1 :         opFuncPtr = apiIter->second;
     158              :     } else {
     159            9 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     160            9 :         AE_RW_LOCK_WR_LOCK(&rwLock_);
     161           18 :         apiIter = apiCacher_.find(kernelName);
     162            9 :         if (apiIter != apiCacher_.end()) {
     163            0 :             opFuncPtr = apiIter->second;
     164              :         } else {
     165            9 :             char_t* kernelSoName = PtrToPtr<void, char_t>(ValueToPtr(cceKernelBase->kernelSo));
     166            9 :             if (GetApiBySoname(kernelType, kernelSoName, opFuncPtr, kernelName) != AE_STATUS_SUCCESS) {
     167            7 :                 AE_RW_LOCK_UN_LOCK(&rwLock_);
     168            7 :                 AE_ERR_LOG(
     169              :                     AE_MODULE_ID, "Get KFC kernel api failed, kernelSoName[%s], kernelName[%s].", kernelSoName,
     170              :                     kernelName);
     171            7 :                 return static_cast<int32_t>(AE_STATUS_INNER_ERROR);
     172              :             }
     173            6 :             apiCacher_[kernelName] = opFuncPtr;
     174              :         }
     175              :     }
     176              : 
     177            3 :     AE_RW_LOCK_UN_LOCK(&rwLock_);
     178            3 :     AE_INFO_LOG(AE_MODULE_ID, "Get KFC kernelname[%s] func success", kernelName);
     179            3 :     const uint32_t result = RunAicpuFunc(kernelBase, opFuncPtr);
     180            3 :     return static_cast<int32_t>(TransformKernelErrorCode(result, kernelName));
     181              : }
     182              : 
     183            4 : uint32_t AIKernelsLibAiCpuKFC::RunAicpuFunc(const void* const kernelBase, AicpuKFCOpFuncPtr& opFuncPtr) const
     184              : {
     185            4 :     const auto cceKernelBase = static_cast<const aicpu::HwtsCceKernel*>(kernelBase);
     186            4 :     void* const param = ValueToPtr(static_cast<const uintptr_t>(cceKernelBase->paramBase));
     187            4 :     uint32_t result = 0U;
     188            4 :     if (&aicpu::SetBlockIdxAndBlockNum != nullptr) {
     189            0 :         (void)aicpu::SetBlockIdxAndBlockNum(cceKernelBase->blockId, cceKernelBase->blockNum);
     190              :     }
     191              : #ifdef AICPU_PROFILING
     192              :     uint64_t runStartTick;
     193              :     uint64_t runStartTime;
     194              :     const std::shared_ptr<aicpu::ProfMessage> profHandle = aicpu::GetProfHandle();
     195              :     if (static_cast<bool>(unlikely(profHandle != nullptr))) {
     196              :         aicpu::GetMicrosAndSysTick(runStartTime, runStartTick);
     197              :     }
     198              : #endif
     199            4 :     result = opFuncPtr(param);
     200              : #ifdef AICPU_PROFILING
     201              :     if (static_cast<bool>(unlikely(profHandle != nullptr))) {
     202              :         uint64_t runEndTick;
     203              :         uint64_t runEndTime;
     204              :         aicpu::GetMicrosAndSysTick(runEndTime, runEndTick);
     205              :         (void)profHandle->SetRunStartTime(runStartTime)
     206              :             ->SetRunStartTick(runStartTick)
     207              :             ->SetRunEndTime(runEndTime)
     208              :             ->SetRunEndTick(runEndTick);
     209              :     }
     210              : #endif
     211            4 :     return result;
     212              : }
     213              : 
     214            6 : int32_t AIKernelsLibAiCpuKFC::TransformKernelErrorCode(const uint32_t errCode, const char_t* const kernelName) const
     215              : {
     216            6 :     if (likely(errCode == 0U)) {
     217            2 :         return AE_STATUS_SUCCESS;
     218              :     }
     219              : 
     220            4 :     if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_TASK_ABORT)) {
     221            1 :         AE_INFO_LOG(AE_MODULE_ID, "Get kfc task abort flag");
     222            1 :         return AE_STATUS_TASK_ABORT;
     223              :     }
     224              : 
     225            3 :     if ((errCode >= static_cast<uint32_t>(AicpuOpErrorCode::AICPU_KFC_PASSTHROUGH_START)) &&
     226              :         (errCode <= static_cast<uint32_t>(AicpuOpErrorCode::AICPU_KFC_PASSTHROUGH_END))) {
     227            1 :         AE_INFO_LOG(AE_MODULE_ID, "KFC %s run passthrough ret[%u]", kernelName, errCode);
     228            1 :         return static_cast<int32_t>(errCode);
     229              :     }
     230              : 
     231            2 :     AE_ERR_LOG(AE_MODULE_ID, "KFC %s run failed ret[%u]", kernelName, errCode);
     232            2 :     return AE_STATUS_TASK_FAIL;
     233              : }
     234              : } // namespace cce
        

Generated by: LCOV version 2.0-1