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 "inc/client_manager.h"
12 : #include "driver/ascend_hal.h"
13 : #include "tsd_util_func.h"
14 : #include "tsd_log.h"
15 : #include "inc/process_mode_manager.h"
16 : #include "inc/thread_mode_manager.h"
17 : #include "driver/dsmi_common_interface.h"
18 : #include "env_internal_api.h"
19 : namespace tsd {
20 : namespace {
21 : std::mutex g_destructFlagMut;
22 : // runtime的context析构时会调TsdClose接口,此时全局变量对象可能已经析构,所以此处使用指针
23 : std::map<const uint32_t, bool>* g_destructFlagMap = nullptr;
24 :
25 : std::mutex g_tsdClientMut;
26 : // tsdClientInstanceMap_中存储的对象是全局的,进程销毁时才销毁
27 : static std::map<const uint32_t, std::shared_ptr<ClientManager>> tsdClientInstanceMap_;
28 :
29 : static std::map<const uint32_t, uint32_t>* g_userDeviceInfo = nullptr;
30 : bool g_hadGetVisibleDevices = false;
31 :
32 : struct PlatformInfo {
33 : uint32_t onlineStatus;
34 : ChipType_t chipType;
35 : bool isAdcEnv;
36 : };
37 : static PlatformInfo g_platInfo;
38 : bool g_hadGetPlatformInfo = false;
39 : } // namespace
40 :
41 : RunningMode ClientManager::g_runningMode = RunningMode::UNSET_MODE;
42 : std::mutex ClientManager::g_profilingCallbackMut;
43 : MsprofReporterCallback ClientManager::g_profilingCallback;
44 : SchedMode ClientManager::aicpuSchedMode_ = AICPU_SCHED_MODE_INTERRUPT;
45 :
46 69 : bool ClientManager::CheckDestructFlag(const uint32_t logicDevId)
47 : {
48 69 : const uint32_t inputDeviceId = logicDevId;
49 69 : uint32_t logicDeviceId = logicDevId;
50 69 : const auto ret = ChangeUserDeviceIdToLogicDeviceId(logicDevId, logicDeviceId);
51 69 : if (ret != TSD_OK) {
52 1 : return false;
53 : }
54 :
55 : // logicDevId is actually user device id
56 68 : if (!g_hadGetPlatformInfo && (ClientManager::GetPlatformInfo(logicDeviceId) != TSD_OK)) {
57 1 : return false;
58 : }
59 :
60 67 : if (!IsSupportSetVisibleDevices()) {
61 67 : logicDeviceId = inputDeviceId;
62 : }
63 :
64 67 : const std::lock_guard<std::mutex> lk(g_destructFlagMut);
65 67 : if (g_destructFlagMap == nullptr) {
66 1 : g_destructFlagMap = new (std::nothrow) std::map<const uint32_t, bool>;
67 1 : if (g_destructFlagMap == nullptr) {
68 0 : TSD_ERROR("[TsdClient] new g_destructFlagMap failed");
69 0 : return true;
70 : }
71 : }
72 67 : const std::map<const uint32_t, bool>::const_iterator iter = g_destructFlagMap->find(logicDeviceId);
73 67 : if (iter != g_destructFlagMap->end()) {
74 66 : return iter->second;
75 : } else {
76 1 : (void)g_destructFlagMap->insert(std::make_pair(logicDeviceId, false));
77 1 : return false;
78 : }
79 67 : }
80 :
81 270 : ClientManager::ClientManager(const uint32_t& deviceId)
82 270 : : logicDeviceId_(deviceId),
83 270 : profilingMode_(ProfilingMode::PROFILING_CLOSE),
84 270 : envInfo_(deviceId, g_platInfo.onlineStatus, g_platInfo.isAdcEnv, static_cast<uint32_t>(g_platInfo.chipType)),
85 270 : packagePath_(envInfo_.packagePath_),
86 270 : packageName_(envInfo_.packageName_),
87 270 : packagePattern_(envInfo_.packagePattern_)
88 : {
89 270 : GetProfilingMode();
90 270 : }
91 :
92 270 : ClientManager::~ClientManager()
93 : {
94 270 : if (g_destructFlagMap != nullptr) {
95 270 : const auto iter = g_destructFlagMap->find(logicDeviceId_);
96 270 : if (iter != g_destructFlagMap->end()) {
97 257 : iter->second = true;
98 : } else {
99 13 : TSD_INFO("[TsdClient] tsd is not open, deviceId[%u]", logicDeviceId_);
100 : }
101 : }
102 270 : }
103 :
104 1 : TSD_StatusT ClientManager::GetHdcConctStatus(int32_t& hdcSessStat)
105 : {
106 1 : hdcSessStat = HDC_SESSION_STATUS_CONNECT;
107 1 : return TSD_OK;
108 : }
109 :
110 214 : std::shared_ptr<ClientManager> ClientManager::GetInstance(
111 : const uint32_t& deviceId, const uint32_t deviceMode, const bool transDevIdFlag)
112 : {
113 214 : const uint32_t inputDeviceId = deviceId;
114 214 : uint32_t logicDeviceId = deviceId;
115 214 : if (transDevIdFlag) {
116 122 : const auto ret = ChangeUserDeviceIdToLogicDeviceId(deviceId, logicDeviceId);
117 122 : if (ret != TSD_OK) {
118 1 : return nullptr;
119 : }
120 : }
121 :
122 213 : if (!g_hadGetPlatformInfo && (ClientManager::GetPlatformInfo(logicDeviceId) != TSD_OK)) {
123 2 : return nullptr;
124 : }
125 :
126 211 : if (!IsSupportSetVisibleDevices()) {
127 211 : logicDeviceId = inputDeviceId;
128 : }
129 :
130 211 : const std::lock_guard<std::mutex> lk(g_tsdClientMut);
131 211 : std::shared_ptr<ClientManager> clientManager = nullptr;
132 : const std::map<const uint32_t, std::shared_ptr<ClientManager>>::const_iterator iter =
133 211 : tsdClientInstanceMap_.find(logicDeviceId);
134 211 : if (iter != tsdClientInstanceMap_.end()) {
135 203 : return iter->second;
136 : } else {
137 8 : TSD_INFO(
138 : "[ClientManager] GetInstance, deviceId[%u], g_runningMode[%d], begin saving instance", logicDeviceId,
139 : g_runningMode);
140 8 : const RunningMode curMode = GetClientRunMode(logicDeviceId);
141 8 : TSD_RUN_INFO("[ClientManager] Current mode:%u", static_cast<uint32_t>(curMode));
142 8 : if (curMode == RunningMode::PROCESS_MODE) {
143 4 : clientManager.reset(new (std::nothrow) ProcessModeManager(logicDeviceId, deviceMode));
144 4 : } else if (curMode == RunningMode::THREAD_MODE) {
145 3 : clientManager.reset(new (std::nothrow) ThreadModeManager(logicDeviceId));
146 : } else {
147 1 : TSD_ERROR("[TsdClient] current mode is error");
148 1 : return nullptr;
149 : }
150 7 : TSD_CHECK((clientManager != nullptr), nullptr, "Fail to create clientManager");
151 7 : (void)tsdClientInstanceMap_.insert(std::make_pair(logicDeviceId, clientManager));
152 : }
153 7 : return clientManager;
154 211 : }
155 :
156 22 : TSD_StatusT ClientManager::GetPlatformInfo(const uint32_t deviceId)
157 : {
158 22 : uint32_t mode = 0U;
159 22 : drvError_t drvRet = drvGetPlatformInfo(&mode);
160 22 : if (drvRet != DRV_ERROR_NONE) {
161 1 : TSD_ERROR("get run mode by drvGetPlatformInfo failed, errorCode[%d]", drvRet);
162 1 : return TSD_CLT_OPEN_FAILED;
163 : }
164 21 : int64_t hardwareVersion = 0;
165 21 : drvRet = halGetDeviceInfo(deviceId, MODULE_TYPE_SYSTEM, INFO_TYPE_VERSION, &hardwareVersion);
166 21 : if (drvRet != DRV_ERROR_NONE) {
167 1 : TSD_ERROR("get device info by halGetDeviceInfo failed, errorCode[%d] deviceId[%u]", drvRet, deviceId);
168 1 : return TSD_CLT_OPEN_FAILED;
169 : }
170 20 : const ChipType_t chipType = static_cast<ChipType_t>(TSD_PLAT_GET_CHIP(static_cast<uint64_t>(hardwareVersion)));
171 20 : TSD_INFO("[TsdClient] mode[%u] chipType[%u]", static_cast<uint32_t>(mode), static_cast<uint32_t>(chipType));
172 20 : g_platInfo.onlineStatus = mode;
173 20 : g_platInfo.chipType = chipType;
174 20 : if ((chipType == static_cast<uint32_t>(CHIP_ADC)) || (chipType == static_cast<uint32_t>(CHIP_AS31XM1)) ||
175 20 : (chipType == static_cast<uint32_t>(CHIP_610LITE)) || (chipType == static_cast<uint32_t>(CHIP_MC62CM12A)) ||
176 : (chipType == static_cast<uint32_t>(CHIP_MC32DM11A))) {
177 0 : g_platInfo.isAdcEnv = true;
178 : }
179 20 : g_hadGetPlatformInfo = true;
180 20 : return TSD_OK;
181 : }
182 :
183 525 : uint32_t ClientManager::GetPlatInfoMode() const { return g_platInfo.onlineStatus; }
184 :
185 263 : uint32_t ClientManager::GetPlatInfoChipType() { return static_cast<uint32_t>(g_platInfo.chipType); }
186 :
187 1023 : bool ClientManager::IsAdcEnv() const { return g_platInfo.isAdcEnv; }
188 :
189 1 : void ClientManager::SetPlatInfoMode(const uint32_t platInfoMode) const { g_platInfo.onlineStatus = platInfoMode; }
190 :
191 2 : void ClientManager::SetProfilingCallback(const MsprofReporterCallback& callback)
192 : {
193 2 : const std::lock_guard<std::mutex> lk(g_profilingCallbackMut);
194 2 : if (g_profilingCallback == nullptr) {
195 2 : TSD_RUN_INFO("[TsdClient] set profiling callback successfully");
196 : }
197 2 : g_profilingCallback = callback;
198 2 : }
199 :
200 555 : TSD_StatusT ClientManager::SetRunMode(const std::string& valueStr)
201 : {
202 555 : g_runningMode = RunningMode::UNSET_MODE;
203 555 : if (valueStr == "PROCESS_MODE") {
204 486 : g_runningMode = RunningMode::PROCESS_MODE;
205 : }
206 555 : if (valueStr == "THREAD_MODE") {
207 66 : g_runningMode = RunningMode::THREAD_MODE;
208 : }
209 555 : TSD_RUN_INFO("[TsdClient] set run mode success. runmode[%u]", g_runningMode);
210 555 : return tsd::TSD_OK;
211 : }
212 :
213 1 : TSD_StatusT ClientManager::SetAicpuSchedMode(const uint32_t schedMode)
214 : {
215 1 : if (schedMode >= AICPU_SCHED_MODE_INVALID) {
216 0 : TSD_RUN_WARN(
217 : "[TsdClient] Invalid aicpu sched mode use interrupt mode. in=%u, max=%u", schedMode,
218 : static_cast<uint32_t>(AICPU_SCHED_MODE_INVALID));
219 0 : aicpuSchedMode_ = AICPU_SCHED_MODE_INTERRUPT;
220 0 : return tsd::TSD_OK;
221 : }
222 :
223 1 : TSD_RUN_INFO("[TsdClient] Set aicpu sched mode to %u.", schedMode);
224 1 : aicpuSchedMode_ = static_cast<SchedMode>(schedMode);
225 :
226 1 : return tsd::TSD_OK;
227 : }
228 :
229 4 : bool ClientManager::GetPackageTitle(std::string& packageTitle) const
230 : {
231 8 : return PackageEnvInfo::ResolvePackageTitle(
232 4 : static_cast<uint32_t>(g_platInfo.chipType), g_platInfo.onlineStatus, packageTitle);
233 : }
234 :
235 270 : void ClientManager::GetProfilingMode()
236 : {
237 270 : profilingMode_ = ProfilingMode::PROFILING_CLOSE;
238 270 : std::string isProfiling;
239 270 : GetEnvFromMmSys(MM_ENV_AICPU_PROFILING_MODE, "AICPU_PROFILING_MODE", isProfiling);
240 270 : TSD_INFO("Get AICPU_PROFILING_MODE[%s]", isProfiling.c_str());
241 270 : if (!isProfiling.empty()) {
242 3 : if (isProfiling == "true") {
243 0 : profilingMode_ = ProfilingMode::PROFILING_OPEN;
244 : }
245 : }
246 270 : }
247 :
248 9 : RunningMode ClientManager::GetClientRunMode(const uint32_t logicDeviceId)
249 : {
250 : (void)logicDeviceId;
251 9 : if (g_runningMode == RunningMode::UNSET_MODE) {
252 3 : if ((g_platInfo.onlineStatus == static_cast<uint32_t>(ModeType::OFFLINE)) && !g_platInfo.isAdcEnv) {
253 1 : return RunningMode::THREAD_MODE;
254 : } else {
255 2 : return RunningMode::PROCESS_MODE;
256 : }
257 : }
258 6 : return g_runningMode;
259 : }
260 :
261 : // just for ut test don't use other place
262 6 : void ClientManager::SetPlatInfoChipType(const ChipType_t curType) { g_platInfo.chipType = curType; }
263 :
264 35 : void ClientManager::ResetPlatInfoFlag() { g_hadGetPlatformInfo = false; }
265 :
266 246 : bool ClientManager::IsSupportSetVisibleDevices()
267 : {
268 246 : bool flag = false;
269 246 : switch (g_platInfo.chipType) {
270 1 : case CHIP_ASCEND_910A:
271 : case CHIP_DC:
272 : case CHIP_ASCEND_910B:
273 : case CHIP_MINI_V3:
274 : case CHIP_ASCEND_950:
275 : case CHIP_ASCEND_350:
276 : case CHIP_CLOUD_V5:
277 1 : flag = true;
278 1 : break;
279 245 : default:
280 245 : flag = false;
281 245 : break;
282 : }
283 246 : return flag;
284 : }
285 :
286 23 : bool ClientManager::IsNumeric(const std::string& str)
287 : {
288 23 : if (str.empty()) {
289 2 : return false;
290 : }
291 51 : for (char c : str) {
292 31 : if (!isdigit(c)) {
293 1 : return false;
294 : }
295 : }
296 20 : return true;
297 : }
298 :
299 7 : void ClientManager::SplitString(const std::string& str, std::vector<std::string>& result)
300 : {
301 7 : size_t start = 0;
302 7 : size_t end = str.find(',');
303 :
304 23 : while (end != std::string::npos) {
305 18 : std::string substr = str.substr(start, end - start);
306 18 : if (!IsNumeric(substr)) {
307 2 : TSD_WARN("[TsdClient] invalid device id [%s]", substr.c_str());
308 2 : return;
309 : }
310 16 : result.push_back(substr);
311 16 : start = end + 1;
312 16 : end = str.find(',', start);
313 18 : }
314 :
315 5 : std::string substr = str.substr(start);
316 5 : if (!IsNumeric(substr)) {
317 1 : TSD_WARN("[TsdClient] invalid device id [%s]", substr.c_str());
318 1 : return;
319 : }
320 4 : result.push_back(substr);
321 5 : }
322 :
323 10 : bool ClientManager::GetVisibleDevices()
324 : {
325 : // 标记hadGetVisibleDevices表示即将完成ASCEND_RT_VISIBLE_DEVICES解析
326 10 : g_hadGetVisibleDevices = true;
327 : // 获取并校验ASCEND_RT_VISIBLE_DEVICES环境变量配置
328 10 : std::string inputStr;
329 10 : GetEnvFromMmSys(MM_ENV_ASCEND_RT_VISIBLE_DEVICES, "ASCEND_RT_VISIBLE_DEVICES", inputStr);
330 10 : TSD_INFO("[TsdClient] Get env ASCEND_RT_VISIBLE_DEVICES [%s].", inputStr.c_str());
331 : // 未设置环境变量和设置为空两种情况都认为是没有设置环境变量
332 10 : if (inputStr.empty()) {
333 3 : return false;
334 : }
335 7 : std::vector<uint32_t> userDeviceInfo;
336 : // 配置解析并校验
337 7 : uint32_t deviceCnt = 0U;
338 7 : const drvError_t drvRet = drvGetDevNum(&deviceCnt);
339 7 : if (drvRet != DRV_ERROR_NONE) {
340 0 : TSD_ERROR("[TsdClient] get device count failed, errorCode [%d]", drvRet);
341 0 : return true;
342 : }
343 7 : std::vector<std::string> splitInputStr;
344 7 : SplitString(inputStr, splitInputStr);
345 7 : TSD_INFO("[TsdClient] splitInputStr size [%zu]", splitInputStr.size());
346 22 : for (uint32_t i = 0U; i < static_cast<uint32_t>(splitInputStr.size()); i++) {
347 18 : uint32_t tmpValue = 0U;
348 : try {
349 18 : tmpValue = static_cast<uint32_t>(std::stoi(splitInputStr[i]));
350 1 : } catch (std::exception& e) {
351 1 : TSD_ERROR("[TsdClient] splitInputStr [%s] is invalid, error: %s", splitInputStr[i].c_str(), e.what());
352 1 : break;
353 1 : }
354 17 : if (tmpValue >= deviceCnt) {
355 1 : TSD_WARN("[TsdClient] splitInputStr [%s] is exceed device count [%u]", splitInputStr[i].c_str(), deviceCnt);
356 1 : break;
357 : }
358 16 : if (std::find(userDeviceInfo.begin(), userDeviceInfo.end(), tmpValue) != userDeviceInfo.end()) {
359 1 : TSD_ERROR("[TsdClient] splitInputStr [%s] is repeat", splitInputStr[i].c_str());
360 1 : break;
361 : }
362 15 : userDeviceInfo.push_back(tmpValue);
363 : }
364 7 : TSD_INFO("[TsdClient] userDeviceInfo size [%zu]", userDeviceInfo.size());
365 7 : if (g_userDeviceInfo == nullptr) {
366 1 : g_userDeviceInfo = new (std::nothrow) std::map<const uint32_t, uint32_t>;
367 1 : TSD_CHECK((g_userDeviceInfo != nullptr), true, "[TsdClient] new g_userDeviceInfo failed.");
368 : }
369 22 : for (uint32_t i = 0U; i < userDeviceInfo.size(); i++) {
370 15 : (void)g_userDeviceInfo->insert(std::make_pair(i, userDeviceInfo[i]));
371 : }
372 7 : return true;
373 10 : }
374 :
375 190 : TSD_StatusT ClientManager::ChangeUserDeviceIdToLogicDeviceId(const uint32_t userDevId, uint32_t& logicDevId)
376 : {
377 190 : if (!g_hadGetVisibleDevices && !GetVisibleDevices()) {
378 1 : return TSD_OK;
379 : }
380 :
381 : // user device id匹配logic id
382 189 : if (g_userDeviceInfo == nullptr || g_userDeviceInfo->empty()) {
383 153 : return TSD_OK;
384 : }
385 :
386 36 : const std::map<const uint32_t, uint32_t>::const_iterator iter = g_userDeviceInfo->find(userDevId);
387 36 : if (iter != g_userDeviceInfo->end()) {
388 36 : logicDevId = iter->second;
389 36 : TSD_INFO("[TsdClient] change userDevId [%u] to logicDevId [%u]", userDevId, logicDevId);
390 36 : return TSD_OK;
391 : } else {
392 0 : TSD_ERROR(
393 : "[TsdClient] userDevId [%u] is exceed g_userDeviceInfo size [%zu]", userDevId, g_userDeviceInfo->size());
394 0 : return TSD_PARAMETER_INVALID;
395 : }
396 : }
397 : } // namespace tsd
|