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