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