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