LCOV - code coverage report
Current view: top level - acl/acl_tdt_queue/toolchain - prof_api_reg.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 69 91 75.8 %
Date: 2026-08-27 13:24:42 Functions: 11 13 84.6 %

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

Generated by: LCOV version 1.14