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