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 "hccl_communicator_attrs.h"
12 : #include "device_capacity.h"
13 : #include "common/src/config.h"
14 : #include "externalinput_pub.h"
15 : #include "env_config.h"
16 :
17 : using namespace std;
18 :
19 : namespace hccl
20 : {
21 0 : HcclResult HcclCommunicatorAttrs::Init(HcclCommParams ¶ms, const RankTable_t &rankTable)
22 : {
23 0 : CHK_RET(InitCommParams(params));
24 0 : CHK_RET(InitRankInfo(rankTable));
25 0 : return HCCL_SUCCESS;
26 : }
27 :
28 498 : HcclResult HcclCommunicatorAttrs::Init(HcclCommParams ¶ms, const RankTable_t &rankTable,
29 : const std::map<HcclCMDType, std::vector<HcclAlgoType>>& algoConfigMap)
30 : {
31 498 : algoConfigMap_ = algoConfigMap;
32 498 : CHK_RET(InitCommParams(params));
33 498 : CHK_RET(InitRankInfo(rankTable));
34 495 : return HCCL_SUCCESS;
35 : }
36 :
37 0 : HcclResult HcclCommunicatorAttrs::Init(HcclCommParams ¶ms, const std::vector<RankInfo> &rankList,
38 : WorldGroupInfo &groupCommonData)
39 : {
40 0 : CHK_RET(InitCommParams(params));
41 0 : CHK_RET(InitRankInfoSubGroup(rankList, groupCommonData));
42 0 : return HCCL_SUCCESS;
43 : }
44 :
45 33 : HcclResult HcclCommunicatorAttrs::Init(HcclCommParams ¶ms, const std::vector<RankInfo> &rankList,
46 : WorldGroupInfo &groupCommonData,
47 : const std::map<HcclCMDType, std::vector<HcclAlgoType>>& algoConfigMap)
48 : {
49 33 : algoConfigMap_ = algoConfigMap;
50 33 : CHK_RET(InitCommParams(params));
51 33 : CHK_RET(InitRankInfoSubGroup(rankList, groupCommonData));
52 33 : return HCCL_SUCCESS;
53 : }
54 :
55 527 : bool HcclCommunicatorAttrs::IsStandardCard()
56 : {
57 527 : if (Is310P3Common())
58 : {
59 4 : HCCL_INFO("The current device just support this StandardCard case.");
60 4 : return true;
61 : }
62 816 : return ((pairLinkInfo_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)].size() == 0) &&
63 814 : (pairLinkInfo_[static_cast<u32>(LinkTypeInServer::HCCS_SW_TYPE)].size() == 0) &&
64 806 : (pairLinkInfo_[static_cast<u32>(LinkTypeInServer::SIO_TYPE)].size() == 0));
65 : }
66 :
67 526 : bool HcclCommunicatorAttrs::Is310PDuoCard()
68 : {
69 526 : return (Is310P3Common() && (pairLinkInfo_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)].size() == userRankSize_));
70 : }
71 :
72 4 : bool HcclCommunicatorAttrs::IsCommon310P3DUO(const std::vector<RankInfo_t> &rankList)
73 : {
74 4 : std::vector<u32> devIdList;
75 4 : std::vector<std::vector<u32>> checkDevList;
76 4 : checkDevList.resize(FACTOR_NUM_TWO);
77 :
78 20 : for (RankInfo_t rankInfo : rankList)
79 : {
80 16 : u32 curId = rankInfo.deviceInfo.devicePhyId;
81 16 : devIdList.push_back(curId);
82 16 : }
83 4 : if (devIdList.size() == DEVICE_PER_MODULE)
84 : {
85 0 : return true;
86 : }
87 4 : std::sort(devIdList.begin(), devIdList.end());
88 20 : for (u32 i = 0; i < devIdList.size(); i++)
89 : {
90 16 : if (devIdList[i] % FACTOR_NUM_TWO == 0)
91 : {
92 8 : checkDevList[0].push_back(devIdList[i]); // 主die
93 : }
94 : else
95 : {
96 8 : checkDevList[1].push_back(devIdList[i]); // 从die
97 : }
98 : }
99 4 : if (devIdList.size() == (DEVICE_PER_MODULE / FACTOR_NUM_TWO) && checkDevList[0].size() == checkDevList[1].size())
100 : {
101 8 : return ((checkDevList[1][0] - checkDevList[0][0]) == 1) &&
102 8 : ((checkDevList[1][1] - checkDevList[0][1]) != 0);
103 : }
104 : else
105 : {
106 0 : return false;
107 : }
108 : return false;
109 4 : }
110 :
111 1994 : bool HcclCommunicatorAttrs::CompareWithUserRank(const RankInfo &left, const RankInfo &right)
112 : {
113 1994 : return left.userRank < right.userRank;
114 : }
115 :
116 1490 : HcclResult HcclCommunicatorAttrs::CheckDeviceType(const DevType deviceType) const
117 : {
118 1490 : if ((deviceType >= DevType::DEV_TYPE_COUNT) || (deviceType < DevType::DEV_TYPE_910))
119 : {
120 0 : HCCL_ERROR("[Check][DeviceType]errNo[0x%016llx] device Type[%d] out of range[%d, %d]",
121 : HCCL_ERROR_CODE(HCCL_E_PARA), deviceType, DevType::DEV_TYPE_910, DevType::DEV_TYPE_NOSOC);
122 0 : return HCCL_E_PARA;
123 : }
124 1490 : HCCL_INFO("[HcclCommunicatorAttrs][CheckDeviceType] CheckDeviceType done");
125 1491 : return HCCL_SUCCESS;
126 : }
127 :
128 1490 : HcclResult HcclCommunicatorAttrs::GetNicInfo(const NICDeployment &nicDeploy, const u32 curRankIndex,
129 : const std::vector<RankInfo_t> &servRankList, RankInfo &rankInfo) const
130 : {
131 1490 : CHK_PRT_RET(servRankList.empty(), HCCL_ERROR("[Get][NicInfo]errNo[0x%016llx] server rank list is empty", HCCL_ERROR_CODE(HCCL_E_PARA)), HCCL_E_PARA);
132 1489 : CHK_PRT_RET(curRankIndex >= servRankList.size(), HCCL_ERROR("[Get][NicInfo]rankindex[%u] invalid,rank list "
133 : "size is[%zu]",
134 : curRankIndex, servRankList.size()),
135 : HCCL_E_PARA);
136 1489 : rankInfo.nicDeploy = nicDeploy;
137 1489 : const RankInfo_t &curRankInfo = servRankList[curRankIndex];
138 1489 : if (nicDeploy == NICDeployment::NIC_DEPLOYMENT_HOST && curRankInfo.deviceInfo.deviceIp.size() == 0) {
139 : // 检查网卡个数
140 : // 网卡挂载位置在host时,按rank index从网卡列表中获取
141 0 : rankInfo.nicIp.push_back(curRankInfo.hostIp);
142 : } else {
143 1489 : CHK_PRT_RET(curRankInfo.deviceInfo.deviceIp.size() == 0,
144 : HCCL_ERROR("[Get][NicInfo]rankindex[%u] invalid,deviceIp is zero", curRankIndex), HCCL_E_PARA);
145 1490 : rankInfo.nicIp.push_back(curRankInfo.deviceInfo.deviceIp[0]);
146 1487 : if (curRankInfo.deviceInfo.backupDeviceIp.size() == 0)
147 : {
148 1487 : HcclIpAddress invalidAddr;
149 1491 : rankInfo.backupNicIp.push_back(invalidAddr);
150 1488 : }
151 : else
152 : {
153 0 : rankInfo.backupNicIp.push_back(curRankInfo.deviceInfo.backupDeviceIp[0]);
154 : }
155 1491 : rankInfo.deviceNicPort = curRankInfo.deviceInfo.port;
156 1491 : rankInfo.deviceVnicPort = curRankInfo.deviceInfo.vnicPort;
157 1491 : rankInfo.backupDevicePort = curRankInfo.deviceInfo.backupPort;
158 1491 : HCCL_INFO("[Get][NicInfo]serverId[%s], serverIdx[%u], rankIndex[%u], nicIp[%s], backupNicIp[%s], "
159 : "deviceNicPort[%u], deviceVnicPort[%u], backupDevicePort[%u]",
160 : rankInfo.serverId.c_str(), rankInfo.serverIdx, curRankIndex,
161 : rankInfo.nicIp[0].GetReadableIP(), rankInfo.backupNicIp[0].GetReadableIP(),
162 : rankInfo.deviceNicPort, rankInfo.deviceVnicPort, rankInfo.backupDevicePort);
163 : }
164 1491 : HCCL_INFO("[HcclCommunicatorAttrs][GetNicInfo] GetNicInfo done");
165 1491 : return HCCL_SUCCESS;
166 : }
167 :
168 : // private
169 531 : HcclResult HcclCommunicatorAttrs::InitCommParams(HcclCommParams ¶ms)
170 : {
171 531 : userRank_ = params.rank;
172 531 : realUserRank_ = params.userRank;
173 531 : userRankSize_ = params.totalRanks;
174 531 : deviceLogicId_ = params.logicDevId;
175 531 : deviceType_ = params.deviceType;
176 :
177 531 : identifier_ = params.identifier;
178 531 : collectiveId_ = params.id.internal;
179 531 : commWorkMode_ = params.commWorkMode;
180 531 : HCCL_DEBUG(
181 : "userRank_: %u realUserRank_: %u userRankSize_: %u deviceLogicId_: %u deviceType_: %u commWorkMode_: %u.",
182 : userRank_, realUserRank_, userRankSize_, deviceLogicId_, deviceType_, commWorkMode_);
183 531 : return HCCL_SUCCESS;
184 : }
185 :
186 498 : HcclResult HcclCommunicatorAttrs::SetServerId(const RankTable_t &rankTable)
187 : {
188 807 : for (u32 i = 0; i < rankTable.rankList.size(); i++)
189 : {
190 805 : if (rankTable.rankList[i].rankId == userRank_)
191 : {
192 496 : serverId_ = rankTable.rankList[i].serverId;
193 496 : superPodId_ = rankTable.rankList[i].superPodId;
194 496 : superDeviceId_ = rankTable.rankList[i].superDeviceId;
195 496 : break;
196 : }
197 : }
198 :
199 498 : if (serverId_.empty())
200 : {
201 2 : HCCL_ERROR("[Set][ServerId]SetServerId fail");
202 2 : return HCCL_E_PARA;
203 : }
204 496 : HCCL_INFO("[HcclCommunicatorAttrs][SetServerId] SetServerId done");
205 496 : return HCCL_SUCCESS;
206 : }
207 :
208 529 : HcclResult HcclCommunicatorAttrs::SetServerNum(const std::vector<RankInfo_t> &ranks)
209 : {
210 529 : std::vector<std::string> serverIds;
211 2177 : for (u32 index = 0; index < ranks.size(); index++)
212 : {
213 1648 : std::vector<std::string>::iterator found = find(serverIds.begin(), serverIds.end(), ranks[index].serverId);
214 1648 : if (found == serverIds.end())
215 : {
216 753 : serverIds.push_back(ranks[index].serverId);
217 : }
218 : }
219 529 : serverNum_ = serverIds.size();
220 529 : HCCL_INFO("[HcclCommunicatorAttrs][SetServerNum] SetServerNum done");
221 529 : return HCCL_SUCCESS;
222 529 : }
223 :
224 496 : HcclResult HcclCommunicatorAttrs::SetInnerServerAverageDevice(const RankTable_t &rankTable)
225 : {
226 496 : deviceNumPerServer_ = 0;
227 496 : bool isConnectedWithHCCS = true;
228 496 : LinkTypeInServer linkType = LinkTypeInServer::HCCS_TYPE;
229 1987 : for (u32 i = 0; i < rankTable.rankList.size(); i++)
230 : {
231 : // 同一server的标识IP 是一样的,所以可以以此推算出平均dev个数
232 1491 : if (rankTable.rankList[i].deviceInfo.devicePhyId == HOST_DEVICE_ID && isHaveCpuRank_ != true)
233 : {
234 0 : isHaveCpuRank_ = true;
235 : }
236 2712 : if (serverId_ == rankTable.rankList[i].serverId &&
237 1221 : rankTable.rankList[i].deviceInfo.devicePhyId != HOST_DEVICE_ID)
238 : {
239 1221 : deviceNumPerServer_++;
240 : }
241 : else
242 : {
243 270 : continue;
244 : }
245 1221 : if (Is310PDevice())
246 : {
247 0 : continue;
248 : }
249 1221 : CHK_RET(GetPairDeviceLinkType(rankTable, i, isConnectedWithHCCS, linkType));
250 : }
251 496 : if (deviceType_ == DevType::DEV_TYPE_910B && !isConnectedWithHCCS)
252 : {
253 0 : deviceNumPerAggregation_ = deviceNumPerServer_ / FACTOR_NUM_TWO;
254 : }
255 : else
256 : {
257 496 : deviceNumPerAggregation_ = deviceNumPerServer_;
258 : }
259 496 : return HCCL_SUCCESS;
260 : }
261 :
262 : // sub group适配获取server内设配数
263 33 : HcclResult HcclCommunicatorAttrs::SetInnerServerAverageDevice(const std::vector<RankInfo> &rankList)
264 : {
265 33 : deviceNumPerServer_ = 0;
266 33 : bool isConnectedWithHCCS = true;
267 33 : LinkTypeInServer linkType = LinkTypeInServer::HCCS_TYPE;
268 190 : for (u32 i = 0; i < rankList.size(); i++)
269 : {
270 : // 同一server的标识IP 是一样的,所以可以以此推算出平均dev个数
271 157 : if (serverId_ == rankList[i].serverId && rankList[i].devicePhyId != HOST_DEVICE_ID)
272 : {
273 118 : deviceNumPerServer_++;
274 : }
275 : else
276 : {
277 39 : continue;
278 : }
279 118 : if (Is310PDevice() || isHaveCpuRank_)
280 : {
281 : // 异构场景无需获取链路类型并校验
282 0 : continue;
283 : }
284 419 : for (u32 j = i + 1; j < rankList.size(); j++)
285 : {
286 301 : if (rankList[i].serverId == rankList[j].serverId)
287 : {
288 262 : CHK_RET(hrtGetPairDeviceLinkType(rankList[i].devicePhyId, rankList[j].devicePhyId, linkType));
289 : }
290 301 : if (linkType != LinkTypeInServer::HCCS_TYPE)
291 : {
292 0 : isConnectedWithHCCS = false;
293 : }
294 : }
295 : }
296 33 : if (deviceType_ == DevType::DEV_TYPE_910B && !isConnectedWithHCCS)
297 : {
298 0 : deviceNumPerAggregation_ = deviceNumPerServer_ / FACTOR_NUM_TWO;
299 : }
300 : else
301 : {
302 33 : deviceNumPerAggregation_ = deviceNumPerServer_;
303 : }
304 33 : return HCCL_SUCCESS;
305 : }
306 :
307 530 : HcclResult HcclCommunicatorAttrs::TransformRankInfoByServerId(
308 : const std::vector<RankInfo_t> &rankList, ServRankInfo &servRankInfo) const
309 : {
310 2178 : for (size_t index = 0; index < rankList.size(); ++index)
311 : {
312 1648 : const RankInfo_t &rankInfo = rankList[index];
313 1648 : std::string serverId = SalTrim(rankInfo.serverId);
314 1648 : ServRankInfo::iterator itr = servRankInfo.find(serverId);
315 1648 : if (itr != servRankInfo.end())
316 : {
317 895 : itr->second.push_back(rankInfo);
318 : }
319 : else
320 : {
321 753 : std::vector<RankInfo_t> rankInfoList;
322 753 : rankInfoList.push_back(rankInfo);
323 753 : std::pair<std::string, std::vector<RankInfo_t>> rankInfoPair(serverId, rankInfoList);
324 753 : servRankInfo.insert(rankInfoPair);
325 753 : }
326 1648 : }
327 : // 每个server下的rank列表按 设备Id 从小到大的顺序排序
328 1283 : for (auto &iter : servRankInfo)
329 : {
330 753 : std::sort(iter.second.begin(), iter.second.end(), CompareWithDevicePhyId);
331 : }
332 530 : return HCCL_SUCCESS;
333 : }
334 :
335 1790 : bool HcclCommunicatorAttrs::CompareWithDevicePhyId(const RankInfo_t &left, const RankInfo_t &right)
336 : {
337 1790 : return left.deviceInfo.devicePhyId < right.deviceInfo.devicePhyId;
338 : }
339 :
340 531 : HcclResult HcclCommunicatorAttrs::SetModuleInfo(const std::vector<RankInfo_t> &rankList)
341 : {
342 531 : isDiffDeviceType_ = IsDiffDeviceType(rankList);
343 531 : isDiffDeviceModule_ = IsDiffDeviceModule(rankList);
344 531 : HCCL_DEBUG("[SetModuleInfo]isDiffDeviceModule_[%u] isDiffDeviceType_[%u]", isDiffDeviceModule_, isDiffDeviceType_);
345 531 : multiModuleDiffDeviceNumMode_ = false;
346 531 : moduleNum_ = serverNum_;
347 :
348 531 : std::map<u32, std::vector<RankInfo_t>> moduleMap;
349 2194 : for (RankInfo_t rankInfo : rankList)
350 : {
351 1663 : u32 moduleIdx = INVALID_UINT;
352 1663 : CHK_RET(GetModuleIdx(rankInfo, moduleIdx)); // 这里不判断混合组网,只提取每个server实际的moduleidx
353 1663 : if (static_cast<s32>(rankInfo.deviceInfo.devicePhyId) == HOST_DEVICE_ID)
354 : {
355 0 : continue;
356 : }
357 1663 : auto iter = moduleMap.find(moduleIdx);
358 1663 : if (iter == moduleMap.end())
359 : {
360 758 : std::vector<RankInfo_t> rankInfoList;
361 758 : rankInfoList.push_back(rankInfo);
362 758 : moduleMap.insert(std::make_pair(moduleIdx, rankInfoList));
363 757 : }
364 : else
365 : {
366 905 : iter->second.push_back(rankInfo);
367 : }
368 1663 : }
369 531 : if (moduleMap.size() == 0)
370 : {
371 0 : return HCCL_SUCCESS;
372 : }
373 :
374 531 : std::vector<u32> moduleDeviceNumVec;
375 :
376 531 : moduleNum_ = moduleMap.size();
377 531 : u32 preDeviceNum = moduleMap.begin()->second.size();
378 530 : u32 curDeviceNum = preDeviceNum;
379 530 : std::vector<u32> devicePhyIdInfoList;
380 1287 : for (auto &moduleInfo : moduleMap)
381 : {
382 758 : curDeviceNum = moduleInfo.second.size();
383 758 : if (curDeviceNum != preDeviceNum)
384 : {
385 17 : multiModuleDiffDeviceNumMode_ = true;
386 : }
387 :
388 758 : moduleDeviceNumVec.push_back(curDeviceNum);
389 :
390 758 : HCCL_INFO("module[%d] contains [%d]devices", moduleInfo.first, moduleInfo.second.size());
391 758 : devicePhyIdInfoList.clear();
392 2421 : for (auto &rankInfo : moduleInfo.second)
393 : {
394 1662 : devicePhyIdInfoList.push_back(rankInfo.deviceInfo.devicePhyId);
395 1661 : HCCL_INFO("moduleIdx[%d] Info: rankId[%d], serverId[%s], serverIdx[%d], devicePhyId[%d]",
396 : moduleInfo.first, rankInfo.rankId, rankInfo.serverId.c_str(), rankInfo.serverIdx,
397 : rankInfo.deviceInfo.devicePhyId);
398 : }
399 758 : if (!CheckDoubleRingWithRohTopo(devicePhyIdInfoList)) {
400 474 : isARSDoubleRing_ = false;
401 474 : HCCL_DEBUG("SetModuleInfo isARSDoubleRing[%llu]", isARSDoubleRing_);
402 : }
403 : }
404 :
405 531 : if (isDiffDeviceType_)
406 : {
407 0 : gcdDeviceNumPerAggregation_ = CalGCD(moduleDeviceNumVec);
408 0 : multiModuleDiffDeviceNumMode_ = false;
409 0 : deviceNumPerAggregation_ = gcdDeviceNumPerAggregation_;
410 0 : useSuperPodMode_ = false;
411 0 : HCCL_INFO("[HcclCommunicatorAttrs][SetModuleInfo]mix mode, set multiModuleDiffDeviceNumMode to false, "
412 : "gcdDeviceNumPerAggregation [%u] deviceNumPerAggregation [%u]",
413 : gcdDeviceNumPerAggregation_, deviceNumPerAggregation_);
414 : }
415 :
416 531 : HCCL_RUN_INFO("different module contains different numbers of cards:[%d]", multiModuleDiffDeviceNumMode_);
417 531 : HCCL_RUN_INFO("different module contains different type of cards:[%d]", isDiffDeviceType_);
418 531 : return HCCL_SUCCESS;
419 531 : }
420 :
421 528 : HcclResult HcclCommunicatorAttrs::SetSuperPodInfo(const std::vector<RankInfo_t> &rankList)
422 : {
423 : // 1.超节点数目 2.超节点间server数是否一致 3.
424 528 : superPodNum_ = 0;
425 528 : multiSuperPodDiffServerNumMode_ = false;
426 528 : multiSuperPodDiffDeviceNumMode_ = false;
427 528 : std::map<std::string, std::set<u32>> superPodToServerNum; // 记录每个超节点中的server数目
428 529 : std::map<std::string, std::vector<RankInfo_t>> superPodToDeviceNum; //记录每个超节点中的设备(rank)数目
429 598 : for (RankInfo_t rankInfo : rankList)
430 : {
431 : // superPodId为空时, 返回超节点数量为0, 按照非超节点模式处理
432 584 : CHK_PRT_RET(rankInfo.superPodId.empty(),
433 : HCCL_DEBUG("ranks[%u] superPodId[%s] is empty, set superPodNum to zero", rankInfo.rankId,
434 : rankInfo.superPodId.c_str()),
435 : HCCL_SUCCESS);
436 :
437 69 : superPodToServerNum[rankInfo.superPodId].insert(rankInfo.serverIdx);
438 69 : auto iter = superPodToDeviceNum.find(rankInfo.superPodId);
439 69 : if (iter == superPodToDeviceNum.end()) {
440 30 : std::vector<RankInfo_t> rankInfoList;
441 30 : rankInfoList.push_back(rankInfo);
442 30 : superPodToDeviceNum.insert(std::make_pair(rankInfo.superPodId, rankInfoList));
443 30 : } else {
444 39 : iter->second.push_back(rankInfo);
445 : }
446 586 : }
447 12 : superPodNum_ = superPodToServerNum.size();
448 12 : std::vector<u32> superPodServerNumVec;
449 12 : u32 preServerNum = superPodToServerNum.begin()->second.size();
450 12 : u32 curServerNum = preServerNum;
451 42 : for (auto superPodItem : superPodToServerNum)
452 : {
453 30 : curServerNum = superPodItem.second.size();
454 30 : if (curServerNum != preServerNum)
455 : {
456 11 : multiSuperPodDiffServerNumMode_ = true;
457 : }
458 30 : superPodServerNumVec.push_back(curServerNum);
459 30 : HCCL_INFO("[Set][SuperPodInfo]SuperPod[%s] contains [%d]servers", superPodItem.first.c_str(), superPodItem.second.size());
460 30 : }
461 12 : HCCL_RUN_INFO("[Set][SuperPodInfo]different surperPod contains different numbers of servers:[%d]",
462 : multiSuperPodDiffServerNumMode_);
463 :
464 : // 计算最大公约数
465 12 : if (!IsConfigAHCAlgo(algoConfigMap_) && !multiModuleDiffDeviceNumMode_ && multiSuperPodDiffServerNumMode_)
466 : {
467 8 : gcdServerNumPerSuperPod_ = CalGCD(superPodServerNumVec);
468 8 : multiSuperPodDiffServerNumMode_ = false; // 取公约数不存在server数不一致场景
469 8 : superPodNum_ = serverNum_ / gcdServerNumPerSuperPod_;
470 8 : HCCL_RUN_INFO("[Set][SuperPodInfo] gcdServerNumPerSuperPod[%u] original superPodNum[%u] converted superPodNum[%u]",
471 : gcdServerNumPerSuperPod_, superPodToServerNum.size(), superPodNum_);
472 : }
473 :
474 12 : if (isDiffDeviceType_)
475 : {
476 0 : multiSuperPodDiffServerNumMode_ = false;
477 0 : HCCL_RUN_INFO("mix mode, set multiSuperPodDiffServerNumMode to false");
478 : }
479 :
480 42 : for (auto item: superPodToDeviceNum) {
481 30 : u32 curDeviceNum = item.second.size();
482 30 : if (curDeviceNum != superPodToDeviceNum.begin()->second.size()) {
483 11 : multiSuperPodDiffDeviceNumMode_ = true;
484 : }
485 30 : HCCL_INFO("[Set][SuperPodInfo]SuperPod[%s] contains [%d] devices", item.first.c_str(), item.second.size());
486 30 : }
487 12 : return HCCL_SUCCESS;
488 529 : }
489 :
490 : // 集群中存在910B A+X时,0-7卡: moduleIdx = 2 * serverIdx; 8-15卡: moduleIdx = 2 * serverIdx + 1
491 : // 集群中不存在910B A+X时,moduleIdx = serverIdx
492 1663 : HcclResult HcclCommunicatorAttrs::GetModuleIdx(const RankInfo_t &rankInfo, u32 &moduleIdx)
493 : {
494 1663 : CHK_PRT_RET(rankInfo.serverIdx == INVALID_UINT,
495 : HCCL_ERROR("serverIdx is invalid:[%u], rankId:[%u]", rankInfo.serverIdx, rankInfo.rankId), HCCL_E_PARA);
496 1663 : CHK_PRT_RET(deviceType_ == DevType::DEV_TYPE_COUNT,
497 : HCCL_ERROR("deviceType_ is invalid:[%d], rankId:[%u]", deviceType_, rankInfo.rankId), HCCL_E_PARA);
498 1663 : u32 serverIdx = rankInfo.serverIdx;
499 1663 : if (GetRankInfoDevType(rankInfo) == DevType::DEV_TYPE_910B && isDiffDeviceModule_)
500 : {
501 17 : moduleIdx = serverIdx * FACTOR_NUM_TWO + rankInfo.deviceInfo.devicePhyId / DEVICE_PER_MODULE;
502 : }
503 1646 : else if (isDiffDeviceType_)
504 : {
505 0 : moduleIdx = serverIdx * FACTOR_NUM_TWO;
506 : }
507 : else
508 : {
509 1646 : moduleIdx = serverIdx;
510 : }
511 1663 : CHK_PRT_RET(moduleIdx == INVALID_UINT,
512 : HCCL_ERROR("GetModuleIdx failed. moduleIdx:[%d], rankId:[%u]", moduleIdx, rankInfo.rankId), HCCL_E_PARA);
513 1663 : return HCCL_SUCCESS;
514 : }
515 :
516 : // 用于标识集群中是否存在 910B A+X形态
517 531 : bool HcclCommunicatorAttrs::IsDiffDeviceModule(const std::vector<RankInfo_t> &rankList) const
518 : {
519 531 : bool minDevice = false;
520 531 : bool maxDevice = false;
521 531 : bool isDiffMeshAggregation = false;
522 531 : if (!isDiffDeviceType_ && (deviceType_ != DevType::DEV_TYPE_910B || rankList.size() == 0))
523 : {
524 365 : HCCL_INFO("[IsDiffDeviceModule] deviceType_[%d], rankList.size[%u]", deviceType_, rankList.size());
525 365 : return false;
526 : }
527 :
528 983 : for (const RankInfo_t &rankInfo : rankList)
529 : {
530 817 : if (GetRankInfoDevType(rankInfo) == DevType::DEV_TYPE_910B && !isStandardCard_)
531 : {
532 817 : if (rankInfo.deviceInfo.devicePhyId < DEVICE_PER_MODULE)
533 : {
534 809 : minDevice = true;
535 : }
536 : else
537 : {
538 8 : maxDevice = true;
539 : }
540 : }
541 : }
542 166 : if (minDevice && maxDevice)
543 : {
544 3 : isDiffMeshAggregation = true;
545 : }
546 166 : return isDiffMeshAggregation;
547 : }
548 :
549 529 : HcclResult HcclCommunicatorAttrs::InitHccsPortNum()
550 : {
551 : DevType deviceType;
552 529 : CHK_RET(hrtGetDeviceType(deviceType));
553 529 : if (deviceType == DevType::DEV_TYPE_910_93)
554 : {
555 9 : CHK_RET(hrtGetHccsPortNum(deviceLogicId_, hccsPortNum_));
556 : }
557 529 : return HCCL_SUCCESS;
558 : }
559 :
560 493 : HcclResult HcclCommunicatorAttrs::SetRankInfoList(const RankTable_t &rankTable)
561 : {
562 : // 检查rank table入参正确性
563 493 : CHK_RET(CheckRankTable(rankTable, servRankInfo_));
564 : // 获取芯片类型
565 493 : DevType deviceType = DevType::DEV_TYPE_COUNT;
566 493 : CHK_RET(hrtGetDeviceType(deviceType));
567 :
568 : // 遍历rank table获取rank信息
569 493 : rankInfoList_.clear();
570 1176 : for (auto iter = servRankInfo_.begin(); iter != servRankInfo_.end(); ++iter)
571 : {
572 2168 : for (u32 index = 0; index < iter->second.size(); ++index)
573 : {
574 1487 : const RankInfo_t &orgRankInfo = iter->second[index];
575 : // 构建comm 使用的rank 信息
576 1487 : RankInfo rankInfo;
577 1491 : rankInfo.userRank = orgRankInfo.rankId;
578 1491 : rankInfo.worldRank = orgRankInfo.rankId;
579 :
580 1491 : rankInfo.deviceType = GetRankInfoDevType(orgRankInfo);
581 1490 : CHK_RET(CheckDeviceType(rankInfo.deviceType));
582 :
583 1490 : if (rankInfo.deviceType != DevType::DEV_TYPE_910B || rankInfo.deviceType != DevType::DEV_TYPE_910_93)
584 : {
585 : // 910B、910_93形态不做devicePhyId最大值的判断
586 1490 : CHK_RET(CheckDevPhyId(orgRankInfo.deviceInfo.devicePhyId));
587 : }
588 1491 : rankInfo.devicePhyId = orgRankInfo.deviceInfo.devicePhyId;
589 1491 : rankInfo.deviceNicPort = orgRankInfo.deviceInfo.port;
590 1491 : rankInfo.deviceVnicPort = orgRankInfo.deviceInfo.vnicPort;
591 :
592 1491 : rankInfo.serverId = orgRankInfo.serverId;
593 1491 : rankInfo.serverIdx = orgRankInfo.serverIdx;
594 1491 : rankInfo.hostIp = orgRankInfo.hostIp;
595 1490 : rankInfo.hostPort = orgRankInfo.hostPort;
596 1490 : rankInfo.localRank = orgRankInfo.localRank;
597 1490 : rankInfo.superDeviceId = orgRankInfo.superDeviceId;
598 1490 : if (gcdServerNumPerSuperPod_ > 0) {
599 49 : u32 gcdSuperPodIdx = rankInfo.serverIdx / gcdServerNumPerSuperPod_;
600 49 : rankInfo.superPodId = orgRankInfo.superPodId + "_" + std::to_string(gcdSuperPodIdx);
601 49 : rankInfo.superPodIdx = gcdSuperPodIdx;
602 49 : if (userRank_ == rankInfo.userRank) {
603 8 : HCCL_RUN_INFO("[SetRankInfoList] userRank[%u] serverId[%s] serverIdx[%u] original superPodId[%s] "
604 : "superPodIdx[%u] converted superPodId[%s] superPodIdx[%u]",
605 : userRank_, rankInfo.serverId.c_str(), rankInfo.serverIdx, orgRankInfo.superPodId.c_str(),
606 : orgRankInfo.superPodIdx, rankInfo.superPodId.c_str(), rankInfo.superPodIdx);
607 : }
608 : } else {
609 1441 : rankInfo.superPodId = orgRankInfo.superPodId;
610 1438 : rankInfo.superPodIdx = orgRankInfo.superPodIdx;
611 : }
612 1487 : CHK_RET(GetNicInfo(orgRankInfo.deviceInfo.nicDeploy, index, iter->second, rankInfo));
613 1491 : rankInfo.nicIdx.assign(nicList_.begin(), nicList_.end());
614 1490 : rankInfoList_.push_back(rankInfo);
615 1489 : }
616 : }
617 : // 将rank id从小到大的顺序返回
618 496 : CHK_RET(SortRankInfoList());
619 494 : return HCCL_SUCCESS;
620 : }
621 :
622 501 : HcclResult HcclCommunicatorAttrs::CheckRankTable(const RankTable_t &rankTable, const ServRankInfo &servRankInfo)
623 : {
624 : // 检查网卡挂载位置
625 501 : if (CheckNicDeploy(rankTable.nicDeploy, deviceType_) != HCCL_SUCCESS)
626 : {
627 1 : HCCL_ERROR("[Check][RankTable]errNo[0x%016llx] nicDeploy[%d] out of range[%d, %d]",
628 : HCCL_ERROR_CODE(HCCL_E_PARA), rankTable.nicDeploy,
629 : static_cast<int32_t>(NICDeployment::NIC_DEPLOYMENT_HOST),
630 : static_cast<int32_t>(NICDeployment::NIC_DEPLOYMENT_DEVICE));
631 1 : return HCCL_E_PARA;
632 : }
633 :
634 500 : if (Is310PDevice())
635 : {
636 : // 异构场景无需检查server内device个数
637 0 : return HCCL_SUCCESS;
638 : }
639 :
640 499 : if (CheckSuperDeviceId(rankTable) != HCCL_SUCCESS)
641 : {
642 0 : HCCL_ERROR("[Check][RankTable]errNo[0x%016llx] super_device_id is invalid in ranktable, "
643 : "ranktable config value: rankId[%u], superDeviceId[0x%x]",
644 : HCCL_ERROR_CODE(HCCL_E_PARA), userRank_, superDeviceId_);
645 0 : return HCCL_E_PARA;
646 : }
647 :
648 : // 检查服务器上的设备信息
649 499 : ServRankInfo::const_iterator iterBegin = servRankInfo.begin();
650 500 : u32 devNum = 0;
651 500 : CHK_RET(GetDevNum(iterBegin->second, devNum));
652 :
653 497 : bool multiServerDiffDeviceNumMode = false;
654 1183 : for (ServRankInfo::const_iterator iter = iterBegin; iter != servRankInfo.end(); ++iter)
655 : {
656 : // 检测每个服务器内的设备数是否相等,如果不相同即为多server不同卡模式
657 689 : u32 curServerDevNum = 0;
658 689 : CHK_RET(GetDevNum(iter->second, curServerDevNum));
659 686 : if (devNum != curServerDevNum)
660 : {
661 17 : HCCL_WARNING("[Check][RankTable] devnum isn't same,(serverA:[%s],serverB:[%s])"
662 : "devNum(%u, %u)",
663 : iterBegin->first.c_str(), iter->first.c_str(), devNum, curServerDevNum);
664 17 : multiServerDiffDeviceNumMode = true;
665 : }
666 : }
667 :
668 : // 非多server不同卡模式下,判断实际设备数目和userRank_table中的记录一致
669 501 : if (multiServerDiffDeviceNumMode == false && rankTable.deviceNum != devNum * servRankInfo.size())
670 : {
671 2 : HCCL_WARNING("[Check][RankTable]errNo[0x%016llx] devnum isn't same, number in rankTable:[%u], actual:[%llu]",
672 : HCCL_ERROR_CODE(HCCL_E_PARA), rankTable.deviceNum, devNum * servRankInfo.size());
673 2 : return HCCL_E_PARA;
674 : }
675 :
676 : // 910模组:服务器内设备的数目必须是2的次幂,在此check(非模组形态无此限制不check)
677 : // 910B、910_93模组形态未定,服务器内设备的数目校验规则后续补充
678 655 : if (pairLinkInfo_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)].size() > 0 && devNum > HCCL_DEVICE_NUM_TWO &&
679 157 : (deviceType_ != DevType::DEV_TYPE_910B && deviceType_ != DevType::DEV_TYPE_910_93 && !Is310P3Common()))
680 : {
681 30 : CHK_PRT_RET(CheckDevCount(devNum) != HCCL_SUCCESS,
682 : HCCL_ERROR("[Check][RankTable]errNo[0x%016llx] devnum is invalid in server.",
683 : HCCL_ERROR_CODE(HCCL_E_PARA)),
684 : HCCL_E_PARA);
685 : }
686 495 : return HCCL_SUCCESS;
687 : }
688 :
689 1491 : HcclResult HcclCommunicatorAttrs::CheckDevPhyId(const s32 &devicePhyId) const
690 : {
691 1491 : if (devicePhyId > COMM_MAX_DEVICE_ID && devicePhyId != HOST_DEVICE_ID)
692 : {
693 0 : HCCL_ERROR("[Check][DevPhyId]errNo[0x%016llx] devicePhyId[%d] out of range[-1, %d]",
694 : HCCL_ERROR_CODE(HCCL_E_PARA), devicePhyId, COMM_MAX_DEVICE_ID);
695 0 : return HCCL_E_PARA;
696 : }
697 1491 : return HCCL_SUCCESS;
698 : }
699 :
700 496 : HcclResult HcclCommunicatorAttrs::SortRankInfoList()
701 : {
702 : // 按rank id从小到大的顺序返回
703 496 : std::sort(rankInfoList_.begin(), rankInfoList_.end(), CompareWithUserRank);
704 :
705 1981 : for (u32 index = 0; index < rankInfoList_.size(); ++index)
706 : {
707 1487 : CHK_PRT_RET((index != rankInfoList_[index].userRank),
708 : HCCL_ERROR("[HcclCommunicatorAttrs][SortRankInfoList]errNo[0x%016llx] index[%u] != rankInfoList.userRank[%u]",
709 : HCCL_ERROR_CODE(HCCL_E_PARA), index, rankInfoList_[index].userRank),
710 : HCCL_E_PARA);
711 : }
712 494 : return HCCL_SUCCESS;
713 : }
714 :
715 501 : HcclResult HcclCommunicatorAttrs::CheckNicDeploy(NICDeployment nicDeploy, DevType deviceType) const
716 : {
717 : (void)deviceType;
718 501 : if (nicDeploy >= NICDeployment::NIC_DEPLOYMENT_RESERVED)
719 : {
720 1 : HCCL_ERROR("[Check][NicDeploy]errNo[0x%016llx] nicDeploy[%u] out of range[%d, %d]",
721 : HCCL_ERROR_CODE(HCCL_E_PARA), nicDeploy,
722 : static_cast<int32_t>(NICDeployment::NIC_DEPLOYMENT_HOST),
723 : static_cast<int32_t>(NICDeployment::NIC_DEPLOYMENT_DEVICE));
724 1 : return HCCL_E_PARA;
725 : }
726 500 : return HCCL_SUCCESS;
727 : }
728 :
729 32 : HcclResult HcclCommunicatorAttrs::CheckDevCount(const u32 devNum)
730 : {
731 32 : if (devNum > HCCL_AISERVER_DEVICE_NUM)
732 : {
733 1 : HCCL_ERROR("[Check][DevCount]errNo[0x%016llx] devNum[%u] out of range[%u, %u]", HCCL_ERROR_CODE(HCCL_E_PARA),
734 : devNum, 0, HCCL_AISERVER_DEVICE_NUM);
735 1 : return HCCL_E_PARA;
736 : }
737 : // 其他拓扑算法设备数目: 1 server: 1, 2, 4, 8
738 : // n server: 1*n, 2*n, 4*n, 8*n
739 31 : if (!Check2N(devNum))
740 : {
741 14 : RPT_ENV_ERR(true,
742 : "EI0014",
743 : std::vector<std::string>({ "value", "variable" ,"expect" }),
744 : std::vector<std::string>({std::to_string(devNum), "devNum", "to be 1, 2 or 4, or a multiple of 8"}));
745 1 : HCCL_ERROR("[%s][%s]errNo[0x%016llx] devNum[%u] devNum must be divisible by 8, or equal to 1, 2 or 4",
746 : LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(),
747 : HCCL_ERROR_CODE(HCCL_E_PARA), devNum);
748 1 : return HCCL_E_PARA;
749 : }
750 30 : return HCCL_SUCCESS;
751 2 : }
752 :
753 32 : bool HcclCommunicatorAttrs::Check2N(u32 num) const
754 : {
755 32 : if (num < 1)
756 : {
757 0 : return false;
758 : }
759 : else
760 : {
761 32 : return ((num & (num - 1)) == 0);
762 : }
763 : }
764 :
765 494 : HcclResult HcclCommunicatorAttrs::SetLocalRankInfo()
766 : {
767 802 : for (u32 i = 0; i < rankInfoList_.size(); i++)
768 : {
769 801 : HCCL_DEBUG(" host ip: %s host port: %u dev phy id: %d.", rankInfoList_[i].hostIp.GetReadableAddress(),
770 : rankInfoList_[i].hostPort, rankInfoList_[i].devicePhyId);
771 803 : if (rankInfoList_[i].userRank == userRank_)
772 : {
773 495 : devicePhyId_ = rankInfoList_[i].devicePhyId;
774 495 : devIpAddr_ = rankInfoList_[i].nicIp;
775 495 : devBackupIpAddr_ = rankInfoList_[i].backupNicIp;
776 495 : devBackupPort_ = rankInfoList_[i].backupDevicePort;
777 495 : hostIp_ = rankInfoList_[i].hostIp;
778 495 : hostPort_ = rankInfoList_[i].hostPort;
779 495 : localRank_ = rankInfoList_[i].localRank;
780 495 : HCCL_DEBUG("localRank_[%u].", localRank_);
781 495 : break;
782 : }
783 : }
784 : // 在确定 servRankInfo_ 和 serverId_ 信息后,就完成初始判断
785 495 : HCCL_DEBUG("[HcclCommunicatorAttrs][Init]deviceType[%u].", deviceType_);
786 495 : if (static_cast<s32>(devicePhyId_) == HOST_DEVICE_ID)
787 : {
788 0 : HCCL_ERROR("[HcclCommunicatorAttrs][Init]not support cpu rank");
789 0 : return HCCL_E_NOT_SUPPORT;
790 : }
791 : else
792 : {
793 495 : HCCL_DEBUG("[HcclCommunicatorAttrs][Init]devicePhyId[%u] != HOST_DEVICE_ID", devicePhyId_);
794 495 : CHK_RET(hrtGetDevice(&deviceLogicId_));
795 : }
796 495 : return HCCL_SUCCESS;
797 : }
798 :
799 33 : HcclResult HcclCommunicatorAttrs::SetLocalRankInfoSubGroup(const std::vector<RankInfo> &rankList)
800 : {
801 33 : rankInfoList_.assign(rankList.begin(), rankList.end());
802 33 : for (u32 i = 0; i < rankInfoList_.size(); i++)
803 : {
804 33 : if (rankInfoList_[i].userRank == userRank_)
805 : {
806 33 : devIpAddr_ = rankInfoList_[i].nicIp;
807 33 : devBackupIpAddr_ = rankInfoList_[i].backupNicIp;
808 33 : devBackupPort_ = rankInfoList_[i].backupDevicePort;
809 33 : devicePhyId_ = rankInfoList_[i].devicePhyId;
810 33 : superPodId_ = rankInfoList_[i].superPodId;
811 33 : superDeviceId_ = rankInfoList_[i].superDeviceId;
812 33 : hostIp_ = rankInfoList_[i].hostIp;
813 33 : hostPort_ = rankInfoList_[i].hostPort;
814 33 : nicList_.assign(rankInfoList_[i].nicIdx.begin(), rankInfoList_[i].nicIdx.end());
815 33 : nicDeployment_ = rankInfoList_[i].nicDeploy;
816 33 : break;
817 : }
818 : }
819 33 : return HCCL_SUCCESS;
820 : }
821 :
822 521 : HcclResult HcclCommunicatorAttrs::CheckLocalRankInfo()
823 : {
824 2147 : for (u32 i = 0; i < rankInfoList_.size(); ++i)
825 : {
826 1626 : if (userRank_ == rankInfoList_[i].userRank)
827 : {
828 521 : CHK_PRT_RET(static_cast<s32>(devicePhyId_) != rankInfoList_[i].devicePhyId,
829 : HCCL_ERROR("[Init][Para]errNo[0x%016llx] parameter check failed, "
830 : "userrank[%u] == rankInfoList.userrank[%u], phyid[%d] != rankInfoList.devid[%d]",
831 : HCCL_ERROR_CODE(HCCL_E_PARA), userRank_, rankInfoList_[i].userRank,
832 : static_cast<s32>(devicePhyId_), rankInfoList_[i].devicePhyId),
833 : HCCL_E_PARA);
834 : }
835 : }
836 521 : return HCCL_SUCCESS;
837 : }
838 :
839 91 : u32 HcclCommunicatorAttrs::CalMeshAggRankSize(int halfDevNum) const
840 : {
841 91 : u32 size = INVALID_VALUE_RANKSIZE;
842 182 : for (auto iter = servRankInfo_.begin(); iter != servRankInfo_.end(); ++iter)
843 : {
844 91 : u32 aggregationRankSize0 = 0;
845 91 : u32 aggregationRankSize1 = 0;
846 462 : for (u32 index = 0; index < iter->second.size(); ++index)
847 : {
848 371 : const RankInfo_t &orgRankInfo = iter->second[index];
849 371 : if (orgRankInfo.deviceInfo.devicePhyId < halfDevNum)
850 : {
851 275 : aggregationRankSize0++;
852 : }
853 : else
854 : {
855 96 : aggregationRankSize1++;
856 : }
857 : }
858 91 : u32 tmpsize = INVALID_VALUE_RANKSIZE;
859 91 : if ((aggregationRankSize0 != 0) && (aggregationRankSize1 != 0))
860 : {
861 24 : tmpsize = aggregationRankSize0;
862 : }
863 : else
864 : {
865 67 : tmpsize = iter->second.size();
866 : }
867 91 : size = size > tmpsize ? tmpsize : size;
868 : }
869 91 : return size;
870 : }
871 :
872 521 : HcclResult HcclCommunicatorAttrs::SetMeshAggregationRankSize(u32 size)
873 : {
874 521 : HCCL_INFO("[Set][HcclCommunicatorAttrs][MeshAggregationRankSize]set MeshAggregationRankSize[%u].", size);
875 521 : meshAggregationRankSize_ = size;
876 521 : return HCCL_SUCCESS;
877 : }
878 :
879 521 : HcclResult HcclCommunicatorAttrs::CalAndSetMeshAggRankSize()
880 : {
881 521 : u32 size = INVALID_VALUE_RANKSIZE;
882 521 : if ((deviceType_ == DevType::DEV_TYPE_910B) && isDiffDeviceModule_)
883 : { // 910B 16p场景
884 0 : size = CalMeshAggRankSize(HCCL_DEVICE_NUM_EIGHT);
885 : }
886 521 : else if (deviceType_ == DevType::DEV_TYPE_910)
887 : {
888 321 : if (pairLinkInfo_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)].size() == 0)
889 : { // 标卡
890 230 : size = 1;
891 : }
892 : else
893 : { // 模组
894 91 : size = CalMeshAggRankSize(HCCL_DEVICE_NUM_FOUR);
895 : }
896 : }
897 : else
898 : { // 910B的8卡、310P 直接返回server内的size数量
899 200 : size = servRankInfo_.begin()->second.size();
900 : }
901 521 : CHK_RET(SetMeshAggregationRankSize(size));
902 521 : return HCCL_SUCCESS;
903 : }
904 :
905 34 : HcclResult HcclCommunicatorAttrs::SetWorldGroupInfo(
906 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>> &phyIdNicInfoMap,
907 : std::vector<RankInfo> &worldRankInfoList, std::vector<u32> &nicRanksPort, std::vector<u32> &vnicRanksPort)
908 : {
909 34 : for (auto &ipInfo : phyIdNicInfoMap)
910 : {
911 0 : for (auto &devInfo : ipInfo.second)
912 : {
913 0 : rankDevicePhyIdNicInfoMap_[ipInfo.first][devInfo.first] = devInfo.second;
914 0 : HCCL_DEBUG("phyIdNicInfoMap print hostIp[%s] devId[%u] devIp[%s]",
915 : ipInfo.first.c_str(), devInfo.first, devInfo.second.GetReadableAddress());
916 : }
917 : }
918 :
919 34 : for (auto &rankInfo : worldRankInfoList)
920 : {
921 0 : worldRankInfoList_.push_back(rankInfo);
922 : }
923 :
924 34 : for (auto &port : nicRanksPort)
925 : {
926 0 : nicRanksPort_.push_back(port);
927 0 : HCCL_DEBUG("nicRanksPort port[%u]", port);
928 : }
929 35 : for (auto &port : vnicRanksPort)
930 : {
931 1 : vnicRanksPort_.push_back(port);
932 1 : HCCL_DEBUG("vnicRanksPort port[%u]", port);
933 : }
934 34 : return HCCL_SUCCESS;
935 : }
936 :
937 33 : HcclResult HcclCommunicatorAttrs::TransformRankList(
938 : const std::vector<RankInfo> &rankListIn, std::vector<RankInfo_t> &rankListOut)
939 : {
940 190 : for (size_t index = 0; index < rankListIn.size(); ++index)
941 : {
942 157 : RankInfo_t rankInfoTmp;
943 157 : rankInfoTmp.serverId = rankListIn[index].serverId;
944 157 : rankInfoTmp.deviceInfo.devicePhyId = rankListIn[index].devicePhyId;
945 157 : rankInfoTmp.deviceInfo.deviceType = rankListIn[index].deviceType;
946 157 : rankInfoTmp.serverIdx = rankListIn[index].serverIdx;
947 157 : rankInfoTmp.rankId = rankListIn[index].userRank;
948 157 : rankInfoTmp.hostIp = rankListIn[index].hostIp;
949 157 : rankInfoTmp.hostPort = rankListIn[index].hostPort;
950 157 : rankInfoTmp.localRank = rankListIn[index].localRank;
951 157 : rankInfoTmp.superDeviceId = rankListIn[index].superDeviceId;
952 157 : rankInfoTmp.superPodId = rankListIn[index].superPodId;
953 157 : rankInfoTmp.superPodIdx = rankListIn[index].superPodIdx;
954 157 : rankListOut.push_back(rankInfoTmp);
955 157 : }
956 33 : return HCCL_SUCCESS;
957 : }
958 :
959 722 : bool HcclCommunicatorAttrs::IsEnableRoce()
960 : {
961 : // 910B单机两种使能roce场景:1、a+x同时使用两module 2.标卡
962 722 : bool roceSwitch = IsSupportEnableRoce();
963 722 : bool isInterServerVnic = false;
964 : // 910_93超节点内节点间走HCCS通信 && Vnic建链, 不需要使能NIC
965 722 : if (useSuperPodMode_ && superPodNum_ == 1 && GetExternalInputInterHccsDisable() == false)
966 : {
967 0 : isInterServerVnic = true;
968 : }
969 722 : bool ret = (interServer_ && !isInterServerVnic) || roceSwitch;
970 722 : HCCL_INFO("IsEnableRoce ret: %d, interServer_: %d, isInterServerVnic: %d, roceSwitch: %d, "
971 : "isSingleMeshAggregation_: %u",
972 : ret, interServer_, isInterServerVnic, roceSwitch, isSingleMeshAggregation_);
973 722 : return ret;
974 : }
975 :
976 : // a+x mesh间需要同时保证ip有效和roce开关打开才能走rdma
977 6 : bool HcclCommunicatorAttrs::IsUsedRdmaLevel0AndIpInvalid()
978 : {
979 6 : u32 nicNum = devIpAddr_.size();
980 6 : bool ipInvalid = true;
981 12 : for (u32 i = 0; i < nicNum; i++)
982 : {
983 6 : if (devIpAddr_[i].IsInvalid())
984 : {
985 0 : HCCL_INFO("[Init][Nic]nic num[%u] deviceip is invalid, total nicNum[%u]", i, nicNum);
986 0 : ipInvalid = false;
987 0 : continue;
988 : }
989 : }
990 : // 机间卡数不一致场景下,IP有效情况下就走RDMA
991 : // 机间卡数一致场景下,需环境变量ROCE打开(多机环境下未对IsEnableRoce开关进行控制)且IP有效情况下走RDMA
992 6 : return ((GetExternalInputIntraRoceSwitch() != 0 || multiModuleDiffDeviceNumMode_ || isDiffDeviceType_) && ipInvalid);
993 : }
994 :
995 722 : bool HcclCommunicatorAttrs::IsSupportEnableRoce()
996 : {
997 : // 910B单机两种使能roce场景:1、a+x同时使用两module 2.标卡
998 722 : bool roceSwitch = false;
999 722 : HCCL_INFO("[HcclCommunicator]IsSupportEnableRoce");
1000 722 : if (isDiffDeviceType_)
1001 : {
1002 0 : roceSwitch = true;
1003 : }
1004 722 : else if (deviceType_ == DevType::DEV_TYPE_910B)
1005 : {
1006 672 : roceSwitch = ((GetExternalInputIntraRoceSwitch() != 0) && (!isSingleMeshAggregation_ || isStandardCard_)) ||
1007 336 : multiModuleDiffDeviceNumMode_;
1008 : }
1009 386 : else if (deviceType_ == DevType::DEV_TYPE_910_93)
1010 : {
1011 480 : roceSwitch = multiSuperPodDiffServerNumMode_ ||
1012 240 : (multiModuleDiffDeviceNumMode_ && superPodNum_ > 1);
1013 : }
1014 : else
1015 : { // 其他单机场景为了防止用户误用roce开关
1016 146 : roceSwitch = isStandardCard_ ? GetExternalInputIntraRoceSwitch() : false;
1017 : }
1018 722 : return roceSwitch;
1019 : }
1020 :
1021 1275 : void HcclCommunicatorAttrs::GetTopoAttr(HcclTopoAttr &topoAttr)
1022 : {
1023 1275 : topoAttr.serverNum = serverNum_;
1024 1275 : topoAttr.superPodNum = superPodNum_;
1025 1275 : topoAttr.moduleNum = moduleNum_;
1026 1275 : topoAttr.deviceNumPerServer = deviceNumPerServer_;
1027 1275 : topoAttr.deviceNumPerAggregation = deviceNumPerAggregation_;
1028 1275 : topoAttr.multiModuleDiffDeviceNumMode = multiModuleDiffDeviceNumMode_;
1029 1275 : topoAttr.multiSuperPodDiffServerNumMode = multiSuperPodDiffServerNumMode_;
1030 1275 : topoAttr.multiSuperPodDiffDeviceNumMode = multiSuperPodDiffDeviceNumMode_;
1031 1275 : topoAttr.meshAggregationRankSize = meshAggregationRankSize_;
1032 1275 : topoAttr.isDiffDeviceModule = isDiffDeviceModule_;
1033 1275 : topoAttr.isDiffDeviceType = isDiffDeviceType_;
1034 1275 : topoAttr.gcdDeviceNumPerAggregation = gcdDeviceNumPerAggregation_;
1035 1275 : topoAttr.isSingleMeshAggregation = isSingleMeshAggregation_;
1036 1275 : topoAttr.isAllRankSamePlane = isAllRankSamePlane_;
1037 1275 : topoAttr.userRank = userRank_;
1038 1275 : topoAttr.realUserRank = realUserRank_;
1039 1275 : topoAttr.userRankSize = userRankSize_;
1040 1275 : topoAttr.devicePhyId = devicePhyId_;
1041 1275 : topoAttr.useSuperPodMode = useSuperPodMode_;
1042 1275 : topoAttr.deviceLogicId = deviceLogicId_;
1043 1275 : topoAttr.deviceType = deviceType_;
1044 1275 : topoAttr.isStandardCard = isStandardCard_;
1045 1275 : topoAttr.is310PDuoCard = is310PDuoCard_;
1046 1275 : topoAttr.isCommon310P3DUO = isCommon310P3DUO_;
1047 1275 : topoAttr.hccsPortNum = hccsPortNum_;
1048 1275 : topoAttr.nicList = nicList_;
1049 1275 : topoAttr.pairLinkCounter = pairLinkCounter_;
1050 1275 : topoAttr.pairLinkInfo = pairLinkInfo_;
1051 1275 : topoAttr.rankInfoList = rankInfoList_;
1052 1275 : topoAttr.isSupportRdmaLite = isSupportRdmaLite_;
1053 1275 : topoAttr.isSupportHccsAndSio = isSupportHccsAndSio_;
1054 1275 : topoAttr.localNicPort = GetLocalNicPort(NicType::DEVICE_NIC_TYPE);
1055 1275 : topoAttr.isNeedInitNic = isNeedInitNic_;
1056 1275 : topoAttr.isARSDoubleRing = isARSDoubleRing_;
1057 1275 : }
1058 :
1059 521 : void HcclCommunicatorAttrs::GetAlgoAttr(HcclAlgoAttr &algoAttr)
1060 : {
1061 521 : algoAttr.isHaveCpuRank = isHaveCpuRank_;
1062 521 : algoAttr.inlineReduceSwitchOn = inlineReduceSwitchOn_;
1063 521 : algoAttr.isUsedRdmaLevel0 = isUsedRdmaLevel0_;
1064 521 : HCCL_INFO("[CollectAlgoAttr]:isUsedRdmaLevel0:[%d]", isUsedRdmaLevel0_);
1065 521 : algoAttr.isUsedInterHccsMode = isUsedInterHccsMode_;
1066 521 : algoAttr.identifier = identifier_;
1067 521 : algoAttr.collectiveId = collectiveId_;
1068 521 : algoAttr.nicDeployment = nicDeployment_;
1069 521 : algoAttr.commWorkMode = commWorkMode_;
1070 521 : algoAttr.commAlgoConfig = algoConfigMap_;
1071 521 : }
1072 :
1073 1275 : u32 HcclCommunicatorAttrs::GetLocalNicPort(NicType nicType)
1074 : {
1075 1275 : if (nicDeployment_ == NICDeployment::NIC_DEPLOYMENT_HOST)
1076 : {
1077 0 : return GetHostPort(devicePhyId_);
1078 : }
1079 : // isUseRankPort_在ranksPort初始化时一同配置:1. 异构场景 2. 开启device侧端口配置
1080 : // groupRanksPort_为空说明此时处于全局通信域,要从ranksPort_取监听端口;否则取groupRanksPort_
1081 1275 : if (nicType == NicType::HOST_NIC_TYPE)
1082 : {
1083 0 : return GetHostPort(devicePhyId_);
1084 : }
1085 1275 : if (nicType == NicType::VNIC_TYPE && GetExternalInputNpuPortSwitch())
1086 : {
1087 : // vnic ports仅在开启device侧端口配置时单独配置
1088 0 : std::vector<u32> &ranksPorts = groupVnicRanksPort_.empty() ? vnicRanksPort_ : groupVnicRanksPort_;
1089 0 : return GetNicPort(devicePhyId_, ranksPorts, userRank_, isUseRankPort_);
1090 : }
1091 : else
1092 : {
1093 : // 1. 开启device侧端口配置时的nic port时使用ranksPorts
1094 : // 2. 异构场景使用ranksPorts
1095 : // 3. 其余场景场景isUseRankPort_应当为false,使用默认port
1096 1275 : std::vector<u32> &ranksPorts = groupNicRanksPort_.empty() ? nicRanksPort_ : groupNicRanksPort_;
1097 1275 : return GetNicPort(devicePhyId_, ranksPorts, userRank_, isUseRankPort_);
1098 : }
1099 : }
1100 : }
|