LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/selector - base_selector.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 256 0
Test Date: 2026-08-04 10:52:23 Functions: 0.0 % 29 0

            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 "base_selector.h"
      12              : 
      13              : 
      14              : #include <numeric>
      15              : 
      16              : namespace Hccl {
      17            0 : BaseSelector &BaseSelector::SetVirtualTopo(RankGraph *rankGraph)
      18              : {
      19            0 :     rankGraph_ = rankGraph;
      20            0 :     return *this;
      21              : }
      22              : 
      23            0 : BaseSelector &BaseSelector::SetDevType(DevType devType)
      24              : {
      25            0 :     devType_ = devType;
      26            0 :     return *this;
      27              : }
      28              : 
      29            0 : BaseSelector &BaseSelector::SetMyRank(RankId myRank)
      30              : {
      31            0 :     myRank_ = myRank;
      32            0 :     return *this;
      33              : }
      34              : 
      35            0 : BaseSelector &BaseSelector::SetRankSize(u32 rankSize)
      36              : {
      37            0 :     rankSize_ = rankSize;
      38            0 :     return *this;
      39              : }
      40              : 
      41            0 : BaseSelector &BaseSelector::SetSeverId(std::string severId)
      42              : {
      43            0 :     severId_ = severId;
      44            0 :     return *this;
      45              : }
      46              : 
      47            0 : BaseSelector &BaseSelector::SetDeviceNumPerSever(u32 deviceNumPerSever)
      48              : {
      49            0 :     deviceNumPerSever_ = deviceNumPerSever;
      50            0 :     return *this;
      51              : }
      52              : 
      53            0 : BaseSelector &BaseSelector::SetServerNum(u32 serverNum)
      54              : {
      55            0 :     serverNum_ = serverNum;
      56            0 :     return *this;
      57              : }
      58              : 
      59            0 : BaseSelector &BaseSelector::SetIsMc2(bool isMc2)
      60              : {
      61            0 :     isMc2_ = isMc2;
      62            0 :     return *this;
      63              : }
      64              : 
      65            0 : BaseSelector &BaseSelector::SetOpConfig(OpExecuteConfig opConfig)
      66              : {
      67            0 :     opConfig_ = opConfig;
      68            0 :     return *this;
      69              : }
      70              : 
      71            0 : RankGraph *BaseSelector::GetVirtualTopo()
      72              : {
      73            0 :     return rankGraph_;
      74              : }
      75              : 
      76            0 : DevType BaseSelector::GetDevType()
      77              : {
      78            0 :     return devType_;
      79              : }
      80              : 
      81            0 : RankId BaseSelector::GetMyRank() const
      82              : {
      83            0 :     return myRank_;
      84              : }
      85              : 
      86            0 : u32 BaseSelector::GetRankSize() const
      87              : {
      88            0 :     return rankSize_;
      89              : }
      90              : 
      91            0 : std::string BaseSelector::GetSeverId()
      92              : {
      93            0 :     return severId_;
      94              : }
      95              : 
      96            0 : u32 BaseSelector::GetDeviceNumPerSever() const
      97              : {
      98            0 :     return deviceNumPerSever_;
      99              : }
     100              : 
     101            0 : u32 BaseSelector::GetServerNum() const
     102              : {
     103            0 :     return serverNum_;
     104              : }
     105              : 
     106            0 : u32 BaseSelector::Gcd(u32 a, u32 b) const
     107              : {
     108            0 :     while (b != 0) {
     109            0 :         a %= b;
     110            0 :         std::swap(a, b);
     111              :     }
     112            0 :     return a;
     113              : }
     114              : 
     115            0 : u32 BaseSelector::GcdOfArray(const std::vector<u32> &numbers) const
     116              : {
     117            0 :     if (numbers.empty()) {
     118            0 :         return 0;
     119              :     }
     120            0 :     u32 result = numbers[0];
     121            0 :     for (size_t i = 1; i < numbers.size(); ++i) {
     122            0 :         result = Gcd(result, numbers[i]);  // C++17 及以上推荐使用 std::gcd
     123              :     }
     124            0 :     return result;
     125              : }
     126              : 
     127            0 : u32 BaseSelector::GetLevel0Gcd() {
     128            0 :     std::vector<u32> instSizeList = {};
     129            0 :     u32 listSize = 0;
     130            0 :     rankGraph_->GetNetInstanceList(0, instSizeList, listSize);
     131            0 :     return GcdOfArray(instSizeList);
     132            0 : }
     133              : 
     134            0 : bool BaseSelector::IsAsymmetricTopoShapeLevel1Nhr(
     135              :     const std::vector<std::vector<u32>> &localIdPerBoard, u32 gcdRankSizeLevel0) const
     136              : {
     137              :     // Level0的gcd为1分支
     138            0 :     if (gcdRankSizeLevel0 == 1) {
     139            0 :         return true;
     140              :     }
     141              :     // Pod形状不规则分支
     142            0 :     if (localIdPerBoard.size() > 1) {
     143            0 :         if (!IsTopoShapeLevel0Regular(localIdPerBoard)) {
     144            0 :             return true;
     145              :         }
     146              :     }
     147            0 :     return false;
     148              : }
     149              : 
     150            0 : bool BaseSelector::IsTopoShapeLevel0Regular(const std::vector<std::vector<u32>> &localIdPerBoard) const
     151              : {
     152            0 :     u32 rankSizeOfFirstBoard = localIdPerBoard[0].size();
     153            0 :     u32 rankSize = 8;
     154            0 :     for (u32 boardIdx = 1; boardIdx < localIdPerBoard.size(); ++boardIdx) {
     155              :         // 条件1:与第一行rank数是否一致
     156            0 :         if (localIdPerBoard[boardIdx].size() != rankSizeOfFirstBoard) {
     157            0 :             return false;
     158              :         }
     159              :         // 条件2:同一slot内rank数差异是否能被8整除
     160            0 :         for (u32 slotIdx = 0; slotIdx < rankSizeOfFirstBoard; ++slotIdx) {
     161            0 :             if ((localIdPerBoard[boardIdx][slotIdx] - localIdPerBoard[0][slotIdx]) % rankSize != 0) {
     162            0 :                 return false;
     163              :             }
     164              :         }
     165              :     }
     166            0 :     return true;
     167              : }
     168              : 
     169            0 : HcclResult BaseSelector::ExtractNetLayerDetails(TopoInfo &topoInfo) const
     170              : {
     171            0 :     CHK_PRT_RET(rankGraph_ == nullptr, HCCL_ERROR("[BaseSelector][ExtractNetLayerDetails] rankGraph_ is null"), HCCL_E_PTR);
     172              : 
     173            0 :     auto &topoLevelNum = topoInfo.levelNum;
     174            0 :     auto &netLayerNum = topoInfo.netLayerDetails.netLayerNum;
     175            0 :     auto &netLayers = topoInfo.netLayerDetails.netLayers;
     176            0 :     auto &netInstNumOfLayer = topoInfo.netLayerDetails.netInstNumOfLayer;
     177            0 :     auto &instSizeListOfLayer = topoInfo.netLayerDetails.instSizeListOfLayer;
     178            0 :     auto &localNetInsSizeOfLayer = topoInfo.netLayerDetails.localNetInsSizeOfLayer;
     179              : 
     180            0 :     netLayers = rankGraph_->GetLevels(myRank_);  // 有那几层网络 如:[0,1]
     181            0 :     netLayerNum = rankGraph_->GetLevelNum();
     182            0 :     netInstNumOfLayer.resize(netLayerNum);    // 每层网络中有几个网络实例
     183            0 :     instSizeListOfLayer.resize(netLayerNum);  // 每层网络中的各个网络实例的大小
     184            0 :     localNetInsSizeOfLayer.resize(netLayerNum);
     185              : 
     186              :     HcclResult ret;
     187              :     // 获取并校验每一层的网路实例大小
     188            0 :     for (auto layerIdx : netLayers) {
     189            0 :         std::vector<u32> &currLayerInstSizeList = instSizeListOfLayer[layerIdx];
     190            0 :         u32 &currLayerNetInstNum = netInstNumOfLayer[layerIdx];
     191            0 :         ret = rankGraph_->GetNetInstanceList(layerIdx, currLayerInstSizeList, currLayerNetInstNum);
     192            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     193              :             HCCL_ERROR("[BaseSelector][ExtractNetLayerDetails] GetNetInstanceList failed, netLayer[%u]", layerIdx),
     194              :             ret);
     195            0 :         for (u32 i = 0; i < currLayerInstSizeList.size(); i++) {
     196            0 :             HCCL_DEBUG("[BaseSelector][ExtractNetLayerDetails] netInstanceSize[%u] is [%u]", i, currLayerInstSizeList[i]);
     197              :         }
     198            0 :         u32 currLayerRankSize = std::accumulate(currLayerInstSizeList.begin(), currLayerInstSizeList.end(), 0);
     199            0 :         HCCL_INFO("[BaseSelector][ExtractNetLayerDetails] Net layer[%u] instNum[%u]", layerIdx, currLayerNetInstNum);
     200            0 :         CHK_PRT_RET(currLayerRankSize != rankSize_,
     201              :             HCCL_ERROR(
     202              :                 "[BaseSelector][ExtractNetLayerDetails] NetLayer[%u], totalRankSize[%u] is not equal to comm rankSize[%u]",
     203              :                 layerIdx,
     204              :                 currLayerRankSize,
     205              :                 rankSize_),
     206              :             HCCL_E_PARA);
     207            0 :         localNetInsSizeOfLayer[layerIdx] = rankGraph_->GetLocalInstSize(layerIdx);
     208              :     }
     209              : 
     210            0 :     topoLevelNum = 0;
     211              :     // 获取最小的能覆盖所有卡的 layer
     212            0 :     for (auto layerIdx : netLayers) {
     213            0 :         if (netInstNumOfLayer[layerIdx] == 1) {
     214              :             // 当本层只有一个网络实例时, 认为这个就是当前的 topoLevelNum
     215            0 :             topoLevelNum = layerIdx + 1;
     216            0 :             break;
     217              :         }
     218              :     }
     219              : 
     220            0 :     HCCL_INFO(
     221              :         "[BaseSelector][ExtractNetLayerDetails] topoLevelNum[%u], netLayerNum[%u], netLayers.size[%u]",
     222              :         topoLevelNum, netLayerNum, netLayers.size());
     223              : 
     224            0 :     CHK_PRT_RET(topoLevelNum == 0,
     225              :         HCCL_ERROR(
     226              :             "[BaseSelector][ExtractNetLayerDetails] topoLevelNum[%u] is invalid, netLayerNum[%u]", topoLevelNum, netLayerNum),
     227              :         HCCL_E_INTERNAL);
     228            0 :     return HCCL_SUCCESS;
     229              : }
     230              : 
     231            0 : HcclResult BaseSelector::ExtractTopoDetails(TopoInfo &topoInfo) const
     232              : {
     233              :     HcclResult ret;
     234            0 :     CHK_PRT_RET(rankGraph_ == nullptr, HCCL_ERROR("[BaseSelector][ExtractTopoDetails] rankGraph_ is null"), HCCL_E_PTR);
     235            0 :     u32 netLayerNum = topoInfo.netLayerDetails.netLayerNum;
     236              : 
     237              :     // 初始化每一层的 TopoInstDetails
     238            0 :     topoInfo.topoInstDetailsOfLayer.resize(netLayerNum);
     239            0 :     for (u32 netLayerIdx = 0; netLayerIdx < netLayerNum; netLayerIdx++) {
     240            0 :         auto& currentNetLayerTopoTopoDetail = topoInfo.topoInstDetailsOfLayer[netLayerIdx];
     241            0 :         auto& currentLayerTopoSize = currentNetLayerTopoTopoDetail.sizeOfTopo;
     242            0 :         auto& currentLayerTopoType = currentNetLayerTopoTopoDetail.typeOfTopo;
     243            0 :         auto& currentLayerTopoRanks = currentNetLayerTopoTopoDetail.ranksInTopo;
     244            0 :         auto& currentLayerTopo2SizeMap = currentNetLayerTopoTopoDetail.rankNumForTopoType;
     245            0 :         auto& topoInstNum = currentNetLayerTopoTopoDetail.topoInstNum;
     246              : 
     247            0 :         std::vector<u32> topoInsts;
     248            0 :         rankGraph_->GetTopoInstsByLayer(netLayerIdx, topoInsts, topoInstNum);
     249            0 :         HCCL_INFO("[BaseSelector][ExtractTopoDetails] netLayerIdx[%u], topoInstNum[%u]", netLayerIdx, topoInstNum);
     250              :         // 初始化当前层的拓扑信息
     251            0 :         currentLayerTopoSize.resize(topoInstNum);
     252            0 :         currentLayerTopoType.resize(topoInstNum);
     253            0 :         currentLayerTopoRanks.resize(topoInstNum);
     254            0 :         currentLayerTopo2SizeMap.clear();
     255              : 
     256              :         // 填充当前层的拓扑信息
     257            0 :         for (u32 topoInstIdx = 0; topoInstIdx < topoInstNum; topoInstIdx++) {
     258            0 :             u32& topoInstId = topoInsts[topoInstIdx];
     259            0 :             u32& topoSize = currentLayerTopoSize[topoInstIdx];
     260            0 :             TopoType& topoType = currentLayerTopoType[topoInstIdx];
     261            0 :             std::vector<u32>& ranks= currentLayerTopoRanks[topoInstIdx];
     262              : 
     263              :             // 获取拓扑实例的类型
     264            0 :             ret = rankGraph_->GetTopoType(netLayerIdx, topoInstId, topoType);
     265            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     266              :                 HCCL_ERROR("[BaseSelector][ExtractTopoDetails] GetTopoType failed, netLayerIdx[%u], topoInstId[%u]",
     267              :                     netLayerIdx, topoInstId), ret);
     268              : 
     269              :             // 获取拓扑实例中包含的rank
     270            0 :             ret = rankGraph_->GetRanksByTopoInst(netLayerIdx, topoInstId, ranks, topoSize);
     271            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     272              :                 HCCL_ERROR("[BaseSelector][ExtractTopoDetails] GetRanksByTopoInst failed, netLayerIdx[%u], topoInstId[%u]",
     273              :                     netLayerIdx, topoInstId), ret);
     274              : 
     275              :             // 将topoInstId按照topoType进行归类
     276            0 :             currentLayerTopo2SizeMap[topoType].push_back(topoSize);
     277              : 
     278            0 :             HCCL_INFO("[BaseSelector][ExtractTopoDetails] netLayerIdx[%u], topoInstIdx[%u] type is[%s], topoInstId is[%u], "
     279              :                     "topoSize is[%u]",
     280              :                 netLayerIdx,
     281              :                 topoInstIdx,
     282              :                 topoType.Describe().c_str(),
     283              :                 topoInstId,
     284              :                 topoSize);
     285              :         }
     286            0 :     }
     287            0 :     return HCCL_SUCCESS;
     288              : }
     289              : 
     290            0 : HcclResult BaseSelector::CalcLevel0TopoShape(TopoInfo &topoInfo) const
     291              : {
     292            0 :     u32 netLayer = 0;
     293            0 :     u32 topoInstNum2 = 2;
     294            0 :         u32 topoInstNum3 = 3;
     295            0 :     CHK_PRT_RET(topoInfo.topoInstDetailsOfLayer.size() <= netLayer,
     296              :         HCCL_ERROR("[BaseSelector][CalcLevel0TopoShape] topoInstNumOfLayer size[%zu] <= netLayer[%u]", topoInfo.topoInstDetailsOfLayer.size(), netLayer),
     297              :         HCCL_E_INTERNAL);
     298            0 :     TopoInstDetails &level0TopoInstDetails = topoInfo.topoInstDetailsOfLayer[netLayer];
     299            0 :     CHK_PRT_RET(topoInfo.netLayerDetails.localNetInsSizeOfLayer.size() <= netLayer,
     300              :         HCCL_ERROR("[BaseSelector][CalcLevel0TopoShape] localNetInsSizeOfLayer size[%zu] <= netLayer[%u]", topoInfo.netLayerDetails.localNetInsSizeOfLayer.size(), netLayer),
     301              :         HCCL_E_INTERNAL);
     302            0 :     u32 level0LocalRankSize = topoInfo.netLayerDetails.localNetInsSizeOfLayer[netLayer];
     303              : 
     304            0 :     auto &topoInstNum = level0TopoInstDetails.topoInstNum;
     305            0 :     auto &rankNumForTopoType = level0TopoInstDetails.rankNumForTopoType;
     306            0 :     HCCL_INFO("[%s]topoInstNum[%u]", __func__, topoInstNum);
     307            0 :     for (const auto &iter: rankNumForTopoType) {
     308            0 :         HCCL_INFO("[%s]topoType[%d] size[%lu]", __func__, iter.first, iter.second.size());
     309              :     }
     310              : 
     311            0 :     if (topoInstNum == 1 && rankNumForTopoType[TopoType::MESH_1D].size() == 1) {
     312              :         // MESH_1D 拓扑校验
     313            0 :         CHK_PRT_RET(rankNumForTopoType[TopoType::MESH_1D][0] != level0LocalRankSize,
     314              :             HCCL_ERROR("[BaseSelector][CalcLevel0TopoShape] MESH_1D rankSize[%u] is not equal to level0LocalRankSize[%u]",
     315              :                 rankNumForTopoType[TopoType::MESH_1D][0],
     316              :                 level0LocalRankSize),
     317              :             HCCL_E_INTERNAL);
     318            0 :         topoInfo.level0Shape = Level0Shape::MESH_1D;
     319            0 :         return HCCL_SUCCESS;
     320            0 :     } else if (topoInstNum == 1 && rankNumForTopoType[TopoType::CLOS].size() == 1) {
     321              :         // CLOS 拓扑校验
     322            0 :         CHK_PRT_RET(rankNumForTopoType[TopoType::CLOS][0] != level0LocalRankSize,
     323              :             HCCL_ERROR("[BaseSelector][CalcLevel0TopoShape] CLOS rankSize[%u] is not equal to level0LocalRankSize[%u]",
     324              :                 rankNumForTopoType[TopoType::CLOS][0],
     325              :                 level0LocalRankSize),
     326              :             HCCL_E_INTERNAL);
     327            0 :         topoInfo.level0Shape = Level0Shape::CLOS;
     328            0 :         if (IsLevel0PcieMix()) {
     329            0 :             topoInfo.level0PcieMix = true;
     330              :         }
     331            0 :         return HCCL_SUCCESS;
     332            0 :     } else if (topoInstNum == topoInstNum2 && rankNumForTopoType[TopoType::CLOS].size() == 1 &&
     333            0 :                rankNumForTopoType[TopoType::MESH_1D].size() == 1) {
     334              :         // MESH_1D_CLOS 拓扑校验
     335            0 :         CHK_PRT_RET(rankNumForTopoType[TopoType::CLOS][0] != level0LocalRankSize,
     336              :             HCCL_ERROR("[BaseSelector][CalcLevel0TopoShape] CLOS rankSize[%u] is not equal to level0LocalRankSize[%u]",
     337              :                 rankNumForTopoType[TopoType::CLOS][0],
     338              :                 level0LocalRankSize),
     339              :             HCCL_E_INTERNAL);
     340            0 :         topoInfo.level0Shape = Level0Shape::MESH_1D_CLOS;
     341              : 
     342            0 :         if (IsLevel0PcieMix()) {
     343            0 :             topoInfo.level0PcieMix = true;
     344              :         }
     345            0 :         if (rankNumForTopoType[TopoType::CLOS].at(0) > BIG_CLOS_RANGE) {
     346            0 :             topoInfo.level0BigClosRange = true;
     347              :         }
     348            0 :         return HCCL_SUCCESS;
     349            0 :     } else if (topoInstNum == topoInstNum3 && rankNumForTopoType[TopoType::MESH_1D].size() == topoInstNum2 &&
     350            0 :                rankNumForTopoType[TopoType::CLOS].size() == 1) {
     351              :         // MESH_2D 拓扑校验
     352            0 :         CHK_PRT_RET(rankNumForTopoType[TopoType::MESH_1D][0] * rankNumForTopoType[TopoType::MESH_1D][1] != level0LocalRankSize,
     353              :             HCCL_ERROR(
     354              :                 "[BaseSelector][CalcLevel0TopoShape] mesh rankSize[%u] * [%u] is not equal to level0LocalRankSize[%u]",
     355              :                 rankNumForTopoType[TopoType::MESH_1D][0],
     356              :                 rankNumForTopoType[TopoType::MESH_1D][1],
     357              :                 level0LocalRankSize),
     358              :             HCCL_E_INTERNAL);
     359            0 :         topoInfo.level0Shape = Level0Shape::MESH_2D;
     360            0 :         return HCCL_SUCCESS;
     361              :     }
     362            0 :     HCCL_ERROR("Unknown topo for level 0, topoInstNum[%u]", topoInstNum);
     363            0 :     return HCCL_E_INTERNAL;
     364              : }
     365              : 
     366            0 : void BaseSelector::CalcTopoShape(TopoInfo &topoInfo) const
     367              : {
     368            0 :     CHK_PRT_THROW(ExtractNetLayerDetails(topoInfo) != HCCL_SUCCESS,
     369              :         HCCL_ERROR("[BaseSelector][CalcTopoShape] ExtractNetLayerDetails Failed"),
     370              :         InvalidParamsException, "ExtractNetLayerDetails Failed");
     371            0 :     HCCL_INFO("[BaseSelector][CalcTopoShape] topoInfo.levelNum is [%u]", topoInfo.levelNum);
     372              : 
     373            0 :     CHK_PRT_THROW(ExtractTopoDetails(topoInfo) != HCCL_SUCCESS,
     374              :         HCCL_ERROR("[BaseSelector][CalcTopoShape] ExtractTopoDetails Failed"),
     375              :         InvalidParamsException, "ExtractTopoDetails Failed");
     376            0 :     HCCL_INFO("[BaseSelector][ExtractTopoDetails] topoInstDetails size[%zu]", topoInfo.topoInstDetailsOfLayer.size());
     377              : 
     378            0 :     CHK_PRT_THROW(CalcLevel0TopoShape(topoInfo),
     379              :         HCCL_ERROR("[BaseSelector][CalcTopoShape] CalcLevel0TopoShape Failed"),
     380              :         InvalidParamsException, "CalcLevel0TopoShape Failed");
     381            0 :     HCCL_INFO("[BaseSelector][CalcTopoShape] topoInfo.level0Shape is [%d], level0PcieMix is [%d], level0BigClosRange is [%d]", 
     382              :         topoInfo.level0Shape, topoInfo.level0PcieMix, topoInfo.level0BigClosRange);
     383            0 : }
     384              : 
     385            0 : bool BaseSelector::IsLayerAllConnetedWithTopo(const TopoInfo &topoInfo, const u32 netLayer, const TopoType topoType) const
     386              : {
     387            0 :     CHK_PRT_THROW(rankGraph_ == nullptr,
     388              :         HCCL_ERROR("[BaseSelector][IsLayerAllConnetedWithTopo] rankGraph is nullptr"),
     389              :         NullPtrException, "[IsLayerAllConnetedWithTopo] rankGraph is nullptr");
     390              : 
     391            0 :     CHK_PRT_RET(topoInfo.netLayerDetails.localNetInsSizeOfLayer.size() <= netLayer,
     392              :         HCCL_WARNING("[BaseSelector][IsLayerAllConnetedWithTopo] localNetInsSizeOfLayer size[%zu] <= netLayer[%u]",
     393              :         topoInfo.netLayerDetails.localNetInsSizeOfLayer.size(), netLayer), false);
     394            0 :     u32 localRankSize = topoInfo.netLayerDetails.localNetInsSizeOfLayer[netLayer];
     395              : 
     396            0 :     CHK_PRT_RET(topoInfo.topoInstDetailsOfLayer.size() <= netLayer,
     397              :         HCCL_WARNING("[BaseSelector][IsLayerAllConnetedWithTopo] topoInstDetailsOfLayer size[%zu] <= netLayer[%u]",
     398              :         topoInfo.topoInstDetailsOfLayer.size(), netLayer), false);
     399              : 
     400            0 :     auto rankNumForTopoTypeItr = topoInfo.topoInstDetailsOfLayer[netLayer].rankNumForTopoType.find(topoType);
     401            0 :     if (rankNumForTopoTypeItr == topoInfo.topoInstDetailsOfLayer[netLayer].rankNumForTopoType.end()) {
     402            0 :         return false;
     403              :     }
     404              : 
     405            0 :     for (auto topoRankNum : rankNumForTopoTypeItr->second) {
     406            0 :         if (topoRankNum == localRankSize) {
     407            0 :             return true;
     408              :         }
     409              :     }
     410            0 :     return false;
     411              : }
     412              : 
     413            0 : bool BaseSelector::IsInputOutputOverlap(const std::shared_ptr<Buffer> &inputMem, const std::shared_ptr<Buffer> &outputMem) const
     414              : {
     415            0 :     CHK_PRT_RET(inputMem == nullptr || outputMem == nullptr,
     416              :         HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer is null. Not overlap."),
     417              :         false);
     418              : 
     419            0 :     u64 inputStart = inputMem->GetAddr();
     420            0 :     u64 outputStart = outputMem->GetAddr();
     421              : 
     422            0 :     CHK_PRT_RET(inputStart == 0 || outputStart == 0,
     423              :         HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer addr is null. Not overlap."),
     424              :         false);
     425              : 
     426            0 :     u64 inputDataSize = inputMem->GetSize();
     427            0 :     u64 outputDataSize = outputMem->GetSize();
     428              : 
     429            0 :     CHK_PRT_RET(inputDataSize == 0 || outputDataSize == 0,
     430              :         // 不存在overlap情况
     431              :         HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] The input or output buffer size is 0. Not overlap."),
     432              :         false);
     433              : 
     434            0 :     u64 inputEnd = inputStart + inputDataSize - 1;
     435            0 :     u64 outputEnd = outputStart + outputDataSize - 1;
     436              : 
     437            0 :     HCCL_DEBUG("[Algo][BaseSelector][IsInputOutputOverlap] inputStart[%llu], inputEnd[%llu], outputStart[%llu], "
     438              :                "outputEnd[%llu].",
     439              :         inputStart,
     440              :         inputEnd,
     441              :         outputStart,
     442              :         outputEnd);
     443              : 
     444            0 :     CHK_PRT_RET(inputStart <= outputEnd && outputStart <= inputEnd,
     445              :         HCCL_INFO("[Algo][BaseSelector][IsInputOutputOverlap] inputStart[%llu], inputEnd[%llu], outputStart[%llu], "
     446              :                   "outputEnd[%llu]. Overlap detected.",
     447              :             inputStart,
     448              :             inputEnd,
     449              :             outputStart,
     450              :             outputEnd),
     451              :         true);
     452              : 
     453            0 :     HCCL_DEBUG("[Algo][BaseSelector][IsInputOutputOverlap]No overlap between input and output memory.");
     454            0 :     return false;
     455              : }
     456              : 
     457            0 : bool BaseSelector::Is2DieFullMesh() const
     458              : {
     459            0 :     u32 netLayer = 0;  // 0 级拓扑
     460            0 :     const NetInstance *netInstance = rankGraph_->GetNetInstanceByRankId(netLayer, myRank_);
     461            0 :     std::set<RankId> rankSet = netInstance->GetRankIds();
     462            0 :     if (rankSet.size() <= 2) { // 小于2张卡的话,肯定不是2die全互连
     463            0 :         return false;
     464              :     }
     465              :     // 遍历所有对端,校验是否和所有卡有全连链路,并判断链路中本端端口所所对应的 CCU die 是否一致;
     466            0 :     u32 dieNum = 2;  // 一共2个die
     467            0 :     std::vector<u32> dieLinkCounter(dieNum, 0);
     468            0 :     for (RankId rankId : rankSet) {
     469            0 :         if (rankId == myRank_) {
     470            0 :             continue;
     471              :         }
     472            0 :         std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(netLayer, myRank_, rankId);
     473            0 :         CHK_PRT_RET(paths.size() == 0 || paths[0].links.size() == 0,
     474              :             HCCL_INFO("[BaseSelector][Is2DieFullMesh], Can not find path from Local[%d] to Rmt[%d], in netLayer %u. "
     475              :                       "Topo is not mesh",
     476              :                 myRank_,
     477              :                 rankId,
     478              :                 netLayer),
     479              :             false);
     480            0 :         NetInstance::Link &link = paths[0].links[0];  // 只取第一条路径的第一条link
     481            0 :         std::shared_ptr<NetInstance::ConnInterface> connInterface = link.GetSourceIface();
     482            0 :         u32 dieID = connInterface->GetLocalDieId();
     483            0 :         CHK_PRT_RET(dieID >= dieNum,
     484              :             HCCL_WARNING(
     485              :                 "[BaseSelector][Is2DieFullMesh], Link from Local[%d] to Rmt[%d] die id[%u] is out of range[%u].",
     486              :                 myRank_,
     487              :                 rankId,
     488              :                 dieID,
     489              :                 dieNum), false);
     490            0 :         dieLinkCounter[dieID]++;
     491            0 :         HCCL_INFO("[BaseSelector][Is2DieFullMesh], Link from Local[%d] to Rmt[%d] use die[%u], current counter[%u]",
     492              :             myRank_, rankId, dieID, dieLinkCounter[dieID]);
     493            0 :     }
     494            0 :     for (u32 i = 0; i < dieNum; i++) {
     495            0 :         if (dieLinkCounter[i] == 0) {
     496            0 :             return false;
     497              :         }
     498              :     }
     499            0 :     return true;
     500            0 : }
     501              : 
     502            0 : bool BaseSelector::IsLevel0PcieMix() const
     503              : {
     504            0 :     u32 netLayer = 0;  // 0 级拓扑
     505            0 :     const NetInstance *netInstance = rankGraph_->GetNetInstanceByRankId(netLayer, myRank_);
     506            0 :     std::set<RankId> rankSet = netInstance->GetRankIds();
     507            0 :     for (RankId rankId : rankSet) {
     508            0 :         if (rankId == myRank_) {
     509            0 :             continue;
     510              :         }
     511            0 :         std::vector<NetInstance::Path> paths = rankGraph_->GetPaths(netLayer, myRank_, rankId);
     512            0 :         CHK_PRT_RET(paths.size() == 0 || paths[0].links.size() == 0,
     513              :             HCCL_INFO("[BaseSelector][IsLevel0PcieMix], Can not find path from Local[%d] to Rmt[%d], in netLayer %u. "
     514              :                       "Topo is not mesh",
     515              :                 myRank_,
     516              :                 rankId,
     517              :                 netLayer),
     518              :             false);
     519            0 :         NetInstance::Link &link = paths[0].links[0];  // 只取第一条路径的第一条link
     520            0 :         std::shared_ptr<NetInstance::ConnInterface> connInterface = link.GetSourceIface();
     521            0 :         std::set<LinkProtocol> linkProtocolsSet = connInterface->GetLinkProtocols();
     522              :         // 判断协议类型包含PCIE
     523            0 :         if (linkProtocolsSet.find(LinkProtocol::PCIE) != linkProtocolsSet.end()) {
     524            0 :             HCCL_INFO("IsLevel0PcieMix[true]");
     525            0 :             return true;
     526              :         }
     527            0 :     }
     528            0 :     HCCL_INFO("IsLevel0PcieMix[false]");
     529            0 :     return false;
     530            0 : }
     531              : }  // namespace Hccl
        

Generated by: LCOV version 2.0-1