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 "acl/acl.h"
12 :
13 : #include <cstdint>
14 : #include <mutex>
15 : #include <fstream>
16 : #include <cctype>
17 : #include <algorithm>
18 : #include "acl_rt_impl.h"
19 : #include "runtime/rt_preload_task.h"
20 : #include "runtime/rt.h"
21 : #include "runtime/rts/rts_device.h"
22 : #include "runtime/rts/rts_stars.h"
23 : #include "runtime/event.h"
24 : #include "base/err_mgr.h"
25 : #include "common/log_inner.h"
26 : #include "toolchain/plog.h"
27 : #include "toolchain/dump.h"
28 : #include "toolchain/dump_shim.h"
29 : #include "toolchain/profiling.h"
30 : #include "common/error_codes_inner.h"
31 : #include "common/resource_statistics.h"
32 : #include "platform/platform_info.h"
33 : #include "common/json_parser.h"
34 : #include "utils/hash_utils.h"
35 : #include "utils/data_type_utils.h"
36 : #include "utils/string_utils.h"
37 : #include "utils/file_utils.h"
38 : #include "aclrt_impl/acl_rt_impl_base.h"
39 : #include "aclrt_impl/init_callback_manager.h"
40 :
41 : namespace {
42 : bool aclFinalizeFlag = false;
43 : thread_local static std::string aclRecentErrMsg;
44 : bool isEnableDefaultDevice = false;
45 : constexpr int32_t INVALID_DEFAULT_DEVICE = -1;
46 : constexpr int32_t ACL_DEFAULT_DEVICE_DISABLE = 0xFFFFFFFF;
47 : std::string aclInitJsonHash;
48 : std::string aclInitJsonPath;
49 : constexpr const char_t* const kAscendHomeEnvName = "ASCEND_HOME_PATH";
50 : constexpr const char_t* const kVersionInfoKey = "Version=";
51 : constexpr const char_t* const kDriverPathKey = "Driver_Install_Path_Param=";
52 : constexpr const char_t* const kFirmwarePathKey = "Firmware_Install_Path_Param=";
53 : constexpr const char_t* const kDriverPkgName = "driver";
54 : constexpr const char_t* const kFirmwarePkgName = "firmware";
55 : constexpr const char_t* const kRelPathInfo = "/share/info/";
56 : constexpr const char_t* const kInfoFileName = "/version.info";
57 : constexpr const char_t* const kPreAlpha = "alpha";
58 : constexpr const char_t* const kPreBeta = "beta";
59 : constexpr const char_t* const kPreRC = "rc";
60 : constexpr int32_t kWeightMajor = 10000000;
61 : constexpr int32_t kWeightMinor = 100000;
62 : constexpr int32_t kWeightPatch = 1000;
63 : constexpr int32_t kWeightAlpha = 300;
64 : constexpr int32_t kWeightBeta = 200;
65 : constexpr int32_t kWeightRC = 100;
66 : const std::string kAscendInstallPath = "/etc/ascend_install.info";
67 : const std::map<aclCANNPackageName, std::string> kMapToPkgName = {
68 : {ACL_PKG_NAME_CANN, "runtime"},
69 : {ACL_PKG_NAME_RUNTIME, "runtime"},
70 : {ACL_PKG_NAME_COMPILER, "bisheng-compiler"},
71 : {ACL_PKG_NAME_HCCL, "hccl"},
72 : {ACL_PKG_NAME_TOOLKIT, "oam-tools"},
73 : {ACL_PKG_NAME_OPP, "ops-legacy"},
74 : {ACL_PKG_NAME_OPP_KERNEL, "ops-legacy"},
75 : {ACL_PKG_NAME_DRIVER, "driver"},
76 : };
77 :
78 5 : aclError GetPlatformInfoWithKey(const std::string& key, int64_t* value)
79 : {
80 : #ifdef __GNUC__
81 5 : const char* socName = aclrtGetSocNameImpl();
82 5 : if (socName == nullptr) {
83 0 : ACL_LOG_ERROR("Failed to init SocVersion.");
84 0 : return ACL_ERROR_INTERNAL_ERROR;
85 : }
86 : // call after aclInit
87 5 : const string socVersion(socName);
88 :
89 : // init platform info
90 5 : if (fe::PlatformInfoManager::GeInstance().InitializePlatformInfo() != 0U) {
91 1 : ACL_LOG_INNER_ERROR("Failed to init runtime platform info, SocVersion = %s.", socVersion.c_str());
92 1 : return ACL_ERROR_INTERNAL_ERROR;
93 : }
94 :
95 4 : fe::PlatFormInfos platformInfos;
96 4 : fe::OptionalInfos optionalInfos;
97 4 : if (fe::PlatformInfoManager::GeInstance().GetPlatformInfos(socVersion, platformInfos, optionalInfos) != 0U) {
98 1 : ACL_LOG_INNER_ERROR("Failed to get platform info, SocVersion = %s.", socVersion.c_str());
99 1 : return ACL_ERROR_INTERNAL_ERROR;
100 : }
101 3 : std::string strVal;
102 6 : if (!platformInfos.GetPlatformResWithLock("SoCInfo", key, strVal)) {
103 1 : ACL_LOG_CALL_ERROR("get platform result failed, key = %s", key.c_str());
104 1 : return ACL_ERROR_INTERNAL_ERROR;
105 : }
106 :
107 : try {
108 2 : *value = std::stoll(strVal);
109 1 : } catch (...) {
110 1 : ACL_LOG_INNER_ERROR("Failed to convert strVal[%s] to digital value.", strVal.c_str());
111 1 : return ACL_ERROR_INTERNAL_ERROR;
112 1 : }
113 1 : ACL_LOG_INFO("Successfully get platform info, key = %s, value = %ld", key.c_str(), *value);
114 : #endif
115 1 : return ACL_SUCCESS;
116 5 : }
117 :
118 96 : std::string ConvertVersion(const std::string& version)
119 : {
120 96 : const size_t dashPos = version.find('-');
121 96 : if (dashPos == std::string::npos) {
122 95 : return version;
123 : }
124 :
125 1 : std::string prefix = version.substr(0, dashPos);
126 1 : std::string suffix = version.substr(dashPos + 1U);
127 1 : suffix.erase(std::remove(suffix.begin(), suffix.end(), '.'), suffix.end());
128 :
129 1 : return prefix + "." + suffix;
130 1 : }
131 : const std::map<rtLimitType_t, std::string> limitToKeyMap = {
132 : {RT_LIMIT_TYPE_STACK_SIZE, "aicore_stack_size"},
133 : {RT_LIMIT_TYPE_SIMT_STACK_SIZE, "simt_stack_size"},
134 : {RT_LIMIT_TYPE_SIMT_DVG_WARP_STACK_SIZE, "simt_divergence_stack_size"}};
135 :
136 90 : aclError SetStackSizeByType(const char_t* const configPath, rtLimitType_t limitType, const std::string& typeName)
137 : {
138 90 : size_t stackSize = 0;
139 90 : bool stackSizeExist = false;
140 :
141 90 : const aclError ret = acl::JsonParser::GetStackSizeByType(configPath, typeName, stackSize, stackSizeExist);
142 90 : if (ret != ACL_SUCCESS) {
143 3 : return ACL_ERROR_FAILURE;
144 : }
145 :
146 87 : if (!stackSizeExist) {
147 69 : return ACL_SUCCESS;
148 : }
149 :
150 : // Tolerate FEATURE_NOT_SUPPORT for backward compatibility: older versions
151 : // always returned SUCCESS even on platforms that do not support the limit type.
152 18 : const rtError_t rtErr = rtDeviceSetLimit(0, limitType, static_cast<uint32_t>(stackSize));
153 18 : if (rtErr != RT_ERROR_NONE) {
154 3 : if (rtErr == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
155 0 : ACL_LOG_WARN("set limit (%s %zu) not supported on this platform, skip.", typeName.c_str(), stackSize);
156 0 : return ACL_SUCCESS;
157 : }
158 3 : return ACL_GET_ERRCODE_RTS(rtErr);
159 : }
160 15 : ACL_LOG_INFO("get %s stack size %zu success\n", typeName.c_str(), stackSize);
161 15 : return ACL_SUCCESS;
162 : }
163 32 : aclError SetAllStackSizes(const char_t* const configPath)
164 : {
165 119 : for (const auto& entry : limitToKeyMap) {
166 90 : const rtLimitType_t limitType = entry.first;
167 90 : const std::string& typeName = entry.second;
168 :
169 90 : const aclError ret = SetStackSizeByType(configPath, limitType, typeName.c_str());
170 90 : if (ret == ACL_ERROR_FAILURE) {
171 3 : return ret;
172 : }
173 : }
174 29 : return ACL_SUCCESS;
175 : }
176 :
177 : const std::map<rtLimitType_t, std::string> fifoSizeToKeyMap = {
178 : {RT_LIMIT_TYPE_SIMD_PRINTF_FIFO_SIZE_PER_CORE, "simd_printf_fifo_size_per_core"},
179 : {RT_LIMIT_TYPE_SIMT_PRINTF_FIFO_SIZE, "simt_printf_fifo_size"}};
180 :
181 31 : aclError SetPrintFifoSizeByType(const char_t* const configPath, rtLimitType_t limitType, const std::string& typeName)
182 : {
183 31 : size_t fifoSize = 0;
184 31 : bool found = false;
185 :
186 31 : const aclError ret = acl::JsonParser::GetPrintFifoSizeByType(configPath, typeName, fifoSize, found);
187 31 : if (ret != ACL_SUCCESS) {
188 2 : return ACL_ERROR_FAILURE;
189 : }
190 :
191 29 : if (!found) {
192 26 : return ACL_SUCCESS;
193 : }
194 :
195 : // Tolerate FEATURE_NOT_SUPPORT for backward compatibility: older versions
196 : // always returned SUCCESS even on platforms that do not support the limit type.
197 3 : const rtError_t rtErr = rtDeviceSetLimit(0, limitType, static_cast<uint32_t>(fifoSize));
198 3 : if (rtErr != RT_ERROR_NONE) {
199 1 : if (rtErr == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
200 0 : ACL_LOG_WARN("set limit (%s %zu) not supported on this platform, skip.", typeName.c_str(), fifoSize);
201 0 : return ACL_SUCCESS;
202 : }
203 1 : return ACL_GET_ERRCODE_RTS(rtErr);
204 : }
205 2 : ACL_LOG_INFO("set %s fifo size %zu success", typeName.c_str(), fifoSize);
206 2 : return ACL_SUCCESS;
207 : }
208 :
209 17 : aclError SetPrintFifoSizes(const char_t* const configPath)
210 : {
211 45 : for (const auto& entry : fifoSizeToKeyMap) {
212 31 : const rtLimitType_t limitType = entry.first;
213 31 : const std::string& typeName = entry.second;
214 :
215 31 : const aclError ret = SetPrintFifoSizeByType(configPath, limitType, typeName);
216 31 : if (ret != ACL_SUCCESS) {
217 3 : return ret;
218 : }
219 : }
220 14 : return ACL_SUCCESS;
221 : }
222 : } // namespace
223 :
224 : namespace acl {
225 646 : void resetAclJsonHash() { aclInitJsonHash.clear(); }
226 :
227 6 : void aclGetMsgCallback(const char_t* msg, uint32_t len)
228 : {
229 6 : if (msg == nullptr) {
230 1 : return;
231 : }
232 5 : (void)aclRecentErrMsg.assign(msg, static_cast<size_t>(len));
233 : }
234 :
235 6 : int32_t UpdateOpSystemRunCfg(void* cfgAddr, uint32_t cfgLen)
236 : {
237 6 : ACL_LOG_INFO("start to execute UpdateOpSystemRunCfg");
238 10 : ACL_REQUIRES_NOT_NULL_RET_INPUT_REPORT_WITH_FUNC_DESC(
239 : cfgAddr, ACL_ERROR_RT_PARAM_INVALID, "Updating the system running configuration for operator delivery");
240 8 : ACL_CHECK_INVALID_PARAM_WITH_REASON_RET_AND_FUNC_DESC(
241 : static_cast<size_t>(cfgLen) < sizeof(size_t), cfgLen, "cfgLen must be greater than or equal to sizeof(size_t)",
242 : ACL_ERROR_RT_PARAM_INVALID, "Updating the system running configuration for operator delivery");
243 :
244 : // get device id
245 4 : int32_t devId = 0;
246 4 : auto rtErr = rtGetDevice(&devId);
247 4 : if (rtErr != RT_ERROR_NONE) {
248 1 : ACL_LOG_ERROR("Cannot get device id, runtime errorCode is %d", rtErr);
249 1 : return rtErr;
250 : }
251 :
252 3 : uint64_t offset = 0;
253 : // rts interface
254 3 : rtErr = rtGetL2CacheOffset(devId, &offset);
255 3 : if (rtErr != RT_ERROR_NONE) {
256 2 : if (rtErr == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
257 1 : ACL_LOG_WARN("Cannot get l2 cache offset, feature is not supported, device id = %d", devId);
258 : } else {
259 1 : ACL_LOG_ERROR("Cannot get l2 cache offset, runtime errorCode is %d, device id = %d", rtErr, devId);
260 : }
261 2 : return rtErr;
262 : }
263 :
264 1 : uint64_t* addr = static_cast<uint64_t*>(cfgAddr);
265 1 : *addr = offset;
266 :
267 1 : ACL_LOG_INFO("execute UpdateOpSystemRunCfg successfully, l2 cache offset is %lu, device id = %d", offset, devId);
268 1 : return ACL_RT_SUCCESS;
269 : }
270 :
271 43 : aclError HandleErrorManagerConfig(const char_t* const configPath, error_message::ErrorMessageMode& error_mode)
272 : {
273 86 : const std::string ACL_ERR_MSG_CONFIG_NAME = "err_msg_mode";
274 43 : const std::string PROCESS_MODE = "\"1\"";
275 43 : error_mode = error_message::ErrorMessageMode::INTERNAL_MODE;
276 :
277 43 : if ((configPath != nullptr) && (strlen(configPath) != 0UL)) {
278 26 : std::string strConfig = PROCESS_MODE;
279 26 : bool found = false;
280 26 : const auto ret = acl::JsonParser::GetJsonCtxByKey(configPath, strConfig, ACL_ERR_MSG_CONFIG_NAME, found);
281 26 : if (ret != ACL_SUCCESS) {
282 1 : ACL_LOG_INNER_ERROR("Cannot parse err_msg config from file[%s], errorCode = %d", configPath, ret);
283 1 : return ret;
284 : }
285 25 : if (!found) {
286 21 : return ACL_SUCCESS;
287 : }
288 4 : ACL_LOG_INFO("err_msg mode is set [%s].", strConfig.c_str());
289 4 : const std::string INTERNAL_MODE = "\"0\"";
290 4 : if (strConfig == INTERNAL_MODE) {
291 1 : error_mode = error_message::ErrorMessageMode::INTERNAL_MODE;
292 3 : } else if (strConfig == PROCESS_MODE) {
293 1 : error_mode = error_message::ErrorMessageMode::PROCESS_MODE;
294 : } else {
295 2 : ACL_LOG_ERROR("err_msg mode config is invalid %s", strConfig.c_str());
296 2 : acl::AclErrorLogManager::ReportInputError(
297 4 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
298 2 : std::vector<const char*>(
299 2 : {"Parsing the configuration of the error information reporting mode", strConfig.c_str(),
300 4 : "err_msg mode", "err_msg mode config is invalid, only support INTERNAL_MODE and PROCESS_MODE"}));
301 2 : return ACL_ERROR_INVALID_PARAM;
302 : }
303 28 : }
304 19 : return ACL_SUCCESS;
305 43 : }
306 :
307 15 : aclError HandleEventModeConfig(const char_t* const configPath)
308 : {
309 15 : ACL_LOG_INFO("Start to execute HandleEventModeConfig, configPath:[%s].", configPath);
310 15 : uint8_t event_mode = 0;
311 15 : bool found = false;
312 :
313 15 : const auto ret = acl::JsonParser::GetEventModeFromFile(configPath, event_mode, found);
314 15 : if (ret != ACL_SUCCESS) {
315 2 : ACL_LOG_ERROR("Cannot parse event mode config from file[%s], errorCode = %d", configPath, ret);
316 2 : return ret;
317 : }
318 13 : if (!found) {
319 11 : ACL_LOG_INFO("Event mode config is not found in file[%s].", configPath);
320 11 : return ACL_SUCCESS;
321 : }
322 2 : ACL_LOG_INFO("event mode is set [%d].", event_mode);
323 2 : ACL_REQUIRES_RTS_OK_WARN_NOT_SUPPORT(rtEventWorkModeSet(event_mode), rtEventWorkModeSet);
324 2 : ACL_LOG_INFO("Successfully handled event mode config.");
325 2 : return ACL_SUCCESS;
326 : }
327 :
328 17 : aclError HandlePrintFifoSizeConfig(const char_t* const configPath)
329 : {
330 17 : ACL_REQUIRES_OK(SetPrintFifoSizes(configPath));
331 14 : return ACL_SUCCESS;
332 : }
333 :
334 32 : aclError HandleDefaultDeviceAndStackSize(const char_t* const configPath)
335 : {
336 : // 调用批量设置函数
337 32 : ACL_REQUIRES_OK(SetAllStackSizes(configPath));
338 : // 设置默认设备
339 29 : int32_t defaultDeviceId = INVALID_DEFAULT_DEVICE;
340 29 : const auto ret = acl::JsonParser::GetDefaultDeviceIdFromFile(configPath, defaultDeviceId);
341 29 : if (ret != ACL_SUCCESS) {
342 3 : return ACL_ERROR_FAILURE;
343 : }
344 26 : if (defaultDeviceId == INVALID_DEFAULT_DEVICE) {
345 22 : return ACL_SUCCESS;
346 : }
347 4 : ACL_REQUIRES_RTS_OK(rtSetDefaultDeviceId(defaultDeviceId));
348 2 : isEnableDefaultDevice = true;
349 2 : ACL_LOG_INFO("set default device %d success\n", defaultDeviceId);
350 2 : return ACL_SUCCESS;
351 : }
352 :
353 54 : bool IsEnableAutoUCMemeory()
354 : {
355 54 : const char_t* autoUcMemory = nullptr;
356 54 : MM_SYS_GET_ENV(MM_ENV_AUTO_USE_UC_MEMORY, autoUcMemory);
357 : // enable: env does not exist or set to 1
358 54 : const bool enable = ((autoUcMemory == nullptr) || (strlen(autoUcMemory) == 0UL) || (autoUcMemory[0] == '1'));
359 54 : ACL_LOG_INFO("auto-uc-memory is %s.", enable ? "enabled" : "disabled");
360 54 : return enable;
361 : }
362 :
363 23 : void GetAllPackageVersion()
364 : {
365 207 : for (const auto& pkgName : kMapToPkgName) {
366 184 : aclCANNPackageVersion pkgVersion = {};
367 184 : const aclError ret = aclsysGetCANNVersionImpl(pkgName.first, &pkgVersion);
368 184 : if (ret == ACL_SUCCESS) {
369 91 : ACL_LOG_EVENT(
370 : "Version of %s package is %s", pkgName.second.c_str(), static_cast<const char*>(pkgVersion.version));
371 : } else {
372 93 : ACL_LOG_EVENT("Version of %s package is not found", pkgName.second.c_str());
373 : }
374 : }
375 23 : }
376 : } // namespace acl
377 :
378 : #ifdef __cplusplus
379 : extern "C" {
380 : #endif
381 :
382 55 : aclError aclInitImpl(const char* configPath)
383 : {
384 55 : ACL_LOG_INFO("start to execute aclInit");
385 55 : const std::unique_lock<std::recursive_mutex> lk(acl::GetAclInitMutex());
386 :
387 55 : auto& aclInitRefCount = acl::GetAclInitRefCount();
388 55 : if (aclInitRefCount > 0) {
389 10 : aclInitRefCount++;
390 10 : ACL_LOG_INFO("repeatedly initialized, new aclInitRefCount: %lu", aclInitRefCount);
391 10 : return ACL_ERROR_REPEAT_INITIALIZE;
392 : }
393 :
394 45 : std::string configStr;
395 45 : auto ret = acl::GetStrFromConfigPath(configPath, configStr);
396 45 : if (ret != ACL_SUCCESS) {
397 1 : ACL_LOG_INNER_ERROR("Get Content from configPath failed, ret=%d", ret);
398 1 : return ret;
399 : }
400 44 : acl::SetConfigPathStr(configStr);
401 :
402 : // 读取并计算当前文件的哈希值(若文件不存在或无法打开,上面的json_parser中会检验住,此处无须再次判断)
403 44 : std::string currentHash;
404 44 : (void)acl::hash_utils::CalculateSimpleHash(configPath, configStr, currentHash);
405 : // 内容不一致
406 44 : if (!aclInitJsonHash.empty() && currentHash != aclInitJsonHash) {
407 1 : ACL_LOG_ERROR(
408 : "config content of [%s] differs from the first aclInit config file path: [%s]", configPath,
409 : aclInitJsonPath.c_str());
410 : std::string errMsg = acl::AclErrorLogManager::FormatStr(
411 1 : "config content differs from the first aclInit config file path: %s", aclInitJsonPath.c_str());
412 1 : acl::AclErrorLogManager::ReportInputError(
413 2 : acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
414 2 : std::vector<const char*>({configPath, errMsg.c_str()}));
415 1 : return ACL_ERROR_INVALID_PARAM;
416 1 : }
417 :
418 43 : error_message::ErrorMessageMode error_mode = error_message::ErrorMessageMode::INTERNAL_MODE;
419 43 : ACL_LOG_INFO("call ErrorManager.Initialize");
420 43 : ret = acl::HandleErrorManagerConfig(configPath, error_mode);
421 43 : if (ret != ACL_SUCCESS) {
422 3 : ACL_LOG_INNER_ERROR("[Process][ErrorMsg]process HandleErrorManagerConfig failed, ret=%d", ret);
423 3 : return ret;
424 : }
425 :
426 40 : const int32_t initRet = static_cast<uint32_t>(error_message::ErrMgrInit(error_mode));
427 40 : if (initRet != 0) {
428 1 : ACL_LOG_WARN("Cannot init ge errorManager, ge errorCode = %d", initRet);
429 : }
430 :
431 40 : if (DlogReportInitialize() != 0) {
432 40 : ACL_LOG_WARN("Cannot init device's log module");
433 : }
434 :
435 : // init acl_model
436 40 : auto cfgStr = configStr.c_str();
437 40 : const size_t cfgLen = configStr.size();
438 40 : ret = acl::InitCallbackManager::GetInstance().NotifyInitCallback(ACL_REG_TYPE_ACL_MODEL, cfgStr, cfgLen);
439 40 : if (ret != ACL_SUCCESS) {
440 1 : ACL_LOG_INNER_ERROR("call acl_model init callback failed, ret:%d", ret);
441 1 : return ret;
442 : }
443 :
444 39 : if ((configPath != nullptr) && (strlen(configPath) != 0UL)) {
445 : // config dump
446 23 : ACL_LOG_INFO("set DumpConfig in aclInit");
447 23 : ret = acl::AclDump::GetInstance().HandleDumpConfig(configPath);
448 23 : if (ret != ACL_SUCCESS) {
449 0 : ACL_LOG_INNER_ERROR("[Process][DumpConfig]process HandleDumpConfig failed");
450 0 : return ret;
451 : }
452 23 : ACL_LOG_INFO("set HandleDumpConfig success in aclInit");
453 :
454 : // init acl_op_executor
455 23 : ret = acl::InitCallbackManager::GetInstance().NotifyInitCallback(ACL_REG_TYPE_ACL_OP_EXECUTOR, cfgStr, cfgLen);
456 23 : if (ret != ACL_SUCCESS) {
457 1 : ACL_LOG_INNER_ERROR("call acl_op_executor init callback failed, ret:%d.", ret);
458 1 : return ret;
459 : }
460 :
461 22 : ACL_LOG_INFO("set HandleDefaultDeviceAndStackSize in aclInit");
462 : // parse configPath for defaultDevice and call rtSetDefaultDeviced; parse device limit
463 22 : ret = acl::HandleDefaultDeviceAndStackSize(configPath);
464 22 : if (ret != ACL_SUCCESS) {
465 5 : ACL_LOG_INNER_ERROR("[Process][DefaultDevice]process HandleDefaultDevice failed");
466 5 : return ret;
467 : }
468 17 : ACL_LOG_INFO("set HandleDefaultDeviceAndStackSize success in aclInit");
469 :
470 : // print fifo size config
471 17 : ret = acl::HandlePrintFifoSizeConfig(configPath);
472 17 : if (ret != ACL_SUCCESS) {
473 3 : ACL_LOG_INNER_ERROR("[Process][PrintFifoSize]process HandlePrintFifoSizeConfig failed, ret=%d", ret);
474 3 : return ret;
475 : }
476 14 : ACL_LOG_INFO("set HandlePrintFifoSizeConfig success in aclInit");
477 :
478 14 : ret = acl::HandleEventModeConfig(configPath);
479 14 : if (ret != ACL_SUCCESS) {
480 1 : ACL_LOG_INNER_ERROR("[Process][EventMode]process HandleEventModeConfig failed, ret=%d", ret);
481 1 : return ret;
482 : }
483 : }
484 29 : const auto profRet = MsprofRegisterCallback(ASCENDCL, &acl::AclProfCtrlHandle);
485 29 : if (profRet != 0) {
486 29 : ACL_LOG_WARN("Cannot register Callback, prof result = %d", profRet);
487 : }
488 :
489 : // config profiling
490 29 : ACL_LOG_INFO("set ProfilingConfig in aclInit");
491 29 : ret = acl::AclProfiling::HandleProfilingConfig(configPath);
492 29 : if (ret != ACL_SUCCESS) {
493 0 : ACL_LOG_INNER_ERROR("[Process][ProfConfig]process HandleProfilingConfig failed");
494 0 : return ret;
495 : }
496 :
497 : // get socVersion
498 29 : const char* socName = aclrtGetSocNameImpl();
499 29 : if (socName == nullptr) {
500 0 : ACL_LOG_INNER_ERROR("[Init][Version]init SoC version failed.");
501 0 : return ACL_ERROR_INTERNAL_ERROR;
502 : }
503 :
504 : // init acl dvpp
505 29 : ret = acl::InitCallbackManager::GetInstance().NotifyInitCallback(ACL_REG_TYPE_ACL_DVPP, cfgStr, cfgLen);
506 29 : if (ret != ACL_SUCCESS) {
507 1 : ACL_LOG_INNER_ERROR("call acl_dvpp init callback failed, ret:%d", ret);
508 1 : return ret;
509 : }
510 :
511 : // register kernel launch fill function
512 28 : if (acl::IsEnableAutoUCMemeory()) {
513 28 : ACL_LOG_INFO("register kernel launch fill function in aclInit");
514 28 : const auto rtRegErr = rtRegKernelLaunchFillFunc("g_opSystemRunCfg", acl::UpdateOpSystemRunCfg);
515 28 : if (rtRegErr != RT_ERROR_NONE) {
516 2 : if (rtRegErr == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
517 1 : ACL_LOG_WARN("Cannot register kernel launch fill function, feature is not supported.");
518 : } else {
519 1 : ACL_LOG_INNER_ERROR(
520 : "[Init][RegFillFunc]Failed to register kernel launch fill function, ret = %d.", rtRegErr);
521 1 : return ACL_GET_ERRCODE_RTS(rtRegErr);
522 : }
523 : }
524 : }
525 :
526 27 : ret = acl::InitCallbackManager::GetInstance().NotifyInitCallback(ACL_REG_TYPE_OTHER, cfgStr, cfgLen);
527 27 : if (ret != ACL_SUCCESS) {
528 4 : ACL_LOG_ERROR("[Init][NotifyCallback]notify other init callback failed, ret = %d", ret);
529 4 : return ret;
530 : }
531 :
532 23 : acl::GetAllPackageVersion();
533 :
534 23 : aclFinalizeFlag = false;
535 23 : aclInitRefCount = 1UL;
536 : // 如果 aclJsonHash 为空,说明是第一次调用,设置aclJsonHash
537 23 : if (aclInitJsonHash.empty()) {
538 15 : aclInitJsonHash = currentHash;
539 15 : if (configPath != nullptr) {
540 11 : aclInitJsonPath = configPath;
541 : }
542 : }
543 23 : ACL_LOG_INFO("successfully execute aclInit, aclInitRefCount is %lu", aclInitRefCount);
544 23 : return ACL_SUCCESS;
545 55 : }
546 :
547 33 : aclError aclFinalizeInternal()
548 : {
549 33 : ACL_LOG_INFO("start to execute aclFinalizeInternal");
550 :
551 33 : if (DlogReportFinalize() != 0) {
552 33 : ACL_LOG_WARN("Cannot init device's log module");
553 : }
554 33 : acl::ResourceStatistics::GetInstance().TraverseStatistics();
555 33 : const int32_t profRet = MsprofFinalize();
556 33 : if (profRet != MSPROF_ERROR_NONE) {
557 0 : ACL_LOG_CALL_ERROR("[Finalize][Profiling]Failed to call MsprofFinalize, prof errorCode = %d.", profRet);
558 : }
559 :
560 33 : auto ret = acl::InitCallbackManager::GetInstance().NotifyFinalizeCallback(ACL_REG_TYPE_ACL_OP_COMPILER);
561 33 : if (ret != ACL_SUCCESS) {
562 1 : ACL_LOG_INNER_ERROR("call acl_op_compiler finalize callback failed, ret:%d", ret);
563 1 : return ret;
564 : }
565 :
566 32 : ret = acl::InitCallbackManager::GetInstance().NotifyFinalizeCallback(ACL_REG_TYPE_ACL_MODEL);
567 32 : if (ret != ACL_SUCCESS) {
568 3 : ACL_LOG_INNER_ERROR("call acl_model finalize callback failed, ret:%d", ret);
569 3 : return ret;
570 : }
571 :
572 29 : if (acl::AclDump::GetInstance().GetAdxInitFromAclInitFlag()) {
573 29 : const auto& funcs = acl::GetAdumpCallbacks();
574 29 : if (funcs.serverUnInit == nullptr) {
575 0 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump server uninit callback is not registered.");
576 0 : return ACL_ERROR_INTERNAL_ERROR;
577 : }
578 29 : const int32_t adxRet = funcs.serverUnInit();
579 29 : if (adxRet != 0) {
580 1 : ACL_LOG_CALL_ERROR("[Generate][DumpFile]generate dump file failed in disk, adx errorCode = %d", adxRet);
581 1 : return ACL_ERROR_INTERNAL_ERROR;
582 : }
583 : }
584 :
585 : // finalize acl dvpp
586 28 : ret = acl::InitCallbackManager::GetInstance().NotifyFinalizeCallback(ACL_REG_TYPE_ACL_DVPP);
587 28 : if (ret != ACL_SUCCESS) {
588 2 : ACL_LOG_INNER_ERROR("call acl_dvpp finalize callback failed, ret:%d", ret);
589 2 : return ret;
590 : }
591 :
592 26 : if (acl::IsEnableAutoUCMemeory()) {
593 : // unregister kernel launch fill function
594 26 : ACL_LOG_INFO("unregister kernel launch fill function in aclFinalize");
595 26 : const auto rtRegErr = rtUnRegKernelLaunchFillFunc("g_opSystemRunCfg");
596 26 : if (rtRegErr != RT_ERROR_NONE) {
597 2 : if (rtRegErr == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
598 1 : ACL_LOG_WARN("Cannot unregister kernel launch fill function, feature is not supported.");
599 : } else {
600 1 : ACL_LOG_INNER_ERROR(
601 : "[Finalize][UnRegFillFunc]Failed to unregister kernel launch fill function, ret = %d.", rtRegErr);
602 1 : return ACL_GET_ERRCODE_RTS(rtRegErr);
603 : }
604 : }
605 : }
606 :
607 : // disable default device
608 25 : if (isEnableDefaultDevice) {
609 23 : ACL_LOG_INFO("disable default device");
610 23 : const auto rtErr = rtSetDefaultDeviceId(ACL_DEFAULT_DEVICE_DISABLE);
611 23 : if (rtErr != RT_ERROR_NONE) {
612 1 : ACL_LOG_WARN("close default device failed, ret:%d", rtErr);
613 1 : return ACL_GET_ERRCODE_RTS(rtErr);
614 : }
615 : }
616 :
617 24 : ret = acl::InitCallbackManager::GetInstance().NotifyFinalizeCallback(ACL_REG_TYPE_OTHER);
618 24 : if (ret != ACL_SUCCESS) {
619 1 : ACL_LOG_ERROR("[Init][NotifyCallback]notify other finalize callback failed, ret = %d", ret);
620 1 : return ret;
621 : }
622 :
623 23 : aclFinalizeFlag = true;
624 23 : auto& aclInitRefCount = acl::GetAclInitRefCount();
625 23 : aclInitRefCount = 0UL;
626 23 : ACL_LOG_INFO("execute aclFinalizeInternal successfully");
627 23 : return ACL_SUCCESS;
628 : }
629 :
630 30 : aclError aclFinalizeImpl()
631 : {
632 30 : ACL_LOG_INFO("start to execute aclFinalize");
633 30 : const std::unique_lock<std::recursive_mutex> lk(acl::GetAclInitMutex());
634 30 : if (aclFinalizeFlag) {
635 0 : ACL_LOG_INNER_ERROR("[Finalize][Acl]repeatedly finalized");
636 0 : return ACL_ERROR_REPEAT_FINALIZE;
637 : }
638 :
639 30 : const aclError ret = aclFinalizeInternal();
640 30 : if (ret != ACL_SUCCESS) {
641 9 : ACL_LOG_INNER_ERROR("[Finalize][Acl]finalize internal failed, errorCode = %d", ret);
642 9 : return ret;
643 : }
644 21 : ACL_LOG_INFO("successfully execute aclFinalize");
645 21 : return ACL_SUCCESS;
646 30 : }
647 :
648 14 : aclError aclFinalizeReferenceImpl(uint64_t* refCount)
649 : {
650 14 : ACL_LOG_INFO("start to execute aclFinalizeReference");
651 14 : const std::unique_lock<std::recursive_mutex> lk(acl::GetAclInitMutex());
652 14 : auto& aclInitRefCount = acl::GetAclInitRefCount();
653 14 : if (refCount != nullptr) {
654 14 : *refCount = aclInitRefCount;
655 : }
656 : // 如果计数器大于1,则减少计数器并返回
657 14 : if (aclInitRefCount > 1) {
658 10 : aclInitRefCount--;
659 10 : if (refCount != nullptr) {
660 10 : *refCount = aclInitRefCount;
661 : }
662 10 : ACL_LOG_INFO(
663 : "Found multiple acl references, reducing aclInitRefCount by 1. New aclInitRefCount: %lu", aclInitRefCount);
664 10 : return ACL_SUCCESS;
665 : }
666 : // 如果计数器小于1,报错
667 4 : if (aclInitRefCount < 1) {
668 1 : ACL_LOG_INNER_ERROR("[Finalize][Acl]aclFinalizeReference called repeatedly or called without proper aclInit");
669 1 : return ACL_ERROR_REPEAT_FINALIZE;
670 : }
671 :
672 : // 如果计数器等于1,则执行实际的资源清理操作
673 3 : const aclError ret = aclFinalizeInternal();
674 3 : if (refCount != nullptr) {
675 3 : *refCount = aclInitRefCount;
676 : }
677 3 : if (ret != ACL_SUCCESS) {
678 1 : ACL_LOG_INNER_ERROR("[Finalize][Acl]finalize internal failed, errorCode = %d", ret);
679 1 : return ret;
680 : }
681 2 : ACL_LOG_INFO("successfully execute aclFinalizeReference");
682 2 : return ACL_SUCCESS;
683 14 : }
684 : #ifdef __cplusplus
685 : }
686 : #endif
687 :
688 179 : bool IsFileExist(const std::string& path)
689 : {
690 179 : char_t realPath[MMPA_MAX_PATH] = {};
691 358 : return mmRealPath(path.c_str(), realPath, MMPA_MAX_PATH) == EN_OK;
692 : }
693 :
694 99 : static bool ParseVersionInfo(const std::string& path, std::string& versionInfo)
695 : {
696 99 : std::ifstream ifs(path, std::ifstream::in);
697 99 : ACL_CHECK_FILE_OPEN_FAILED(ifs.is_open(), path.c_str(), "Failed to open file", false);
698 :
699 99 : std::string line;
700 99 : std::string lineVersion;
701 103 : while (std::getline(ifs, line)) {
702 100 : const auto& pos = line.find(kVersionInfoKey);
703 100 : if (pos != std::string::npos) {
704 96 : ACL_LOG_DEBUG("Parse version success, content is [%s].", line.c_str());
705 96 : lineVersion = line.substr(pos + strlen(kVersionInfoKey));
706 96 : break;
707 : }
708 : }
709 99 : ifs.close();
710 :
711 99 : if (!lineVersion.empty()) {
712 96 : versionInfo = lineVersion;
713 96 : return true;
714 : }
715 3 : return false;
716 99 : }
717 :
718 96 : bool FillinPackageVersion(const std::string& versionInfo, aclCANNPackageVersion& version)
719 : {
720 96 : std::string versionAlternative = ConvertVersion(versionInfo);
721 96 : (void)memset_s(&version, sizeof(aclCANNPackageVersion), 0, sizeof(aclCANNPackageVersion));
722 96 : std::vector<std::string> parts;
723 96 : acl::StringUtils::Split(versionAlternative, '.', parts);
724 96 : constexpr uint32_t pkgVersionPartsMinCount = 2;
725 96 : constexpr uint32_t pkgVersionPartsMaxCount = 4;
726 :
727 96 : if (parts.size() < pkgVersionPartsMinCount) {
728 2 : return false;
729 : }
730 :
731 185 : while (parts.size() < pkgVersionPartsMaxCount) {
732 182 : parts.push_back("0");
733 : }
734 :
735 94 : if ((versionAlternative.copy(version.version, ACL_PKG_VERSION_MAX_SIZE - 1) > 0) &&
736 94 : (parts[0].copy(version.majorVersion, ACL_PKG_VERSION_PARTS_MAX_SIZE - 1) > 0) &&
737 94 : (parts[1].copy(version.minorVersion, ACL_PKG_VERSION_PARTS_MAX_SIZE - 1) > 0) &&
738 282 : (parts[2].copy(version.releaseVersion, ACL_PKG_VERSION_PARTS_MAX_SIZE - 1) > 0) &&
739 94 : (parts[3].copy(version.patchVersion, ACL_PKG_VERSION_PARTS_MAX_SIZE - 1) > 0)) {
740 94 : return true;
741 : }
742 :
743 0 : return false;
744 96 : }
745 :
746 31 : bool GetDriverPath(const std::string& ascendInstallPath, std::string& driverPath)
747 : {
748 31 : if (!IsFileExist(ascendInstallPath)) {
749 24 : ACL_LOG_WARN("[Check]ascendInstallPath [%s] does not exist.", ascendInstallPath.c_str());
750 24 : return false;
751 : }
752 :
753 7 : std::ifstream ifs(ascendInstallPath, std::ifstream::in);
754 7 : ACL_CHECK_FILE_OPEN_FAILED(ifs.is_open(), ascendInstallPath.c_str(), "Failed to open file", false);
755 :
756 7 : driverPath.clear();
757 7 : std::string line;
758 8 : while (std::getline(ifs, line)) {
759 7 : const auto& pos = line.find(kDriverPathKey);
760 7 : if (pos == std::string::npos) {
761 1 : continue;
762 : }
763 6 : ACL_LOG_DEBUG("Parse driver path success, content is [%s].", line.c_str());
764 6 : driverPath = line.substr(pos + strlen(kDriverPathKey));
765 6 : if (!driverPath.empty()) {
766 6 : ifs.close();
767 6 : ACL_LOG_INFO("driver path is [%s].", driverPath.c_str());
768 6 : return true;
769 : }
770 : }
771 1 : ifs.close();
772 1 : return false;
773 7 : }
774 :
775 103 : aclError GetCANNVersionInternal(
776 : const aclCANNPackageName name, aclCANNPackageVersion& version, const std::string& installPath)
777 : {
778 103 : std::string pkgName = kMapToPkgName.at(name);
779 :
780 103 : std::string versionInfoPath = installPath + "/" + pkgName + "/version.info";
781 103 : if (!IsFileExist(versionInfoPath)) {
782 44 : ACL_LOG_INFO(
783 : "[Check]versionInfoPath [%s] does not exist, try use Alternative versionInfoPath.",
784 : versionInfoPath.c_str());
785 44 : std::string pkgNameAlternative = pkgName;
786 44 : if (pkgName.find('-') != std::string::npos) {
787 40 : std::replace(pkgNameAlternative.begin(), pkgNameAlternative.end(), '-', '_');
788 : }
789 44 : versionInfoPath = installPath + "/" + pkgNameAlternative + "/version.info";
790 44 : ACL_LOG_INFO("[Check]use Alternative versionInfoPath [%s].", versionInfoPath.c_str());
791 44 : if (!IsFileExist(versionInfoPath)) {
792 4 : ACL_LOG_WARN("[Check]versionInfoPath [%s] does not exist.", versionInfoPath.c_str());
793 4 : return ACL_ERROR_INVALID_FILE;
794 : }
795 44 : }
796 :
797 99 : std::string versionInfo;
798 99 : if (!ParseVersionInfo(versionInfoPath, versionInfo)) {
799 3 : ACL_LOG_ERROR("[Check]Failed to parse versionInfo, the versionInfoPath is [%s].", versionInfoPath.c_str());
800 3 : return ACL_ERROR_INVALID_FILE;
801 : }
802 :
803 96 : ACL_LOG_INFO("versionInfo is [%s].", versionInfo.c_str());
804 96 : if (!FillinPackageVersion(versionInfo, version)) {
805 2 : ACL_LOG_ERROR("[Check]Failed to run FillinPackageVersion.");
806 2 : return ACL_ERROR_INVALID_FILE;
807 : }
808 :
809 94 : return ACL_SUCCESS;
810 103 : }
811 :
812 : #ifdef __cplusplus
813 : extern "C" {
814 : #endif
815 :
816 191 : aclError aclsysGetCANNVersionImpl(aclCANNPackageName name, aclCANNPackageVersion* version)
817 : {
818 191 : ACL_LOG_INFO("start to execute aclsysGetCANNVersion.");
819 191 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(version);
820 191 : ACL_LOG_INFO(
821 : "enum name id is [%d], enum name is [%s].", (int32_t)name,
822 : (kMapToPkgName.count(name) > 0) ? kMapToPkgName.at(name).c_str() : "unknown");
823 :
824 191 : char* pathEnv = nullptr;
825 191 : std::string driverPath;
826 191 : aclError ret = ACL_SUCCESS;
827 191 : switch (name) {
828 167 : case ACL_PKG_NAME_CANN:
829 : case ACL_PKG_NAME_RUNTIME:
830 : case ACL_PKG_NAME_COMPILER:
831 : case ACL_PKG_NAME_HCCL:
832 : case ACL_PKG_NAME_TOOLKIT:
833 : case ACL_PKG_NAME_OPP:
834 : case ACL_PKG_NAME_OPP_KERNEL:
835 167 : MM_SYS_GET_ENV(MM_ENV_ASCEND_HOME_PATH, pathEnv);
836 167 : if (pathEnv == nullptr) {
837 71 : ACL_LOG_WARN("[Check]Cannot get env [%s].", kAscendHomeEnvName);
838 71 : ret = ACL_ERROR_INVALID_FILE;
839 71 : break;
840 : }
841 96 : ACL_LOG_INFO("value of env [%s] is [%s].", kAscendHomeEnvName, pathEnv);
842 96 : ret = GetCANNVersionInternal(name, *version, std::string(pathEnv) + "/share/info");
843 96 : break;
844 23 : case ACL_PKG_NAME_DRIVER:
845 23 : if (!GetDriverPath(kAscendInstallPath, driverPath)) {
846 23 : ret = ACL_ERROR_INVALID_FILE;
847 23 : break;
848 : }
849 0 : ret = GetCANNVersionInternal(name, *version, driverPath);
850 0 : break;
851 1 : default:
852 1 : ACL_LOG_ERROR("[Check]package name enum id [%d] is invalid.", (int32_t)name);
853 1 : ret = ACL_ERROR_INVALID_PARAM;
854 1 : break;
855 : }
856 191 : return ret;
857 191 : }
858 : #ifdef __cplusplus
859 : }
860 : #endif
861 :
862 1 : bool GetPkgPath(const std::string& ascendInstallPath, std::string& pkgPath, const std::string& pkgPathKey)
863 : {
864 : // Get the path of driver or firmware
865 1 : if (!IsFileExist(ascendInstallPath)) {
866 0 : ACL_LOG_WARN(
867 : "[Check]ascendInstallPath [%s] does not exist. Please check if ASCEND_HOME_PATH is set.",
868 : ascendInstallPath.c_str());
869 0 : return false;
870 : }
871 :
872 1 : std::ifstream ifs(ascendInstallPath, std::ifstream::in);
873 1 : if (!ifs.is_open()) {
874 0 : std::string errMsg = acl::AclErrorLogManager::FormatStr("Failed to open file, %s", strerror(errno));
875 0 : acl::AclErrorLogManager::ReportInputError(
876 0 : acl::INVALID_FILE_MSG, std::vector<const char*>({"path", "reason"}),
877 0 : std::vector<const char*>({ascendInstallPath.c_str(), errMsg.c_str()}));
878 0 : ACL_LOG_ERROR(
879 : "[Check]Open file [%s] failed, reason is [%s]. Please check if ASCEND_HOME_PATH is set.",
880 : ascendInstallPath.c_str(), strerror(errno));
881 0 : return false;
882 0 : }
883 :
884 1 : pkgPath.clear();
885 1 : std::string line;
886 1 : while (std::getline(ifs, line)) {
887 1 : const auto pos = line.find(pkgPathKey);
888 1 : if (pos == std::string::npos) {
889 0 : continue;
890 : }
891 1 : ACL_LOG_DEBUG("Parse path success, key is [%s], content is [%s].", pkgPathKey.c_str(), line.c_str());
892 1 : pkgPath = line.substr(pos + pkgPathKey.length());
893 1 : if (!pkgPath.empty()) {
894 1 : ifs.close();
895 1 : ACL_LOG_INFO("pkg path is [%s].", pkgPath.c_str());
896 1 : return true;
897 : }
898 : }
899 0 : ifs.close();
900 0 : return false;
901 1 : }
902 :
903 15 : aclError GetVersionStringInternal(
904 : const std::string& fullPath, const char_t* pkgName, std::string& versionOut, bool isSilent = false)
905 : {
906 15 : std::ifstream ifs(fullPath);
907 15 : if (!ifs.is_open()) {
908 2 : if (isSilent) {
909 2 : ACL_LOG_WARN("Version file not found at [%s] (Silent check, will retry alternative).", fullPath.c_str());
910 : } else {
911 0 : ACL_LOG_ERROR(
912 : "Version file not found at [%s]. Please check if the package name [%s] is correct and the package is "
913 : "installed.",
914 : fullPath.c_str(), pkgName);
915 : }
916 2 : return ACL_ERROR_INVALID_FILE;
917 : }
918 :
919 13 : std::string line;
920 13 : bool found = false;
921 13 : const size_t keyLen = std::strlen(kVersionInfoKey);
922 :
923 14 : while (std::getline(ifs, line)) {
924 13 : const size_t pos = line.find(kVersionInfoKey);
925 13 : if (pos != std::string::npos) {
926 12 : versionOut = acl::StringUtils::Trim(line.substr(pos + keyLen));
927 12 : found = true;
928 12 : break;
929 : }
930 : }
931 13 : ifs.close();
932 :
933 16 : ACL_CHECK_INVALID_FILE_MSG_RET(
934 : !found || versionOut.empty(), fullPath.c_str(), "Keyword Version= not found in version info file",
935 : ACL_ERROR_INVALID_FILE);
936 :
937 12 : return ACL_SUCCESS;
938 15 : }
939 :
940 17 : static aclError GetVersionByPkgName(const std::string& targetPkgName, std::string& versionContent, bool isSilent)
941 : {
942 17 : std::string fullPath;
943 :
944 : // Driver/Firmware
945 17 : if (targetPkgName == kDriverPkgName || targetPkgName == kFirmwarePkgName) {
946 0 : std::string pkgPath;
947 0 : std::string pkgPathKey = (targetPkgName == kDriverPkgName) ? kDriverPathKey : kFirmwarePathKey;
948 :
949 0 : if (!GetPkgPath(kAscendInstallPath, pkgPath, pkgPathKey)) {
950 0 : return ACL_ERROR_INVALID_FILE;
951 : }
952 0 : fullPath = pkgPath + "/" + targetPkgName + kInfoFileName;
953 0 : } else {
954 17 : char* pathEnv = nullptr;
955 17 : MM_SYS_GET_ENV(MM_ENV_ASCEND_HOME_PATH, pathEnv);
956 17 : if (pathEnv == nullptr) {
957 1 : ACL_LOG_WARN("Cannot get env [%s]. Please check if ASCEND_HOME_PATH is set.", "ASCEND_HOME_PATH");
958 3 : return ACL_ERROR_INVALID_FILE;
959 : }
960 16 : std::string homePath(pathEnv);
961 16 : homePath = acl::file_utils::GetLocalRealPath(homePath);
962 16 : if (homePath.empty()) {
963 2 : ACL_LOG_WARN("ASCEND_HOME_PATH [%s] does not exist.", homePath.c_str());
964 2 : return ACL_ERROR_INVALID_FILE;
965 : }
966 14 : fullPath = homePath + kRelPathInfo + targetPkgName + kInfoFileName;
967 16 : }
968 :
969 14 : return GetVersionStringInternal(fullPath, targetPkgName.c_str(), versionContent, isSilent);
970 17 : }
971 :
972 15 : aclError GetPkgVersionContent(const char* pkgName, std::string& versionContent)
973 : {
974 15 : std::string originPkgName(pkgName);
975 15 : std::string altPkgName = originPkgName;
976 15 : bool hasAlternative = false;
977 :
978 15 : if (originPkgName.find('-') != std::string::npos) {
979 1 : std::replace(altPkgName.begin(), altPkgName.end(), '-', '_');
980 1 : hasAlternative = true;
981 : } else {
982 14 : if (originPkgName.find('_') != std::string::npos) {
983 1 : std::replace(altPkgName.begin(), altPkgName.end(), '_', '-');
984 1 : hasAlternative = true;
985 : }
986 : }
987 :
988 15 : bool isSilent = hasAlternative;
989 :
990 15 : aclError ret = GetVersionByPkgName(originPkgName, versionContent, isSilent);
991 15 : if (ret == ACL_SUCCESS) {
992 9 : return ret;
993 : }
994 :
995 6 : if (hasAlternative) {
996 2 : ACL_LOG_INFO("Pkg [%s] not found, trying alternative name [%s]...", originPkgName.c_str(), altPkgName.c_str());
997 :
998 2 : ret = GetVersionByPkgName(altPkgName, versionContent, false);
999 2 : if (ret == ACL_SUCCESS) {
1000 2 : ACL_LOG_INFO("Found version info using alternative name [%s].", altPkgName.c_str());
1001 2 : return ACL_SUCCESS;
1002 : }
1003 : }
1004 :
1005 4 : return ret;
1006 15 : }
1007 :
1008 : #ifdef __cplusplus
1009 : extern "C" {
1010 : #endif
1011 :
1012 8 : aclError aclsysGetVersionStrImpl(char* pkgName, char* versionStr)
1013 : {
1014 8 : ACL_LOG_INFO("start to execute aclsysGetVersionStr.");
1015 8 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(versionStr);
1016 8 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(pkgName);
1017 :
1018 8 : std::string verInfo;
1019 :
1020 8 : const aclError ret = GetPkgVersionContent(pkgName, verInfo);
1021 8 : if (ret != ACL_SUCCESS) {
1022 4 : return ret;
1023 : }
1024 :
1025 4 : const errno_t strcpyRet = strcpy_s(versionStr, ACL_PKG_VERSION_MAX_SIZE, verInfo.c_str());
1026 4 : if (strcpyRet != EOK) {
1027 1 : std::stringstream ss;
1028 1 : ss << std::hex << "src=0x" << reinterpret_cast<uintptr_t>(verInfo.c_str()) << ", versionStr=0x"
1029 1 : << reinterpret_cast<uintptr_t>(versionStr) << std::dec
1030 1 : << ", dest_max=" << static_cast<size_t>(ACL_PKG_VERSION_MAX_SIZE) << ".";
1031 1 : const std::string extendInfo = ss.str();
1032 1 : const std::string strcpyRetVal = std::to_string(strcpyRet);
1033 1 : std::string funcName = acl::AclErrorLogManager::GetFuncNameWithoutImplSuffix(__func__);
1034 1 : acl::AclErrorLogManager::ReportInputError(
1035 : acl::STANDARD_FUNC_FAILED_MSG,
1036 2 : std::vector<const char*>({"func1", "func2", "ret_code", "reason", "extend_info"}),
1037 1 : std::vector<const char*>(
1038 2 : {funcName.c_str(), "strcpy_s", strcpyRetVal.c_str(), strerror(strcpyRet), extendInfo.c_str()}));
1039 1 : ACL_LOG_ERROR(
1040 : "Copy string failed. Dest buffer size is [%zu], source len is [%zu].",
1041 : static_cast<size_t>(ACL_PKG_VERSION_MAX_SIZE), verInfo.length());
1042 1 : return ACL_ERROR_INTERNAL_ERROR;
1043 1 : }
1044 :
1045 3 : ACL_LOG_INFO("aclsysGetVersionStr success. Pkg:[%s], Ver:[%s]", pkgName, versionStr);
1046 3 : return ret;
1047 8 : }
1048 : #ifdef __cplusplus
1049 : }
1050 : #endif
1051 :
1052 : // Allowed format: "001", ".1", "-1"
1053 : // Not allowed format: "..1", ".", "-a", "a"
1054 2 : static bool ParsePreNumStrict(const std::string& suffix, int32_t& outNum)
1055 : {
1056 2 : if (suffix.empty()) {
1057 0 : outNum = 0;
1058 0 : return true;
1059 : }
1060 :
1061 2 : size_t digitPos = std::string::npos;
1062 :
1063 : // scan characters
1064 4 : for (size_t i = 0; i < suffix.length(); ++i) {
1065 4 : const char c = suffix[i];
1066 4 : if (std::isdigit(static_cast<unsigned char>(c)) != 0) {
1067 2 : digitPos = i;
1068 2 : break;
1069 2 : } else if (c == '.' || c == '-') {
1070 2 : continue; // legal character
1071 : } else {
1072 0 : return false; // illegal character
1073 : }
1074 : }
1075 :
1076 : // No number found.
1077 2 : if (digitPos == std::string::npos) {
1078 0 : return false;
1079 : }
1080 :
1081 : // Separators more than one.
1082 2 : if (digitPos > 1) {
1083 0 : return false;
1084 : }
1085 :
1086 : // Analyze prerelease number.
1087 2 : std::string numStr = suffix.substr(digitPos);
1088 2 : size_t endPos = 0;
1089 : try {
1090 2 : outNum = std::stoi(numStr, &endPos);
1091 0 : } catch (...) {
1092 0 : return false;
1093 0 : }
1094 :
1095 : // Ensure that number does not contain any suffix characters.
1096 2 : if (endPos != numStr.length()) {
1097 1 : return false;
1098 : }
1099 :
1100 1 : return true;
1101 2 : }
1102 :
1103 7 : static aclError ParseBaseVersion(const std::string& verStr, int32_t& baseVal, size_t& endPos)
1104 : {
1105 7 : int32_t major = 0;
1106 7 : int32_t minor = 0;
1107 7 : int32_t patch = 0;
1108 :
1109 : try {
1110 : // Find first point
1111 7 : const size_t dot1 = verStr.find('.');
1112 7 : if (dot1 == std::string::npos || dot1 == 0) {
1113 2 : ACL_LOG_ERROR("Invalid format [%s]. Missing major version.", verStr.c_str());
1114 2 : return ACL_ERROR_INTERNAL_ERROR;
1115 : }
1116 :
1117 : // Find second point
1118 5 : const size_t dot2 = verStr.find('.', dot1 + 1UL);
1119 5 : if (dot2 == std::string::npos || dot2 == dot1 + 1UL) {
1120 1 : ACL_LOG_ERROR("Invalid format [%s]. Missing minor version.", verStr.c_str());
1121 1 : return ACL_ERROR_INTERNAL_ERROR;
1122 : }
1123 :
1124 : // Find patch number
1125 4 : const size_t numStart = dot2 + 1UL;
1126 4 : size_t numEnd = numStart;
1127 8 : while (numEnd < verStr.length() && std::isdigit(static_cast<uint8_t>(verStr[numEnd])) != 0) {
1128 4 : numEnd++;
1129 : }
1130 :
1131 4 : if (numEnd == numStart) {
1132 0 : ACL_LOG_ERROR("Invalid format [%s]. Missing patch version.", verStr.c_str());
1133 0 : return ACL_ERROR_INTERNAL_ERROR;
1134 : }
1135 :
1136 4 : major = std::stoi(verStr.substr(0, dot1));
1137 4 : minor = std::stoi(verStr.substr(dot1 + 1, dot2 - dot1 - 1U));
1138 4 : patch = std::stoi(verStr.substr(numStart, numEnd - numStart));
1139 :
1140 4 : endPos = numEnd;
1141 0 : } catch (...) {
1142 0 : ACL_LOG_ERROR("Parse base version failed. Contains non-numeric chars?");
1143 0 : return ACL_ERROR_INTERNAL_ERROR;
1144 0 : }
1145 :
1146 4 : baseVal = major * kWeightMajor + minor * kWeightMinor + patch * kWeightPatch;
1147 4 : return ACL_SUCCESS;
1148 : }
1149 :
1150 4 : static aclError ParsePrereleasePart(const std::string& rawSuffix, int32_t& adjustment)
1151 : {
1152 4 : std::string suffix = rawSuffix;
1153 30 : (void)std::transform(suffix.begin(), suffix.end(), suffix.begin(), [](unsigned char c) { return std::tolower(c); });
1154 :
1155 : // Match prerelease keyword(alpha:300, beta:200, rc:100)
1156 4 : int32_t weight = 0;
1157 4 : size_t keywordLen = 0;
1158 4 : size_t keywordIndex = std::string::npos;
1159 :
1160 4 : if ((keywordIndex = suffix.find(kPreAlpha)) != std::string::npos) {
1161 1 : weight = kWeightAlpha;
1162 1 : keywordLen = strlen(kPreAlpha);
1163 3 : } else if ((keywordIndex = suffix.find(kPreBeta)) != std::string::npos) {
1164 1 : weight = kWeightBeta;
1165 1 : keywordLen = strlen(kPreBeta);
1166 2 : } else if ((keywordIndex = suffix.find(kPreRC)) != std::string::npos) {
1167 1 : weight = kWeightRC;
1168 1 : keywordLen = strlen(kPreRC);
1169 : } else {
1170 1 : ACL_LOG_ERROR("Unknown version suffix in [%s].", rawSuffix.c_str());
1171 1 : return ACL_ERROR_INTERNAL_ERROR;
1172 : }
1173 :
1174 : // Verify the separator before the keyword(zero or one separator allowed).
1175 3 : if (keywordIndex > 1) {
1176 1 : ACL_LOG_ERROR("Invalid separator format in [%s]. Too many separators before keyword.", rawSuffix.c_str());
1177 1 : return ACL_ERROR_INTERNAL_ERROR;
1178 : }
1179 :
1180 : // Obtain the numeric part after the keyword.
1181 2 : std::string numPart = rawSuffix.substr(keywordIndex + keywordLen);
1182 2 : int32_t preNum = 0;
1183 :
1184 : // Strictly verify the format of the numeric part.
1185 2 : if (!ParsePreNumStrict(numPart, preNum)) {
1186 1 : ACL_LOG_ERROR("Invalid prerelease number format in [%s].", rawSuffix.c_str());
1187 1 : return ACL_ERROR_INTERNAL_ERROR;
1188 : }
1189 :
1190 : // Calculate the final version number: baseValue - weight + preNum
1191 1 : adjustment = -weight + preNum;
1192 1 : return ACL_SUCCESS;
1193 4 : }
1194 :
1195 7 : aclError CalculateVersionNum(const std::string& verStr, int32_t* verNum)
1196 : {
1197 7 : int32_t baseValue = 0;
1198 7 : size_t endPos = 0;
1199 :
1200 : // Analyze base version (X.Y.Z)
1201 7 : aclError ret = ParseBaseVersion(verStr, baseValue, endPos);
1202 7 : if (ret != ACL_SUCCESS) {
1203 3 : return ret;
1204 : }
1205 :
1206 : // Check if there is a suffix content.
1207 4 : if (endPos >= verStr.length()) {
1208 0 : *verNum = baseValue;
1209 0 : return ACL_SUCCESS;
1210 : }
1211 :
1212 4 : std::string suffixStr = verStr.substr(endPos);
1213 4 : int32_t adjustment = 0;
1214 :
1215 4 : ret = ParsePrereleasePart(suffixStr, adjustment);
1216 4 : if (ret != ACL_SUCCESS) {
1217 3 : return ret;
1218 : }
1219 :
1220 1 : *verNum = baseValue + adjustment;
1221 1 : return ACL_SUCCESS;
1222 4 : }
1223 :
1224 : #ifdef __cplusplus
1225 : extern "C" {
1226 : #endif
1227 :
1228 7 : aclError aclsysGetVersionNumImpl(char* pkgName, int32_t* versionNum)
1229 : {
1230 7 : ACL_LOG_INFO("start to execute aclsysGetVersionNum.");
1231 7 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(versionNum);
1232 7 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(pkgName);
1233 :
1234 7 : std::string verInfo;
1235 :
1236 7 : aclError ret = GetPkgVersionContent(pkgName, verInfo);
1237 7 : if (ret != ACL_SUCCESS) {
1238 0 : return ret;
1239 : }
1240 :
1241 7 : ret = CalculateVersionNum(verInfo, versionNum);
1242 7 : if (ret != ACL_SUCCESS) {
1243 6 : return ret;
1244 : }
1245 :
1246 1 : ACL_LOG_INFO("aclsysGetVersionNum success. Pkg:[%s], Num:[%d]", pkgName, *versionNum);
1247 1 : return ACL_SUCCESS;
1248 7 : }
1249 : #ifdef __cplusplus
1250 : }
1251 : #endif
1252 :
1253 9 : static std::string GetFaultEventInfo()
1254 : {
1255 9 : std::string faultInfo;
1256 :
1257 9 : int32_t deviceId = 0;
1258 9 : auto ret = rtGetDevice(&deviceId);
1259 9 : if (ret != RT_ERROR_NONE) {
1260 1 : ACL_LOG_INFO("Cannot get device id, runtime errorCode is %d", static_cast<int32_t>(ret));
1261 1 : return faultInfo;
1262 : }
1263 :
1264 8 : rtDmsEventFilter filter = {};
1265 8 : constexpr uint32_t maxFaultNum = 128U; // max is 128
1266 8 : std::vector<rtDmsFaultEvent> faultEventInfo(maxFaultNum, rtDmsFaultEvent{});
1267 8 : uint32_t eventCount = 0U;
1268 8 : ret = rtGetFaultEvent(deviceId, &filter, &faultEventInfo[0U], maxFaultNum, &eventCount);
1269 8 : if (ret != RT_ERROR_NONE || eventCount == 0UL) {
1270 4 : ACL_LOG_INFO(
1271 : "Cannot get fault event of device %d, runtime errorCode is %d", deviceId, static_cast<int32_t>(ret));
1272 4 : return faultInfo;
1273 : }
1274 :
1275 12 : for (uint32_t faultIndex = 0; faultIndex < eventCount; ++faultIndex) {
1276 8 : std::ostringstream oss;
1277 8 : oss << std::hex << faultEventInfo[faultIndex].eventId;
1278 8 : faultInfo = faultInfo + "[0x" + oss.str() + "]" + faultEventInfo[faultIndex].eventName + ";";
1279 8 : }
1280 :
1281 4 : if (faultInfo.empty()) {
1282 0 : return faultInfo;
1283 : }
1284 4 : faultInfo = "Fault diagnosis analysis: " + faultInfo;
1285 4 : return faultInfo;
1286 8 : }
1287 :
1288 : #ifdef __cplusplus
1289 : extern "C" {
1290 : #endif
1291 :
1292 9 : const char* aclGetRecentErrMsgImpl()
1293 : {
1294 9 : ACL_LOG_INFO("start to execute aclGetRecentErrMsg.");
1295 9 : constexpr const rtGetDevMsgType_t msgType = RT_GET_DEV_ERROR_MSG;
1296 9 : const auto ret = rtGetDevMsg(msgType, &acl::aclGetMsgCallback);
1297 9 : if (ret != RT_ERROR_NONE) {
1298 1 : ACL_LOG_DEBUG("Cannot get device errorMessage, runtime errorCode is %d", static_cast<int32_t>(ret));
1299 : }
1300 :
1301 9 : const std::string faultEventMsg = GetFaultEventInfo();
1302 9 : if (!faultEventMsg.empty()) {
1303 4 : if (aclRecentErrMsg.empty()) {
1304 2 : aclRecentErrMsg = faultEventMsg;
1305 : } else {
1306 2 : aclRecentErrMsg = aclRecentErrMsg + "\n" + faultEventMsg;
1307 : }
1308 : }
1309 :
1310 9 : const std::string aclHostErrMsg = std::string(error_message::GetErrMgrErrorMessage().get());
1311 9 : if ((aclHostErrMsg.empty()) && (aclRecentErrMsg.empty())) {
1312 0 : ACL_LOG_DEBUG("get errorMessage is empty");
1313 0 : return nullptr;
1314 : }
1315 :
1316 9 : if (aclHostErrMsg.empty()) {
1317 3 : return aclRecentErrMsg.c_str();
1318 : }
1319 :
1320 6 : if (aclRecentErrMsg.empty()) {
1321 1 : (void)aclRecentErrMsg.assign(aclHostErrMsg);
1322 1 : return aclRecentErrMsg.c_str();
1323 : }
1324 :
1325 5 : aclRecentErrMsg = aclHostErrMsg + "\n" + aclRecentErrMsg;
1326 5 : ACL_LOG_INFO("execute aclGetRecentErrMsg successfully.");
1327 5 : return aclRecentErrMsg.c_str();
1328 9 : }
1329 :
1330 5 : aclError aclGetCannAttributeListImpl(const aclCannAttr** cannAttrList, size_t* num)
1331 : {
1332 5 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(cannAttrList);
1333 4 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(num);
1334 3 : const aclError ret = acl::CannInfoUtils::GetAttributeList(cannAttrList, num);
1335 3 : if (ret != ACL_SUCCESS) {
1336 2 : ACL_LOG_ERROR("Failed to get attrList, ret = %d.", ret);
1337 2 : return ret;
1338 : }
1339 1 : ACL_LOG_INFO("execute aclGetCannAttributeList successfully.");
1340 1 : return ACL_SUCCESS;
1341 : }
1342 :
1343 11 : aclError aclGetCannAttributeImpl(aclCannAttr cannAttr, int32_t* value)
1344 : {
1345 11 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(value);
1346 10 : const aclError ret = acl::CannInfoUtils::GetAttribute(cannAttr, value);
1347 10 : if (ret != ACL_SUCCESS) {
1348 8 : ACL_LOG_ERROR("Failed to check, attr value = %s, ret = %d.", acl::GetCannAttrDesc(cannAttr), ret);
1349 8 : return ret;
1350 : }
1351 2 : ACL_LOG_INFO("execute aclGetCannAttribute successfully.");
1352 2 : return ACL_SUCCESS;
1353 : }
1354 :
1355 9 : aclError aclGetDeviceCapabilityImpl(uint32_t deviceId, aclDeviceInfo deviceInfo, int64_t* value)
1356 : {
1357 9 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(value);
1358 8 : int32_t count = -1;
1359 8 : ACL_REQUIRES_RTS_OK(rtGetDeviceCount(&count));
1360 : // currently check only, deviceId with [0, count - 1]
1361 7 : if (deviceId > static_cast<uint32_t>(count - 1)) {
1362 1 : ACL_LOG_ERROR("%s failed because deviceId %u greater than deviceNum %d.", __func__, deviceId, count);
1363 1 : const std::string deviceIdVal = std::to_string(deviceId);
1364 : std::string errMsg =
1365 1 : acl::AclErrorLogManager::FormatStr("deviceId %u greater than deviceNum %d", deviceId, count);
1366 1 : std::string funcName = acl::AclErrorLogManager::GetFuncNameWithoutImplSuffix(__func__);
1367 1 : acl::AclErrorLogManager::ReportInputError(
1368 2 : acl::INVALID_PARAM_REASON_MSG, std::vector<const char*>({"func", "value", "param", "reason"}),
1369 2 : std::vector<const char*>({funcName.c_str(), deviceIdVal.c_str(), "deviceId", errMsg.c_str()}));
1370 1 : return ACL_ERROR_INVALID_PARAM;
1371 1 : }
1372 :
1373 : const std::map<aclDeviceInfo, std::string> infoTypeToKey = {
1374 0 : {ACL_DEVICE_INFO_AI_CORE_NUM, "ai_core_cnt"},
1375 0 : {ACL_DEVICE_INFO_VECTOR_CORE_NUM, "vector_core_cnt"},
1376 30 : {ACL_DEVICE_INFO_L2_SIZE, "l2_size"}};
1377 6 : const auto iter = infoTypeToKey.find(deviceInfo);
1378 6 : if (iter == infoTypeToKey.end()) {
1379 1 : ACL_LOG_WARN("get device info failed, invalid info type = %s", acl::GetDeviceInfoDesc(deviceInfo));
1380 1 : return ACL_ERROR_INVALID_PARAM;
1381 : }
1382 5 : const auto& key = iter->second;
1383 5 : const aclError ret = GetPlatformInfoWithKey(key, value);
1384 5 : if (ret != ACL_SUCCESS) {
1385 4 : ACL_LOG_ERROR(
1386 : "get device info failed, info type = %s, key = %s", acl::GetDeviceInfoDesc(deviceInfo), key.c_str());
1387 4 : return ret;
1388 : }
1389 1 : ACL_LOG_INFO("execute aclGetDeviceCapability successfully.");
1390 1 : return ACL_SUCCESS;
1391 12 : }
1392 : #ifdef __cplusplus
1393 : }
1394 : #endif
|