LCOV - code coverage report
Current view: top level - aicpu_processer - ae_kernel_lib_fwk.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 80.4 % 199 160
Test Date: 2026-07-28 10:54:05 Functions: 94.4 % 18 17

            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_fwk.hpp"
      12              : #include "securec.h"
      13              : #include "aicpu_context.h"
      14              : #include "aicpu_event_struct.h"
      15              : 
      16              : namespace {
      17              :     // aicpu so root dir, must be absolute path.
      18              :     constexpr const char *AICPU_SO_ROOT_PATH = "/usr/lib64/aicpu_kernels/";
      19              :     // tf kernels so name
      20              :     constexpr const char *TF_SO_NAME = "libtf_kernels.so";
      21              :     // tensorflow so name
      22              :     constexpr const char *TENSORFLOW_SO_NAME = "libtensorflow.so";
      23              :     // tensorflow tar uncompress path
      24              :     constexpr const char *TENSORFLOW_SO_UNCOMPRESS_PAHT = "sand_box";
      25              :     // aicpu kernels tar uncompress path
      26              :     constexpr const char *AICPU_SO_UNCOMPRESS_PATH = "aicpu_kernels_device";
      27              :     constexpr const uint32_t MAX_SO_PATH = 4096U;
      28              :     const std::string THREAD_MODE_SO_PATH_FIX = "aicpu_kernels";
      29              : }
      30              : 
      31              : namespace cce {
      32              :     AIKernelsLibFWK *AIKernelsLibFWK::instance_ = nullptr;
      33              :     std::mutex AIKernelsLibFWK::mtx_;
      34              : 
      35            9 :     AIKernelsLibFWK *AIKernelsLibFWK::GetInstance()
      36              :     {
      37            9 :         const std::lock_guard<std::mutex> lockGuard(mtx_);
      38            9 :         if (instance_ != nullptr) {
      39            5 :             return instance_;
      40              :         } else {
      41            4 :             instance_ = new(std::nothrow) AIKernelsLibFWK();
      42            4 :             if (instance_ == nullptr) {
      43            0 :                 return nullptr;
      44              :             }
      45            4 :             (void)instance_->Init();
      46            4 :             return instance_;
      47              :         }
      48            9 :     }
      49              : 
      50            4 :     void AIKernelsLibFWK::DestroyInstance()
      51              :     {
      52            4 :         const std::lock_guard<std::mutex> lockGuard(mtx_);
      53            4 :         if (instance_ == nullptr) {
      54            0 :             return;
      55              :         }
      56            4 :         delete instance_;
      57            4 :         instance_ = nullptr;
      58            4 :     }
      59              : 
      60            4 :     aeStatus_t AIKernelsLibFWK::Init()
      61              :     {
      62            4 :         return tfImpl_.Init();
      63              :     }
      64              : 
      65              : 
      66            1 :     aeStatus_t AIKernelsLibFWK::CloseSo(const char_t * const soName)
      67              :     {
      68              :         (void)soName;
      69            1 :         return AE_STATUS_SUCCESS;
      70              :     }
      71              : 
      72            4 :     int32_t AIKernelsLibFWK::CallKernelApi(const aicpu::KernelType kernelType, const void * const kernelBase)
      73              :     {
      74            4 :         const auto fwkKernel = reinterpret_cast<const aicpu::HwtsFwkKernel * const>(kernelBase);
      75            4 :         if (static_cast<bool>(unlikely(fwkKernel == nullptr))) {
      76            1 :             AE_ERR_LOG(AE_MODULE_ID, "Input param fwkKernelBase is NULL.");
      77            1 :             return AE_STATUS_BAD_PARAM;
      78              :         }
      79              : 
      80            3 :         const auto fwkOpKernelPtr = static_cast<const uintptr_t>(fwkKernel->kernel);
      81            3 :         const auto fwkOpKernel = reinterpret_cast<const STR_FWK_OP_KERNEL * const>(fwkOpKernelPtr);
      82            3 :         if (static_cast<bool>(unlikely(fwkOpKernel == nullptr))) {
      83            0 :             AE_ERR_LOG(AE_MODULE_ID, "Input param fwkOpKernel is NULL.");
      84            0 :             return AE_STATUS_BAD_PARAM;
      85              :         }
      86            3 :         AE_INFO_LOG(AE_MODULE_ID, "Current kernelType:%d, FWK op kernel kernel type:%d.",
      87              :                     kernelType, fwkOpKernel->fwkKernelType);
      88              : 
      89              :         // Call different Implement method switch by kernel type.
      90            3 :         int32_t ret = AE_STATUS_SUCCESS;
      91            3 :         switch (static_cast<FwkkernelType_t>(fwkOpKernel->fwkKernelType)) {
      92            3 :             case FMK_KERNEL_TYPE_TF:
      93            3 :                 ret =  tfImpl_.CallKernelApi(PtrToValue(PtrToPtr<const ::aicpu::FWKAdapter::FWKOperateParam, 
      94              :                                              const void>(&fwkOpKernel->fwkKernelBase.fwk_kernel)));
      95            3 :                 break;
      96            0 :             default:
      97            0 :                 AE_ERR_LOG(AE_MODULE_ID, "Input param fwkKernelType in STR_FWK_OP_KERNEL is invalid :%d",
      98              :                            fwkOpKernel->fwkKernelType);
      99            0 :                 ret = AE_STATUS_BAD_PARAM;
     100            0 :                 break;
     101              :         }
     102            3 :         return ret;
     103              :     }
     104              : 
     105            3 :     aeStatus_t AIKernelsLibFWK::BatchLoadKernelSo(const aicpu::KernelType kernelType,
     106              :                                                   std::vector<std::string> &soVec)
     107              :     {
     108            3 :         AE_INFO_LOG(AE_MODULE_ID, "Begin to batch load kernel so, kerelType:[%d].", kernelType);
     109            3 :         if (soVec.empty()) {
     110            0 :             return AE_STATUS_SUCCESS;
     111              :         }
     112              :         // only one tf so
     113            3 :         return tfImpl_.LoadTfSo();
     114              :     }
     115              : 
     116              :     // need refresh soFile_
     117           24 :     FWKKernelTfImpl::FWKKernelTfImpl() : kernelName_("TFOperateAPI"),
     118           12 :                                          funcAddr_(nullptr),
     119           12 :                                          soHandle_(nullptr),
     120           12 :                                          soTensorflowHandle_(nullptr)
     121              :     {
     122           12 :     }
     123              : 
     124            4 :     aeStatus_t FWKKernelTfImpl::Init()
     125              :     {
     126            4 :         std::string baseSoFile(AICPU_SO_ROOT_PATH);
     127            4 :         (void)baseSoFile.append(TF_SO_NAME);
     128            4 :         soFile_ = baseSoFile;
     129              :         aicpu::aicpuContext_t currentAicpuCtx;
     130            4 :         const aicpu::status_t status = aicpu::aicpuGetContext(&currentAicpuCtx);
     131            4 :         if (status == aicpu::AICPU_ERROR_NONE) {
     132            4 :             std::string soPath(AICPU_SO_ROOT_PATH);
     133            8 :             (void)soPath.append(std::to_string(aicpu::GetUniqueVfId()))
     134            4 :                 .append("/")
     135            4 :                 .append(AICPU_SO_UNCOMPRESS_PATH)
     136            4 :                 .append("/");
     137            4 :             soFile_ = soPath + TF_SO_NAME;
     138            4 :             GetThreadModelSoPath(soPath);
     139              :             // check so file
     140            4 :             const aeStatus_t ret = SingleSoManager::CheckSoFile(soPath, soFile_);
     141            4 :             if (ret != AE_STATUS_SUCCESS) {
     142            4 :                 soFile_ = baseSoFile;
     143            4 :                 AE_RUN_INFO_LOG(AE_MODULE_ID, "So does not exist in path %s, use default soFile %s.",
     144              :                                 soPath.c_str(), baseSoFile.c_str());
     145              :             }
     146            4 :         }
     147            4 :         AE_INFO_LOG(AE_MODULE_ID, "FWKernelTfImpl init success, soFile_=%s.", soFile_.c_str());
     148            4 :         return AE_STATUS_SUCCESS;
     149            4 :     }
     150              : 
     151           12 :     FWKKernelTfImpl::~FWKKernelTfImpl()
     152              :     {
     153           12 :         AE_RW_LOCK_WR_LOCK(&rwLock_);
     154           12 :         funcAddr_ = nullptr;
     155           12 :         aeStatus_t ret = SingleSoManager::CloseSo(soHandle_);
     156           12 :         if (ret != AE_STATUS_SUCCESS) {
     157            0 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "~FWKKernelTfImpl CloseSo failed, ret is[%d]", ret);
     158              :         }
     159           12 :         ret = SingleSoManager::CloseSo(soTensorflowHandle_);
     160           12 :         if (ret != AE_STATUS_SUCCESS) {
     161            0 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "~FWKKernelTensorflowImpl CloseSo failed, ret is[%d]", ret);
     162              :         }
     163           12 :         soHandle_ = nullptr;
     164           12 :         soTensorflowHandle_ = nullptr;
     165           12 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     166           12 :         AE_RW_LOCK_DESTROY(&rwLock_);
     167           12 :     }
     168              : 
     169            8 :     void FWKKernelTfImpl::GetTfKernelThreadModeSoPath(std::string &soPath) const
     170              :     {
     171            8 :         (void)soPath.append(THREAD_MODE_SO_PATH_FIX)
     172            8 :             .append("/")
     173           16 :             .append(std::to_string(aicpu::GetUniqueVfId()))
     174            8 :             .append("/")
     175            8 :             .append(AICPU_SO_UNCOMPRESS_PATH)
     176            8 :             .append("/");
     177            8 :         return;
     178              :     }
     179              : 
     180            0 :     void FWKKernelTfImpl::GetTensorflowThreadModeSoPath(std::string soPath)
     181              :     {
     182            0 :         (void)soPath.append(THREAD_MODE_SO_PATH_FIX)
     183            0 :             .append("/")
     184            0 :             .append(std::to_string(aicpu::GetUniqueVfId()))
     185            0 :             .append("/")
     186            0 :             .append(AICPU_SO_UNCOMPRESS_PATH)
     187            0 :             .append("/")
     188            0 :             .append(TENSORFLOW_SO_UNCOMPRESS_PAHT)
     189            0 :             .append("/");
     190            0 :         tensorflowSoFile_ = soPath + TENSORFLOW_SO_NAME;
     191            0 :         return;
     192              :     }
     193              : 
     194            9 :     aeStatus_t FWKKernelTfImpl::GetTfThreadModeSoPath(std::string &soPath)
     195              :     {
     196            9 :         const char_t * const innerDirName = getenv("HOME");
     197            9 :         if (innerDirName != nullptr) {
     198            8 :             const std::string str =  innerDirName;
     199            8 :             const size_t len = str.length();
     200            8 :             if ((len == 0U) || (len >= static_cast<size_t>(MAX_SO_PATH))) {
     201            0 :                 AE_ERR_LOG(AE_MODULE_ID, "Length[%zu] of inner so dir is invalid.", len);
     202            0 :                 return AE_STATUS_INNER_ERROR;
     203              :             }
     204            8 :             soPath = str;
     205            8 :             if (soPath[soPath.size() - 1UL] != '/') {
     206            8 :                 (void)soPath.append("/");
     207              :             }
     208            8 :             GetTensorflowThreadModeSoPath(soPath);
     209            8 :             GetTfKernelThreadModeSoPath(soPath);
     210            8 :             return AE_STATUS_SUCCESS;
     211            8 :         } else {
     212            1 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "Get HOME env failed, get tf thread mode so path failed.");
     213            1 :             return AE_STATUS_INNER_ERROR;
     214              :         }
     215              :     }
     216              : 
     217            7 :     void FWKKernelTfImpl::GetThreadModelSoPath(std::string &soPath)
     218              :     {
     219              :         uint32_t runMode;
     220            7 :         aicpu::status_t status = aicpu::GetAicpuRunMode(runMode);
     221            7 :         if (status != aicpu::AICPU_ERROR_NONE) {
     222            1 :             AE_ERR_LOG(AE_MODULE_ID, "Get current aicpu ctx failed.");
     223            2 :             return;
     224              :         }
     225            6 :         if (runMode != aicpu::AicpuRunMode::THREAD_MODE) {
     226            0 :             return;
     227              :         }
     228            6 :         std::string threadSoPath;
     229            6 :         if (GetTfThreadModeSoPath(threadSoPath) != AE_STATUS_SUCCESS) {
     230            1 :             AE_WARN_LOG(AE_MODULE_ID, "GetThreadModeSoPath failed.");
     231            1 :             return;
     232              :         }
     233            5 :         soPath = threadSoPath;
     234            5 :         soFile_ = threadSoPath + TF_SO_NAME;
     235            6 :     }
     236              : 
     237            3 :     int32_t FWKKernelTfImpl::CallKernelApi(const uint64_t fwkKernelParam)
     238              :     {
     239            3 :         void *theFuncAddr = nullptr;
     240            3 :         AE_RW_LOCK_RD_LOCK(&rwLock_);
     241            3 :         if (static_cast<bool>(unlikely(funcAddr_ != nullptr))) {
     242            0 :             theFuncAddr = funcAddr_;
     243              :         }
     244            3 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     245              : 
     246            3 :         if (static_cast<bool>(unlikely(theFuncAddr == nullptr))) {
     247            3 :             AE_RW_LOCK_WR_LOCK(&rwLock_);
     248            3 :             if (static_cast<bool>(unlikely(funcAddr_ == nullptr))) {
     249            3 :                 AE_INFO_LOG(AE_MODULE_ID, "Begin to GetApi, soFile=%s, kernelName=%s.",
     250              :                     GetSoFile().c_str(), GetKernelName().c_str());
     251              : 
     252            3 :                 aeStatus_t retGetApi = AE_STATUS_SUCCESS;
     253            3 :                 if (static_cast<bool>(unlikely(soHandle_ == nullptr))) {
     254            3 :                     retGetApi = SingleSoManager::GetApi(GetSoFile().data(), GetKernelName().data(),
     255              :                                                         &funcAddr_, &soHandle_);
     256              :                 } else {
     257            0 :                     retGetApi = SingleSoManager::GetFunc(soHandle_, GetKernelName().data(), &funcAddr_);
     258              :                 }
     259            3 :                 AE_INFO_LOG(AE_MODULE_ID, "End to GetApi, retGetApi=%d.", retGetApi);
     260              : 
     261            3 :                 if (static_cast<bool>(unlikely((retGetApi == AE_STATUS_SUCCESS) && (funcAddr_ == nullptr)))) {
     262            1 :                     AE_RW_LOCK_UN_LOCK(&rwLock_);
     263            1 :                     AE_ERR_LOG(AE_MODULE_ID, "Get a NULL func addr, but status is success.");
     264            1 :                     return AE_STATUS_INNER_ERROR;
     265            2 :                 } else if (static_cast<bool>(unlikely(retGetApi != AE_STATUS_SUCCESS))) {
     266            2 :                     AE_RW_LOCK_UN_LOCK(&rwLock_);
     267            2 :                     AE_ERR_LOG(AE_MODULE_ID, "Get API or Func failed, ret[%d].", static_cast<int32_t>(retGetApi));
     268            2 :                     return retGetApi;
     269              :                 } else {
     270            0 :                     AE_INFO_LOG(AE_MODULE_ID, "Get API or Func success.");
     271              :                 }
     272              :             }
     273            0 :             theFuncAddr = funcAddr_;
     274            0 :             AE_RW_LOCK_UN_LOCK(&rwLock_);
     275              :         }
     276              : 
     277            0 :         const uint32_t tfRet = (reinterpret_cast<FwkTfOpFuncPtr>(theFuncAddr))(fwkKernelParam);
     278              :         // for tensorflow will should check the result.
     279            0 :         return static_cast<int32_t>(TransformKernelErrorCode(tfRet, fwkKernelParam));
     280              :     }
     281              : 
     282            3 :     aeStatus_t FWKKernelTfImpl::LoadTfSo()
     283              :     {
     284            3 :         AE_RW_LOCK_RD_LOCK(&rwLock_);
     285            3 :         if (soHandle_ != nullptr) {
     286            0 :             AE_RW_LOCK_UN_LOCK(&rwLock_);
     287            0 :             return AE_STATUS_SUCCESS;
     288              :         }
     289            3 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     290              : 
     291            3 :         AE_RW_LOCK_WR_LOCK(&rwLock_);
     292            3 :         if (soHandle_ != nullptr) {
     293            0 :             AE_RW_LOCK_UN_LOCK(&rwLock_);
     294            0 :             return AE_STATUS_SUCCESS;
     295              :         }
     296            3 :         aeStatus_t ret = SingleSoManager::OpenSo(tensorflowSoFile_, &soTensorflowHandle_);
     297            3 :         if (ret != AE_STATUS_SUCCESS) {
     298            3 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "load tensorflow so failed, ret is[%d]", ret);
     299              :         }
     300            3 :         ret = SingleSoManager::OpenSo(soFile_, &soHandle_);
     301            3 :         if (ret != AE_STATUS_SUCCESS) {
     302            3 :             AE_RW_LOCK_UN_LOCK(&rwLock_);
     303            3 :             AE_RUN_WARN_LOG(AE_MODULE_ID, "LoadTfSo open so failed, soFile[%s], ret[%u].", soFile_.c_str(), ret);
     304            3 :             return ret;
     305              :         }
     306            0 :         AE_RW_LOCK_UN_LOCK(&rwLock_);
     307            0 :         return AE_STATUS_SUCCESS;
     308              :     }
     309              : 
     310            3 :     aeStatus_t FWKKernelTfImpl::TransformKernelErrorCode(const uint32_t errCode, const uint64_t fwkKernelParam)
     311              :     {
     312            3 :         if (errCode == 0U) {
     313            1 :             return AE_STATUS_SUCCESS;
     314              :         }
     315              :         // check tf end of sequence
     316            2 :         if (errCode == aicpu::FWKAdapter::FWK_ADPT_NATIVE_END_OF_SEQUENCE) {
     317            1 :             return AE_STATUS_END_OF_SEQUENCE;
     318              :         }
     319            1 :         uint32_t returnCode = errCode;
     320            1 :         if (errCode == aicpu::FWKAdapter::FWK_ADPT_NOT_SUPPORT_OPTYPE) {
     321            0 :             returnCode = AE_STATUS_BAD_PARAM;
     322              :         }
     323            1 :         AE_ERR_LOG(AE_MODULE_ID, "Call tf api return failed:%u, returncode:%u, input param to tf api:0x%lx",
     324              :             errCode, returnCode, fwkKernelParam);
     325              :         // other error code: transform to inner_error
     326            1 :         return static_cast<aeStatus_t>(returnCode);
     327              :     }
     328              : 
     329            2 :     const std::string &FWKKernelTfImpl::GetSoFile() const
     330              :     {
     331            2 :         return soFile_;
     332              :     }
     333              : 
     334            6 :     const std::string &FWKKernelTfImpl::GetKernelName() const
     335              :     {
     336            6 :         return kernelName_;
     337              :     }
     338              : }
        

Generated by: LCOV version 2.0-1