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 "sal.h"
12 :
13 : #include <cmath>
14 : #include <cstdlib>
15 : #include <fcntl.h>
16 : #include <mutex>
17 : #include <syscall.h>
18 : #include <sys/time.h> /* 获取时间 */
19 : #include <dlog_pub.h>
20 : #include <securec.h>
21 : #include <unistd.h>
22 :
23 : #include "adapter_error_manager_pub.h"
24 : #include "adapter_rts.h"
25 : #include "adapter_hccp_common.h"
26 : #include "adapter_hal.h"
27 : #include "externalinput.h"
28 : #include "dlhal_function.h"
29 : #include "device_capacity.h"
30 :
31 : using namespace std;
32 : constexpr uint32_t HOST = 1;
33 :
34 : #if HCOMM_T_DESC("C字符串处理函数适配", true)
35 :
36 8229 : u32 SalStrLen(const char* s, u32 maxLen) { return strnlen(s, maxLen); }
37 :
38 : // 字符串转换成浮点数
39 3 : HcclResult SalStrToDouble(const std::string str, double& val)
40 : {
41 : try {
42 3 : val = std::stod(str);
43 0 : } catch (std::invalid_argument&) {
44 0 : HCCL_ERROR("[Transform][StrToDouble]stod invalid argument, str[%s] val[%f]", str.c_str(), val);
45 0 : return HCCL_E_PARA;
46 0 : } catch (std::out_of_range&) {
47 0 : HCCL_ERROR("[Transform][StrToDouble]stod out of range, str[%s] val[%f]", str.c_str(), val);
48 0 : return HCCL_E_PARA;
49 0 : } catch (...) {
50 0 : HCCL_ERROR("[Transform][StrToDouble]stod catch error, str[%s] val[%f]", str.c_str(), val);
51 0 : return HCCL_E_PARA;
52 0 : }
53 3 : return HCCL_SUCCESS;
54 : }
55 :
56 : #endif
57 :
58 : #if HCOMM_T_DESC("时间处理接口适配", true)
59 :
60 44550 : void SaluSleep(u32 usec)
61 : {
62 : /* usleep()可能会因为进程收到信号(比如alarm)而提前返回EINTR, 后续优化 */
63 44550 : s32 iRet = usleep(usec);
64 44548 : if (iRet != 0) {
65 0 : HCCL_WARNING("Sleep: usleep failed[%d]: %s [%d]", iRet, strerror(errno), errno);
66 : }
67 44548 : }
68 :
69 1 : void SalSleep(u32 sec)
70 : {
71 : /* sleep()可能会因为进程收到信号(比如alarm)而提前返回EINTR, 后续优化 */
72 1 : s32 iRet = sleep(sec);
73 1 : if (iRet != 0) {
74 0 : HCCL_WARNING("Sleep: sleep failed[%d]: %s [%d]", iRet, strerror(errno), errno);
75 : }
76 1 : }
77 :
78 14 : HcclResult SalGetCurrentTimestamp(u64& timestamp)
79 : {
80 : struct timeval tv;
81 14 : int ret = gettimeofday(&tv, nullptr);
82 14 : CHK_PRT_RET(
83 : ret != 0,
84 : HCCL_ERROR(
85 : "[Get][tCurrentTimestamp]errNo[0x%016llx] get timestamp fail, return[%d].", HCCL_ERROR_CODE(HCCL_E_SYSCALL),
86 : ret),
87 : HCCL_E_SYSCALL);
88 14 : timestamp = tv.tv_sec * 1000000 + tv.tv_usec; // 1000000: 单位转换 秒 -> 微秒
89 14 : return HCCL_SUCCESS;
90 : }
91 :
92 3176939 : u64 GetCurAicpuTimestamp()
93 : {
94 : struct timespec timestamp;
95 3176939 : (void)clock_gettime(1, ×tamp);
96 3176939 : return static_cast<u64>((timestamp.tv_sec * 1000000000U) + (timestamp.tv_nsec));
97 : }
98 :
99 : #endif
100 :
101 : #if HCOMM_T_DESC("跨进程处理函数", true)
102 :
103 : // 去除字符串中的首位空格
104 1713 : std::string SalTrim(const std::string& s)
105 : {
106 1713 : std::string tempStr = s;
107 1713 : if (!tempStr.empty()) {
108 1713 : auto fiFirst = tempStr.find_first_not_of(" ");
109 1713 : if (fiFirst != std::string::npos) {
110 1713 : (void)tempStr.erase(0, fiFirst);
111 : }
112 :
113 1713 : auto fiLast = tempStr.find_last_not_of(" ");
114 1713 : if (fiLast != std::string::npos) {
115 1713 : (void)tempStr.erase(fiLast + 1);
116 : }
117 : }
118 :
119 1713 : return tempStr;
120 0 : }
121 :
122 : // 返回当前进程ID
123 15509 : s32 SalGetPid() { return getpid(); }
124 :
125 1065 : HcclResult SalGetBareTgid(s32* pid)
126 : {
127 1065 : CHK_PTR_NULL(pid);
128 1065 : CHK_RET(hrtDeviceGetBareTgid(pid));
129 1065 : return HCCL_SUCCESS;
130 : }
131 :
132 : // 返回当前线程ID
133 17592 : s32 SalGetTid() { return syscall(SYS_gettid); }
134 :
135 : // 获取当前用户ID
136 0 : u32 SalGetUid() { return getuid(); }
137 :
138 : #endif
139 :
140 : #if HCOMM_T_DESC("环境变量处理适配", true)
141 :
142 263 : std::string SalGetEnv(const char* name)
143 : {
144 263 : if (name == nullptr || getenv(name) == nullptr) {
145 508 : return "EmptyString";
146 : }
147 :
148 18 : return getenv(name);
149 : }
150 : #endif
151 :
152 : #if HCOMM_T_DESC("系统时间处理适配", true)
153 :
154 : // 获取系统当前时间
155 5032 : s64 SalGetSysTime()
156 : {
157 : // 获取当前系统时间,将时分秒清零
158 5032 : time_t curTime = time(&curTime); // time_t是一种时间类型,一般用来存放自1970年1月1日0点0时0分开始的秒数
159 :
160 5032 : return static_cast<s64>(curTime);
161 : }
162 :
163 : #endif
164 :
165 : #if HCOMM_T_DESC("库函数封装", true)
166 : // 字符串转换成整型
167 44 : HcclResult SalStrToInt(const std::string str, int base, s32& val)
168 : {
169 : try {
170 44 : val = std::stoi(str, nullptr, base);
171 0 : } catch (std::invalid_argument&) {
172 0 : HCCL_ERROR("[Transform][StrToInt]strtoi invalid argument, str[%s] base[%d] val[%d]", str.c_str(), base, val);
173 0 : return HCCL_E_PARA;
174 0 : } catch (std::out_of_range&) {
175 0 : HCCL_ERROR("[Transform][StrToInt]strtoi out of range, str[%s] base[%d] val[%d]", str.c_str(), base, val);
176 0 : return HCCL_E_PARA;
177 0 : } catch (...) {
178 0 : HCCL_ERROR("[Transform][StrToInt]strtoi catch error, str[%s] base[%d] val[%d]", str.c_str(), base, val);
179 0 : return HCCL_E_PARA;
180 0 : }
181 44 : return HCCL_SUCCESS;
182 : }
183 :
184 : // 字串符转换成无符号整型
185 4251 : HcclResult SalStrToULong(const std::string str, int base, u32& val)
186 : {
187 : try {
188 4251 : u64 tmp = std::stoull(str, nullptr, base);
189 4248 : if (tmp > INVALID_UINT) {
190 0 : HCCL_ERROR("[Transform][StrToULong]stoul out of range, str[%s] base[%d] val[%llu]", str.c_str(), base, tmp);
191 0 : return HCCL_E_PARA;
192 : } else {
193 4248 : val = static_cast<u32>(tmp);
194 : }
195 2 : } catch (std::invalid_argument&) {
196 2 : HCCL_ERROR("[Transform][StrToULong]stoull invalid argument, str[%s] base[%d] val[%u]", str.c_str(), base, val);
197 2 : return HCCL_E_PARA;
198 2 : } catch (std::out_of_range&) {
199 0 : HCCL_ERROR("[Transform][StrToULong]stoull out of range, str[%s] base[%d] val[%u]", str.c_str(), base, val);
200 0 : return HCCL_E_PARA;
201 0 : } catch (...) {
202 0 : HCCL_ERROR("[Transform][StrToULong]stoull catch error, str[%s] base[%d] val[%u]", str.c_str(), base, val);
203 0 : return HCCL_E_PARA;
204 0 : }
205 4248 : return HCCL_SUCCESS;
206 : }
207 :
208 : // 字串符转换成无符号长整型
209 0 : HcclResult SalStrToULonglong(const std::string str, int base, u64& val)
210 : {
211 : try {
212 0 : val = std::stoull(str, nullptr, base);
213 0 : } catch (std::invalid_argument&) {
214 0 : HCCL_ERROR(
215 : "[Transform][StrToULonglong]stoull invalid argument, str[%s] base[%d] val[%llu]", str.c_str(), base, val);
216 0 : return HCCL_E_PARA;
217 0 : } catch (std::out_of_range&) {
218 0 : HCCL_ERROR(
219 : "[Transform][StrToULonglong]stoull out of range, str[%s] base[%d] val[%llu]", str.c_str(), base, val);
220 0 : return HCCL_E_PARA;
221 0 : } catch (...) {
222 0 : HCCL_ERROR("[Transform][StrToULonglong]stoull catch error, str[%s] base[%d] val[%llu]", str.c_str(), base, val);
223 0 : return HCCL_E_PARA;
224 0 : }
225 0 : return HCCL_SUCCESS;
226 : }
227 :
228 : // 字串符转换成长整型
229 5 : HcclResult SalStrToLonglong(const std::string str, int base, s64& val)
230 : {
231 : try {
232 5 : val = std::stoll(str, nullptr, base);
233 3 : } catch (std::invalid_argument&) {
234 2 : HCCL_ERROR(
235 : "[Transform][SalStrToLonglong]stoll invalid argument, str[%s] base[%d] val[%lld]", str.c_str(), base, val);
236 2 : return HCCL_E_PARA;
237 3 : } catch (std::out_of_range&) {
238 1 : HCCL_ERROR(
239 : "[Transform][SalStrToLonglong]stoll out of range, str[%s] base[%d] val[%lld]", str.c_str(), base, val);
240 1 : return HCCL_E_PARA;
241 1 : } catch (...) {
242 0 : HCCL_ERROR(
243 : "[Transform][SalStrToLonglong]stoll catch error, str[%s] base[%d] val[%lld]", str.c_str(), base, val);
244 0 : return HCCL_E_PARA;
245 0 : }
246 2 : return HCCL_SUCCESS;
247 : }
248 : #endif
249 :
250 : #if HCOMM_T_DESC("路径信息函数", true)
251 0 : HcclResult SalIsDirExist(const std::string& dir, s32& status)
252 : {
253 : // 文件存在:0,不存在:-1,异常:1
254 0 : if (dir.length() == 0) {
255 0 : HCCL_ERROR("[Check][DirExist]invalid path length:%d", dir.length());
256 0 : status = 1;
257 0 : return HCCL_E_PARA;
258 : }
259 0 : char realPath[PATH_MAX] = {0};
260 0 : if (realpath(dir.c_str(), realPath) == nullptr) {
261 : // 如果错误码是文件不存在,记录状态,否则报错
262 0 : if (errno == ENOENT) {
263 0 : status = -1;
264 0 : return HCCL_SUCCESS;
265 : } else {
266 0 : status = 1;
267 0 : HCCL_ERROR("[Check][DirExist]path %s is invalid errno(%d):%s", dir.c_str(), errno, strerror(errno));
268 0 : return HCCL_E_PARA;
269 : }
270 : } else {
271 0 : status = 0;
272 : }
273 0 : return HCCL_SUCCESS;
274 : }
275 : #endif
276 :
277 : #if HCOMM_T_DESC("数学计算处理函数", true)
278 0 : s32 SalLog2(s32 data) { return static_cast<s32>(log2(data)); }
279 : #endif
280 :
281 : #if HCOMM_T_DESC("计算类型占用内存大小函数", true)
282 155 : HcclResult SalGetDataTypeSize(HcclDataType dataType, u32& dataTypeSize)
283 : {
284 155 : if ((dataType >= HCCL_DATA_TYPE_INT8) && (dataType < HCCL_DATA_TYPE_RESERVED)) {
285 155 : dataTypeSize = SIZE_TABLE[dataType];
286 : } else {
287 0 : HCCL_ERROR(
288 : "[Get][DataTypeSize]errNo[0x%016llx] get date size failed. dataType[%s] is invalid.",
289 : HCOM_ERROR_CODE(HCCL_E_PARA), GetDataTypeEnumStr(dataType).c_str());
290 0 : return HCCL_E_PARA;
291 : }
292 155 : return HCCL_SUCCESS;
293 : }
294 : #endif
295 :
296 : #if HCOMM_T_DESC("设置指定位值函数", true)
297 208 : void SalSetBitOne(u64& value, u64 index)
298 : {
299 208 : u64 bit = static_cast<u64>(1) << index;
300 208 : value |= bit;
301 208 : return;
302 : }
303 : #endif
304 :
305 : #if HCOMM_T_DESC("json处理函数", true)
306 0 : HcclResult SalParseInformation(nlohmann::json& parseInformation, const std::string& information)
307 : {
308 : try {
309 0 : parseInformation = nlohmann::json::parse(information);
310 0 : } catch (...) {
311 0 : HCCL_ERROR(
312 : "[Parse][Information] errNo[0x%016llx] load allocated resource to json fail. "
313 : "please check json input!",
314 : HCOM_ERROR_CODE(HCCL_E_PARA));
315 0 : return HCCL_E_PARA;
316 0 : }
317 0 : return HCCL_SUCCESS;
318 : }
319 :
320 0 : HcclResult SalGetJsonProperty(const nlohmann::json& obj, const std::string& propName, std::string& propValue)
321 : {
322 : /* 查找json对象中是否有该属性, 不存在的属性不能直接访问 */
323 0 : CHK_PRT_RET(
324 : obj.find(propName) == obj.end(),
325 : HCCL_ERROR("[Get][JsonProperty]json object has no property called %s", propName.c_str()), HCCL_E_INTERNAL);
326 :
327 : /* 所有属性值都必须是字符串 */
328 0 : if (obj[propName].is_string()) {
329 0 : propValue = obj[propName];
330 0 : return HCCL_SUCCESS;
331 : } else {
332 0 : printf("property value of Name[%s] is not string!", propName.c_str());
333 0 : return HCCL_E_INTERNAL;
334 : }
335 : }
336 : #endif
337 :
338 0 : HcclResult GetLocalHostIP(hccl::HcclIpAddress& ip, u32 devPhyId)
339 : {
340 0 : if (!ip.IsInvalid()) {
341 0 : return HCCL_SUCCESS;
342 : }
343 0 : std::vector<std::pair<std::string, hccl::HcclIpAddress>> ifInfos;
344 0 : CHK_RET(hrtGetHostIf(ifInfos, devPhyId));
345 0 : CHK_PRT_RET(ifInfos.empty(), HCCL_ERROR("[Get][LocalHostIP]there is no valid host if."), HCCL_E_NOT_FOUND);
346 :
347 0 : CHK_RET(FindLocalHostIP(ifInfos, ip));
348 :
349 0 : return HCCL_SUCCESS;
350 0 : }
351 :
352 8 : bool FindHostIPByNicClass(
353 : const std::map<std::string, std::map<std::string, hccl::HcclIpAddress>>& nicClassifyInfo,
354 : const std::string& nicClass, hccl::HcclIpAddress& ip)
355 : {
356 8 : auto iterClass = nicClassifyInfo.find(nicClass);
357 8 : if (iterClass != nicClassifyInfo.end()) {
358 8 : if (iterClass->second.empty()) {
359 0 : HCCL_WARNING("nic class[%s]: no valid ip.", nicClass.c_str());
360 0 : return false;
361 : }
362 8 : ip = iterClass->second.begin()->second;
363 8 : HCCL_INFO(
364 : "get host ip success. host ifname[%s] ip[%s]", iterClass->second.begin()->first.c_str(),
365 : ip.GetReadableAddress());
366 8 : return true;
367 : }
368 0 : return false;
369 : }
370 :
371 2 : HcclResult FindLocalHostIPByIfname(
372 : std::vector<std::pair<std::string, hccl::HcclIpAddress>>& ifInfos, s32 family, hccl::HcclIpAddress& ip)
373 : {
374 2 : for (auto& ifInfo : ifInfos) {
375 2 : if (ifInfo.second.GetFamily() != family) {
376 0 : continue;
377 : }
378 2 : u32 matchLen = ifInfo.first.size();
379 2 : bool configIfNamesFlag = false;
380 4 : for (u32 i = 0; i < GetExternalInputHcclSocketIfName().configIfNames.size(); i++) {
381 4 : matchLen = GetExternalInputHcclSocketIfName().searchExact ?
382 1 : ifInfo.first.size() :
383 1 : GetExternalInputHcclSocketIfName().configIfNames[i].size();
384 2 : if (ifInfo.first.compare(0, matchLen, GetExternalInputHcclSocketIfName().configIfNames[i], 0, matchLen)
385 2 : == 0) {
386 2 : configIfNamesFlag = true;
387 : }
388 : }
389 2 : if ((configIfNamesFlag) ^ (GetExternalInputHcclSocketIfName().searchNot)) {
390 2 : configIfNamesFlag = false;
391 2 : ip = ifInfo.second;
392 2 : HCCL_RUN_INFO(
393 : "get host ip success. name[%s] ip[%s]", ifInfo.first.c_str(), ifInfo.second.GetReadableAddress());
394 2 : return HCCL_SUCCESS;
395 : }
396 : }
397 0 : return HCCL_E_NOT_FOUND;
398 : }
399 :
400 : HcclResult
401 2 : FindLocalHostIPByIfname(std::vector<std::pair<std::string, hccl::HcclIpAddress>>& ifInfos, hccl::HcclIpAddress& ip)
402 : {
403 2 : s32 firstFamily = (GetExternalInputHcclSocketFamily() == -1) ? AF_INET : GetExternalInputHcclSocketFamily();
404 2 : HcclResult ret = FindLocalHostIPByIfname(ifInfos, firstFamily, ip);
405 2 : if (ret == HCCL_E_NOT_FOUND) {
406 0 : s32 family = (firstFamily == AF_INET) ? AF_INET6 : AF_INET;
407 0 : ret = FindLocalHostIPByIfname(ifInfos, family, ip);
408 : }
409 2 : return ret;
410 : }
411 :
412 8 : HcclResult FindLocalHostIPDefault(
413 : std::vector<std::pair<std::string, hccl::HcclIpAddress>>& ifInfos, s32 family, hccl::HcclIpAddress& ip)
414 : {
415 8 : std::map<std::string, std::map<std::string, hccl::HcclIpAddress>> nicClassify;
416 40 : for (auto& ifInfo : ifInfos) {
417 32 : if (ifInfo.second.GetFamily() != family) {
418 8 : continue;
419 : }
420 24 : if (ifInfo.first.find("lo") == 0) {
421 16 : nicClassify["lo"].insert({ifInfo.first, ifInfo.second});
422 16 : } else if (ifInfo.first.find("docker") == 0) {
423 16 : nicClassify["docker"].insert({ifInfo.first, ifInfo.second});
424 : } else {
425 16 : nicClassify["normal"].insert({ifInfo.first, ifInfo.second});
426 : }
427 24 : HCCL_DEBUG("ifname[%s] addr[%s]", ifInfo.first.c_str(), ifInfo.second.GetReadableAddress());
428 : }
429 :
430 16 : if (FindHostIPByNicClass(nicClassify, "normal", ip)) {
431 8 : HCCL_RUN_INFO("nic class[normal]: find nic[%s] success.", ip.GetReadableAddress());
432 8 : return HCCL_SUCCESS;
433 0 : } else if (FindHostIPByNicClass(nicClassify, "docker", ip)) {
434 0 : HCCL_RUN_INFO("nic class[docker]: find nic[%s] success.", ip.GetReadableAddress());
435 0 : return HCCL_SUCCESS;
436 0 : } else if (FindHostIPByNicClass(nicClassify, "lo", ip)) {
437 0 : HCCL_RUN_INFO("nic class[lo]: find nic[%s] success.", ip.GetReadableAddress());
438 0 : return HCCL_SUCCESS;
439 : }
440 0 : return HCCL_E_NOT_FOUND;
441 8 : }
442 :
443 : HcclResult
444 8 : FindLocalHostIPDefault(std::vector<std::pair<std::string, hccl::HcclIpAddress>>& ifInfos, hccl::HcclIpAddress& ip)
445 : {
446 8 : s32 firstFamily = (GetExternalInputHcclSocketFamily() == -1) ? AF_INET : GetExternalInputHcclSocketFamily();
447 8 : HcclResult ret = FindLocalHostIPDefault(ifInfos, firstFamily, ip);
448 8 : if (ret == HCCL_E_NOT_FOUND) {
449 0 : s32 family = (firstFamily == AF_INET) ? AF_INET6 : AF_INET;
450 0 : ret = FindLocalHostIPDefault(ifInfos, family, ip);
451 : }
452 8 : return ret;
453 : }
454 :
455 13 : HcclResult FindLocalHostIP(std::vector<std::pair<std::string, hccl::HcclIpAddress>>& ifInfos, hccl::HcclIpAddress& ip)
456 : {
457 13 : CHK_PRT_RET(
458 : ifInfos.empty(),
459 : HCCL_ERROR("[Find][LocalHostIP]there is no valid host if. (host if is not exist or not in whitelist)"),
460 : HCCL_E_NOT_FOUND);
461 :
462 13 : hccl::HcclIpAddress tmpIp;
463 13 : std::string ipModleInfo;
464 13 : if (!GetExternalInputMasterInfo().agentIp.IsInvalid()) {
465 0 : tmpIp = GetExternalInputMasterInfo().agentIp;
466 0 : ipModleInfo = "WORKER IP";
467 13 : } else if (!GetExternalInputHcclControlIfIp().IsInvalid()) {
468 3 : tmpIp = GetExternalInputHcclControlIfIp();
469 3 : ipModleInfo = "IF IP";
470 : }
471 13 : if (!tmpIp.IsInvalid()) {
472 : // 匹配指定IP的网卡信息
473 5 : for (auto& ifInfo : ifInfos) {
474 5 : if (ifInfo.second == tmpIp) {
475 3 : ip = ifInfo.second;
476 3 : HCCL_RUN_INFO(
477 : "get host ip success by if IP of [%s]. name[%s] ip[%s]", ipModleInfo.c_str(), ifInfo.first.c_str(),
478 : ifInfo.second.GetReadableAddress());
479 3 : return HCCL_SUCCESS;
480 : }
481 : }
482 0 : std::string errormessage = "ip [" + std::string(tmpIp.GetReadableAddress()) + "] of [" + ipModleInfo
483 0 : + "] is not found in the nic list.";
484 0 : HCCL_ERROR(
485 : "[%s][%s]%s", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(), errormessage.c_str());
486 0 : RPT_ENV_ERR(
487 : true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
488 : std::vector<std::string>(
489 : {tmpIp.GetReadableAddress(), "HCCL_SOCKET_IFNAME",
490 : "an ip address that exists in the local network interfaces list"}));
491 0 : return HCCL_E_NOT_FOUND;
492 10 : } else if (!GetExternalInputHcclSocketIfName().configIfNames.empty()) {
493 : // 使用Host网卡名和环境变量HCCL_SOCKET_IFNAME配置的网卡名进行比较
494 2 : HcclResult ret = FindLocalHostIPByIfname(ifInfos, ip);
495 2 : if (ret != HCCL_SUCCESS) {
496 0 : std::string hcclSocketIfnameStr;
497 0 : for (u32 i = 0; i < GetExternalInputHcclSocketIfName().configIfNames.size(); ++i) {
498 0 : hcclSocketIfnameStr += GetExternalInputHcclSocketIfName().configIfNames[i];
499 0 : if (i != GetExternalInputHcclSocketIfName().configIfNames.size() - 1) {
500 0 : hcclSocketIfnameStr += ",";
501 : }
502 : }
503 0 : std::string errormessage = "set ifname to [" + hcclSocketIfnameStr
504 : + "] by HCCL_SOCKET_IFNAME, but not found in the environment, ifnames in the "
505 0 : "environment is as follows";
506 0 : HCCL_ERROR(
507 : "[%s][%s]%s", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(), errormessage.c_str());
508 0 : RPT_ENV_ERR(
509 : true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
510 : std::vector<std::string>(
511 : {hcclSocketIfnameStr, "HCCL_SOCKET_IFNAME",
512 : "a valid network interface name (e.g., eth0, bound0) present on this host"}));
513 0 : for (auto& ifInfo : ifInfos) {
514 0 : HCCL_ERROR(
515 : "[%s][%s]get host ip fail by socket Ifname. name[%s] ip[%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
516 : LOG_KEYWORDS_ENV_CONFIG.c_str(), ifInfo.first.c_str(), ifInfo.second.GetReadableAddress());
517 : }
518 0 : return HCCL_E_NOT_FOUND;
519 0 : }
520 : } else {
521 8 : CHK_PRT_RET(
522 : FindLocalHostIPDefault(ifInfos, ip), HCCL_ERROR("[Find][LocalHostIP]there is no host if."),
523 : HCCL_E_NOT_FOUND);
524 : }
525 10 : return HCCL_SUCCESS;
526 13 : }
527 :
528 0 : std::string GetLocalServerId(std::string& serverId)
529 : {
530 0 : hccl::HcclIpAddress hostIP;
531 0 : HcclResult ret = GetLocalHostIP(hostIP);
532 0 : if (ret != HCCL_SUCCESS) {
533 0 : HCCL_WARNING("[Get][ServerId]GetLocalHostIP Failed, Use INVALID value");
534 0 : serverId = "0.0.0.0";
535 : } else {
536 0 : serverId = hostIP.GetReadableAddress();
537 : }
538 0 : return serverId;
539 0 : }
540 :
541 12 : HcclResult IsAllDigit(const char* strNum)
542 : {
543 : // 参数有效性检查
544 12 : CHK_PTR_NULL(strNum);
545 12 : u32 index = 0;
546 :
547 12 : u32 nLength = SalStrLen(strNum);
548 12 : if (strNum[0] == '-') {
549 0 : index = 1;
550 : }
551 44 : for (; index < nLength; index++) {
552 32 : if (!isdigit(strNum[index])) {
553 0 : HCCL_ERROR(
554 : "[Check][Isdigit]errNo[0x%016llx] In judge all digit, check isdigit failed."
555 : "ensure that the number is an integer. strNum[%u] is [%d](Dec)",
556 : HCCL_ERROR_CODE(HCCL_E_PARA), index, strNum[index]);
557 0 : return HCCL_E_PARA;
558 : }
559 : }
560 12 : return HCCL_SUCCESS;
561 : }
562 :
563 0 : HcclResult CheckHexUInt(const std::string& str)
564 : {
565 0 : if (str.length() != 10) { // 有效的16进制无符号整型数如0xFFFFFFFF共10个字符
566 0 : HCCL_ERROR("[Check][HexUInt]string[%s] is not a valid hexadecimal uint value.", str.c_str());
567 0 : return HCCL_E_PARA;
568 : }
569 0 : if (str.substr(0, 2) != "0x" && str.substr(0, 2) != "0X") { // 字符串前两2个字符,有效的16进制数以0x或者0X开头
570 0 : HCCL_ERROR("[Check][HexUInt]string[%s] is not a valid hexadecimal uint value.", str.c_str());
571 0 : return HCCL_E_PARA;
572 : }
573 0 : for (int i = 2; i < 10; i++) { // 从第2个字符到第10个字符判断是否是有效字符
574 0 : if ((str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'f') || (str[i] >= 'A' && str[i] <= 'F')) {
575 0 : continue;
576 : } else {
577 0 : HCCL_ERROR("[Check][HexUInt]string[%s] is not a valid hexadecimal uint value.", str.c_str());
578 0 : return HCCL_E_PARA;
579 : }
580 : }
581 0 : return HCCL_SUCCESS;
582 : }
583 :
584 1805 : bool IsGeneralServer()
585 : {
586 1805 : CHK_RET(hccl::DlHalFunction::GetInstance().DlHalFunctionInit());
587 1805 : uint32_t numDev = 0;
588 1805 : HcclResult ret = hrtDrvGetDevNum(&numDev);
589 1805 : if (ret != HCCL_SUCCESS) {
590 0 : HCCL_WARNING("GetDevNum Failed, numDev INVALID value 0");
591 0 : return false;
592 : }
593 1805 : return (numDev == 0);
594 : }
595 :
596 : bool g_isHdcMode = true;
597 0 : void SetHostUseDevNicFlag(bool isHdcMode) { g_isHdcMode = isHdcMode; }
598 :
599 : // 判断host侧是否需要使用device网卡
600 416 : HcclResult IsHostUseDevNic(bool& isHdcMode)
601 : {
602 416 : CHK_RET(hccl::DlHalFunction::GetInstance().DlHalFunctionInit());
603 : // 如果不位于host侧直接返回
604 416 : uint32_t info = 0;
605 416 : CHK_RET(hrtDrvGetPlatformInfo(&info));
606 416 : if (info != HOST) {
607 416 : HCCL_INFO("[IsHostUseDevNic] : now on device, info: [%u]", info);
608 416 : isHdcMode = false;
609 416 : return HCCL_SUCCESS;
610 : }
611 :
612 : // 通用服务器直接返回
613 0 : if (IsGeneralServer()) {
614 0 : isHdcMode = false;
615 0 : HCCL_INFO("[IsHostUseDevNic] : universal server, isHdcMode[%u]", isHdcMode);
616 0 : return HCCL_SUCCESS;
617 : }
618 :
619 : // 在aiserver上判断该环境变量是否设置
620 0 : isHdcMode = g_isHdcMode;
621 0 : HCCL_INFO("IsHostUseDevNic[%u]", isHdcMode);
622 :
623 0 : return HCCL_SUCCESS;
624 : }
625 :
626 1540 : u32 GetNicPort(u32 devicePhyId, const std::vector<u32>& ranksPort, u32 userRank, bool isUseRanksPort)
627 : {
628 1540 : if (isUseRanksPort && userRank < ranksPort.size() && ranksPort[userRank] != HCCL_INVALID_PORT) {
629 257 : return ranksPort[userRank];
630 1283 : } else if (!isUseRanksPort && !hccl::Is310PDevice()) {
631 : // 使用device nic时且无外部配置的port(ranksPort长度为0或者有port但为无效值)时,默认16666
632 1283 : return HETEROG_CCL_PORT;
633 0 : } else if (GetExternalInputHcclIfBasePort() == HCCL_INVALID_PORT) {
634 0 : HCCL_INFO("[Init][Nic] port is set to HOST_PARA_BASE_PORT");
635 0 : return (HOST_PARA_BASE_PORT + devicePhyId);
636 : } else {
637 0 : return (GetExternalInputHcclIfBasePort() + HCCL_AISERVER_DEVICE_NUM + devicePhyId);
638 : }
639 : // peer及hdc模式下listen_start/batch_connect/listen_stop调用支持指定端口
640 : // server及client按照此相同规则指定端口
641 : }
642 :
643 193 : void SetThreadName(const std::string& threadStr)
644 : {
645 : // 线程名应限制在15个字符内,防止被截断
646 193 : s32 sRet = pthread_setname_np(pthread_self(), threadStr.c_str());
647 193 : CHK_PRT_CONT(sRet != 0, HCCL_WARNING("err[%d] link[%s] nameSet failed.", sRet, threadStr.c_str()));
648 193 : }
|