LCOV - code coverage report
Current view: top level - acl/acl_tdt_queue/toolchain - prof_api_reg.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.4 % 98 69
Test Date: 2026-07-28 10:53:01 Functions: 83.3 % 12 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 "prof_api_reg.h"
      12              : #include <mutex>
      13              : #include <unordered_set>
      14              : #include <map>
      15              : #include "mmpa/mmpa_api.h"
      16              : #include "runtime/base.h"
      17              : #include "common/log_inner.h"
      18              : 
      19              : namespace {
      20              : static bool g_profRun = false;
      21              : static std::mutex g_profMutex;
      22              : static std::unordered_set<uint32_t> g_deviceList;
      23              : constexpr uint64_t ACL_PROF_ACL_API = 0x0001U;
      24              : constexpr uint32_t START_PROFILING = 1U;
      25              : constexpr uint32_t STOP_PROFILING = 2U;
      26              : 
      27            0 : static bool IsDumpToStdEnabled()
      28              : {
      29            0 :     const char* profilingToStdOut = nullptr;
      30            0 :     MM_SYS_GET_ENV(MM_ENV_GE_PROFILING_TO_STD_OUT, profilingToStdOut);
      31            0 :     return profilingToStdOut != nullptr;
      32              : }
      33              : 
      34              : static const std::map<acl::AclTdtQueueProfType, std::string> TDT_QUEUE_PROF_TYPE_TO_NAMES = {
      35              :     {acl::AclTdtQueueProfType::AcltdtEnqueue, "acltdtEnqueue"},
      36              :     {acl::AclTdtQueueProfType::AcltdtDequeue, "acltdtDequeue"},
      37              :     {acl::AclTdtQueueProfType::AcltdtEnqueueData, "acltdtEnqueueData"},
      38              :     {acl::AclTdtQueueProfType::AcltdtDequeueData, "acltdtDequeueData"},
      39              : };
      40              : 
      41            1 : static aclError RegisterProfType()
      42              : {
      43            5 :     for (auto& iter : TDT_QUEUE_PROF_TYPE_TO_NAMES) {
      44            4 :         const uint32_t typeId = static_cast<uint32_t>(iter.first);
      45            4 :         const auto ret = MsprofRegTypeInfo(MSPROF_REPORT_ACL_LEVEL, typeId, iter.second.c_str());
      46            4 :         if (ret != MSPROF_ERROR_NONE) {
      47            0 :             ACL_LOG_CALL_ERROR("Registered api type [%u] failed = %d", typeId, ret);
      48            0 :             return ACL_ERROR_PROFILING_FAILURE;
      49              :         }
      50              :     }
      51            1 :     return ACL_SUCCESS;
      52              : }
      53              : 
      54            1 : static aclError AddDeviceList(const uint32_t* const deviceIdList, const uint32_t deviceNums)
      55              : {
      56            1 :     ACL_REQUIRES_NOT_NULL(deviceIdList);
      57            2 :     for (size_t devId = 0U; devId < deviceNums; devId++) {
      58            1 :         if (g_deviceList.count(*(deviceIdList + devId)) == 0U) {
      59            1 :             (void)g_deviceList.insert(*(deviceIdList + devId));
      60            1 :             ACL_LOG_INFO("device id %u is successfully added in acl profiling", *(deviceIdList + devId));
      61              :         }
      62              :     }
      63            1 :     return ACL_SUCCESS;
      64              : }
      65              : 
      66            1 : static aclError RemoveDeviceList(const uint32_t* const deviceIdList, const uint32_t deviceNums)
      67              : {
      68            1 :     ACL_REQUIRES_NOT_NULL(deviceIdList);
      69            2 :     for (size_t devId = 0U; devId < deviceNums; devId++) {
      70            1 :         const auto iter = g_deviceList.find(*(deviceIdList + devId));
      71            1 :         if (iter != g_deviceList.end()) {
      72            1 :             (void)g_deviceList.erase(iter);
      73            1 :             ACL_LOG_INFO("device id %u is successfully deleted from acl profiling", *(deviceIdList + devId));
      74              :         }
      75              :     }
      76            1 :     return ACL_SUCCESS;
      77              : }
      78              : 
      79            1 : static aclError ProfInnerStart(const rtProfCommandHandle_t* const profilerConfig)
      80              : {
      81            1 :     ACL_LOG_INFO("start to execute ProfInnerStart");
      82            1 :     if (!g_profRun) {
      83            1 :         (void)RegisterProfType();
      84            1 :         g_profRun = true;
      85              :     }
      86            1 :     (void)AddDeviceList(profilerConfig->devIdList, profilerConfig->devNums);
      87            1 :     ACL_LOG_INFO("successfully execute ProfInnerStart");
      88            1 :     return ACL_SUCCESS;
      89              : }
      90              : 
      91            1 : static aclError ProfInnerStop(const rtProfCommandHandle_t* const profilerConfig)
      92              : {
      93            1 :     ACL_LOG_INFO("start to execute ProfInnerStop");
      94            1 :     (void)RemoveDeviceList(profilerConfig->devIdList, profilerConfig->devNums);
      95              : 
      96            1 :     if (g_deviceList.empty() && g_profRun) {
      97            1 :         g_profRun = false;
      98              :     }
      99            1 :     ACL_LOG_INFO("successfully execute ProfInnerStop");
     100            1 :     return ACL_SUCCESS;
     101              : }
     102              : 
     103            2 : static aclError ProcessProfData(void* const data, const uint32_t len)
     104              : {
     105            2 :     ACL_LOG_INFO("start to execute ProcessProfData");
     106            2 :     const std::lock_guard<std::mutex> lk(g_profMutex);
     107            2 :     ACL_REQUIRES_NOT_NULL(data);
     108            2 :     constexpr size_t commandLen = sizeof(rtProfCommandHandle_t);
     109            2 :     if (len < commandLen) {
     110            0 :         const std::string lenVal = std::to_string(len);
     111            0 :         std::string errMsg = acl::AclErrorLogManager::FormatStr("len should not be smaller than %zu", commandLen);
     112            0 :         ACL_LOG_ERROR("[Check][Len]len[%u] is invalid, it should not be smaller than %zu", len, commandLen);
     113            0 :         acl::AclErrorLogManager::ReportInputError(
     114            0 :             acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
     115            0 :             std::vector<const char*>(
     116            0 :                 {"Processing profiling configuration data", lenVal.c_str(), "len", errMsg.c_str()}));
     117            0 :         return ACL_ERROR_INVALID_PARAM;
     118            0 :     }
     119            2 :     rtProfCommandHandle_t* const profilerConfig = static_cast<rtProfCommandHandle_t*>(data);
     120            2 :     aclError ret = ACL_SUCCESS;
     121            2 :     const uint64_t profSwitch = profilerConfig->profSwitch;
     122            2 :     const uint32_t type = profilerConfig->type;
     123            2 :     if (((profSwitch & ACL_PROF_ACL_API) != 0U) && (type == START_PROFILING)) {
     124            1 :         ret = ProfInnerStart(profilerConfig);
     125              :     }
     126            2 :     if (((profSwitch & ACL_PROF_ACL_API) != 0U) && (type == STOP_PROFILING)) {
     127            1 :         ret = ProfInnerStop(profilerConfig);
     128              :     }
     129              : 
     130            2 :     return ret;
     131            2 : }
     132              : 
     133              : class AclRegProfCallback {
     134              : public:
     135            1 :     AclRegProfCallback()
     136              :     {
     137            1 :         const auto profRet = MsprofRegisterCallback(ASCENDCL, &acl::AclTdtQueueProfCtrlHandle);
     138            1 :         if (profRet != 0) {
     139            1 :             ACL_LOG_ERROR("can not register Callback, prof result = %d", profRet);
     140              :         }
     141            1 :     }
     142              :     ~AclRegProfCallback() = default;
     143              : };
     144              : static AclRegProfCallback g_profCbReg;
     145              : } // namespace
     146              : 
     147              : namespace acl {
     148            2 : aclError AclTdtQueueProfCtrlHandle(uint32_t dataType, void* data, uint32_t dataLen)
     149              : {
     150            2 :     ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(data);
     151              : 
     152            2 :     if (dataType == RT_PROF_CTRL_SWITCH) {
     153            2 :         const aclError ret = ProcessProfData(data, dataLen);
     154            2 :         if (ret != ACL_SUCCESS) {
     155            0 :             ACL_LOG_INNER_ERROR("[Process][ProfSwitch]failed to call ProcessProfData, result is %u.", ret);
     156            0 :             return ret;
     157              :         }
     158            2 :         return ACL_SUCCESS;
     159              :     }
     160              : 
     161            0 :     ACL_LOG_INFO("get unsupported dataType %u while processing profiling data", dataType);
     162            0 :     return ACL_SUCCESS;
     163              : }
     164              : 
     165            4 : AclTdtQueueProfilingReporter::AclTdtQueueProfilingReporter(const AclTdtQueueProfType apiId) : aclApi_(apiId)
     166              : {
     167            4 :     if (g_profRun && (!IsDumpToStdEnabled())) {
     168            0 :         startTime_ = MsprofSysCycleTime();
     169              :     }
     170            4 : }
     171              : 
     172            4 : AclTdtQueueProfilingReporter::~AclTdtQueueProfilingReporter() noexcept
     173              : {
     174            4 :     if (g_profRun && (!IsDumpToStdEnabled()) && (startTime_ != 0UL)) {
     175              :         // 1000 ^ 3 converts second to nanosecond
     176            0 :         const uint64_t endTime = MsprofSysCycleTime();
     177            0 :         MsprofApi api{};
     178            0 :         api.beginTime = startTime_;
     179            0 :         api.endTime = endTime;
     180            0 :         thread_local static const auto tid = mmGetTid();
     181            0 :         api.threadId = static_cast<uint32_t>(tid);
     182            0 :         api.level = MSPROF_REPORT_ACL_LEVEL;
     183            0 :         api.type = static_cast<uint32_t>(aclApi_);
     184            0 :         (void)MsprofReportApi(true, &api);
     185              :     }
     186            4 : }
     187              : } // namespace acl
        

Generated by: LCOV version 2.0-1