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 <unordered_map>
12 : #include "virtual_topo.h"
13 : #include "string_util.h"
14 : #include "binary_stream.h"
15 : #include "exception_util.h"
16 : #include "topo_common_types.h"
17 : #include "null_ptr_exception.h"
18 : #include "internal_exception.h"
19 : #include "not_support_exception.h"
20 : #include "rank_gph.h"
21 :
22 : namespace Hccl {
23 :
24 : using namespace std;
25 :
26 718 : void RankGraph::AddPeer(const shared_ptr<NetInstance::Peer>& peer)
27 : {
28 718 : if (!initFlag_) {
29 717 : if (peer == nullptr) {
30 1 : THROW<NullPtrException>("[RankGraph][AddPeer] peer is nullptr.");
31 : }
32 :
33 716 : RankId rankId = peer->GetRankId();
34 716 : peers_[rankId] = peer;
35 : } else {
36 1 : THROW<InternalException>("RankGraph AddPeer fail, rankGraph has been initialized, please check.");
37 : }
38 716 : }
39 :
40 299 : void RankGraph::AddNetInstance(const shared_ptr<NetInstance>& netInst)
41 : {
42 299 : if (netInst == nullptr) {
43 2 : THROW<NullPtrException>(StringFormat("[RankGraph][AddNetInstance] netInst is nullptr"));
44 : }
45 298 : if (!initFlag_) {
46 : // 外部调用保证netInst非空
47 : // 处理添加的netInst中的rank在virtualTopo中没有的情况
48 766 : for (const auto rankId : netInst->GetRankIds()) {
49 470 : if (!HasRank(rankId)) {
50 1 : THROW<InvalidParamsException>(
51 3 : StringFormat("[RankGraph][AddNetInstance] Non-innerRank[%d] exists netInst.", rankId));
52 : }
53 297 : }
54 :
55 : // 添加netInst, 若重复添加打印日志
56 296 : auto res = netInsts_[netInst->GetNetLayer()].emplace(netInst->GetNetInstId(), netInst);
57 296 : if (!res.second) {
58 0 : HCCL_WARNING(
59 : "[RankGraph][AddNetInstance] netLayer[%u] netInstId[%s] is existed.", netInst->GetNetLayer(),
60 : netInst->GetNetInstId().c_str());
61 : }
62 : } else {
63 1 : THROW<InternalException>("RankGraph AddNetInstance fail, rankGraph has been initialized, please check.");
64 : }
65 296 : }
66 :
67 208 : void RankGraph::InitInnerRanks()
68 : {
69 : // 只支持在创建好InnerGroup之后调用, 否则抛异
70 208 : auto innerInstance = GetNetInstanceByRankId(0, myRank_);
71 208 : if (innerInstance == nullptr) {
72 1 : THROW<NullPtrException>(
73 3 : StringFormat("[RankGraph][SetInnerRanks] myRank[%d] netLayer[0] netInst is not existed.", myRank_));
74 : }
75 :
76 207 : innerRanks_ = innerInstance->GetRankIds();
77 207 : }
78 :
79 31 : void RankGraph::InitFinish() { initFlag_ = true; }
80 :
81 2222 : bool RankGraph::HasRank(RankId rankId) const
82 : {
83 2222 : if (peers_.find(rankId) == peers_.end()) {
84 6 : HCCL_DEBUG("[RankGraph][HasRank] rankId[%d] is not existed", rankId);
85 6 : return false;
86 : }
87 2216 : return true;
88 : }
89 :
90 553 : u32 RankGraph::GetRankSize() const { return peers_.size(); }
91 :
92 7 : u32 RankGraph::GetInnerRankSize() const { return innerRanks_.size(); }
93 :
94 45 : RankId RankGraph::GetMyRank() const { return myRank_; }
95 :
96 572 : LocalId RankGraph::GetLocalId(RankId rankId) const
97 : {
98 572 : if (!HasRank(rankId)) {
99 0 : THROW<InvalidParamsException>(StringFormat("[RankGraph][GetLocalId] rankId[%d] is not existed.", rankId));
100 : }
101 :
102 572 : return peers_.at(rankId)->GetLocalId();
103 : }
104 :
105 10 : LocalId RankGraph::GetReplacedLocalId(RankId rankId) const
106 : {
107 10 : if (!HasRank(rankId)) {
108 0 : THROW<InvalidParamsException>(StringFormat("[RankGraph][GetLocalId] rankId[%d] is not existed.", rankId));
109 : }
110 :
111 10 : return peers_.at(rankId)->GetReplacedLocalId();
112 : }
113 :
114 98 : set<u32> RankGraph::GetLevels(RankId rankId) const
115 : {
116 98 : if (!HasRank(rankId)) {
117 0 : THROW<InvalidParamsException>(StringFormat("[RankGraph][GetLevels] rankId[%d] is not existed.", rankId));
118 : }
119 :
120 98 : return peers_.at(rankId)->GetLevels();
121 : }
122 :
123 3 : u32 RankGraph::GetLevelNum() const
124 : {
125 3 : u32 validLevelNum{0};
126 27 : for (const auto& netInst : netInsts_) {
127 24 : if (!netInst.empty()) {
128 5 : validLevelNum++;
129 : }
130 : }
131 5 : HCCL_INFO("[RankGraph][%s] validLevelNum[%u]", __func__, validLevelNum);
132 3 : return validLevelNum;
133 : }
134 :
135 8 : const NetInstance* RankGraph::GetNetInstanceByNetInstId(u32 netLayer, const string& netInstId) const
136 : {
137 : // 不存在netInst, 则返回空
138 8 : if (netLayer >= netInsts_.size() || netInsts_.at(netLayer).count(netInstId) == 0) {
139 3 : HCCL_WARNING(
140 : "[RankGraph][GetNetInstance] NetInstance netLayer[%u] netInstId[%s] is not existed.", netLayer,
141 : netInstId.c_str());
142 3 : return nullptr;
143 : }
144 5 : return netInsts_.at(netLayer).at(netInstId).get();
145 : }
146 :
147 7 : NetInstance* RankGraph::GetNetInstanceByNetInstId(u32 netLayer, const std::string& netInstId)
148 : {
149 : // 不存在netInst, 则返回空
150 7 : if (netLayer >= netInsts_.size() || netInsts_.at(netLayer).count(netInstId) == 0) {
151 3 : HCCL_WARNING(
152 : "[RankGraph][GetNetInstance] NetInstance netLayer[%u] netInstId[%s] is not existed.", netLayer,
153 : netInstId.c_str());
154 3 : return nullptr;
155 : }
156 4 : return netInsts_.at(netLayer).at(netInstId).get();
157 : }
158 :
159 167 : const NetInstance* RankGraph::GetNetInstanceByRankId(u32 netLayer, RankId rankId) const
160 : {
161 : // 不存在netInst, 则返回空
162 167 : if (!HasRank(rankId)) {
163 1 : HCCL_WARNING(
164 : "[RankGraph][GetNetInstance] NetInstance rankId[%d] netLayer[%u] is not existed.", rankId, netLayer);
165 1 : return nullptr;
166 : }
167 166 : return peers_.at(rankId)->GetNetInstance(netLayer);
168 : }
169 :
170 328 : NetInstance* RankGraph::GetNetInstanceByRankId(u32 netLayer, RankId rankId)
171 : {
172 328 : if (!HasRank(rankId)) {
173 1 : HCCL_WARNING(
174 : "[RankGraph][GetNetInstance] NetInstance rankId[%d] netLayer[%u] is not existed.", rankId, netLayer);
175 1 : return nullptr;
176 : }
177 327 : const NetInstance* constInstance = peers_.at(rankId)->GetNetInstance(netLayer);
178 327 : if (constInstance == nullptr) {
179 0 : THROW<NullPtrException>(StringFormat("[RankGraph][GetGroup]GetNetInstance(rankId, netLayer) is nullptr"));
180 : }
181 327 : string netInstId = constInstance->GetNetInstId();
182 327 : return netInsts_.at(netLayer).at(netInstId).get();
183 327 : }
184 :
185 569 : const shared_ptr<NetInstance::Peer> RankGraph::GetPeer(RankId rankId) const
186 : {
187 569 : if (!HasRank(rankId)) {
188 2 : HCCL_WARNING("[RankGraph][GetPeer] rankId[%d] is not existed.", rankId);
189 2 : return nullptr;
190 : }
191 :
192 567 : return peers_.at(rankId);
193 : }
194 :
195 1890 : vector<NetInstance::Path> RankGraph::GetPaths(u32 netLayer, RankId sRankId, RankId dRankId) const
196 : {
197 : // 若sRank和dRank均不在innerGroup里,则返回空
198 1890 : if (innerRanks_.count(sRankId) == 0 && innerRanks_.count(dRankId) == 0) {
199 5430 : HCCL_WARNING("[RankGraph][GetPaths] sRankId[%d] and dRankId[%d] are not in innerRanks", sRankId, dRankId);
200 1810 : return {};
201 : }
202 :
203 80 : vector<NetInstance::Path> paths;
204 80 : auto netInst = GetNetInstanceByRankId(netLayer, sRankId);
205 80 : if (netInst == nullptr) {
206 52 : HCCL_WARNING("[RankGraph][GetPaths] netLayer[%u] sRankId[%d] netInst is not existed.", netLayer, sRankId);
207 18 : return {};
208 : }
209 62 : if (!netInst->HasNode(NetInstance::Peer::GenerateNodeId(dRankId))) {
210 1 : HCCL_WARNING(
211 : "[RankGraph][GetPaths] netLayer[%u] sRankId[%d] netInst has no dRankId[%d].", netLayer, sRankId, dRankId);
212 1 : return {};
213 : }
214 :
215 61 : paths = netInst->GetPaths(sRankId, dRankId);
216 61 : if (paths.size() == 0) {
217 12 : HCCL_WARNING(
218 : "[RankGraph][GetPaths] netLayer[%u] sRankId[%d] dRankId[%d] netInst has no path.", netLayer, sRankId,
219 : dRankId);
220 4 : return paths;
221 : }
222 :
223 149 : HCCL_DEBUG(
224 : "[RankGraph][GetPaths] netLayer[%u] sRankId[%d] dRankId[%d] pathsize[%u].", netLayer, sRankId, dRankId,
225 : paths.size());
226 57 : return paths;
227 80 : }
228 :
229 3 : u32 RankGraph::GetLayerRanks(const u32 netLayer) const
230 : {
231 3 : u32 layerRankSize = 0;
232 3 : if (netInsts_.at(netLayer).size() == 0) {
233 0 : HCCL_WARNING("[RankGraph][GetLayerRanks] RankGraph has no netInstance on netLayer %u", netLayer);
234 0 : return 0;
235 : }
236 8 : for (const auto& netInst : netInsts_.at(netLayer)) {
237 5 : layerRankSize += netInst.second->GetRankSize();
238 : }
239 3 : return layerRankSize;
240 : }
241 :
242 6 : void RankGraph::GetLocalInstRanks(const u32 netLayer, vector<u32>& rankList, u32& rankNum) const
243 : {
244 6 : const NetInstance* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
245 6 : if (netInstance == nullptr) {
246 1 : THROW<NullPtrException>(
247 3 : StringFormat("[RankGraph][GetLocalInstRanks] myRank %u has no netInstance on layer %u", myRank_, netLayer));
248 : }
249 5 : set<RankId> rankSet = netInstance->GetRankIds();
250 5 : rankList.clear();
251 15 : for (const RankId& rank : rankSet) {
252 10 : rankList.push_back(static_cast<u32>(rank));
253 : }
254 5 : rankNum = rankSet.size();
255 5 : }
256 :
257 7 : u32 RankGraph::GetLocalInstSize(const u32 netLayer) const
258 : {
259 7 : const NetInstance* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
260 7 : if (netInstance == nullptr) {
261 0 : THROW<NullPtrException>(
262 0 : StringFormat("[RankGraph][GetLocalInstSize] myRank %u has no netInstance on layer %u", myRank_, netLayer));
263 : }
264 7 : return netInstance->GetRankSize();
265 : }
266 :
267 26 : const NetType RankGraph::GetNetType(const u32 netLayer) const
268 : {
269 26 : const NetInstance* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
270 26 : if (netInstance == nullptr) {
271 4 : THROW<NullPtrException>(
272 8 : StringFormat("[RankGraph][GetLocalInstSize] myRank %u has no netInstance on layer %u", myRank_, netLayer));
273 : }
274 22 : return netInstance->GetNetType();
275 : }
276 :
277 6 : HcclResult RankGraph::GetNetInstanceList(const u32 netLayer, vector<u32>& instSizeList, u32& listSize) const
278 : {
279 6 : instSizeList.clear();
280 6 : listSize = 0;
281 6 : if (netInsts_.at(netLayer).size() == 0) {
282 3 : HCCL_WARNING("[RankGraph][GetNetInstanceList] RankGraph has no net instance on layer %u", netLayer);
283 1 : return HCCL_E_PARA;
284 : }
285 12 : for (const auto& netInst : netInsts_.at(netLayer)) {
286 7 : instSizeList.push_back(netInst.second->GetRankSize());
287 : }
288 5 : listSize = instSizeList.size();
289 5 : return HCCL_SUCCESS;
290 : }
291 :
292 2 : void RankGraph::GetTopoInstsByLayer(const u32 netLayer, std::vector<u32>& topoInsts, u32& topoInstNum) const
293 : {
294 2 : auto* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
295 2 : netInstance->GetTopoInstsByLayer(topoInsts, topoInstNum);
296 2 : }
297 :
298 3 : HcclResult RankGraph::GetTopoType(const u32 netLayer, const u32 topoInstId, TopoType& topoType) const
299 : {
300 3 : auto* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
301 3 : CHK_PRT_RET(
302 : netInstance == nullptr,
303 : HCCL_ERROR(
304 : "[RankGraph::GetTopoType] netInstance is nullptr, myRank[%d], netLayer[%u], "
305 : "topoInstId[%u]",
306 : myRank_, netLayer, topoInstId),
307 : HCCL_E_PTR);
308 :
309 3 : auto ret = netInstance->GetTopoType(topoInstId, topoType);
310 3 : CHK_PRT_RET(
311 : ret != HCCL_SUCCESS,
312 : HCCL_ERROR(
313 : "[%s] Failed to GetTopoType, myRank[%d], netLayer[%u], netInstId[%s], topoInstId[%u], "
314 : "ret[%d]",
315 : __func__, myRank_, netLayer, netInstance->GetNetInstId().c_str(), topoInstId, ret),
316 : ret);
317 2 : return HCCL_SUCCESS;
318 : }
319 :
320 : HcclResult
321 3 : RankGraph::GetRanksByTopoInst(const u32 netLayer, const u32 topoInstId, std::vector<u32>& ranks, u32& rankNum) const
322 : {
323 3 : auto* netInstance = GetNetInstanceByRankId(netLayer, myRank_);
324 3 : CHK_PRT_RET(
325 : netInstance == nullptr,
326 : HCCL_ERROR(
327 : "[RankGraph::GetRanksByTopoInst] netInstance is nullptr, myRank[%d], netLayer[%u], "
328 : "topoInstId[%u]",
329 : myRank_, netLayer, topoInstId),
330 : HCCL_E_PTR);
331 :
332 3 : auto ret = netInstance->GetRanksByTopoInst(topoInstId, ranks, rankNum);
333 3 : CHK_PRT_RET(
334 : ret != HCCL_SUCCESS,
335 : HCCL_ERROR(
336 : "[%s] Failed to GetRanksByTopoInst, myRank[%d], netLayer[%u], netInstId[%s], "
337 : "topoInstId[%u], ret[%d]",
338 : __func__, myRank_, netLayer, netInstance->GetNetInstId().c_str(), topoInstId, ret),
339 : ret);
340 2 : return HCCL_SUCCESS;
341 : }
342 :
343 8 : HcclResult RankGraph::GetEndpointNum(uint32_t layer, uint32_t topoInstId, uint32_t* num) const
344 : {
345 8 : auto peer = GetPeer(myRank_);
346 8 : if (peer == nullptr) {
347 1 : HCCL_ERROR("[RankGraph::GetEndpointNum] Peer is nullptr at netLayer [%u]", layer);
348 1 : return HCCL_E_PTR;
349 : }
350 7 : auto ifacesVec = peer->GetIfacesByLayer(layer);
351 7 : uint32_t sum = 0;
352 20 : for (auto& iface : ifacesVec) {
353 13 : if (iface->GetTopoInstId() == topoInstId) {
354 11 : sum += iface->GetLinkProtocols().size();
355 : }
356 : }
357 7 : *num = sum;
358 7 : return HCCL_SUCCESS;
359 8 : }
360 :
361 126 : HcclResult GetCommAddr(CommAddr& commAddr, const IpAddress& ipAddr)
362 : {
363 126 : s32 family = ipAddr.GetFamily();
364 126 : if (family == AF_INET) {
365 102 : string addr = ipAddr.GetIpStr();
366 102 : if (ipAddr.IsEID(addr)) {
367 0 : commAddr.type = COMM_ADDR_TYPE_EID;
368 0 : const auto& eid = ipAddr.GetEid();
369 0 : for (u32 i = 0; i < URMA_EID_LEN && i < sizeof(commAddr.eid); i++) {
370 0 : commAddr.eid[i] = eid.raw[i];
371 : }
372 : } else {
373 102 : commAddr.type = COMM_ADDR_TYPE_IP_V4;
374 102 : commAddr.addr = ipAddr.GetBinaryAddress().addr;
375 : }
376 126 : } else if (family == AF_INET6) {
377 24 : commAddr.type = COMM_ADDR_TYPE_IP_V6;
378 24 : commAddr.addr6 = ipAddr.GetBinaryAddress().addr6;
379 : } else {
380 0 : HCCL_ERROR("invalid commAddrType");
381 0 : return HCCL_E_INTERNAL;
382 : }
383 126 : return HCCL_SUCCESS;
384 : }
385 :
386 104 : EndpointLocType AddrPositionToEndpointLoc(AddrPosition pos)
387 : {
388 104 : switch (pos) {
389 5 : case AddrPosition::HOST:
390 5 : return ENDPOINT_LOC_TYPE_HOST;
391 99 : case AddrPosition::DEVICE:
392 99 : return ENDPOINT_LOC_TYPE_DEVICE;
393 0 : default:
394 0 : return ENDPOINT_LOC_TYPE_RESERVED;
395 : }
396 : }
397 :
398 : HcclResult
399 8 : RankGraph::GetEndpointDesc(uint32_t layer, uint32_t topoInstId, uint32_t* descNum, EndpointDesc* endpointDesc) const
400 : {
401 8 : auto peer = GetPeer(myRank_);
402 8 : CHK_PTR_NULL(peer);
403 :
404 7 : auto ifacesVec = peer->GetIfacesByLayer(layer);
405 7 : uint32_t count = 0;
406 :
407 : // 找到 topoInstId 匹配的 iface
408 19 : for (const auto& iface : ifacesVec) {
409 12 : if (iface->GetTopoInstId() != topoInstId) {
410 2 : continue;
411 : }
412 :
413 : // 对该 iface,从 endpointToIfaceMap_ 中找出所有匹配的 EndpointDesc
414 : // 一个 iface 可能对应多个 protocol(即多个 EndpointDesc)
415 10 : const auto& endpointMap = peer->GetEndpointToIfaceMap();
416 30 : for (const auto& entry : endpointMap) {
417 20 : const EndpointKey& endpoint = entry.first;
418 20 : const std::shared_ptr<NetInstance::ConnInterface>& mappedIface = entry.second;
419 :
420 20 : if (mappedIface != iface || endpoint.netLayer != layer || endpoint.topoInstId != topoInstId) {
421 12 : continue;
422 : }
423 :
424 : // 检查输出缓冲区是否足够
425 8 : if (count >= *descNum) {
426 0 : HCCL_ERROR(
427 : "[RankGraph::GetEndpointDesc] endpointDesc array too small: "
428 : "need %u, given %u",
429 : count + 1, *descNum);
430 0 : return HCCL_E_PARA;
431 : }
432 :
433 8 : CHK_RET(static_cast<HcclResult>(EndpointDescInit(&endpointDesc[count], 1)));
434 8 : endpointDesc[count].commAddr = endpoint.commAddr;
435 8 : endpointDesc[count].protocol = endpoint.protocol;
436 8 : endpointDesc[count].loc.locType = AddrPositionToEndpointLoc(iface->GetPos());
437 8 : CHK_RET(SetEndpointTopoInfo(endpointDesc[count], layer, topoInstId));
438 :
439 20 : HCCL_INFO(
440 : "[RankGraph::GetEndpointDesc] local type is %d, protocol %d", endpointDesc[count].loc.locType,
441 : endpointDesc[count].protocol);
442 8 : count++;
443 : }
444 : }
445 :
446 7 : *descNum = count;
447 7 : return HCCL_SUCCESS;
448 8 : }
449 :
450 6 : HcclResult RankGraph::GetEndpointInfo(
451 : uint32_t rankId, const EndpointDesc* endpointDesc, EndpointAttr endpointAttr, uint32_t infoLen, void* info) const
452 : {
453 6 : if (endpointDesc == nullptr || info == nullptr) {
454 3 : HCCL_ERROR("[GetEndpointInfo] Invalid parameter");
455 1 : return HCCL_E_PTR;
456 : }
457 5 : const std::shared_ptr<NetInstance::Peer> peer = GetPeer(rankId);
458 5 : if (peer == nullptr) {
459 0 : HCCL_ERROR("[RankGraph::GetEndpointInfo] Peer is nullptr for rankId [%u]", rankId);
460 0 : return HCCL_E_PTR;
461 : }
462 :
463 : // 查找接口
464 5 : const auto& endpointToIfaceMap = peer->GetEndpointToIfaceMap();
465 5 : u32 endpointNetLayer = UINT32_MAX;
466 5 : u32 endpointTopoInstId = UINT32_MAX;
467 5 : const bool hasTopoInfo = GetEndpointTopoInfo(*endpointDesc, endpointNetLayer, endpointTopoInstId);
468 : // 旧描述符未携带拓扑定位信息时仅允许唯一匹配,避免跨层静默选错接口。
469 5 : std::shared_ptr<NetInstance::ConnInterface> iface;
470 16 : for (const auto& entry : endpointToIfaceMap) {
471 12 : const EndpointKey& key = entry.first;
472 12 : if (!(key.commAddr == endpointDesc->commAddr) || key.protocol != endpointDesc->protocol) {
473 4 : continue;
474 : }
475 8 : if (hasTopoInfo && (key.netLayer != endpointNetLayer || key.topoInstId != endpointTopoInstId)) {
476 2 : continue;
477 : }
478 6 : if (iface != nullptr && iface != entry.second) {
479 1 : HCCL_ERROR(
480 : "[GetEndpointInfo] Ambiguous endpoint, netLayer[%u], topoInstId[%u], protocol[%d]", endpointNetLayer,
481 : endpointTopoInstId, endpointDesc->protocol);
482 1 : return HCCL_E_PARA;
483 : }
484 5 : iface = entry.second;
485 : }
486 4 : if (iface == nullptr) {
487 0 : HCCL_ERROR("[GetEndpointInfo] No matching interface found");
488 0 : return HCCL_E_NOT_FOUND;
489 : }
490 : // 填充信息
491 4 : switch (endpointAttr) {
492 4 : case ENDPOINT_ATTR_BW_COEFF: {
493 4 : if (infoLen != sizeof(EndpointAttrBwCoeff)) {
494 0 : HCCL_ERROR(
495 : "[GetEndpointInfo] Size mismatch: expected %zu, actual %u", sizeof(EndpointAttrBwCoeff), infoLen);
496 0 : return HCCL_E_PARA;
497 : }
498 4 : *(static_cast<EndpointAttrBwCoeff*>(info)) = iface->GetPorts().size();
499 4 : break;
500 : }
501 0 : case ENDPOINT_ATTR_DIE_ID: {
502 0 : if (infoLen != sizeof(EndpointAttrDieId)) {
503 0 : HCCL_ERROR(
504 : "[GetEndpointInfo] Size mismatch: expected %zu, actual %u", sizeof(EndpointAttrDieId), infoLen);
505 0 : return HCCL_E_PARA;
506 : }
507 0 : *(static_cast<EndpointAttrDieId*>(info)) = iface->GetLocalDieId();
508 0 : HCCL_INFO("GetEndpointInfo rankId[%u] iface[%s]", rankId, iface->Describe().c_str());
509 0 : break;
510 : }
511 0 : case ENDPOINT_ATTR_LOCATION: {
512 0 : if (infoLen != sizeof(EndpointAttrLocation)) {
513 0 : HCCL_ERROR(
514 : "[GetEndpointInfo] Size mismatch: expected %zu, actual %u", sizeof(EndpointAttrLocation), infoLen);
515 0 : return HCCL_E_PARA;
516 : }
517 0 : *(static_cast<EndpointAttrLocation*>(info)) = iface->GetPos();
518 0 : break;
519 : }
520 0 : default: {
521 0 : HCCL_ERROR("[GetEndpointInfo] Invalid endpointAttr [%d]", endpointAttr);
522 0 : return HCCL_E_PARA;
523 : }
524 : }
525 4 : return HCCL_SUCCESS;
526 5 : }
527 :
528 4 : bool RankGraph::IsSymmetric(const u32 netLayer) const
529 : {
530 4 : if (netInsts_.at(netLayer).size() == 0) {
531 1 : THROW<NullPtrException>(
532 3 : StringFormat("[RankGraph][IsSymmetric] RankGraph no netInstance on net layer %u", netLayer));
533 : }
534 3 : std::unordered_set<u32> rankSize;
535 8 : for (const auto& netInst : netInsts_.at(netLayer)) {
536 5 : rankSize.insert(netInst.second->GetRankSize());
537 : }
538 6 : return rankSize.size() == 1;
539 3 : }
540 :
541 130 : std::shared_ptr<NetInstance> GetOrCreateNetInstance(
542 : u32 netLayer, const string& netInstId, NetType type, Level2Id2NetInst& netInsts, RankGraph* rankGraph)
543 : {
544 130 : std::shared_ptr<NetInstance> netInstance;
545 :
546 : // 若netLayer和netInstId对应netInstance没创建则创建
547 130 : if (netInsts[netLayer].count(netInstId) == 0) {
548 48 : if (type == NetType::TOPO_FILE_DESC) {
549 26 : netInstance = std::make_shared<InnerNetInstance>(netLayer, netInstId);
550 22 : } else if (type == NetType::CLOS) {
551 22 : netInstance = std::make_shared<ClosNetInstance>(netLayer, netInstId);
552 : }
553 48 : netInsts[netLayer][netInstId] = netInstance;
554 : // netInstance添加到virtualTopo
555 48 : rankGraph->AddNetInstance(netInstance);
556 :
557 98 : HCCL_DEBUG(
558 : "[CreateNetInstance] create netInstance success, netLayer[%u] netInstId[%s] type[%s].", netLayer,
559 : netInstId.c_str(), type.Describe().c_str());
560 : } else {
561 : // 若netInstance存在, type不一致则报错
562 82 : NetType curType = netInsts[netLayer][netInstId]->GetNetType();
563 82 : if (curType != type) {
564 0 : HCCL_WARNING(
565 : "[CreateNetInstance]FabType [%s] and [%s] no match", curType.Describe().c_str(),
566 : type.Describe().c_str());
567 0 : return nullptr;
568 : }
569 : // 若netInstance存在, type一致则直接获取
570 82 : netInstance = netInsts[netLayer][netInstId];
571 : }
572 130 : return netInstance;
573 130 : }
574 :
575 56 : void GetNewNodeInfo(
576 : u32 layer, RankId newRankId, const NetInstance::Link& oldLink, shared_ptr<NetInstance>& newNetInstance,
577 : RankId2PeerMap& tmpPeers, shared_ptr<NetInstance::Node>& newNode, shared_ptr<NetInstance::ConnInterface>& newIface,
578 : bool isSource)
579 : {
580 56 : shared_ptr<NetInstance::Node> oldNode;
581 56 : shared_ptr<NetInstance::ConnInterface> oldIface;
582 56 : if (isSource) {
583 28 : oldNode = oldLink.GetSourceNode();
584 28 : oldIface = oldLink.GetSourceIface();
585 : } else {
586 28 : oldNode = oldLink.GetTargetNode();
587 28 : oldIface = oldLink.GetTargetIface();
588 : }
589 :
590 56 : NetInstance::Node::NodeType type = oldNode->GetType();
591 56 : if (type == NetInstance::Node::NodeType::PEER) {
592 32 : newIface = oldIface;
593 32 : newNode = tmpPeers.at(newRankId);
594 32 : tmpPeers.at(newRankId)->AddConnInterface(layer, newIface);
595 24 : } else if (type == NetInstance::Node::NodeType::FABRIC) {
596 24 : newIface = nullptr;
597 24 : newNode = oldNode;
598 24 : if (!newNetInstance->HasNode(newNode->GetNodeId())) {
599 1 : newNetInstance->AddNode(newNode);
600 : }
601 : } else {
602 0 : THROW<NotSupportException>(StringFormat(
603 : "[CreateSubNetInstances][GetNewNodeInfo] newRankId[%d] oldLink Node isSource[%d] type[%s] "
604 : "is not supported.",
605 0 : newRankId, isSource, type.Describe().c_str()));
606 : }
607 56 : }
608 :
609 33 : bool NeedUpdateTopoInstForSubGraph(const NetInstance* oldNetInstance, u32 topoInstId, RankId parentMyRank)
610 : {
611 33 : auto topoInstIter = oldNetInstance->topoInsts_.find(topoInstId);
612 33 : if (topoInstIter == oldNetInstance->topoInsts_.end()) {
613 0 : HCCL_DEBUG(
614 : "[SubRankGraph][NeedUpdateTopoInstForSubGraph] skip topoInstId[%u], parentMyRank[%d], "
615 : "not found in parent netInstId[%s]",
616 : topoInstId, parentMyRank, oldNetInstance->GetNetInstId().c_str());
617 0 : return false;
618 : }
619 33 : if (topoInstIter->second == nullptr) {
620 1 : HCCL_WARNING(
621 : "[SubRankGraph][NeedUpdateTopoInstForSubGraph] skip topoInstId[%u], parentMyRank[%u], "
622 : "topoInst is null in parent netInstId[%s]",
623 : topoInstId, parentMyRank, oldNetInstance->GetNetInstId().c_str());
624 1 : return false;
625 : }
626 32 : return topoInstIter->second->ranks.count(parentMyRank) > 0;
627 : }
628 :
629 28 : void AddNewLink(
630 : u32 layer, const NetInstance::Link& oldLink, RankId srcNewRankId, RankId dstNewRankId,
631 : shared_ptr<NetInstance>& newNetInstance, RankId2PeerMap& tmpPeers, const NetInstance* oldNetInstance,
632 : RankId parentMyRank)
633 : {
634 : // 不添加绕路link
635 28 : if (oldLink.GetHop() > 1 && oldLink.GetType() != LinkType::PEER2NET) {
636 0 : return;
637 : }
638 :
639 28 : shared_ptr<NetInstance::ConnInterface> newSourceIface;
640 28 : shared_ptr<NetInstance::ConnInterface> newTargetIface;
641 28 : shared_ptr<NetInstance::Node> newSourceNode;
642 28 : shared_ptr<NetInstance::Node> newTargetNode;
643 : // oldLink有fabicNode需要先addFabricNode
644 : // SourceNode
645 28 : GetNewNodeInfo(layer, srcNewRankId, oldLink, newNetInstance, tmpPeers, newSourceNode, newSourceIface, true);
646 : // TargetNode
647 28 : GetNewNodeInfo(layer, dstNewRankId, oldLink, newNetInstance, tmpPeers, newTargetNode, newTargetIface, false);
648 : // link
649 : shared_ptr<NetInstance::Link> link = make_shared<NetInstance::Link>(
650 56 : newSourceNode, newTargetNode, newSourceIface, newTargetIface, oldLink.GetType(), oldLink.GetLinkProtocols(),
651 56 : oldLink.GetLinkDirection(), oldLink.GetHop());
652 :
653 28 : newNetInstance->AddLink(link);
654 28 : if (newSourceIface != nullptr) {
655 16 : u32 sourceTopoInstId = newSourceIface->GetTopoInstId();
656 16 : TopoType sourceTopoType = newSourceIface->GetTopoType();
657 16 : if (NeedUpdateTopoInstForSubGraph(oldNetInstance, sourceTopoInstId, parentMyRank)) {
658 14 : newNetInstance->UpdateTopoInst(sourceTopoInstId, sourceTopoType, srcNewRankId);
659 : }
660 : }
661 28 : if (newTargetIface != nullptr) {
662 16 : u32 targetTopoInstId = newTargetIface->GetTopoInstId();
663 16 : TopoType targetTopoType = newTargetIface->GetTopoType();
664 16 : if (NeedUpdateTopoInstForSubGraph(oldNetInstance, targetTopoInstId, parentMyRank)) {
665 14 : newNetInstance->UpdateTopoInst(targetTopoInstId, targetTopoType, dstNewRankId);
666 : }
667 : }
668 :
669 83 : for (const auto& pair : newNetInstance->topoInsts_) {
670 55 : uint32_t topoInstId = pair.first;
671 55 : if (pair.second == nullptr) {
672 0 : THROW<NullPtrException>(
673 0 : StringFormat("[SubRankGraph][AddNewLink] topoInstId %u has no TopoInst", topoInstId));
674 : }
675 55 : auto topoType = pair.second->topoType;
676 55 : if (UNLIKELY(HcclCheckLogLevel(DLOG_DEBUG))) {
677 55 : HCCL_DEBUG("[SubRankGraph] topoInstId[%u] topoType[%d]", topoInstId, topoType);
678 : }
679 : }
680 28 : HCCL_DEBUG(
681 : "[RankGraph][AddNewLink] srcNewRankId[%d] dstNewRankId[%d] newLink[%s]", srcNewRankId, dstNewRankId,
682 : link->Describe().c_str());
683 28 : }
684 :
685 5 : void AddGroupLinks(
686 : const vector<RankId>& rankIds, const NetInstance* oldNetInstance, shared_ptr<NetInstance>& newNetInstance,
687 : RankId2PeerMap& tmpPeers, RankId parentMyRank)
688 : {
689 5 : set<RankId> newRankIds = newNetInstance->GetRankIds();
690 5 : u32 layer = newNetInstance->GetNetLayer();
691 5 : if (oldNetInstance == nullptr) {
692 0 : THROW<NullPtrException>(StringFormat("[AddGroupLinks]oldNetInstance is nullptr"));
693 : }
694 5 : if (newRankIds.size() == 1) {
695 : // 子通信域单卡场景直接返回1DMESH
696 4 : RankId singleId = *newRankIds.begin();
697 4 : newNetInstance->UpdateTopoInst(0, TopoType::MESH_1D, singleId);
698 4 : return;
699 : }
700 5 : for (RankId srcRankId : newRankIds) {
701 20 : for (RankId dstRankId : newRankIds) {
702 16 : if (srcRankId == dstRankId) {
703 4 : continue;
704 : }
705 : // 对oldNetInstance中的每一条Link, 创建新的Link添加到newNetInstance
706 12 : vector<NetInstance::Path> oldPaths = oldNetInstance->GetPaths(rankIds[srcRankId], rankIds[dstRankId]);
707 28 : for (auto& oldPath : oldPaths) {
708 44 : for (auto& oldLink : oldPath.links) {
709 28 : AddNewLink(
710 : layer, oldLink, srcRankId, dstRankId, newNetInstance, tmpPeers, oldNetInstance, parentMyRank);
711 : }
712 : }
713 12 : }
714 : }
715 5 : }
716 :
717 3 : void RankGraph::AddSubPeers(const std::vector<RankId>& rankIds, RankGraph* subRankGraph, RankId2PeerMap& peers) const
718 : {
719 : // 遍历rankIds将索引作为子虚拟拓扑的rankId构造subPeer并添加到subRankGraph
720 3 : s32 rankSize = rankIds.size();
721 9 : for (RankId subRankId = 0; subRankId < rankSize; ++subRankId) {
722 6 : RankId rankId = rankIds[subRankId];
723 6 : shared_ptr<NetInstance::Peer> oldPeer = GetPeer(rankId);
724 6 : LocalId localId = oldPeer->GetLocalId();
725 6 : LocalId replacedLocalId = oldPeer->GetReplacedLocalId();
726 6 : DeviceId deviceId = oldPeer->GetDeviceId();
727 6 : u32 devicePort = oldPeer->GetDevicePort();
728 6 : u32 hostPort = oldPeer->GetHostPort();
729 : shared_ptr<NetInstance::Peer> subPeer
730 6 : = make_shared<NetInstance::Peer>(subRankId, localId, replacedLocalId, deviceId, devicePort, hostPort);
731 6 : subRankGraph->AddPeer(subPeer);
732 6 : peers.emplace(subRankId, subPeer);
733 6 : const auto& oldEndpointMap = oldPeer->GetEndpointToIfaceMap();
734 6 : for (const auto& entry : oldEndpointMap) {
735 0 : subPeer->SetEndpointToIface(
736 0 : entry.first.netLayer, entry.first.topoInstId, entry.first.commAddr, entry.first.protocol, entry.second);
737 0 : HCCL_DEBUG(
738 : "[SubRankGraph][AddSubPeers] endpointToIfaceMap: protocol[%d] for subRankId[%d]", entry.first.protocol,
739 : subRankId);
740 : }
741 6 : HCCL_DEBUG(
742 : "[RankGraph][AddSubPeers] oldRankId[%d] subPeer[%s] add success.", rankId, subPeer->Describe().c_str());
743 6 : }
744 3 : }
745 :
746 3 : RankId GetSubRankId(const vector<RankId>& rankIds, RankId rank)
747 : {
748 : RankId subRank;
749 :
750 : // rankIds中查找rank, 数组索引即为subMyRank
751 3 : auto iter = find(begin(rankIds), end(rankIds), rank);
752 3 : if (iter != end(rankIds)) {
753 3 : subRank = distance(begin(rankIds), iter);
754 : } else {
755 0 : THROW<InvalidParamsException>(StringFormat("[RankGraph][CreateSubVirtTopo] rankIds has no rank[%d].", rank));
756 : }
757 :
758 3 : HCCL_DEBUG("[GetSubRank] rank[%d] subRank[%d].", rank, subRank);
759 3 : return subRank;
760 : }
761 :
762 : /**
763 : * 1. 创建子NetInstance
764 : * 2. peer添加对应netInstance
765 : */
766 3 : void RankGraph::CreateSubNetInstances(
767 : const std::vector<RankId> rankIds, Level2Id2NetInst& subNetInstances, RankId2PeerMap& peers,
768 : RankGraph* subRankGraph) const
769 : {
770 : // 遍历rankIds, 获取每个rankId所在的oldNetInstance, 创建subNetInstance
771 3 : RankId rankSize = rankIds.size();
772 9 : for (RankId subRankId = 0; subRankId < rankSize; ++subRankId) {
773 6 : set<u32> curLevels = GetLevels(rankIds[subRankId]);
774 14 : for (u32 netLayer : curLevels) {
775 8 : const NetInstance* oldNetInstance = GetNetInstanceByRankId(netLayer, rankIds[subRankId]);
776 8 : if (oldNetInstance == nullptr) {
777 0 : THROW<NullPtrException>(StringFormat("[RankGraph][CreateSubNetInstances] oldNetInstance is nullptr"));
778 : }
779 : // 创建subNetInstance (根据oldNetInstance.netLayer,id,type)
780 8 : NetType netType = oldNetInstance->GetNetType();
781 8 : string netInstId = oldNetInstance->GetNetInstId();
782 : shared_ptr<NetInstance> subNetInstance
783 8 : = GetOrCreateNetInstance(netLayer, netInstId, netType, subNetInstances, subRankGraph);
784 8 : if (subNetInstance == nullptr) {
785 0 : THROW<NullPtrException>(StringFormat("[RankGraph][CreateSubNetInstances] subNetInstance is nullptr"));
786 : }
787 :
788 : // subNetInstance Add RankId and subPeer
789 8 : shared_ptr<NetInstance::Peer> subPeer = peers.at(subRankId);
790 8 : subNetInstance->AddRankId(subRankId);
791 8 : subNetInstance->AddNode(subPeer);
792 :
793 : // subPeer Add subNetInstance
794 8 : subPeer->AddNetInstance(subNetInstance);
795 8 : HCCL_DEBUG(
796 : "[RankGraph][CreateSubNetInstances] subNetInstance subRankId[%d] subType[%s] subNetInstId[%s]",
797 : subRankId, netType.Describe().c_str(), netInstId.c_str());
798 8 : }
799 6 : }
800 3 : }
801 :
802 3 : void RankGraph::AddSubLinks(
803 : const std::vector<RankId>& rankIds, RankId2PeerMap& peers, Level2Id2NetInst& subNetInsts, RankId parentMyRank) const
804 : {
805 : // 遍历subNetInstances,对每一个NetInstance插入Links
806 27 : for (u32 netLayer = 0; netLayer < subNetInsts.size(); ++netLayer) {
807 29 : for (auto& curNetInstance : subNetInsts[netLayer]) {
808 5 : const NetInstance* oldNetInstance = GetNetInstanceByNetInstId(netLayer, curNetInstance.first);
809 5 : AddGroupLinks(rankIds, oldNetInstance, curNetInstance.second, peers, parentMyRank);
810 : }
811 : }
812 3 : }
813 :
814 3 : unique_ptr<RankGraph> RankGraph::CreateSubRankGraph(const std::vector<u32>& rankIds) const
815 : {
816 : // 参数类型转换
817 3 : vector<RankId> subRankIds;
818 3 : for_each(rankIds.begin(), rankIds.end(), [&](u32 rankId) {
819 6 : subRankIds.emplace_back(static_cast<RankId>(rankId));
820 6 : });
821 :
822 : // 参数检查, 若rankIds中存在当前virtualTopo不存在的rankId, 抛异
823 9 : for (const auto rankId : subRankIds) {
824 6 : if (!HasRank(rankId)) {
825 0 : THROW<InvalidParamsException>(
826 0 : StringFormat("[RankGraph][CreateSubVirtTopo] rankId[%d] is not existed.", rankId));
827 : }
828 : }
829 :
830 : // step1: 创建subRankGraph
831 3 : RankId subMyRankId = GetSubRankId(subRankIds, myRank_);
832 3 : unique_ptr<RankGraph> subRankGraph = make_unique<RankGraph>(subMyRankId);
833 :
834 : // step2: subRankGraph添加subPeers
835 3 : RankId2PeerMap peers; // 保存Peer指针以便后续执行Add操作
836 3 : AddSubPeers(subRankIds, subRankGraph.get(), peers);
837 :
838 : // step3: 构造subNetInstances, NetInstance添加RankId和Peer, Peer添加NetInstance
839 3 : Level2Id2NetInst subNetInstances(MAX_NET_LAYER); // 保存NetInstance指针以便后续执行Add操作
840 3 : CreateSubNetInstances(subRankIds, subNetInstances, peers, subRankGraph.get());
841 :
842 : // step4: subNetInstances添加Links, Peer添加ConnIfaces
843 3 : AddSubLinks(subRankIds, peers, subNetInstances, myRank_);
844 :
845 : // step5: 设置innerRanks
846 3 : subRankGraph->InitInnerRanks();
847 : // step6: 构造完成
848 3 : subRankGraph->InitFinish();
849 :
850 3 : HCCL_INFO("[subRankGraph] Build success!");
851 3 : subRankGraph->Dump();
852 3 : return subRankGraph;
853 3 : }
854 :
855 5 : std::vector<char> RankGraph::GetPackedData(const std::vector<std::pair<u32, RankId>>& netLayerRankPairs) const
856 : {
857 5 : std::vector<u32> numVec;
858 5 : std::vector<LinkData> links;
859 5 : u32 netLayerRankPairsNum = netLayerRankPairs.size();
860 :
861 15 : HCCL_DEBUG("netLayerRankPairs Num=%u", netLayerRankPairsNum);
862 :
863 9 : for (const auto& it : netLayerRankPairs) {
864 4 : auto paths = GetPaths(it.first, myRank_, it.second);
865 4 : numVec.push_back(paths.size());
866 12 : HCCL_DEBUG("RankGraph::GetPackedData: netLayer=%u, srcRank=%u, dstRank=%u", it.first, myRank_, it.second);
867 6 : for (const auto& path : paths) {
868 2 : links.emplace_back(path);
869 6 : HCCL_DEBUG("RankGraph::GetPackedData: %s", links.back().Describe().c_str());
870 : }
871 4 : }
872 5 : if (links.empty()) {
873 12 : HCCL_WARNING("[RankGraph][GetPackedData]connected links is empty");
874 : }
875 :
876 5 : std::vector<char> result;
877 5 : BinaryStream binaryStream;
878 5 : u32 linkSize = links.size();
879 5 : binaryStream << netLayerRankPairsNum;
880 5 : binaryStream << linkSize;
881 15 : HCCL_DEBUG("netLayerRankPairsNum=%u, linkSize=%u", netLayerRankPairsNum, linkSize);
882 5 : u32 idx = 0;
883 9 : for (const auto& it : netLayerRankPairs) {
884 4 : binaryStream << it.first;
885 4 : binaryStream << it.second;
886 4 : binaryStream << numVec[idx];
887 12 : HCCL_DEBUG("netLayer=%u, RankId=%u, num=%u", it.first, it.second, numVec[idx]);
888 4 : idx++;
889 : }
890 :
891 7 : for (const auto& link : links) {
892 2 : binaryStream << link.GetUniqueId();
893 : }
894 5 : binaryStream.Dump(result);
895 :
896 5 : return result;
897 5 : }
898 :
899 78 : string RankIds2Str(const set<RankId>& rankIds)
900 : {
901 78 : stringstream ranks;
902 276 : for (auto it = rankIds.begin(); it != rankIds.end(); ++it) {
903 198 : if (it != rankIds.begin()) {
904 122 : ranks << ", ";
905 : }
906 198 : ranks << *it;
907 : }
908 156 : return ranks.str();
909 78 : }
910 :
911 29 : void RankGraph::Dump() const
912 : {
913 59 : HCCL_DEBUG("RankGraph Dump:");
914 59 : HCCL_DEBUG("myRank: %d", myRank_);
915 59 : HCCL_DEBUG("innerRanks: [%s]", RankIds2Str(innerRanks_).c_str());
916 59 : HCCL_DEBUG("peers:");
917 99 : for (const auto& peer : peers_) {
918 158 : HCCL_DEBUG("%s", peer.second->Describe().c_str());
919 : }
920 59 : HCCL_DEBUG("netInsts:");
921 261 : for (uint32_t i = 0; i < netInsts_.size(); ++i) {
922 281 : for (auto& netInst : netInsts_[i]) {
923 99 : HCCL_DEBUG("[netLayer=%u, netInstId=%s]", i, netInst.first.c_str());
924 99 : HCCL_DEBUG("%s", netInst.second->Describe().c_str());
925 99 : HCCL_DEBUG("rankIds: [%s]", RankIds2Str(netInst.second->GetRankIds()).c_str());
926 99 : HCCL_DEBUG("peers:");
927 180 : for (const auto& peerMapIt : netInst.second->GetPeers()) {
928 299 : HCCL_DEBUG("%s", peerMapIt.second->Describe().c_str());
929 : }
930 99 : HCCL_DEBUG("fabrics:");
931 106 : for (const auto& fabric : netInst.second->GetFabrics()) {
932 137 : HCCL_DEBUG("%s", fabric->Describe().c_str());
933 : }
934 49 : set<NodeId> nodeIds{};
935 99 : HCCL_DEBUG("Graph Nodes:");
936 49 : netInst.second->GetGraph().TraverseNode([&](shared_ptr<NetInstance::Node> node) {
937 188 : nodeIds.insert(node->GetNodeId());
938 436 : HCCL_DEBUG("%s", node->Describe().c_str());
939 188 : });
940 99 : HCCL_DEBUG("Graph Links:");
941 237 : for (NodeId nodeId : nodeIds) {
942 188 : netInst.second->GetGraph().TraverseEdge(nodeId, [&](shared_ptr<NetInstance::Link> link) {
943 926 : HCCL_DEBUG("%s", link->Describe().c_str());
944 374 : });
945 : }
946 49 : }
947 : }
948 29 : }
949 112 : CommProtocol LinkProtocolToCommProtocol(const LinkProtocol& linkProtocol)
950 : {
951 112 : constexpr std::pair<LinkProtocol, CommProtocol> protocolPairs[]
952 : = {{LinkProtocol::UB_CTP, COMM_PROTOCOL_UB_CTP}, {LinkProtocol::UB_TP, COMM_PROTOCOL_UBC_TP},
953 : {LinkProtocol::ROCE, COMM_PROTOCOL_ROCE}, {LinkProtocol::HCCS, COMM_PROTOCOL_HCCS},
954 : {LinkProtocol::PCIE, COMM_PROTOCOL_PCIE}, {LinkProtocol::UB_MEM, COMM_PROTOCOL_UB_MEM},
955 : {LinkProtocol::UBOE, COMM_PROTOCOL_UBOE}, {LinkProtocol::UB_RTP, COMM_PROTOCOL_UB_RTP}};
956 :
957 160 : for (const auto& p : protocolPairs) {
958 160 : if (p.first == linkProtocol) {
959 112 : return p.second;
960 : }
961 : }
962 :
963 0 : return COMM_PROTOCOL_RESERVED;
964 : }
965 : } // namespace Hccl
|