LCOV - code coverage report
Current view: top level - coll_communicator_mgr/rank_graph/rank_graph - rank_graph.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.9 % 542 482
Test Date: 2026-08-25 19:18:03 Functions: 100.0 % 49 49

            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
        

Generated by: LCOV version 2.0-1