LCOV - code coverage report
Current view: top level - coll_communicator_mgr/rank_graph/rank_graph_builder - rank_graph_builder.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.7 % 393 329
Test Date: 2026-08-18 17:47:01 Functions: 92.3 % 26 24

            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 <algorithm>
      12              : #include <array>
      13              : #include "rank_graph_builder.h"
      14              : #include "detour_service.h"
      15              : #include "json_parser.h"
      16              : #include "phy_topo_builder.h"
      17              : 
      18              : namespace Hccl {
      19              : 
      20              : using namespace std;
      21              : 
      22           14 : unique_ptr<RankGraph> RankGraphBuilder::Build(const string& ranktableM, const string& topoPath, RankId myRank)
      23              : {
      24           14 :     PhyTopoBuilder::GetInstance().Build(topoPath);
      25           14 :     topoInfo_ = PhyTopoBuilder::GetInstance().GetTopoInfo();
      26              : 
      27              :     JsonParser rankTableParser;
      28           14 :     RankTableInfo rankTableInfo;
      29           14 :     rankTableParser.ParseString(ranktableM, rankTableInfo);
      30           14 :     rankTable_ = make_unique<RankTableInfo>(rankTableInfo);
      31              : 
      32           14 :     this->myRank_ = myRank;
      33           14 :     BuildRankGraph();
      34              : 
      35           42 :     HCCL_INFO("[RankGraphBuilder] Build VirtualTopo success!");
      36           14 :     rankGraph_->Dump();
      37           28 :     return std::move(rankGraph_);
      38           14 : }
      39              : 
      40            1 : unique_ptr<RankGraph> RankGraphBuilder::Build(const RankTableInfo& ranktable, const string& topoPath, RankId myRank)
      41              : {
      42            1 :     PhyTopoBuilder::GetInstance().Build(topoPath);
      43            1 :     topoInfo_ = PhyTopoBuilder::GetInstance().GetTopoInfo();
      44            1 :     rankTable_ = make_unique<RankTableInfo>(ranktable);
      45              : 
      46            1 :     myRank_ = myRank;
      47            1 :     BuildRankGraph();
      48              : 
      49            0 :     HCCL_INFO("[RankGraphBuilder] Build VirtualTopo success!");
      50            0 :     rankGraph_->Dump();
      51            0 :     return std::move(rankGraph_);
      52              : }
      53              : 
      54           60 : const RankLevelInfo& RankGraphBuilder::GetRankLevelInfoByNetLayer(const NewRankInfo& rankInfo, u32 netLayer) const
      55              : {
      56           60 :     auto it = std::find_if(
      57          150 :         rankInfo.rankLevelInfos.begin(), rankInfo.rankLevelInfos.end(), [netLayer](const RankLevelInfo& levelInfo) {
      58          150 :             return levelInfo.netLayer == netLayer;
      59              :         });
      60           60 :     if (it == rankInfo.rankLevelInfos.end()) {
      61            0 :         THROW<InvalidParamsException>(StringFormat(
      62              :             "[RankGraphBuilder][GetRankLevelInfoByNetLayer] rankId[%u] netLayer[%u] does not exist in ranktable.",
      63            0 :             rankInfo.rankId, netLayer));
      64              :     }
      65          120 :     return *it;
      66              : }
      67              : 
      68           48 : std::vector<shared_ptr<PhyTopo::Link>> GetPeer2NetPhyLinks(u32 netLayer, LocalId localId)
      69              : {
      70           48 :     const shared_ptr<Graph<PhyTopo::Node, PhyTopo::Link>> phyGraph = PhyTopo::GetInstance()->GetTopoGraph(netLayer);
      71           48 :     if (phyGraph == nullptr) {
      72            0 :         THROW<InvalidParamsException>(StringFormat(
      73              :             "[RankGraphBuilder][GetPhyLink] localId[%d] is not level[%u] in"
      74              :             " topo.json, not match rankTable.",
      75              :             localId, netLayer));
      76              :     }
      77           48 :     std::vector<shared_ptr<PhyTopo::Link>> links;
      78           48 :     phyGraph->TraverseEdge(PhyTopo::Peer::GetId(localId), [&](shared_ptr<PhyTopo::Link> link) {
      79           48 :         if (link != nullptr) {
      80           48 :             links.push_back(link);
      81              :         }
      82           48 :     });
      83              : 
      84           48 :     if (links.empty()) {
      85            0 :         THROW<InvalidParamsException>(
      86            0 :             StringFormat("[RankGraphBuilder][GetPhyLink] SourceNode localId[%d] edge does not exist.", localId));
      87              :     }
      88           48 :     return links;
      89           48 : }
      90              : 
      91           48 : void RankGraphBuilder::AddPeer2NetLink(
      92              :     const u32 netLayer, const string& netInstId, RankId rankId, const AddressInfo& addrInfo,
      93              :     const shared_ptr<NetInstance::Fabric>& fabNode, const vector<shared_ptr<PhyTopo::Link>>& links)
      94              : {
      95           96 :     for (shared_ptr<PhyTopo::Link> link : links) {
      96           48 :         if (link->GetSourceIFace() == nullptr) {
      97            0 :             continue;
      98              :         }
      99           48 :         std::set<std::string> ports = link->GetSourceIFace()->GetPorts();
     100           48 :         std::set<std::string> rankGraphPorts;
     101           48 :         std::set_intersection(
     102              :             ports.begin(), ports.end(), addrInfo.ports.begin(), addrInfo.ports.end(),
     103              :             std::inserter(rankGraphPorts, rankGraphPorts.begin()));
     104              : 
     105           48 :         if (rankGraphPorts.empty()) {
     106              :             // 该地址在topo里没有对应边
     107            0 :             continue;
     108              :         }
     109              :         // 获取topoInstId topoType
     110           48 :         u32 topoInstId = link->GetTopoInstId();
     111           48 :         auto topoType = link->GetTopoType();
     112              : 
     113              :         // 构造 RankGraph 的 PeerIface
     114              :         shared_ptr<NetInstance::ConnInterface> peerIface = make_shared<NetInstance::ConnInterface>(
     115           96 :             addrInfo.addr, rankGraphPorts, link->GetSourceIFace()->GetPos(), LinkType::PEER2NET,
     116          144 :             link->GetLinkProtocols(), topoType, topoInstId);
     117              :         // 获取 rankId 对应 PeerNode
     118           48 :         shared_ptr<NetInstance::Peer> peerNode = peers_.at(rankId);
     119           48 :         peerNode->AddConnInterface(netLayer, peerIface);
     120              : 
     121              :         // 构造 peer2netLink 和 net2peerLink 两条link
     122              :         shared_ptr<NetInstance::Link> peer2netLink = make_shared<NetInstance::Link>(
     123           96 :             peerNode, fabNode, peerIface, nullptr, LinkType::PEER2NET, link->GetLinkProtocols(), LinkDirection::BOTH,
     124           96 :             2);
     125              :         shared_ptr<NetInstance::Link> net2peerLink = make_shared<NetInstance::Link>(
     126           96 :             fabNode, peerNode, nullptr, peerIface, LinkType::PEER2NET, link->GetLinkProtocols(), LinkDirection::BOTH,
     127           96 :             2);
     128              : 
     129              :         // 插入 link
     130           48 :         tempNetInsts_[netLayer][netInstId]->AddLink(peer2netLink);
     131           48 :         tempNetInsts_[netLayer][netInstId]->AddLink(net2peerLink);
     132              : 
     133              :         // 将rank插入到当前netInstance对应的topoInstance中
     134           48 :         tempNetInsts_[netLayer][netInstId]->UpdateTopoInst(topoInstId, topoType, rankId);
     135              : 
     136              :         // 只打印当前卡的rank_id和eid对应关系
     137           48 :         if (rankId == myRank_) {
     138           32 :             HCCL_RUN_INFO(
     139              :                 "[RankGraphBuilder][AddPeer2NetLink] Add Peer2NetLink Net2PeerLink success. level[%u] "
     140              :                 "netInstId[%s] rankId[%u] planeId[%s] AddrStr[%s],topoInstId[%u],topoType[%u]",
     141              :                 netLayer, netInstId.c_str(), rankId, fabNode->GetPlaneId().c_str(), addrInfo.addr.Describe().c_str(),
     142              :                 topoInstId, topoType);
     143              :         }
     144           48 :     }
     145           48 : }
     146              : 
     147           12 : void RankGraphBuilder::AddFabricInfo(u32 netLayer)
     148              : {
     149           12 :     auto netInst = rankGraph_->GetNetInstanceByRankId(netLayer, myRank_);
     150           12 :     if (netInst == nullptr) {
     151            0 :         THROW<NullPtrException>(
     152            0 :             StringFormat("[RankGraphBuilder][AddFabricInfo] rankGraph->GetNetInstanceByRankId is nullptr"));
     153              :     }
     154              : 
     155           12 :     if (netInst->GetNetType() != NetType::CLOS) {
     156            0 :         THROW<NotSupportException>(
     157            0 :             StringFormat("[RankGraphBuilder][AddFabricInfo] NetInstance is not CLOS, not support add fabric."));
     158              :     }
     159           12 :     set<RankId> inRanks = netInst->GetRankIds();
     160           12 :     string netInstId = netInst->GetNetInstId();
     161           12 :     const auto& myLevelInfo = GetRankLevelInfoByNetLayer(rankTable_->ranks[myRank_], netLayer);
     162              :     // 根据planeId确认Fabric个数,每个fabricId对应一个planeId
     163           12 :     std::map<PlaneId, FabricId> planeId2Node = GetFabricsFromAddrInfo(myLevelInfo.rankAddrs);
     164              : 
     165           12 :     if (planeId2Node.size() == 0) {
     166            0 :         HCCL_WARNING(
     167              :             "[RankGraphBuilder][AddFabricInfo] current rankId[%d] netLayer[%u] group no net plane", myRank_, netLayer);
     168            0 :         return;
     169              :     }
     170           12 :     vector<shared_ptr<NetInstance::Fabric>> fabNodes(planeId2Node.size(), nullptr);
     171              : 
     172              :     // 遍历每一个rankId,每个rankId都增加 peer2net 和 net2peer 两条链路
     173           60 :     for (RankId srcRankId : inRanks) {
     174           48 :         const auto& srcLevelInfo = GetRankLevelInfoByNetLayer(rankTable_->ranks[srcRankId], netLayer);
     175           48 :         const vector<AddressInfo>& addrs = srcLevelInfo.rankAddrs;
     176              :         // rankId对应的物理逻辑localId
     177           48 :         LocalId localId = rankGraph_->GetLocalId(srcRankId);
     178              :         // 从物理拓扑图中找出 localId在 netLayer 中所有的peer2Net的边。
     179           48 :         std::vector<shared_ptr<PhyTopo::Link>> links = GetPeer2NetPhyLinks(netLayer, localId);
     180              :         // 遍历ranktable中的addr,有几个addr就有几条peer2net的边
     181           96 :         for (AddressInfo addrInfo : addrs) {
     182           48 :             if (addrInfo.addr == IpAddress()) {
     183            0 :                 continue;
     184              :             }
     185              : 
     186           48 :             if (planeId2Node.count(addrInfo.planeId) == 0) {
     187            0 :                 continue;
     188              :             }
     189           48 :             FabricId fabId = planeId2Node[addrInfo.planeId];
     190              :             // 若 fabNodes[fabId] 不存在则创建 如果存在则获取fabNode
     191           48 :             shared_ptr<NetInstance::Fabric> fabNode;
     192           48 :             if (fabNodes[fabId] == nullptr) {
     193           12 :                 fabNode = make_shared<NetInstance::Fabric>(fabId, addrInfo.planeId);
     194           12 :                 tempNetInsts_[netLayer][netInstId]->AddNode(fabNode);
     195           12 :                 fabNodes[fabId] = fabNode;
     196              :             } else {
     197           36 :                 fabNode = fabNodes[fabId];
     198              :             }
     199              :             // 插入peer和fabric的peer2net和net2peer两条link
     200           48 :             AddPeer2NetLink(netLayer, netInstId, srcRankId, addrInfo, fabNode, links);
     201           48 :         }
     202           48 :     }
     203              : 
     204           32 :     HCCL_DEBUG(
     205              :         "[RankGraphBuilder][AddFabricInfo] netLayer [%u] netInstId[%s] Add Fabric Info success!", netLayer,
     206              :         netInstId.c_str());
     207           12 : }
     208              : 
     209           18 : void RankGraphBuilder::AddTopoDescFabricInfo()
     210              : {
     211              :     // 1. 获取物理拓扑图
     212           18 :     auto phyTopoGraph = PhyTopo::GetInstance()->GetTopoGraph(0);
     213           18 :     if (phyTopoGraph == nullptr) {
     214            0 :         THROW<NullPtrException>(StringFormat("[RankGraphBuilder][AddTopoDescFabricInfo] phyTopoGraph is nullptr"));
     215              :     }
     216           46 :     HCCL_INFO("[RankGraphBuilder][AddTopoDescFabricInfo] Successfully retrieved phyTopoGraph");
     217              : 
     218              :     // 2. 获取当前 NetInstance
     219           18 :     NetInstance* innerNetInstance = rankGraph_->GetNetInstanceByRankId(0, myRank_);
     220           18 :     if (innerNetInstance == nullptr) {
     221            0 :         THROW<NullPtrException>(
     222            0 :             StringFormat("[RankGraphBuilder][AddTopoDescFabricInfo] rankGraph->GetNetInstanceByRankId is nullptr"));
     223              :     }
     224           18 :     std::string netInstId = innerNetInstance->GetNetInstId();
     225           18 :     std::set<RankId> rankIds = innerNetInstance->GetRankIds();
     226              : 
     227              :     // 存储所有fabric节点,key为topoInstId
     228           18 :     std::map<u32, std::shared_ptr<NetInstance::Fabric>> fabNodes;
     229              : 
     230           18 :     auto peer = rankGraph_->GetPeer(rankGraph_->GetMyRank());
     231           18 :     auto localDeviceId = peer->GetDeviceId();
     232              : 
     233              :     // 3. 遍历所有rank节点,根据topoInstId创建fabric节点
     234           68 :     for (RankId rankId : rankIds) {
     235           50 :         LocalId localId = rankGraph_->GetLocalId(rankId);
     236           50 :         auto peer2netEdges = phyTopoGraph->GetEdges(localId, PhyTopo::Fabric::GetId());
     237              : 
     238          134 :         HCCL_RUN_INFO(
     239              :             "[RankGraphBuilder][AddTopoDescFabricInfo] Processing rank %d (localId: %u), found %zu peer2net edges",
     240              :             rankId, localId, peer2netEdges.size());
     241              : 
     242          126 :         for (const auto& link : peer2netEdges) {
     243           76 :             u32 topoInstId = link->GetTopoInstId();
     244           76 :             auto topoType = link->GetTopoType();
     245              : 
     246              :             // 创建Fabric节点
     247           76 :             if (fabNodes.find(topoInstId) == fabNodes.end()) {
     248           34 :                 auto fabNodePtr = std::make_shared<NetInstance::Fabric>(topoInstId);
     249           34 :                 innerNetInstance->AddNode(fabNodePtr);
     250           34 :                 fabNodes[topoInstId] = fabNodePtr;
     251           98 :                 HCCL_INFO(
     252              :                     "[RankGraphBuilder][AddTopoDescFabricInfo] Created new Fabric node for topoInstId: %u", topoInstId);
     253           34 :             }
     254              : 
     255              :             // 获取 peer 节点
     256           76 :             auto peerNode = peers_.at(rankId);
     257              : 
     258              :             // 构造连接接口
     259              :             auto peerIfaces = ConstructConnIFromPhyTopoConnIAndPortMap(
     260           76 :                 link->GetSourceIFace(), peerNode->GetPortAddrMapLayer0(), topoType, topoInstId, localDeviceId);
     261              : 
     262          136 :             for (const auto& iface : peerIfaces) {
     263           60 :                 peerNode->AddConnInterface(0, iface);
     264              :             }
     265           76 :             auto fabNodePtr = fabNodes[topoInstId];
     266              :             // 构造 peer2netLink 和 net2peerLink(双向)
     267          136 :             for (const auto& iface : peerIfaces) {
     268              :                 auto peer2netLink = std::make_shared<NetInstance::Link>(
     269          120 :                     peerNode, fabNodePtr, iface, nullptr, LinkType::PEER2NET, link->GetLinkProtocols(),
     270          120 :                     LinkDirection::BOTH, 2);
     271              : 
     272              :                 auto net2peerLink = std::make_shared<NetInstance::Link>(
     273          120 :                     fabNodePtr, peerNode, nullptr, iface, LinkType::PEER2NET, link->GetLinkProtocols(),
     274          120 :                     LinkDirection::BOTH, 2);
     275              : 
     276              :                 // 插入 link
     277           60 :                 tempNetInsts_[0][netInstId]->AddLink(peer2netLink);
     278           60 :                 tempNetInsts_[0][netInstId]->AddLink(net2peerLink);
     279           60 :                 tempNetInsts_[0][netInstId]->UpdateTopoInst(topoInstId, topoType, rankId);
     280          172 :                 HCCL_RUN_INFO(
     281              :                     "[RankGraphBuilder][AddTopoDescFabricInfo] netLayer0 rankId[%u] netInstId[%s] Add Fabric "
     282              :                     "Info success!",
     283              :                     rankId, netInstId.c_str());
     284           60 :             }
     285           76 :         }
     286           50 :     }
     287           46 :     HCCL_INFO("[RankGraphBuilder][AddTopoDescFabricInfo] Successfully completed fabric link construction");
     288           18 : }
     289              : 
     290           12 : std::map<PlaneId, FabricId> GetFabricsFromAddrInfo(const std::vector<AddressInfo>& rankAddrs)
     291              : {
     292           12 :     std::map<PlaneId, FabricId> planeId2FabricId;
     293           24 :     for (const auto& addrInfo : rankAddrs) {
     294           12 :         if (planeId2FabricId.count(addrInfo.planeId) == 0) {
     295           12 :             FabricId fabId = planeId2FabricId.size();
     296           12 :             planeId2FabricId[addrInfo.planeId] = fabId;
     297              :         }
     298              :     }
     299           12 :     return planeId2FabricId;
     300            0 : }
     301              : 
     302           99 : void RankGraphBuilder::CheckNetLayerFromPhyTopo(const u32 netLayer) const
     303              : {
     304           99 :     if (!PhyTopo::GetInstance()->IsNetLayerExisted(netLayer)) {
     305            1 :         THROW<InvalidParamsException>(StringFormat(
     306              :             "[RankGraphBuilder][CheckNetLayerFromPhyTopo]"
     307              :             "netLayer[%u] not exist in topo.",
     308              :             netLayer));
     309              :     }
     310           98 : }
     311              : 
     312              : // 根据ranktable构造添加peers和NetInstances, NetInstance添加nodes和links(peer2net)
     313              : // 1. 创建NetInstance ( 每个NetInstance 添加 Rank, Node, Link);
     314              : // 2. RankGraph中添加NetInstance, Peer, Fabric,
     315           19 : void RankGraphBuilder::BuildFromRankTable()
     316              : {
     317              :     // 保存NetInstance指针以便后续执行Add操作
     318           19 :     tempNetInsts_.resize(MAX_NET_LAYER); // 为了方便修改RankGraph的NetInstance,共享指针。
     319              : 
     320              :     // 遍历rankTable每一个rank, virtualTopo添加Peers
     321           69 :     for (const auto& rankInfo : rankTable_->ranks) {
     322           51 :         updaterFor64Plus1_.SaveReplaceInfo(rankInfo); // 暂存备份替换信息
     323           51 :         RankId rankId = rankInfo.rankId;
     324              :         shared_ptr<NetInstance::Peer> peer = make_shared<NetInstance::Peer>(
     325           51 :             rankId, rankInfo.localId, rankInfo.replacedLocalId, rankInfo.deviceId, rankInfo.devicePort,
     326           51 :             rankInfo.hostPort);
     327           51 :         rankGraph_->AddPeer(peer);
     328           51 :         peers_.emplace(rankId, peer); // rankid2peer
     329              : 
     330              :         // 构造当前rank的每个LevelInfo所在NetInstance, 添加 RankId 和 Peer
     331          149 :         for (const auto& levelInfo : rankInfo.rankLevelInfos) {
     332              :             // 校验netLayer是否在topo中
     333           99 :             CheckNetLayerFromPhyTopo(levelInfo.netLayer);
     334              :             // rankLevelInfo.level、id对应NetInstance,若不存在则创建
     335              :             auto curNetInstance = GetOrCreateNetInstance(
     336           98 :                 levelInfo.netLayer, levelInfo.netInstId, levelInfo.netType, tempNetInsts_, rankGraph_.get());
     337           98 :             if (curNetInstance == nullptr) {
     338            0 :                 continue;
     339              :             }
     340              :             // NetInstance add Peer
     341           98 :             curNetInstance->AddRankId(rankId);
     342           98 :             curNetInstance->AddNode(peer);
     343              :             // Peer add NetInstance
     344           98 :             peer->AddNetInstance(curNetInstance);
     345           98 :             if (levelInfo.netLayer == 0) {
     346           50 :                 peer->SetPortPortAddrMapLayer0(levelInfo.portAddrMap);
     347              :             }
     348          262 :             HCCL_DEBUG(
     349              :                 "[RankGraphBuilder][BuildFromRankTable] rankLevelInfo : rankId[%d] level[%u] "
     350              :                 "netInstId[%s] fabricType[%s].",
     351              :                 rankId, levelInfo.netLayer, levelInfo.netInstId.c_str(), levelInfo.netType.Describe().c_str());
     352           98 :         }
     353           51 :     }
     354              : 
     355              :     // 对 myrank 所在每个level的NetInstance 添加 Fabrics 和 links(peer2net)
     356           18 :     set<u32> myLevels = rankGraph_->GetLevels(myRank_);
     357           46 :     HCCL_DEBUG("myRank netType: level size %u", myLevels.size());
     358           48 :     for (u32 level : myLevels) {
     359           30 :         if (level == 0) {
     360           18 :             AddTopoDescFabricInfo();
     361              :         } else {
     362           12 :             AddFabricInfo(level);
     363              :         }
     364              :     }
     365              : 
     366              :     // 初始化innerRanks
     367           18 :     rankGraph_->InitInnerRanks();
     368              : 
     369           46 :     HCCL_DEBUG("[RankGraphBuilder][BuildFromRankTable] Build VirtualTopo from RankTable success!");
     370           18 : }
     371              : 
     372           18 : void RankGraphBuilder::SetEndpointDesc()
     373              : {
     374           18 :     std::shared_ptr<NetInstance::Peer> peer = peers_[myRank_];
     375           18 :     CHK_PRT_THROW(
     376              :         peer == nullptr, HCCL_ERROR("[RankGraphBuilder::%s] fail", __func__), NullPtrException, "peer is null");
     377              :     // 获取 peer 的 Iface
     378           18 :     std::set<u32> layers = peer->GetLevels();
     379           48 :     for (const auto& layer : layers) {
     380           30 :         auto ifacesVec = peer->GetIfacesByLayer(layer);
     381           89 :         for (const auto& iface : ifacesVec) {
     382           59 :             const auto& protocols = iface->GetLinkProtocols();
     383          118 :             for (const auto& protocol : protocols) {
     384           59 :                 EndpointDesc desc{};
     385              : 
     386           59 :                 HcclResult ret = GetCommAddr(desc.commAddr, iface->GetAddr());
     387           59 :                 CHK_PRT_THROW(
     388              :                     ret != HCCL_SUCCESS, HCCL_ERROR("[RankGraphBuilder::%s] fail", __func__), InternalException,
     389              :                     "GetCommAddr fail");
     390              : 
     391           59 :                 desc.protocol = LinkProtocolToCommProtocol(protocol);
     392           59 :                 desc.loc.locType = AddrPositionToEndpointLoc(iface->GetPos());
     393              : 
     394          165 :                 HCCL_INFO(
     395              :                     "[RankGraphBuilder::SetEndpointDesc] local type[%d] protocol[%d]", desc.loc.locType, desc.protocol);
     396              : 
     397           59 :                 peer->SetEndpointToIface(desc.commAddr, desc.protocol, iface);
     398              :             }
     399           59 :         }
     400           30 :     }
     401           18 : }
     402              : 
     403            0 : std::shared_ptr<NetInstance> RankGraphBuilder::GetNetInstance(const RankLevelInfo& levelInfo)
     404              : {
     405            0 :     auto it = tempNetInsts_[levelInfo.netLayer].find(levelInfo.netInstId);
     406            0 :     if (it == tempNetInsts_[levelInfo.netLayer].end()) {
     407            0 :         return nullptr;
     408              :     }
     409              :     // 若NetInstance存在, type不一致则报错
     410            0 :     NetType netType = it->second->GetNetType();
     411            0 :     if (netType != levelInfo.netType) {
     412            0 :         HCCL_WARNING(
     413              :             "[CreateNetInstance]FabType [%s] and [%s] no match", netType.Describe().c_str(),
     414              :             levelInfo.netType.Describe().c_str());
     415            0 :         return nullptr;
     416              :     }
     417            0 :     return it->second;
     418              : }
     419              : 
     420            0 : std::shared_ptr<NetInstance> RankGraphBuilder::CreateNetInstance(const RankLevelInfo& levelInfo)
     421              : {
     422            0 :     std::shared_ptr<NetInstance> netInst;
     423            0 :     if (levelInfo.netType == NetType::TOPO_FILE_DESC) {
     424            0 :         netInst = std::make_shared<InnerNetInstance>(levelInfo.netLayer, levelInfo.netInstId);
     425            0 :     } else if (levelInfo.netType == NetType::CLOS) {
     426            0 :         netInst = std::make_shared<ClosNetInstance>(levelInfo.netLayer, levelInfo.netInstId);
     427              :     } else {
     428            0 :         THROW<NotSupportException>(
     429            0 :             StringFormat("[RankGraphBuilder][CreateNetInstance] netType: %s is not support", levelInfo.netType));
     430              :     }
     431            0 :     return netInst;
     432            0 : }
     433              : 
     434              : // 从phytopo和ranktable中读取数据共同构建peer2peer的边。
     435           18 : void RankGraphBuilder::BuildPeer2PeerLinks()
     436              : {
     437           18 :     auto phyTopoGraph = PhyTopo::GetInstance()->GetTopoGraph(0);
     438           18 :     if (phyTopoGraph == nullptr) {
     439            0 :         THROW<NullPtrException>(StringFormat("[RankGraphBuilder][BuildPeer2PeerLinks] phyTopoGraph is nullptr"));
     440              :     }
     441              :     // 遍历innerNetInstance中的每两个rankId之间是否存在边,存在则添加peer2peerlink
     442           18 :     NetInstance* innerNetInstance = rankGraph_->GetNetInstanceByRankId(0, myRank_);
     443           18 :     if (innerNetInstance == nullptr) {
     444            0 :         THROW<NullPtrException>(StringFormat("[RankGraphBuilder][BuildPeer2PeerLinks] innerNetInstance is nullptr"));
     445              :     }
     446           18 :     set<RankId> rankIds = innerNetInstance->GetRankIds();
     447              : 
     448           18 :     auto peer = rankGraph_->GetPeer(rankGraph_->GetMyRank());
     449           18 :     auto localDeviceId = peer->GetDeviceId();
     450           68 :     for (const auto srcRankId : rankIds) {
     451          212 :         for (const auto dstRankId : rankIds) {
     452          162 :             if (srcRankId == dstRankId) {
     453           56 :                 continue;
     454              :             }
     455              : 
     456              :             // 得到phyTopoGraph中对应的localId
     457          112 :             LocalId srcLocalId = rankGraph_->GetLocalId(srcRankId);
     458          112 :             LocalId dstLocalId = rankGraph_->GetLocalId(dstRankId);
     459          112 :             if (srcLocalId == BACKUP_LOCAL_ID || dstLocalId == BACKUP_LOCAL_ID) {
     460            6 :                 continue;
     461              :             }
     462              : 
     463              :             std::vector<shared_ptr<PhyTopo::Link>> phyLinks
     464          106 :                 = GetPeer2PeerPhyLinks(phyTopoGraph, srcLocalId, dstLocalId);
     465              :             // 根据ports在ranktable找对对应的地址,几个地址就有几条link。
     466              : 
     467          106 :             shared_ptr<NetInstance::Peer> srcPeer = peers_.at(srcRankId);
     468          106 :             shared_ptr<NetInstance::Peer> dstPeer = peers_.at(dstRankId);
     469              : 
     470          200 :             for (shared_ptr<PhyTopo::Link> phyLink : phyLinks) {
     471              :                 auto sourceIfaces = ConstructConnIFromPhyTopoConnIAndPortMap(
     472          188 :                     phyLink->GetSourceIFace(), srcPeer->GetPortAddrMapLayer0(), phyLink->GetTopoType(),
     473          188 :                     phyLink->GetTopoInstId(), localDeviceId);
     474              :                 auto targetIfaces = ConstructConnIFromPhyTopoConnIAndPortMap(
     475          188 :                     phyLink->GetTargetIFace(), dstPeer->GetPortAddrMapLayer0(), phyLink->GetTopoType(),
     476          188 :                     phyLink->GetTopoInstId(), localDeviceId);
     477           94 :                 if (sourceIfaces.empty() || targetIfaces.empty()) {
     478              :                     // 没有可用的接口。
     479            0 :                     HCCL_WARNING(
     480              :                         "[RankGraphBuilder][BuildPeer2PeerLinks] no available interface, "
     481              :                         "srcRankId[%u] dstRankId[%u].",
     482              :                         srcRankId, dstRankId);
     483            0 :                     continue;
     484            0 :                 }
     485           94 :                 srcPeer->AddConnInterfaces(0, sourceIfaces);
     486           94 :                 dstPeer->AddConnInterfaces(0, targetIfaces);
     487              :                 std::vector<shared_ptr<NetInstance::Link>> links
     488           94 :                     = ConstructLinks(srcPeer, dstPeer, sourceIfaces, targetIfaces, phyLink);
     489          188 :                 for (auto link : links) {
     490           94 :                     innerNetInstance->AddLink(link);
     491           94 :                 }
     492           94 :             }
     493          106 :         }
     494              :     }
     495           18 : }
     496              : 
     497           18 : void RankGraphBuilder::UpdateTopoInstForMyRankOnly()
     498              : {
     499           18 :     auto innerNetInstance = rankGraph_->GetNetInstanceByRankId(0, myRank_);
     500           18 :     if (innerNetInstance == nullptr) {
     501            0 :         THROW<NullPtrException>(
     502            0 :             StringFormat("[RankGraphBuilder][UpdateTopoInstForMyRankOnly] innerNetInstance is nullptr"));
     503              :     }
     504              : 
     505           18 :     auto netInstId = innerNetInstance->GetNetInstId();
     506           18 :     set<RankId> rankIds = innerNetInstance->GetRankIds();
     507              : 
     508           18 :     auto phyTopoGraph = PhyTopo::GetInstance()->GetTopoGraph(0);
     509           18 :     if (phyTopoGraph == nullptr) {
     510            0 :         THROW<NullPtrException>(
     511            0 :             StringFormat("[RankGraphBuilder][UpdateTopoInstForMyRankOnly] phyTopoGraph is nullptr"));
     512              :     }
     513           18 :     if (rankIds.size() == 1) {
     514              :         // 单卡场景直接返回1DMESH
     515            2 :         RankId singleId = *rankIds.begin();
     516            2 :         tempNetInsts_[0][netInstId]->UpdateTopoInst(0, TopoType::MESH_1D, singleId);
     517            2 :         return;
     518              :     }
     519              : 
     520           64 :     for (const auto srcRankId : rankIds) {
     521          208 :         for (const auto dstRankId : rankIds) {
     522              :             // 只处理涉及 myRank_ 的边
     523          160 :             if (srcRankId != myRank_ && dstRankId != myRank_) {
     524           80 :                 continue;
     525              :             }
     526              : 
     527           80 :             LocalId srcLocalId = rankGraph_->GetLocalId(srcRankId);
     528           80 :             LocalId dstLocalId = rankGraph_->GetLocalId(dstRankId);
     529              : 
     530              :             std::vector<shared_ptr<PhyTopo::Link>> phyLinks
     531           80 :                 = GetPeer2PeerPhyLinks(phyTopoGraph, srcLocalId, dstLocalId);
     532              : 
     533          134 :             for (shared_ptr<PhyTopo::Link> phyLink : phyLinks) {
     534           54 :                 u32 topoInstId = phyLink->GetTopoInstId();
     535           54 :                 auto topoType = phyLink->GetTopoType();
     536           54 :                 tempNetInsts_[0][netInstId]->UpdateTopoInst(topoInstId, topoType, dstRankId);
     537           54 :             }
     538           80 :         }
     539              :     }
     540           22 : }
     541              : 
     542          264 : std::vector<std::shared_ptr<NetInstance::ConnInterface>> ConstructConnIFromPhyTopoConnIAndPortMap(
     543              :     std::shared_ptr<PhyTopo::ConnInterface> phyConnIFace,
     544              :     const std::map<std::string, std::vector<IpAddress>>& portAddrMap, const TopoType topoType, const u32 topoInstId,
     545              :     u32 localDeviceId)
     546              : {
     547          264 :     std::vector<std::shared_ptr<NetInstance::ConnInterface>> netConnIFaces;
     548          264 :     std::set<string> phyPorts = phyConnIFace->GetPorts();
     549          264 :     std::map<IpAddress, std::set<string>> addr2Ports;
     550          544 :     for (auto port : phyPorts) {
     551          280 :         if (*(phyConnIFace->GetLinkProtocols().begin()) == LinkProtocol::PCIE) {
     552            0 :             IpAddress tempIp;
     553            0 :             HrtRaSocketGetVnicIpInfos(localDeviceId, DeviceIdType::DEVICE_ID_TYPE_PHY_ID, localDeviceId, tempIp);
     554            0 :             auto it = addr2Ports.find(tempIp);
     555            0 :             if (it == addr2Ports.end()) {
     556            0 :                 std::set<std::string> newPorts;
     557            0 :                 newPorts.insert("d2h");
     558            0 :                 addr2Ports[tempIp] = newPorts;
     559            0 :             } else {
     560            0 :                 it->second.insert("d2h");
     561              :             }
     562              :         } else {
     563          280 :             auto itPort = portAddrMap.find(port);
     564          280 :             if (itPort == portAddrMap.end()) {
     565           84 :                 HCCL_WARNING(
     566              :                     "[RankGraphBuilder][ConstructConnIFromPhyTopoConnIAndPortMap] topo use port [%s] not find addrs in "
     567              :                     "ranktable.",
     568              :                     port.c_str());
     569           28 :                 continue;
     570           28 :             }
     571          504 :             for (auto addr : itPort->second) {
     572          252 :                 auto it = addr2Ports.find(addr);
     573          252 :                 if (it == addr2Ports.end()) {
     574          248 :                     std::set<std::string> newPorts;
     575          248 :                     newPorts.insert(port);
     576          248 :                     addr2Ports[addr] = newPorts;
     577          248 :                 } else {
     578           12 :                     it->second.insert("8080");
     579              :                 }
     580              :             }
     581              :         }
     582          280 :     }
     583              : 
     584          512 :     for (auto it = addr2Ports.begin(); it != addr2Ports.end(); ++it) {
     585          248 :         auto linkType = *(phyConnIFace->GetLinkProtocols().begin()) == LinkProtocol::PCIE ? LinkType::PEER2NET :
     586          248 :                                                                                             LinkType::PEER2PEER;
     587              :         shared_ptr<NetInstance::ConnInterface> netConnIFace = make_shared<NetInstance::ConnInterface>(
     588          496 :             it->first, it->second, phyConnIFace->GetPos(), linkType, phyConnIFace->GetLinkProtocols(), topoType,
     589          248 :             topoInstId);
     590          248 :         netConnIFaces.push_back(netConnIFace);
     591          248 :     }
     592          264 :     return netConnIFaces;
     593          264 : }
     594              : 
     595           94 : std::vector<shared_ptr<NetInstance::Link>> ConstructLinks(
     596              :     shared_ptr<NetInstance::Peer> srcPeer, shared_ptr<NetInstance::Peer> dstPeer,
     597              :     std::vector<std::shared_ptr<NetInstance::ConnInterface>> sourceIfaces,
     598              :     std::vector<std::shared_ptr<NetInstance::ConnInterface>> targetIfaces, shared_ptr<PhyTopo::Link> phyLink)
     599              : {
     600           94 :     std::vector<shared_ptr<NetInstance::Link>> links;
     601          188 :     for (auto sourceIFace : sourceIfaces) {
     602          188 :         for (auto targetIFace : targetIfaces) {
     603              :             shared_ptr<NetInstance::Link> link = make_shared<NetInstance::Link>(
     604           94 :                 srcPeer, dstPeer, sourceIFace, targetIFace, LinkType::PEER2PEER, phyLink->GetLinkProtocols());
     605           94 :             links.push_back(link);
     606           94 :         }
     607           94 :     }
     608           94 :     return links;
     609            0 : }
     610              : 
     611          186 : std::vector<std::shared_ptr<PhyTopo::Link>> GetPeer2PeerPhyLinks(
     612              :     std::shared_ptr<Graph<PhyTopo::Node, PhyTopo::Link>> phyTopoGraph, LocalId srcLocalId, LocalId dstLocalId)
     613              : {
     614          186 :     std::vector<shared_ptr<PhyTopo::Link>> links;
     615          186 :     if (!phyTopoGraph->HasNode(srcLocalId) || !phyTopoGraph->HasNode(dstLocalId)) {
     616            0 :         HCCL_WARNING(
     617              :             "[RankGraphBuilder][BuildFromPhytopo] srcLocalId[%u] dstLocalId[%u] not exist in phyTopoGraph.", srcLocalId,
     618              :             dstLocalId);
     619            0 :         return links;
     620              :     }
     621              :     // 得到phyTopoGraph对应的NodeId
     622          186 :     NodeId srcNodeId = PhyTopo::Peer::GetId(srcLocalId);
     623          186 :     NodeId dstNodeId = PhyTopo::Peer::GetId(dstLocalId);
     624              : 
     625          186 :     phyTopoGraph->TraverseEdge(srcNodeId, dstNodeId, [&](shared_ptr<PhyTopo::Link> link) {
     626          148 :         if (link != nullptr) {
     627          148 :             links.push_back(link);
     628              :         }
     629          148 :     });
     630          186 :     if (links.empty()) {
     631           90 :         HCCL_WARNING(
     632              :             "[RankGraphBuilder][GetPeer2PeerPhyLinks] srcLocalId[%u] dstLocalId[%u] edge does not exist.", srcLocalId,
     633              :             dstLocalId);
     634              :     }
     635          186 :     return links;
     636            0 : }
     637              : 
     638           21 : void RankGraphBuilder::CheckMyRankInRankTable() const
     639              : {
     640           21 :     if (myRank_ >= static_cast<s32>(rankTable_->rankCount)) {
     641            1 :         THROW<InvalidParamsException>(StringFormat(
     642              :             "[RankGraphBuilder][CheckMyRankInRankTable]"
     643              :             "myRank[%d] is not in rankTable rankCount[%u].",
     644            1 :             myRank_, rankTable_->rankCount));
     645              :     }
     646           20 : }
     647              : 
     648           21 : void RankGraphBuilder::BuildRankGraph()
     649              : {
     650              :     // 创建VirtualTopo
     651           21 :     rankGraph_ = make_unique<RankGraph>(myRank_);
     652              : 
     653              :     // 校验myRank在rankTable中
     654           21 :     CheckMyRankInRankTable();
     655              : 
     656              :     // 根据ranktable构造添加peers和NetInstances, 每个NetInstance添加nodes和links(peer2net)
     657           20 :     BuildFromRankTable();
     658              : 
     659              :     // 根据phytopo构造添加InnerGroup中的links(peer2peer), 不包括备份节点
     660           19 :     BuildPeer2PeerLinks();
     661              : 
     662              :     // 使用备份D时需要修改虚拟拓扑
     663           19 :     updaterFor64Plus1_.UpdateRankGraph(rankGraph_.get(), rankTable_.get());
     664              : 
     665              :     // 为myrank的peer2peer更新topoInst
     666           19 :     UpdateTopoInstForMyRankOnly();
     667              : 
     668              :     // 添加绕路 绕路获取
     669           19 :     DetourService::GetInstance().InsertDetourLinks(rankGraph_.get(), rankTable_.get());
     670              : 
     671              :     // 设置endpoint
     672           19 :     SetEndpointDesc();
     673              : 
     674              :     // 构造完成
     675           19 :     rankGraph_->InitFinish();
     676           19 : }
     677              : 
     678            6 : std::unique_ptr<RankTableInfo> RankGraphBuilder::GetRankTableInfo() { return move(rankTable_); }
     679              : 
     680            5 : std::shared_ptr<TopoInfo> RankGraphBuilder::GetTopoInfo() { return topoInfo_; }
     681              : 
     682              : unique_ptr<RankGraph>
     683            5 : RankGraphBuilder::RecoverBuild(const RankTableInfo& rankTableInfo, const TopoInfo& topoInfo, RankId myRank)
     684              : {
     685            5 :     topoInfo_ = std::make_shared<TopoInfo>(topoInfo);
     686            5 :     PhyTopoBuilder::GetInstance().RecoverBuild(*topoInfo_);
     687              : 
     688            5 :     rankTable_ = make_unique<RankTableInfo>(rankTableInfo);
     689            5 :     HCCL_INFO(
     690              :         "[%s] RankTable[%s] RankTableInfo[%s]", __func__, rankTable_->Describe().c_str(),
     691              :         rankTableInfo.Describe().c_str());
     692              : 
     693            5 :     this->myRank_ = myRank;
     694            5 :     BuildRankGraph();
     695              : 
     696            4 :     HCCL_INFO("[RankGraphBuilder] Build VirtualTopo success!");
     697            4 :     rankGraph_->Dump();
     698            4 :     return std::move(rankGraph_);
     699              : }
     700              : 
     701              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1