LCOV - code coverage report
Current view: top level - aicpu_processer - ae_kernel_lib_aicpu.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.8 % 144 102
Test Date: 2026-07-28 10:54:05 Functions: 100.0 % 10 10

            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.hpp"
      12              : #include <sstream>
      13              : #include <string>
      14              : #include <memory>
      15              : #include "securec.h"
      16              : #include "aicpu_event_struct.h"
      17              : #ifdef AICPU_PROFILING
      18              : #include "aicpu_prof/profiling_adp.h"
      19              : #endif
      20              : 
      21              : namespace cce {
      22              :     namespace {
      23              :         // aicpu device side blockdim entry function name
      24              :         constexpr char const *kRunFuncName = "RunCpuKernelWithBlock";
      25              :         // 动态白名单
      26              :         constexpr size_t MAX_WHITE_LIST_SIZE = 100UL;
      27              :         // The interface to call a aicpu kernel api
      28              :         using AicpuOpFuncPtr = uint32_t(*)(void *);
      29              :         // The interface to call a aicpu kernel api with blockdim
      30              :         using AicpuOpFuncPtrWithBlockDim = uint32_t(*)(void *, void *);
      31              : 
      32              :         struct BlkDimInfo {
      33              :             uint32_t  blockNum;   // blockdim number
      34              :             uint32_t  blockId;    // block id
      35              :         };
      36              :     }
      37              : 
      38              :     AIKernelsLibAiCpu *AIKernelsLibAiCpu::instance_ = nullptr;
      39              :     std::mutex AIKernelsLibAiCpu::mtx_;
      40              : 
      41              :     // SINGLETON object get interface
      42          136 :     AIKernelsLibAiCpu *AIKernelsLibAiCpu::GetInstance()
      43              :     {
      44          136 :         const std::lock_guard<std::mutex> lockGuard(mtx_);
      45          136 :         if (instance_ != nullptr) {
      46          129 :             return instance_;
      47              :         } else {
      48            7 :             instance_ = new(std::nothrow) AIKernelsLibAiCpu();
      49            7 :             if (instance_ == nullptr) {
      50            0 :                 return nullptr;
      51              :             }
      52            7 :             if (instance_->Init() != AE_STATUS_SUCCESS) {
      53            2 :                 AE_RUN_WARN_LOG(AE_MODULE_ID,  "AIKernelsLibAiCpu init failed.");
      54            2 :                 delete instance_;
      55            2 :                 instance_ = nullptr;
      56            2 :                 return nullptr;
      57              :             }
      58            5 :             return instance_;
      59              :         }
      60          136 :     }
      61              : 
      62              :     // SINGLETON object destroy interface
      63            9 :     void AIKernelsLibAiCpu::DestroyInstance()
      64              :     {
      65            9 :         const std::lock_guard<std::mutex> lockGuard(mtx_);
      66            9 :         if (instance_ == nullptr) {
      67            5 :             return;
      68              :         }
      69            4 :         delete instance_;
      70            4 :         instance_ = nullptr;
      71            9 :     }
      72              : 
      73          121 :     aeStatus_t AIKernelsLibAiCpu::GetKernelNameAndKernelSoName(char_t *kernelName, char_t *kernelSoName,
      74              :                                                                const char_t *paramKernelSo,
      75              :                                                                const aicpu::HwtsCceKernel *cceKernelBase) const
      76              :     {
      77          121 :         const auto paramKernelName = PtrToPtr<const void, const char_t>(ValueToPtr(cceKernelBase->kernelName));
      78              :         // A nullptr kernel op name is not supported.
      79          121 :         if (paramKernelName == nullptr) {
      80            0 :             AE_ERR_LOG(AE_MODULE_ID, "Input param kernelName is null.");
      81            0 :             return AE_STATUS_BAD_PARAM;
      82              :         }
      83          121 :         errno_t retCpy = strncpy_s(&kernelName[0], AE_MAX_KERNEL_NAME + 1U, paramKernelName, AE_MAX_KERNEL_NAME);
      84          121 :         if (retCpy != EOK) {
      85            0 :             AE_ERR_LOG(AE_MODULE_ID, "copy paramKernelName failed, retCpy=%d.", retCpy);
      86            0 :             return AE_STATUS_INNER_ERROR;
      87              :         }
      88              : 
      89          121 :         retCpy = strncpy_s(&kernelSoName[0], AE_MAX_SO_NAME + 1U, paramKernelSo, AE_MAX_SO_NAME);
      90          121 :         if (retCpy != EOK) {
      91            0 :             AE_ERR_LOG(AE_MODULE_ID, "copy paramKernelSo failed, retCpy=%d.", retCpy);
      92            0 :             return AE_STATUS_INNER_ERROR;
      93              :         }
      94          121 :         return AE_STATUS_SUCCESS;
      95              :     }
      96              : 
      97              :     // Implement call a aicpu op kernel interface
      98          121 :     int32_t AIKernelsLibAiCpu::CallKernelApi(const aicpu::KernelType kernelType, const void * const kernelBase)
      99              :     {
     100          121 :         const aicpu::HwtsCceKernel *cceKernelBase = static_cast<const aicpu::HwtsCceKernel *>(kernelBase);
     101          121 :         if (cceKernelBase == nullptr) {
     102            0 :             AE_ERR_LOG(AE_MODULE_ID, "Input param kernelBase is nullptr.");
     103            0 :             return AE_STATUS_BAD_PARAM;
     104              :         }
     105              : 
     106          121 :         char_t *paramKernelSo = PtrToPtr<void, char_t>(ValueToPtr(cceKernelBase->kernelSo));
     107              :         // Finding a cce op kernel from the whole process space is not supported.
     108              :         // Only get aicpu op kernel a specific so lib.so, kernelSo should not be NULL.
     109          121 :         if (paramKernelSo == nullptr) {
     110            0 :             AE_ERR_LOG(AE_MODULE_ID, "Input param kernelSo is NULL.");
     111            0 :             return AE_STATUS_BAD_PARAM;
     112              :         }
     113          121 :         char_t kernelName[AE_MAX_KERNEL_NAME + 1U] = {};
     114          121 :         char_t kernelSoName[AE_MAX_SO_NAME + 1U] = {};
     115          121 :         aeStatus_t ret = AE_STATUS_SUCCESS;
     116          121 :         ret = GetKernelNameAndKernelSoName(kernelName, kernelSoName, paramKernelSo, cceKernelBase);
     117          121 :         if (ret != AE_STATUS_SUCCESS) {
     118            0 :             AE_ERR_LOG(AE_MODULE_ID, "get kernelName and kernelSoName failed, ret=%u.", ret);
     119            0 :             return ret;
     120              :         }
     121          121 :         void *funcAddr = nullptr;
     122          121 :         ret = soMngr_.GetApi(kernelType, &kernelSoName[0], &kernelName[0], &funcAddr);
     123          121 :         if (ret != AE_STATUS_SUCCESS) {
     124            0 :             AE_ERR_LOG(AE_MODULE_ID, "Get %s api from %s failed.", &kernelName[0], &kernelSoName[0]);
     125            0 :             return ret;
     126              :         }
     127          121 :         if (funcAddr == nullptr) {
     128            0 :             AE_ERR_LOG(AE_MODULE_ID, "Get %s api from %s success, but func is nullptr",
     129              :                        &kernelName[0], &kernelSoName[0]);
     130            0 :             return AE_STATUS_INNER_ERROR;
     131              :         }
     132              : 
     133          121 :         (void)aicpu::SetOpname(kernelName);
     134              : 
     135          120 :         const uint32_t result = RunAicpuFunc(kernelBase, funcAddr, &kernelName[0]);
     136          119 :         return static_cast<int32_t>(TransformKernelErrorCode(result, &kernelName[0], &kernelSoName[0]));
     137              :     }
     138              : 
     139          120 :     uint32_t AIKernelsLibAiCpu::RunAicpuFunc(const void* const kernelBase,
     140              :                                              void* const funcAddr,
     141              :                                              const char_t* const funcName) const
     142              :     {
     143          120 :         uint32_t result = 0U;
     144          120 :         const auto cceKernelBase = static_cast<const aicpu::HwtsCceKernel *>(kernelBase);
     145          120 :         void * const param = ValueToPtr(cceKernelBase->paramBase);
     146              : #ifdef AICPU_PROFILING
     147              :         uint64_t runStartTime;
     148              :         uint64_t runStartTick;
     149              :         aicpu::GetMicrosAndSysTick(runStartTime, runStartTick);
     150              : #endif
     151          120 :         (void)aicpu::SetBlockIdxAndBlockNum(cceKernelBase->blockId, cceKernelBase->blockNum);
     152          120 :         if (strcmp(funcName, kRunFuncName) == 0) {
     153            0 :             AE_INFO_LOG(AE_MODULE_ID, "opFuncPtr is RunCpuKernelWithBlockDim.");
     154            0 :             struct BlkDimInfo blkInfo = {};
     155            0 :             blkInfo.blockId = cceKernelBase->blockId;
     156            0 :             blkInfo.blockNum = cceKernelBase->blockNum;
     157            0 :             const auto opFuncPtr = PtrToFunctionPtr<void, AicpuOpFuncPtrWithBlockDim>(funcAddr);
     158            0 :             result = opFuncPtr(param, &blkInfo);
     159              :         } else {
     160          120 :             const auto opFuncPtr = PtrToFunctionPtr<void, AicpuOpFuncPtr>(funcAddr);
     161          120 :             result = opFuncPtr(param);
     162              :         }
     163              : 
     164              : #ifdef AICPU_PROFILING
     165              :         uint64_t runEndTime;
     166              :         uint64_t runEndTick;
     167              :         aicpu::GetMicrosAndSysTick(runEndTime, runEndTick);
     168              : 
     169              :         const std::shared_ptr<aicpu::ProfMessage> profHandle = aicpu::GetProfHandle();
     170              :         if (profHandle != nullptr) {
     171              :             std::string opName = "null";
     172              :             (void)aicpu::GetOpname(aicpu::GetAicpuThreadIndex(), opName);
     173              :             (void)profHandle->SetRunStartTime(runStartTime)->SetRunStartTick(runStartTick)
     174              :                 ->SetRunEndTime(runEndTime)->SetRunEndTick(runEndTick);
     175              :         }
     176              : #endif
     177          120 :         return result;
     178              :     }
     179              : 
     180            6 :     aeStatus_t AIKernelsLibAiCpu::BatchLoadKernelSo(const aicpu::KernelType kernelType,
     181              :                                                     std::vector<std::string> &soVec)
     182              :     {
     183            6 :         if (soVec.empty()) {
     184            1 :             AE_ERR_LOG(AE_MODULE_ID, "so vec is empty.");
     185            1 :             return AE_STATUS_SUCCESS;
     186              :         }
     187           12 :         for (auto &soName : soVec) {
     188            7 :             const aeStatus_t ret = soMngr_.LoadSo(kernelType, soName);
     189            7 :             if (ret != AE_STATUS_SUCCESS) {
     190            5 :                 AE_RUN_WARN_LOG(AE_MODULE_ID, "Load so %s failed.", soName.c_str());
     191            5 :                 continue;
     192              :             }
     193              :         }
     194            5 :         return AE_STATUS_SUCCESS;
     195              :     }
     196              : 
     197            2 :     aeStatus_t AIKernelsLibAiCpu::CloseSo(const char_t * const soName)
     198              :     {
     199            2 :         if (soName == nullptr) {
     200            1 :             AE_ERR_LOG(AE_MODULE_ID, "soName is null.");
     201            1 :             return AE_STATUS_BAD_PARAM;
     202              :         }
     203            1 :         const std::string kernelSoName(soName);
     204            1 :         return soMngr_.CloseSo(kernelSoName);
     205            1 :     }
     206              : 
     207          120 :     aeStatus_t AIKernelsLibAiCpu::TransformKernelErrorCode(const uint32_t errCode,
     208              :                                                            const char_t * const kernelName,
     209              :                                                            const char_t * const soName) const
     210              :     {
     211          120 :         if (likely(errCode == 0U)) {
     212          110 :             return AE_STATUS_SUCCESS;
     213              :         }
     214              : 
     215           10 :         if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_END_OF_SEQUENCE_FLAG)) {
     216            0 :             AE_INFO_LOG(AE_MODULE_ID, "Get aicpu end of sequence flag.");
     217            0 :             return AE_STATUS_END_OF_SEQUENCE;
     218              :         }
     219           10 :         if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_TASK_WATI_FLAG)) {
     220            0 :             AE_INFO_LOG(AE_MODULE_ID, "Get aicpu task wait flag.");
     221            0 :             return AE_STATUS_TASK_WAIT;
     222              :         }
     223              : 
     224           10 :         if (!aicpu::IsCustAicpuSd()) {
     225           10 :             if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_SILENT_FAULT)) {
     226            0 :                 AE_INFO_LOG(AE_MODULE_ID, "Get aicpu silent fault flag");
     227            0 :                 return AE_STATUS_SILENT_FAULT;
     228              :             }
     229           10 :             if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_DETECT_FAULT)) {
     230            0 :                 AE_INFO_LOG(AE_MODULE_ID, "Get aicpu detect fault flag");
     231            0 :                 return AE_STATUS_DETECT_FAULT;
     232              :             }
     233              : 
     234           10 :             if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_DETECT_FAULT_NORAS)) {
     235            0 :                 AE_INFO_LOG(AE_MODULE_ID, "Get aicpu detect fault no Ras flag");
     236            0 :                 return AE_STATUS_DETECT_FAULT_NORAS;
     237              :             }
     238              : 
     239           10 :             if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_DETECT_LOW_BIT_FAULT)) {
     240            0 :                 AE_INFO_LOG(AE_MODULE_ID, "Get aicpu detect low-bit fault flag");
     241            0 :                 return AE_STATUS_DETECT_LOW_BIT_FAULT;
     242              :             }
     243              : 
     244           10 :             if (errCode == static_cast<uint32_t>(AicpuOpErrorCode::AICPU_DETECT_LOW_BIT_FAULT_NORAS)) {
     245            0 :                 AE_INFO_LOG(AE_MODULE_ID, "Get aicpu detect low-bit fault no Ras flag");
     246            0 :                 return AE_STATUS_DETECT_LOW_BIT_FAULT_NORAS;
     247              :             }
     248              :         }
     249              : 
     250           10 :         AE_ERR_LOG(AE_MODULE_ID, "call aicpu api %s in %s failed, ret:%u.", kernelName, soName, errCode);
     251              :         // other error code: transform to inner_error
     252           10 :         return static_cast<aeStatus_t>(errCode);
     253              :     }
     254              : 
     255            2 :     void AIKernelsLibAiCpu::DeleteSoInWhiteList(const std::string &soName)
     256              :     {
     257            2 :         const std::lock_guard<std::mutex> lk(soWhiteListMtx_);
     258            2 :         if (soWhiteList_.empty()) {
     259            1 :             AE_INFO_LOG(AE_MODULE_ID, "so white list is empty");
     260            1 :             return;
     261              :         }
     262            1 :         auto iter = soWhiteList_.find(soName);
     263            1 :         if (iter != soWhiteList_.end()) {
     264            0 :             soWhiteList_.erase(iter);
     265            0 :             AE_INFO_LOG(AE_MODULE_ID, "erase so:%s in white list", soName.c_str());
     266              :         } else {
     267            1 :             AE_INFO_LOG(AE_MODULE_ID, "so:%s not in white list", soName.c_str());
     268              :         }
     269            2 :     }
     270              : 
     271            2 :     aeStatus_t AIKernelsLibAiCpu::AddSoInWhiteList(const std::string &soName)
     272              :     {
     273            2 :         const std::lock_guard<std::mutex> lk(soWhiteListMtx_);
     274            2 :         if (soWhiteList_.size() >= MAX_WHITE_LIST_SIZE) {
     275            0 :             AE_ERR_LOG(AE_MODULE_ID, "white list is full");
     276            0 :             return AE_STATUS_INNER_ERROR;
     277              :         }
     278            2 :         auto iter = soWhiteList_.find(soName);
     279            2 :         if (iter == soWhiteList_.end()) {
     280            2 :             soWhiteList_[soName] = soName;
     281            2 :             AE_INFO_LOG(AE_MODULE_ID, "add so:%s in white list, list size:%zu", soName.c_str(), soWhiteList_.size());
     282              :         } else {
     283            0 :             AE_INFO_LOG(AE_MODULE_ID, "so:%s already in white list, size:%zu", soName.c_str(), soWhiteList_.size());
     284              :         }
     285            2 :         return AE_STATUS_SUCCESS;
     286            2 :     }
     287              : }
        

Generated by: LCOV version 2.0-1