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 "msprof_manager.h"
12 :
13 : #include <memory>
14 : #include <unordered_map>
15 : #include "securec.h"
16 :
17 : namespace bqs {
18 : namespace {
19 : const std::string PROFILING_RESULT_DIR = "/var/log/npu/profiling/";
20 : }
21 :
22 114 : BqsMsprofManager& BqsMsprofManager::GetInstance()
23 : {
24 114 : static BqsMsprofManager instance;
25 114 : return instance;
26 : }
27 :
28 18 : void BqsMsprofManager::InitBqsMsprofManager(const bool initFlag, const std::string& cfgData)
29 : {
30 18 : if (!initFlag) {
31 3 : DGW_LOG_RUN_INFO("[Prof]Profiling flag set to false, will not start.");
32 3 : return;
33 : }
34 :
35 15 : if (!BqsMsprofApiAdapter::GetInstance().IsSoLoad()) {
36 0 : DGW_LOG_ERROR("[Prof]Profiling flag set to true but so load failed.");
37 0 : return;
38 : }
39 :
40 15 : ProfStatus ret = RegProfCallback();
41 15 : if (ret != ProfStatus::PROF_SUCCESS) {
42 0 : DGW_LOG_ERROR("[Prof]Regist profiling callback failed, ret=%d", static_cast<int32_t>(ret));
43 0 : return;
44 : }
45 :
46 15 : ret = InitProf(cfgData);
47 15 : if (ret != ProfStatus::PROF_SUCCESS) {
48 0 : DGW_LOG_ERROR("[Prof]Init msprof failed, ret=%d, cfgData=%s.", static_cast<int32_t>(ret), cfgData.c_str());
49 0 : return;
50 : }
51 :
52 15 : ret = RegProfType();
53 15 : if (ret != ProfStatus::PROF_SUCCESS) {
54 0 : DGW_LOG_ERROR("[Prof]Regist profiling type failed, ret=%d", static_cast<int32_t>(ret));
55 0 : return;
56 : }
57 :
58 15 : DGW_LOG_RUN_INFO("[Prof]Queue schedule profiling init success, cfgData=%s.", cfgData.c_str());
59 :
60 15 : return;
61 : }
62 :
63 15 : ProfStatus BqsMsprofManager::RegProfCallback() const
64 : {
65 15 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofRegisterCallback(AICPU, &ProfCallback);
66 15 : if (ret != ProfStatus::PROF_SUCCESS) {
67 0 : DGW_LOG_ERROR("[Prof]Regist profiling callback failed, ret=%d.", static_cast<int32_t>(ret));
68 0 : return ret;
69 : }
70 :
71 15 : DGW_LOG_RUN_INFO("[Prof]Regist profiling callback success.");
72 :
73 15 : return ret;
74 : }
75 :
76 15 : ProfStatus BqsMsprofManager::InitProf(const std::string& cfgData)
77 : {
78 15 : std::shared_ptr<MsprofCommandHandleParams> profCfg = std::make_shared<MsprofCommandHandleParams>();
79 15 : if (profCfg == nullptr) {
80 0 : DGW_LOG_ERROR("[Prof]Malloc profiling config struct failed.");
81 0 : return ProfStatus::PROF_FAIL;
82 : }
83 :
84 15 : int32_t ret = memset_s(profCfg.get(), sizeof(*profCfg), 0, sizeof(*profCfg));
85 15 : if (ret != EOK) {
86 0 : DGW_LOG_ERROR("[Prof]Memset profiling config struct failed, ret=%d.", ret);
87 0 : return ProfStatus::PROF_FAIL;
88 : }
89 :
90 15 : const uint32_t cfgDataLen = cfgData.length();
91 15 : const uint32_t pathLen = PROFILING_RESULT_DIR.length();
92 15 : ret = strncpy_s(profCfg->profData, sizeof(profCfg->profData), cfgData.c_str(), cfgDataLen);
93 15 : ret |= strncpy_s(profCfg->path, sizeof(profCfg->path), PROFILING_RESULT_DIR.c_str(), pathLen);
94 15 : if (ret != EOK) {
95 0 : DGW_LOG_ERROR("[Prof]Copy data to profiling config failed, cfgDataLen=%u, pathLen=%u.", cfgDataLen, pathLen);
96 0 : return ProfStatus::PROF_FAIL;
97 : }
98 :
99 15 : profCfg->profDataLen = cfgDataLen;
100 15 : profCfg->pathLen = pathLen;
101 15 : profCfg->storageLimit = UINT32_MAX;
102 :
103 30 : ProfStatus profRet = BqsMsprofApiAdapter::GetInstance().MsprofInit(
104 15 : static_cast<uint32_t>(MSPROF_CTRL_INIT_PURE_CPU), profCfg.get(), sizeof(*profCfg));
105 15 : if (profRet != ProfStatus::PROF_SUCCESS) {
106 0 : DGW_LOG_ERROR(
107 : "[Prof]Init msprof failed, ret=%d, profData=%s, profPath=%s, storageLimit=%u.",
108 : static_cast<int32_t>(profRet), profCfg->profData, profCfg->path, profCfg->storageLimit);
109 0 : return profRet;
110 : }
111 :
112 15 : isInitMsprof_ = true;
113 :
114 15 : DGW_LOG_RUN_INFO(
115 : "[Prof]Init msprof success, profData=%s, profPath=%s, storageLimit=%u.", profCfg->profData, profCfg->path,
116 : profCfg->storageLimit);
117 :
118 15 : return ProfStatus::PROF_SUCCESS;
119 15 : }
120 :
121 15 : ProfStatus BqsMsprofManager::RegProfType() const
122 : {
123 : const std::unordered_map<std::string, DgwProfInfoType> namesToProfTypes = {
124 0 : {"FlowGwHcclTransData", DgwProfInfoType::HCCL_TRANS_DATA},
125 0 : {"FlowGwAlloMbuf", DgwProfInfoType::ALLOC_MBUF},
126 0 : {"FlowGwEnqueueData", DgwProfInfoType::ENQUEUE_DATA},
127 75 : };
128 :
129 60 : for (const auto& name_pair : namesToProfTypes) {
130 45 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofRegTypeInfo(
131 45 : static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL), static_cast<int32_t>(name_pair.second),
132 : name_pair.first.c_str());
133 45 : if (ret != ProfStatus::PROF_SUCCESS) {
134 0 : DGW_LOG_ERROR(
135 : "[Prof]Regist profiling type failed, ret=%d, typeId=%d, typeName=%s.", static_cast<int32_t>(ret),
136 : static_cast<int32_t>(name_pair.second), name_pair.first.c_str());
137 0 : return ProfStatus::PROF_FAIL;
138 : }
139 : }
140 :
141 15 : DGW_LOG_RUN_INFO("[Prof]Regist profiling type success.");
142 :
143 15 : return ProfStatus::PROF_SUCCESS;
144 30 : }
145 :
146 14 : int32_t BqsMsprofManager::ProfCallback(uint32_t type, void* data, uint32_t dataLen)
147 : {
148 14 : DGW_LOG_RUN_INFO("[Prof]Queue schedule start process profiling callback, type=%u.", type);
149 :
150 14 : if ((data == nullptr) || (dataLen < sizeof(MsprofCommandHandle))) {
151 1 : DGW_LOG_ERROR("[Prof]Prorfiling callback data is nullptr or dataLen is invalid, dataLen=%u.", dataLen);
152 1 : return static_cast<int32_t>(ProfStatus::PROF_INVALID_PARA);
153 : }
154 :
155 13 : const MsprofCommandHandle* const profCmdHandle = static_cast<MsprofCommandHandle*>(data);
156 13 : ProfStatus ret = ProfStatus::PROF_SUCCESS;
157 13 : switch (type) {
158 10 : case static_cast<uint32_t>(PROF_CTRL_SWITCH):
159 10 : ret = BqsMsprofManager::GetInstance().HandleCtrlSwitch(*profCmdHandle);
160 10 : break;
161 1 : case static_cast<uint32_t>(PROF_CTRL_REPORTER):
162 1 : ret = BqsMsprofManager::GetInstance().HandelCtrlReporter(*profCmdHandle);
163 1 : break;
164 1 : case static_cast<uint32_t>(PROF_CTRL_STEPINFO):
165 1 : ret = BqsMsprofManager::GetInstance().HandleCtrlStepInfo(*profCmdHandle);
166 1 : break;
167 1 : default:
168 1 : DGW_LOG_INFO("[Prof]Get unknown ctrl type, type=%u.", type);
169 1 : break;
170 : }
171 :
172 13 : return static_cast<int32_t>(ret);
173 : }
174 :
175 10 : ProfStatus BqsMsprofManager::HandleCtrlSwitch(const MsprofCommandHandle& profCmdHandle)
176 : {
177 10 : const uint32_t type = profCmdHandle.type;
178 10 : DGW_LOG_INFO("[Prof]Start process prof ctrl switch, type=%u.", type);
179 10 : switch (type) {
180 3 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_START):
181 3 : isRun_ = true;
182 3 : DGW_LOG_RUN_INFO("[Prof]Start queue schedule profiling.");
183 3 : break;
184 :
185 4 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_STOP):
186 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_FINALIZE):
187 4 : isRun_ = false;
188 4 : DGW_LOG_RUN_INFO("[Prof]Stop queue schedule profiling.");
189 4 : break;
190 :
191 3 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_INIT):
192 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_MODEL_SUBSCRIBE):
193 : case static_cast<uint32_t>(PROF_COMMANDHANDLE_TYPE_MODEL_UNSUBSCRIBE):
194 : default:
195 3 : break;
196 : }
197 :
198 10 : return ProfStatus::PROF_SUCCESS;
199 : }
200 :
201 1 : ProfStatus BqsMsprofManager::HandelCtrlReporter(const MsprofCommandHandle& profCmdHandle) const
202 : {
203 : (void)profCmdHandle;
204 1 : DGW_LOG_INFO("[Prof]Start process prof ctrl reporter.");
205 1 : return ProfStatus::PROF_SUCCESS;
206 : }
207 :
208 1 : ProfStatus BqsMsprofManager::HandleCtrlStepInfo(const MsprofCommandHandle& profCmdHandle) const
209 : {
210 : (void)profCmdHandle;
211 1 : DGW_LOG_INFO("[Prof]Start process prof ctrl step info.");
212 1 : return ProfStatus::PROF_SUCCESS;
213 : }
214 :
215 27 : void BqsMsprofManager::ReportApiPerf(const ProfInfo& profData) const
216 : {
217 27 : if (!isRun_) {
218 22 : return;
219 : }
220 :
221 5 : MsprofApi reportData;
222 5 : reportData.level = static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL);
223 5 : reportData.type = profData.type;
224 5 : reportData.threadId = GetTid();
225 5 : reportData.reserve = 0UL;
226 5 : reportData.beginTime = profData.timeStamp;
227 5 : reportData.endTime = GetTimeStamp();
228 5 : reportData.itemId = profData.itemId;
229 :
230 5 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofReportApi(agingFlag_, &reportData);
231 5 : if (ret != ProfStatus::PROF_SUCCESS) {
232 0 : DGW_LOG_ERROR("[Prof]Report api failed, ret=%d, itemId=%lu", static_cast<int32_t>(ret), profData.itemId);
233 : }
234 :
235 5 : DGW_LOG_INFO("[Prof]Send api perf success, itemId=%lu, beginTime=%lu.", reportData.itemId, reportData.beginTime);
236 :
237 5 : return;
238 : }
239 :
240 2 : void BqsMsprofManager::ReportEventPerf(const ProfInfo& profData)
241 : {
242 2 : if (!isRun_) {
243 1 : return;
244 : }
245 :
246 1 : ++requestId_;
247 1 : MsprofEvent reportData;
248 1 : reportData.level = static_cast<uint16_t>(MSPROF_REPORT_MODEL_LEVEL);
249 1 : reportData.type = profData.type;
250 1 : reportData.threadId = GetTid();
251 1 : reportData.requestId = requestId_.load();
252 1 : reportData.timeStamp = profData.timeStamp;
253 1 : reportData.itemId = profData.itemId;
254 :
255 1 : const ProfStatus ret = BqsMsprofApiAdapter::GetInstance().MsprofReportEvent(agingFlag_, &reportData);
256 1 : if (ret != ProfStatus::PROF_SUCCESS) {
257 0 : DGW_LOG_ERROR(
258 : "[Prof]Report event failed, ret=%d, requestId=%u, itemId=%lu.", static_cast<int32_t>(ret),
259 : reportData.requestId, reportData.itemId);
260 : }
261 :
262 1 : DGW_LOG_INFO(
263 : "[Prof]Send event perf success, requestId=%u, itemId=%lu, timeStamp=%lu.", reportData.requestId,
264 : reportData.itemId, reportData.timeStamp);
265 :
266 1 : return;
267 : }
268 :
269 : } // namespace bqs
|