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 : #include "profiling.h"
11 : #include "mmpa/mmpa_api.h"
12 : #include "common/log_inner.h"
13 : #include "common/json_parser.h"
14 : #include "profiling_manager.h"
15 :
16 : namespace {
17 : const std::string ACL_PROF_CONFIG_NAME = "profiler";
18 : std::mutex g_aclProfMutex;
19 : constexpr uint64_t ACL_PROF_ACL_API = 0x0001U;
20 : constexpr uint32_t START_PROFILING = 1U;
21 : constexpr uint32_t STOP_PROFILING = 2U;
22 :
23 1 : static aclError ProfInnerStart(const rtProfCommandHandle_t* const profilerConfig)
24 : {
25 1 : ACL_LOG_INFO("start to execute ProfInnerStart");
26 1 : if (!acl::AclProfilingManager::GetInstance().AclProfilingIsRun()) {
27 1 : const aclError ret = acl::AclProfilingManager::GetInstance().Init();
28 1 : if (ret != ACL_SUCCESS) {
29 1 : ACL_LOG_INNER_ERROR(
30 : "[Init][ProfilingManager]start acl profiling module failed,"
31 : " errorCode = %d",
32 : ret);
33 1 : return ret;
34 : }
35 : }
36 0 : (void)acl::AclProfilingManager::GetInstance().AddDeviceList(profilerConfig->devIdList, profilerConfig->devNums);
37 0 : ACL_LOG_INFO("successfully execute ProfInnerStart");
38 0 : return ACL_SUCCESS;
39 : }
40 :
41 : // inner interface for stoping profiling
42 0 : static aclError ProfInnerStop(const rtProfCommandHandle_t* const profilerConfig)
43 : {
44 0 : ACL_LOG_INFO("start to execute ProfInnerStop");
45 0 : if (!acl::AclProfilingManager::GetInstance().IsDeviceListEmpty()) {
46 0 : (void)acl::AclProfilingManager::GetInstance().RemoveDeviceList(
47 0 : profilerConfig->devIdList, profilerConfig->devNums);
48 : }
49 :
50 0 : if ((acl::AclProfilingManager::GetInstance().IsDeviceListEmpty()) &&
51 0 : (acl::AclProfilingManager::GetInstance().AclProfilingIsRun())) {
52 0 : const aclError ret = acl::AclProfilingManager::GetInstance().UnInit();
53 0 : if (ret != ACL_SUCCESS) {
54 0 : ACL_LOG_INNER_ERROR("[Uninit][ProfilingManager]stop acl failed, errorCode = %d", ret);
55 0 : return ret;
56 : }
57 : }
58 0 : ACL_LOG_INFO("successfully execute ProfInnerStop");
59 0 : return ACL_SUCCESS;
60 : }
61 :
62 2 : aclError ProcessProfData(void* const data, const uint32_t len)
63 : {
64 2 : ACL_LOG_INFO("start to execute ProcessProfData");
65 2 : const std::lock_guard<std::mutex> locker(g_aclProfMutex);
66 2 : ACL_REQUIRES_NOT_NULL(data);
67 2 : constexpr size_t commandLen = sizeof(rtProfCommandHandle_t);
68 2 : if (len < commandLen) {
69 1 : ACL_LOG_INNER_ERROR("[Check][Len]len[%u] is invalid, it should not be smaller than %zu", len, commandLen);
70 1 : return ACL_ERROR_INVALID_PARAM;
71 : }
72 1 : rtProfCommandHandle_t* const profilerConfig = static_cast<rtProfCommandHandle_t*>(data);
73 1 : aclError ret = ACL_SUCCESS;
74 1 : const uint64_t profSwitch = profilerConfig->profSwitch;
75 1 : const uint32_t type = profilerConfig->type;
76 1 : if (((profSwitch & ACL_PROF_ACL_API) != 0U) && (type == START_PROFILING)) {
77 1 : ret = ProfInnerStart(profilerConfig);
78 : }
79 1 : if (((profSwitch & ACL_PROF_ACL_API) != 0U) && (type == STOP_PROFILING)) {
80 0 : ret = ProfInnerStop(profilerConfig);
81 : }
82 :
83 1 : return ret;
84 2 : }
85 : } // namespace
86 :
87 : namespace acl {
88 34 : aclError AclProfiling::HandleProfilingCommand(
89 : const std::string& config, const bool configFileFlag, const bool noValidConfig)
90 : {
91 34 : ACL_LOG_INFO("start to execute HandleProfilingCommand");
92 34 : int32_t ret = MSPROF_ERROR_NONE;
93 34 : if (noValidConfig) {
94 31 : ret = MsprofInit(MSPROF_CTRL_INIT_DYNA, nullptr, 0U);
95 31 : if (ret != MSPROF_ERROR_NONE) {
96 0 : ACL_LOG_CALL_ERROR("[Init][Profiling]init profiling with nullptr failed, profiling errorCode = %d", ret);
97 0 : return ACL_SUCCESS;
98 : }
99 : } else {
100 3 : if (configFileFlag) {
101 2 : ret = MsprofInit(
102 2 : MSPROF_CTRL_INIT_ACL_JSON, const_cast<char_t*>(config.c_str()), static_cast<uint32_t>(config.size()));
103 2 : if (ret != MSPROF_ERROR_NONE) {
104 1 : ACL_LOG_CALL_ERROR(
105 : "[Init][Profiling]handle json config of profiling failed, profiling "
106 : "result = %d",
107 : ret);
108 1 : return ACL_ERROR_INVALID_PARAM;
109 : }
110 : } else {
111 1 : ret = MsprofInit(
112 1 : MSPROF_CTRL_INIT_ACL_ENV, const_cast<char_t*>(config.c_str()), static_cast<uint32_t>(config.size()));
113 1 : if (ret != MSPROF_ERROR_NONE) {
114 1 : ACL_LOG_CALL_ERROR(
115 : "[Init][Profiling]handle env config of profiling failed, profiling "
116 : "result = %d",
117 : ret);
118 1 : return ACL_ERROR_INVALID_PARAM;
119 : }
120 : }
121 : }
122 32 : ACL_LOG_INFO("set profiling config successfully");
123 32 : return ACL_SUCCESS;
124 : }
125 :
126 32 : bool AclProfiling::GetProfilingConfigFile(std::string& fileName)
127 : {
128 32 : const char_t* environment = nullptr;
129 32 : MM_SYS_GET_ENV(MM_ENV_PROFILER_SAMPLECONFIG, environment);
130 32 : if (environment != nullptr) {
131 0 : ACL_LOG_INFO("get profiling config envValue[%s]", environment);
132 0 : fileName = environment;
133 0 : return true;
134 : }
135 32 : ACL_LOG_INFO("no profiling config file.");
136 32 : return false;
137 : }
138 :
139 32 : aclError AclProfiling::HandleProfilingConfig(const char_t* const configPath)
140 : {
141 32 : ACL_LOG_INFO("start to execute HandleProfilingConfig");
142 32 : std::string strConfig;
143 32 : bool configFileFlag = true; // flag of using config flie mode or not
144 32 : bool noValidConfig = false;
145 32 : aclError ret = ACL_SUCCESS;
146 32 : std::string envValue;
147 : // use profiling config from env variable if exist
148 32 : if ((GetProfilingConfigFile(envValue)) && (!envValue.empty())) {
149 0 : configFileFlag = false;
150 0 : ACL_LOG_INFO("start to use profiling config by env mode");
151 : }
152 :
153 : // use profiling config from acl.json if exist
154 32 : if (configFileFlag) {
155 32 : if ((configPath == nullptr) || (strnlen(configPath, 255U) == 0U)) {
156 17 : ACL_LOG_INFO("configPath is null, no need to do profiling.");
157 17 : noValidConfig = true;
158 17 : ret = HandleProfilingCommand(strConfig, configFileFlag, noValidConfig);
159 17 : if (ret != ACL_SUCCESS) {
160 0 : ACL_LOG_INNER_ERROR("[Handle][Command]handle profiling command failed, errorCode = %d", ret);
161 : }
162 17 : return ret;
163 : }
164 15 : bool found = false;
165 15 : ret = acl::JsonParser::GetJsonCtxByKey(configPath, strConfig, ACL_PROF_CONFIG_NAME, found);
166 15 : if ((ret != ACL_SUCCESS) || (!found)) {
167 14 : ACL_LOG_INFO("Cannot parse profiling config from file[%s], errorCode = %d", configPath, ret);
168 14 : noValidConfig = true;
169 : }
170 :
171 15 : if (strConfig.empty()) {
172 14 : ACL_LOG_INFO("profiling config file[%s] is empty", configPath);
173 14 : noValidConfig = true;
174 : }
175 :
176 15 : ACL_LOG_INFO("start to use profiling config by config file mode");
177 : }
178 :
179 15 : ACL_LOG_INFO("ParseJsonFromFile ok in HandleProfilingConfig");
180 15 : ret = HandleProfilingCommand(strConfig, configFileFlag, noValidConfig);
181 15 : if (ret != ACL_SUCCESS) {
182 0 : ACL_LOG_INNER_ERROR("[Handle][Command]handle profiling command failed, errorCode = %d", ret);
183 0 : return ret;
184 : }
185 :
186 15 : ACL_LOG_INFO("set HandleProfilingConfig success");
187 15 : return ret;
188 32 : }
189 2 : aclError AclProfCtrlHandle(uint32_t dataType, void* data, uint32_t dataLen)
190 : {
191 2 : ACL_REQUIRES_NOT_NULL(data);
192 :
193 2 : if (dataType == RT_PROF_CTRL_SWITCH) {
194 2 : const aclError ret = ProcessProfData(data, dataLen);
195 2 : if (ret != ACL_SUCCESS) {
196 2 : ACL_LOG_INNER_ERROR("[Process][ProfSwitch]failed to call ProcessProfData, result is %u", ret);
197 2 : return ret;
198 : }
199 : } else {
200 0 : ACL_LOG_INFO("get unsupported dataType %u while processing profiling data", dataType);
201 : }
202 0 : return ACL_SUCCESS;
203 : }
204 : } // namespace acl
|