LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/communicator - topo_info_extractor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.0 % 899 800
Test Date: 2026-07-28 12:11:00 Functions: 93.9 % 49 46

            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 "topo_info_extractor.h"
      12              : #include "externalinput_pub.h"
      13              : #include "device_capacity.h"
      14              : #include "search_path.h"
      15              : #include "comm_base_pub.h"
      16              : #include "hccl_impl_pub.h"
      17              : 
      18              : 
      19              : namespace hccl {
      20              : 
      21              : constexpr u32 SERVER_RANK_SIZE = 8;
      22              : 
      23          520 : TopoInfoExtractor::TopoInfoExtractor(HcclAlgoAttr &algoAttr, HcclTopoAttr &topoAttr, const TopoType topoType)
      24          520 :     : identifier_(algoAttr.identifier), userRank_(topoAttr.userRank), userRankSize_(topoAttr.userRankSize),
      25          520 :       topoType_(topoType), deviceType_(topoAttr.deviceType), rankVector_(topoAttr.rankInfoList),
      26         1040 :       meshAggregationRankSize_(topoAttr.meshAggregationRankSize), isUsedRdmaLevel0_(algoAttr.isUsedRdmaLevel0),
      27          520 :       isUsedInterHccsMode_(algoAttr.isUsedInterHccsMode), isDiffAggregation_(topoAttr.isDiffDeviceModule),
      28          520 :       isConfigAHC_(false),
      29          520 :       isConfigNULL_(false),
      30          520 :       multiModuleDiffDeviceNumMode_(topoAttr.multiModuleDiffDeviceNumMode),
      31          520 :       multiSuperPodDiffServerNumMode_(topoAttr.multiSuperPodDiffServerNumMode),
      32          520 :       multiSuperPodDiffDeviceNumMode_(topoAttr.multiSuperPodDiffDeviceNumMode),
      33          520 :       isDiffDeviceType_(topoAttr.isDiffDeviceType),
      34          520 :       gcdDeviceNumPerAggregation_(topoAttr.gcdDeviceNumPerAggregation),
      35         1040 :       CommPlaneSubGroupVector_(COMM_LEVEL_RESERVED),
      36         2080 :       CommPlaneVector_(COMM_LEVEL_RESERVED)
      37          520 : { };
      38              : 
      39              : #ifdef CCL_LLT
      40              : // 为了适配老的LLT框架提供的构造函数
      41           11 : TopoInfoExtractor::TopoInfoExtractor(std::string identifier, u32 userRank, u32 userRankSize, TopoType topoType,
      42              :     DevType deviceType, std::vector<RankInfo>& rankVector, u32 meshAggregationRankSize,
      43              :     bool isUsedRdmaLevel0, bool isUsedInterHccsMode, bool multiModuleDiffDeviceNumMode, bool multiSuperPodDiffServerNumMode,
      44           11 :     bool multiSuperPodDiffDeviceNumMode, bool isDiffDeviceType, u32 gcdDeviceNumPerAggregation)
      45           11 :     : identifier_(identifier), userRank_(userRank), userRankSize_(userRankSize), topoType_(topoType),
      46           11 :       deviceType_(deviceType), rankVector_(rankVector), meshAggregationRankSize_(meshAggregationRankSize),
      47           11 :       isUsedRdmaLevel0_(isUsedRdmaLevel0), isUsedInterHccsMode_(isUsedInterHccsMode), isDiffAggregation_(false),
      48           11 :       multiModuleDiffDeviceNumMode_(multiModuleDiffDeviceNumMode),
      49           11 :       multiSuperPodDiffServerNumMode_(multiSuperPodDiffServerNumMode),
      50           11 :       multiSuperPodDiffDeviceNumMode_(multiSuperPodDiffDeviceNumMode),
      51           11 :       isDiffDeviceType_(isDiffDeviceType), gcdDeviceNumPerAggregation_(gcdDeviceNumPerAggregation),
      52           11 :       isConfigAHC_(false),
      53           11 :       isConfigNULL_(false),
      54           22 :       CommPlaneVector_(COMM_LEVEL_RESERVED),
      55           44 :       CommPlaneSubGroupVector_(COMM_LEVEL_RESERVED)
      56           11 : {};
      57              : #endif
      58              : 
      59         1061 : TopoInfoExtractor::~TopoInfoExtractor()
      60          531 : {}
      61              : 
      62          523 : HcclResult TopoInfoExtractor::Init(std::map<HcclCMDType, std::vector<HcclAlgoType>> &algoConfig)
      63              : {
      64          523 :     HCCL_INFO(
      65              :         "factory init:collective id[%s], user rank[%u], user rank size[%u], topo type[%d], device Type[%d], "\
      66              :         "meshAggregationRankSize[%u]",
      67              :         identifier_.c_str(), userRank_, userRankSize_, topoType_, deviceType_, meshAggregationRankSize_);
      68              : 
      69              :     // 参数有效性校验
      70          523 :     CHK_RET(CheckInitInfo());
      71              : 
      72              :     // 初始化 AHC 相关信息
      73          523 :     InitAHCConfig(algoConfig);
      74              : 
      75              :     // 填充必要数据结构
      76          523 :     CHK_RET(SetRankInfo());
      77              : 
      78          522 :     if (IsGeneralServer() && GetRemoteIsHdc()) {
      79            0 :         HCCL_INFO("heterog ES ps factory init no need set topoInfo");
      80              :     } else {
      81              :         // 设置拓扑信息
      82          522 :         CHK_RET(SetTopologyInfo());
      83              :         // 根据拓扑类型以及芯片类型,校验两层拓扑(外层/内层)、单层拓扑的平面个数合法性
      84          522 :         CHK_RET(CheckPlaneInfo());
      85              :     }
      86              : 
      87          522 :     CHK_RET(SetRankMap());
      88          522 :     return HCCL_SUCCESS;
      89              : }
      90              : 
      91          522 : HcclResult TopoInfoExtractor::SetRankMap()
      92              : {
      93              :     // 构建由UserRank到子通信域的映射
      94          522 :     subCommRank2UserRank_.resize(static_cast<u32>(COMM_LEVEL_RESERVED));
      95          522 :     userRank2subCommRank_.resize(static_cast<u32>(COMM_LEVEL_RESERVED));
      96          522 :     HCCL_DEBUG("[TopoInfoExtractor]SetRankMap begin");
      97              : 
      98         8874 :     for (u32 levelIndex = 0; levelIndex < CommPlaneVector_.size(); levelIndex++) {
      99         8352 :         u32 ringSize = CommPlaneVector_[levelIndex].size();
     100         8352 :         subCommRank2UserRank_[levelIndex].resize(ringSize);
     101         8352 :         userRank2subCommRank_[levelIndex].resize(ringSize);
     102        14069 :         for (u32 ringIndex = 0; ringIndex < ringSize; ringIndex++) {
     103         5717 :             u32 rankSize = CommPlaneVector_[levelIndex][ringIndex].size();
     104        17274 :             for (u32 rankIndex = 0; rankIndex < rankSize; rankIndex++) {
     105        11557 :                 u32 userRank = CommPlaneVector_[levelIndex][ringIndex][rankIndex].userRank;
     106        11557 :                 subCommRank2UserRank_[levelIndex][ringIndex][rankIndex] = userRank;
     107        11557 :                 userRank2subCommRank_[levelIndex][ringIndex][userRank] = rankIndex;
     108              :             }
     109              :         }
     110              :     }
     111          522 :     return HCCL_SUCCESS;
     112              : }
     113              : 
     114         1053 : HcclResult TopoInfoExtractor::CheckInitInfo()
     115              : {
     116         1053 :     if (rankVector_.size() == 0) {
     117            0 :         HCCL_ERROR("[Check][InitInfo]Not support the scenes: rank_vector size is zero");
     118            0 :         return HCCL_E_PARA;  // 没有rank_table的场景直接报错
     119              :     }
     120              : 
     121              :     // 构造函数入参有效性检查:user_rank_size与user_rank_
     122         1053 :     if (userRankSize_ <= userRank_) {
     123            0 :         HCCL_ERROR("[Check][InitInfo]userRankSize_[%u] or userRank_[%u] is invalid.", userRankSize_, userRank_);
     124            0 :         return HCCL_E_PARA;
     125              :     }
     126              : 
     127         1053 :     if (userRankSize_ != rankVector_.size()) {
     128            0 :         HCCL_ERROR("[Check][InitInfo]userRankSize_[%u] is not equal to rank_vector size[%llu].", userRankSize_,\
     129              :             rankVector_.size());
     130            0 :         return HCCL_E_PARA;
     131              :     }
     132              : 
     133         1053 :     bool isParaInvalid = ((topoType_ == TopoType::TOPO_TYPE_RESERVED) || (deviceType_ >= DevType::DEV_TYPE_COUNT));
     134         1053 :     if (isParaInvalid) {
     135            2 :         HCCL_ERROR("[Check][InitInfo]Not support the scenes: TopoType[%d] or deviceType[%d] is invalid.",
     136              :             topoType_, deviceType_);
     137            2 :         return HCCL_E_PARA;
     138              :     }
     139              : 
     140              :     // 入参组合有效性检查:不支持4P_RING
     141         1051 :     if ((deviceType_ == DevType::DEV_TYPE_910 || deviceType_ == DevType::DEV_TYPE_910B ||
     142         1051 :          deviceType_ == DevType::DEV_TYPE_910_93) && (topoType_ == TopoType::TOPO_TYPE_4P_RING)) {
     143            1 :         HCCL_ERROR("[Check][InitInfo]Not support the scenes: TopoType[%d] with deviceType[%d] is invalid.", topoType_,
     144              :             deviceType_);
     145            1 :         return HCCL_E_PARA;
     146              :     }
     147              : 
     148         1050 :     return HCCL_SUCCESS;
     149              : }
     150              : 
     151          523 : HcclResult TopoInfoExtractor::SetRankInfo()
     152              : {
     153          838 :     for (u32 index = 0; index < rankVector_.size(); index++) {
     154          838 :         if (userRank_ == rankVector_[index].userRank) {
     155          523 :             rankData_ = rankVector_[index];
     156          523 :             HCCL_INFO("[SetRankInfo]rankData_: userRank[%u], devicePhyId[%d], serverIdx[%u], superPodId[%s], superPodIdx[%u]",
     157              :                 rankData_.userRank, rankData_.devicePhyId, rankData_.serverIdx, rankData_.superPodId.c_str(), rankData_.superPodIdx);
     158          523 :             break;
     159              :         }
     160              :     }
     161              : 
     162          523 :     std::set<u32> serverIdxs;
     163          523 :     std::set<u32> moduleIdxs;
     164         2162 :     for (u32 index = 0; index < rankVector_.size(); index++) {
     165              :         // 填充superPodRankMap_, 记录superPodId -> rankInfo
     166         1639 :         auto itSuperPod = superPodToRank_.find(rankVector_[index].superPodIdx);
     167         1639 :         if (itSuperPod != superPodToRank_.end()) {
     168         1075 :             itSuperPod->second.push_back(rankVector_[index]);
     169              :         } else {
     170          564 :             std::vector<RankInfo> rankVecTmp;
     171          564 :             rankVecTmp.push_back(rankVector_[index]);
     172          564 :             superPodToRank_.insert(std::make_pair(rankVector_[index].superPodIdx, rankVecTmp));
     173          564 :         }
     174              : 
     175         1639 :         u32 moduleIdx = 0;
     176         1639 :         CHK_RET(GetModuleIdx(rankVector_[index], moduleIdx));
     177         1639 :         moduleIdxs.insert(moduleIdx);
     178              :         // 填充serverRankMap_, 只记录本superPod下的serverIdx -> rankInfo
     179         1639 :         if (rankVector_[index].superPodId == rankData_.superPodId || isDiffDeviceType_) {
     180         1588 :             auto itServer = serverToRank_.find(moduleIdx);
     181         1588 :             if (itServer != serverToRank_.end()) {  // 存在该服务器内相关rank的对应信息
     182          896 :                 itServer->second.push_back(rankVector_[index]);
     183              :             } else {  // 不存在则新增一条map记录
     184          692 :                 std::vector<RankInfo> rankVecTmp;
     185          692 :                 rankVecTmp.push_back(rankVector_[index]);
     186          692 :                 serverToRank_.insert(std::make_pair(moduleIdx, rankVecTmp));
     187          692 :             }
     188              :         }
     189              : 
     190              :         // 填充 serverToRankMerge_, server 和 superPod 两层合并的通信域内所有 rank 信息
     191         1639 :         auto itServer = serverToRankMerge_.find(moduleIdx);
     192         1639 :         if (itServer != serverToRankMerge_.end()) { // 存在该服务器内相关rank的对应信息
     193          898 :             itServer->second.push_back(rankVector_[index]);
     194              :         } else { // 不存在则新增一条map记录
     195          741 :             std::vector<RankInfo> rankVecTmp;
     196          741 :             rankVecTmp.push_back(rankVector_[index]);
     197          741 :             serverToRankMerge_.insert(std::make_pair(moduleIdx, rankVecTmp));
     198          741 :         }
     199              : 
     200              :         // 同一个server内, 记录本rank和其他rank的链路
     201         1639 :         if (rankVector_[index].serverIdx == rankData_.serverIdx) {
     202         1336 :             LinkTypeInServer linkType = LinkTypeInServer::RESERVED_LINK_TYPE;
     203         1336 :             if (rankData_.devicePhyId != rankVector_[index].devicePhyId &&
     204          813 :                 rankData_.devicePhyId != HOST_DEVICE_ID &&
     205         2962 :                 rankVector_[index].devicePhyId != HOST_DEVICE_ID &&
     206          813 :                 topoType_ != TopoType::TOPO_TYPE_HETEROG) {
     207          813 :                 CHK_RET(hrtGetPairDeviceLinkType(rankData_.devicePhyId, rankVector_[index].devicePhyId, linkType));
     208              :             }
     209         1336 :             deviceLinkTypeMap_.insert(std::make_pair(rankVector_[index].devicePhyId, linkType));
     210              :         }
     211              : 
     212         1639 :         u32 serverIdx = 0;
     213         1639 :         CHK_RET(GetServerIdx(rankVector_[index], serverIdx));
     214         1639 :         serverIdxs.insert(serverIdx);
     215              :     }
     216              : 
     217          523 :     u32 rankNumPerAggregation = userRankSize_ / static_cast<u32>(moduleIdxs.size());
     218          523 :     if (isDiffDeviceType_) {
     219            0 :         rankNumPerAggregation = gcdDeviceNumPerAggregation_;
     220            0 :         HCCL_INFO("[SetRankInfo] isDiffDeviceType[%u] userRankSize[%u] moduleIdxs.size[%u] rankNumPerAggregation[%u]",
     221              :             isDiffDeviceType_, userRankSize_, moduleIdxs.size(), rankNumPerAggregation);
     222              :     }
     223              : 
     224              :     // 调整每个server内的user_rank排序(server内userRank从小到大,一定连续)
     225         1215 :     for (auto iterMap = serverToRank_.begin(); iterMap != serverToRank_.end(); iterMap++) {
     226          692 :         if (!(iterMap->second).empty()) {
     227          692 :             std::sort(iterMap->second.begin(), iterMap->second.end(), Ascending);
     228              :         }
     229              :     }
     230              : 
     231              :     // 调整每个superPod内的user_rank排序, 按照serverIdx从小到大、userRank从小到大排序
     232         1087 :     for (auto iterMap = superPodToRank_.begin(); iterMap != superPodToRank_.end(); iterMap++) {
     233          564 :         if (!(iterMap->second).empty()) {
     234          564 :             std::sort(iterMap->second.begin(), iterMap->second.end(), Ascending);
     235              :         }
     236              :     }
     237              : 
     238              :     // 调整多个 superPod 合并的 user_rank 排序,按照 serverIdx 从小到大、userRank从小到大排序
     239         1264 :     for (auto iterMap = serverToRankMerge_.begin(); iterMap!= serverToRankMerge_.end(); iterMap++) {
     240          741 :         if (!(iterMap->second).empty()) {
     241          741 :             std::sort(iterMap->second.begin(), iterMap->second.end(), Ascending);
     242              :         }
     243              :     }
     244              : 
     245         1215 :     for (auto it = serverToRank_.begin(); it != serverToRank_.end(); it++) {
     246          692 :         HCCL_DEBUG("[SetRankInfo][MIX_DEBUG] serverID[%u]", it->first);
     247         2280 :         for (auto index = it->second.begin(); index != it->second.end(); index++) {
     248         1588 :             HCCL_DEBUG("[SetRankInfo][MIX_DEBUG] userRank[%u], devicePhyId[%d], serverIdx[%u], superPodId[%s]",
     249              :                 index->userRank, index->devicePhyId, index->serverIdx, index->superPodId.c_str());
     250              :         }
     251              :     }
     252              : 
     253         1264 :     for (auto it = serverToRankMerge_.begin(); it != serverToRankMerge_.end(); it++) {
     254          741 :         HCCL_DEBUG("[SetRankInfo][AHC_DEBUG] serverID[%u]", it->first);
     255         2380 :         for (auto index = it->second.begin(); index != it->second.end(); index++) {
     256         1639 :             HCCL_DEBUG("[SetRankInfo][AHC_DEBUG] userRank[%u], devicePhyId[%d], serverIdx[%u], superPodId[%s]",
     257              :                 index->userRank, index->devicePhyId, index->serverIdx, index->superPodId.c_str());
     258              :         }
     259              :     }
     260          523 :     HCCL_DEBUG("[SetRankInfo][AHC_DEBUG] rankNumPerAggregation[%u] moduleIdxs.size()=[%u]",
     261              :         rankNumPerAggregation, moduleIdxs.size());
     262              : 
     263          523 :     ranksOneNode_ = { 0, 8, 4, 2, 1, 4, rankNumPerAggregation, 0, rankNumPerAggregation, rankNumPerAggregation};
     264              : 
     265              :     // 校验每个server内的设备个数与topo类型的组合是否正确
     266          523 :     if (topoType_ != TopoType::TOPO_TYPE_COMMON) {
     267          485 :         CHK_RET(CheckServerInfo());
     268              :     }
     269              :     // 校验每个superPod下的device数量相同
     270          522 :     CHK_RET(CheckSuperPodInfo());
     271              : 
     272          522 :     return HCCL_SUCCESS;
     273          523 : }
     274              : 
     275          522 : HcclResult TopoInfoExtractor::CheckSuperPodInfo()
     276              : {
     277         1085 :     for (auto iter = superPodToRank_.begin(); iter != superPodToRank_.end(); iter++) {
     278          563 :         u32 devNum = superPodToRank_.begin()->second.size();
     279          563 :         u32 curDevNum = iter->second.size();
     280          563 :         if (devNum != curDevNum) {
     281            0 :             HCCL_INFO("[Check][SuperPodInfo]devNum[%u] in superPodIdx[%u] is inconsistent with "\
     282              :             "devNum[%u] in superPodIdx[%u].", devNum, superPodToRank_.begin(),
     283              :             curDevNum, iter->first);
     284              :         }
     285              :     }
     286          522 :     return HCCL_SUCCESS;
     287              : }
     288              : 
     289          485 : HcclResult TopoInfoExtractor::CheckServerInfo()
     290              : {
     291              :     /*
     292              :      * HCOM模块:
     293              :      * 1、每个AI server之间的芯片个数必须一致,不一致则报错;
     294              :      * 2、每个AI server之间的芯片ID(device ID)必须相同(server0里面devID分别是0、1、4、5;server1->server127也必须是相同的)
     295              :      *   ,不一致则报错;
     296              :      * HCCL API模块:
     297              :      * 3、校验rank_table传进来devID,与rt_get_device查询到的devID,是否相同,不一致则报错(针对当前设备)
     298              :      * 因此,上层模块已经校验过的不再重复,本函数仅用于校验每个server内的设备个数与topo类型的组合是否正确
     299              :      */
     300          485 :     u32 moduleIdx = 0;
     301          485 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     302          485 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     303          485 :     bool check = (iterRank == serverToRank_.end());
     304          485 :     CHK_PRT_RET(check,
     305              :         HCCL_ERROR("[Check][ServerInfo]can't find serverId[%s] in rank map", rankData_.serverId.c_str()),
     306              :         HCCL_E_NOT_FOUND);
     307              : 
     308          485 :     HcclResult ret = HCCL_SUCCESS;
     309              : 
     310          485 :     switch (topoType_) {
     311          124 :         case TopoType::TOPO_TYPE_NP_MESH:
     312              :         case TopoType::TOPO_TYPE_4P_MESH:
     313              :         case TopoType::TOPO_TYPE_2P_MESH:
     314              :         case TopoType::TOPO_TYPE_1P_MESH: {  // 4p_mesh场景下,支持server(4P+4P)和server(4P)+server(4P),2p_mesh/1p_mesh同理
     315          124 :             ret = (((iterRank->second).size() == ranksOneNode_[static_cast<u32>(topoType_)]) ||
     316            0 :                    ((iterRank->second).size() == 2 * ranksOneNode_[static_cast<u32>(topoType_)])) // 2表示8P满配走4PMESH算法
     317          124 :                         ? HCCL_SUCCESS
     318              :                         : HCCL_E_UNAVAIL;
     319          124 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     320              :                 HCCL_ERROR("[Check][ServerInfo]check server info err:server rank size[%llu], expected "\
     321              :                 "value[%u], topo type[%d]", (iterRank->second).size(), ranksOneNode_[static_cast<u32>(topoType_)],
     322              :                 topoType_), HCCL_E_UNAVAIL);
     323          124 :             break;
     324              :         }
     325          329 :         case TopoType::TOPO_TYPE_NP_SINGLE_RING:
     326          329 :             ret = ((iterRank->second).size() == ranksOneNode_[static_cast<u32>(topoType_)]) ? HCCL_SUCCESS :
     327              :                 HCCL_E_UNAVAIL;
     328          329 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     329              :                 HCCL_ERROR("[Check][ServerInfo]check server info err:server rank size[%llu], expected "\
     330              :                 "less than value[%u], topo type[%d]", (iterRank->second).size(),
     331              :                 ranksOneNode_[static_cast<u32>(topoType_)], topoType_), HCCL_E_UNAVAIL);
     332          329 :             break;
     333            0 :         case TopoType::TOPO_TYPE_HETEROG:
     334              :         case TopoType::TOPO_TYPE_ES_MESH:
     335            0 :             break;
     336           32 :         default: {  // 8P_RING or 4P_RING
     337           32 :             ret = ((iterRank->second).size() == ranksOneNode_[static_cast<u32>(topoType_)]) ? HCCL_SUCCESS :
     338              :                 HCCL_E_UNAVAIL;
     339           32 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     340              :                 HCCL_ERROR("[Check][ServerInfo]check server info err:server rank size[%llu], expected "\
     341              :                 "value[%u], topo type[%d]", (iterRank->second).size(),
     342              :                 ranksOneNode_[static_cast<u32>(topoType_)], topoType_), HCCL_E_UNAVAIL);
     343           31 :             break;
     344              :         }
     345              :     }
     346              : 
     347          484 :     HCCL_INFO("check server info:server rank size[%llu], expected value[%u], topo type[%d]",
     348              :               (iterRank->second).size(),
     349              :               ranksOneNode_[static_cast<u32>(topoType_)],
     350              :               topoType_);
     351          484 :     return ret;
     352              : }
     353              : 
     354         5851 : HcclResult TopoInfoExtractor::GetServerIdx(const RankInfo &rankInfo, u32 &serverIdx) const
     355              : {
     356              :     // 通过ranktable指定集群信息场景,可以调整server在ranktable的排序(serverIdx)来指定server间通信的topo,从优化通信拓扑
     357              :     // rootInfo初始化场景,会自动收集集群信息,外部无法指定server的排序,可以无视serverIdx,使用serverID来代替
     358              :     // PS:返回的serverIdx,会影响rankMap_中server的排序,从而影响bridgeRank的选择,优化通信拓扑
     359         5851 :     CHK_PRT_RET((rankInfo.serverIdx == INVALID_UINT), HCCL_ERROR("server idx is invalid."), HCCL_E_INTERNAL);
     360         5851 :     serverIdx = rankInfo.serverIdx;
     361         5851 :     return HCCL_SUCCESS;
     362              : }
     363              : 
     364          522 : HcclResult TopoInfoExtractor::SetTopologyInfo()
     365              : {
     366          522 :     CHK_RET(SetTopoDefaultInfo());
     367              : 
     368          522 :     CHK_RET(SetTopoInfoForLevel0());
     369          522 :     CHK_RET(SetTopoInfoForLevel1());
     370          522 :     CHK_RET(SetTopoInfoForLevel2());
     371          522 :     CHK_RET(SetTopoInfoForARS());
     372          522 :     CHK_RET(SetTopoInfoForCombineL1());
     373              : 
     374          522 :     CHK_RET(SetAHCSubGroupsAndAlgOption());
     375              : 
     376              :     // 是否支持按mesh划分通信拓扑
     377         1042 :     bool isSupportMeshTopo = meshAggregationRankSize_ > 0 &&
     378          520 :                              userRankSize_ % meshAggregationRankSize_ == 0;
     379          522 :     if (isSupportMeshTopo) {
     380          520 :         CHK_RET(SetTopoInfoForMeshL0());
     381          520 :         CHK_RET(SetTopoInfoForMeshL1());
     382              :     } else {
     383            2 :         HCCL_INFO("[Set][TopologyInfo]topo is not support Mesh, meshAggregationRankSize_[%u], userRankSize_[%u]",
     384              :             meshAggregationRankSize_, userRankSize_);
     385              :     }
     386          522 :     CommPlaneVector_[COMM_COMBINE_ORDER].push_back(rankVector_);
     387          522 :     return HCCL_SUCCESS;
     388              : }
     389              : 
     390          522 : HcclResult TopoInfoExtractor::SetTopoDefaultInfo()
     391              : {
     392              :     // 填充combined_rank_vector_:不区分board_type,只生成default单层拓扑
     393          522 :     std::vector<RankInfo> tmpCombinedVector;
     394              : 
     395          522 :     bool incrementFlag = true; // 节点间建链的两个deviceID必须相同(同一个网段平面),server间需要特殊处理
     396              :     // 维护topo输出的信息
     397          522 :     std::string outLogInfo = "userRank/devicePhyId: ";
     398          522 :     RankInfo tempRankData;
     399              : 
     400              :     // 填充combined_rank_vector_的内层vector:combined场景只有一条固定的环
     401         1189 :     for (auto iterMap = serverToRank_.begin(); iterMap != serverToRank_.end(); iterMap++) {
     402          691 :         if (!(iterMap->second).empty()) {
     403              :             // TOPO_TYPE_COMMON为单环拓扑场景,不需要执行如下判断设置流程
     404          691 :             if (topoType_ != TopoType::TOPO_TYPE_COMMON) {
     405          653 :                 if (((iterMap->second).size() == SERVER_RANK_SIZE) && !IsDiffDeviceModuleInServer()
     406          653 :                     && (topoType_ != TopoType::TOPO_TYPE_HETEROG) && !Is310PDevice()) {
     407           48 :                     CHK_RET(SetTopoDefaultInfoFor8P()); // 服务器内dev个数相同已在hcom层做过校验
     408           24 :                     return HCCL_SUCCESS;
     409              :                 }
     410              :             }
     411              : 
     412          667 :             if (incrementFlag) {
     413         1740 :                 for (u32 incrementIndex = 0; incrementIndex < (iterMap->second).size(); incrementIndex++) {
     414         1196 :                     u32 combinedUserRank = (iterMap->second)[incrementIndex].userRank;
     415         1196 :                     bool checkError = (rankVector_.size() <= combinedUserRank);
     416         1196 :                     CHK_PRT_RET(checkError, HCCL_ERROR("[Set][TopoDefaultInfo]combined userRank[%u] is bigger than "\
     417              :                         "rank vector", combinedUserRank), HCCL_E_INTERNAL);
     418         1196 :                     tempRankData = rankVector_[combinedUserRank];
     419         1196 :                     outLogInfo.append(std::to_string(tempRankData.userRank));
     420         1196 :                     outLogInfo.append("/");
     421         1196 :                     outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     422         1196 :                     outLogInfo.append("; ");
     423         1196 :                     tmpCombinedVector.push_back(tempRankData);
     424              :                 }
     425              : 
     426          544 :                 incrementFlag = false;
     427              :             } else {
     428          321 :                 for (u32 decrementIndex = (iterMap->second).size(); decrementIndex > 0; decrementIndex--) {
     429          198 :                     u32 combinedUserRank = (iterMap->second)[decrementIndex - 1].userRank;
     430          198 :                     bool checkError = (rankVector_.size() <= combinedUserRank);
     431          198 :                     CHK_PRT_RET(checkError, HCCL_ERROR("[Set][TopoDefaultInfo]combined userRank[%u] is bigger than "\
     432              :                         "rank vector", combinedUserRank), HCCL_E_INTERNAL);
     433          198 :                     tempRankData = rankVector_[combinedUserRank];
     434          198 :                     outLogInfo.append(std::to_string(tempRankData.userRank));
     435          198 :                     outLogInfo.append("/");
     436          198 :                     outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     437          198 :                     outLogInfo.append("; ");
     438          198 :                     tmpCombinedVector.push_back(tempRankData);
     439              :                 }
     440              : 
     441          123 :                 incrementFlag = true;
     442              :             }
     443              :         }
     444              :     }
     445          498 :     if (topoType_ == TopoType::TOPO_TYPE_COMMON) {
     446           38 :         std::sort(tmpCombinedVector.begin(), tmpCombinedVector.end(), CompareWithUserRankAscend);
     447              :     }
     448              : 
     449          498 :     CommPlaneVector_[COMM_COMBINE].push_back(tmpCombinedVector);
     450          498 :     return HCCL_SUCCESS;
     451          522 : }
     452              : 
     453          522 : HcclResult TopoInfoExtractor::CheckPlaneInfo()
     454              : {
     455          522 :     bool isTopoComm = (topoType_ == TopoType::TOPO_TYPE_COMMON) && (CommPlaneVector_[COMM_COMBINE].size() != 1);
     456          522 :     CHK_PRT_RET(isTopoComm,
     457              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d] and combined plane nub[%llu] are not match",
     458              :         topoType_, CommPlaneVector_[COMM_COMBINE].size()), HCCL_E_INTERNAL);
     459              : 
     460          546 :     bool isTopo8pring = (topoType_ == TopoType::TOPO_TYPE_8P_RING) &&
     461           48 :         ((CommPlaneVector_[COMM_LEVEL0].size() != meshAggregationRankSize_) ||
     462           24 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     463          522 :     CHK_PRT_RET(isTopo8pring,
     464              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     465              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     466              : 
     467          536 :     bool isTopo2pring = (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) &&
     468           14 :         ((CommPlaneVector_[COMM_LEVEL0].size() != 2) || // 2表示一个节点内通信域里面是否只有2个ring
     469            7 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     470          522 :     CHK_PRT_RET(isTopo2pring,
     471              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     472              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     473              : 
     474          522 :     bool isTopo4pRing = (topoType_ == TopoType::TOPO_TYPE_4P_RING) &&
     475            0 :         ((CommPlaneVector_[COMM_LEVEL0].size() != 1) ||    // 1表示一个节点内通信域里面是否只有一个device
     476            0 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     477          522 :     CHK_PRT_RET(isTopo4pRing,
     478              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     479              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     480              : 
     481          543 :     bool isTopo4pMesh = (topoType_ == TopoType::TOPO_TYPE_4P_MESH) &&
     482           42 :         ((CommPlaneVector_[COMM_LEVEL0].size() !=  (ranksOneNode_[static_cast<u32>(topoType_)] - 1)) ||
     483           21 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     484          522 :     CHK_PRT_RET(isTopo4pMesh,
     485              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     486              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     487              : 
     488          625 :     bool isTopoNpMesh = (topoType_ == TopoType::TOPO_TYPE_NP_MESH) &&
     489          206 :         ((CommPlaneVector_[COMM_LEVEL0].size() != (ranksOneNode_[static_cast<u32>(topoType_)] - 1)) ||
     490          103 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     491          522 :     CHK_PRT_RET(isTopoNpMesh,
     492              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     493              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     494              : 
     495              :     // 1表示一个module里面是否只有一个device
     496          522 :     bool isTopo2pMesh = (topoType_ == TopoType::TOPO_TYPE_2P_MESH) &&
     497            0 :         ((CommPlaneVector_[COMM_LEVEL0].size() != 1) ||
     498            0 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     499          522 :     CHK_PRT_RET(isTopo2pMesh,
     500              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     501              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     502              : 
     503          522 :     bool isTopo1pMesh = (topoType_ == TopoType::TOPO_TYPE_1P_MESH) &&
     504            0 :         ((CommPlaneVector_[COMM_LEVEL0].size() != 1) ||    // 1表示一个节点内通信域里面是否只有一个device
     505            0 :         (ranksOneNode_[static_cast<u32>(topoType_)] != CommPlaneVector_[COMM_LEVEL1].size()));
     506          522 :     CHK_PRT_RET(isTopo1pMesh,
     507              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     508              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     509              : 
     510         1180 :     bool isTopoNpSingleRing = (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING) && (!IsDiffDeviceModuleInServer()) &&
     511          329 :         ((CommPlaneVector_[COMM_LEVEL0].size() != 1) ||
     512          329 :         (CommPlaneVector_[COMM_LEVEL1].size() != ranksOneNode_[static_cast<u32>(topoType_)]));
     513          522 :     CHK_PRT_RET(isTopoNpSingleRing,
     514              :         HCCL_ERROR("[Check][PlaneInfo]topo type[%d], level0 plane nub[%llu], level1 plane nub[%llu], is not match",
     515              :         topoType_, CommPlaneVector_[COMM_LEVEL0].size(), CommPlaneVector_[COMM_LEVEL1].size()), HCCL_E_INTERNAL);
     516              : 
     517          522 :     HCCL_RUN_INFO(
     518              :         "plane info:topo type[%d], device type[%d], COMM_COMBINE size[%llu], COMM_LEVEL0 size[%llu], COMM_LEVEL1 " \
     519              :         "size[%llu], COMM_LEVEL2 size[%llu], COMM_MESH_L0 size[%llu], COMM_MESH_L1 size[%llu]",
     520              :         topoType_, deviceType_, CommPlaneVector_[COMM_COMBINE].size(), CommPlaneVector_[COMM_LEVEL0].size(),
     521              :         CommPlaneVector_[COMM_LEVEL1].size(), CommPlaneVector_[COMM_LEVEL2].size(),
     522              :         CommPlaneVector_[COMM_MESH_L0].size(), CommPlaneVector_[COMM_MESH_L1].size());
     523              : 
     524          522 :     return HCCL_SUCCESS;
     525              : }
     526              : 
     527          522 : HcclResult TopoInfoExtractor::SetTopoInfoForLevel0()
     528              : {
     529          522 :     u32 moduleIdx = 0;
     530          522 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     531          522 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     532          522 :     bool check = (iterRank == serverToRank_.end());
     533          522 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][TopoInfoForLevel0]can't find serverId[%s] in rank map",
     534              :                                   rankData_.serverId.c_str()), HCCL_E_NOT_FOUND);
     535              :     // 查询本rank所在服务器的rank数
     536          522 :     u32 ranksSize = (iterRank->second).size();
     537              : 
     538          522 :     multiLevel0Order_.clear();
     539              :     // 生成mockNicList
     540          522 :     std::vector<u32> mockNicList;
     541          522 :     mockNicList.reserve(ranksSize);
     542         1856 :     for (u32 startIndex = 0; startIndex < ranksSize; startIndex++) {
     543         1334 :         mockNicList.push_back(startIndex);
     544              :     }
     545              : 
     546          522 :     multiLevel0Order_ = GetRingsOrderByTopoType(ranksSize, topoType_, mockNicList);
     547              : 
     548          522 :     HCCL_DEBUG("[TopoInfoExtractor] The ring number is %zu, the rank size is %lu.", multiLevel0Order_.size(), ranksSize);
     549          522 :     if (multiLevel0Order_.size() == 1) {
     550          491 :         CHK_RET(SetSingleLevel0());
     551              :     } else {    // 8p-ring/np ring 环场景
     552           31 :         u32 ringNum = multiLevel0Order_.size();
     553           31 :         CHK_RET(SetMultiLevel0(ringNum)); // 8P_RING场景下,外层拓扑中有四个环; 910_93场景中适配双环
     554              :     }
     555              : 
     556          522 :     AHCCommSubgroupInit(); // 准备 AHC COMM 场景下的分组
     557              : 
     558          522 :     return HCCL_SUCCESS;
     559          522 : }
     560              : 
     561         1044 : HcclResult TopoInfoExtractor::SetTopoInfoForLevel1(bool prepareAHC)
     562              : {
     563         1044 :     std::map<u32, std::vector<RankInfo>> &serverToRank =
     564              :         (prepareAHC) ? serverToRankMerge_ : serverToRank_;
     565              : 
     566         1044 :     CommPlane commPlaneLevel1 = (prepareAHC) ? COMM_LEVEL1_AHC : COMM_LEVEL1;
     567              : 
     568         1044 :     u32 moduleIdx = 0;
     569         1044 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     570         1044 :     auto iterRank = serverToRank.find(moduleIdx); // 查询本rank所在服务器
     571         1044 :     bool check = (iterRank == serverToRank.end());
     572         1044 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][TopoInfoForLevel1]can't find serverId[%s] in rank map",
     573              :                                   rankData_.serverId.c_str()), HCCL_E_NOT_FOUND);
     574              : 
     575              :     u32 ringSize;
     576         1044 :     if (topoType_ == TopoType::TOPO_TYPE_2P_MESH) { // 2P_MESH在任何情况下,内层拓扑平面始终为2
     577            0 :         ringSize = ranksOneNode_[static_cast<u32>(topoType_)];
     578         1044 :     } else if (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING) { // 标卡内层拓扑的环数
     579          658 :         ringSize = (iterRank->second).size();
     580              :     } else { // 其他场景下内层拓扑平面为每个module中的device数量
     581          386 :         ringSize = ranksOneNode_[static_cast<u32>(topoType_)];
     582              :     }
     583         1044 :     HCCL_INFO("[Set][TopoInfoForLevel1] topoType_[%u] ringSize[%u]",topoType_, ringSize);
     584              : 
     585              :     // 计算每个 level 环的超节点分组,每个环都一致,只计算一次
     586         1044 :     std::vector<std::string> idsForIndexingVector;
     587         1044 :     std::map<std::string, std::vector<u32>> aggregatedSubGroup;
     588         1044 :     bool calcGroupDone = false;
     589              : 
     590              :     // 内层拓扑的每层环
     591         3252 :     for (u32 ringIndex = 0; ringIndex < ringSize; ringIndex++) {
     592         2208 :         std::vector<RankInfo> tmpBridgeVector;
     593         2208 :         bool bridgeRankFlag = false;
     594         2208 :         std::string outLogInfo = ""; // 维护topo输出的信息
     595         2208 :         outLogInfo.append(" ringIndex: ");
     596         2208 :         outLogInfo.append(std::to_string(ringIndex));
     597         2208 :         outLogInfo.append(", ");
     598         2208 :         outLogInfo.append("userRank/serverId/devicePhyId/nicIp/isBridgeRank: ");
     599              : 
     600              :         // 2、填充bridge_rank_vector_的内层vector和is_bridge_vector_
     601         2208 :         u32 subGroupIndex = 0;
     602         4859 :         for (auto iterMap = serverToRank.begin(); iterMap != serverToRank.end(); iterMap++) {
     603         2651 :             if (!(iterMap->second).empty()) {
     604         2651 :                 RankInfo tmpBridgePara;
     605         2651 :                 u32 bridgeUserRank = (iterMap->second)[ringIndex].userRank;
     606         2651 :                 u32 bridgeDevicePhyId = (iterMap->second)[ringIndex].devicePhyId;
     607         2651 :                 std::vector<u32> bridgeNic((iterMap->second)[ringIndex].nicIdx);
     608         2651 :                 bool checkError = (rankVector_.size() <= bridgeUserRank);
     609         2651 :                 CHK_PRT_RET(checkError, HCCL_ERROR("[Set][TopoInfoForLevel1]bridge userRank[%u] is bigger than rank "\
     610              :                     "vector", bridgeUserRank), HCCL_E_INTERNAL);
     611         2651 :                 CHK_RET(SetBridgeLinkInfo(tmpBridgePara, bridgeUserRank));
     612         2651 :                 tmpBridgeVector.push_back(tmpBridgePara);
     613         2651 :                 std::vector<u32>::iterator iterNic = std::find(bridgeNic.begin(), bridgeNic.end(), bridgeDevicePhyId);
     614         2651 :                 if ((bridgeNic.size() == 0) || (iterNic != bridgeNic.end())) {
     615         2649 :                     if (bridgeUserRank == static_cast<u32>(userRank_)) { // 本rank是否为bridge_rank
     616          968 :                         bridgeRankFlag = true;
     617              :                     }
     618              :                 }
     619              : 
     620         2651 :                 outLogInfo.append(std::to_string(tmpBridgePara.userRank));
     621         2651 :                 outLogInfo.append("/");
     622         2651 :                 outLogInfo.append(tmpBridgePara.serverId);
     623         2651 :                 outLogInfo.append("/");
     624         2651 :                 outLogInfo.append(std::to_string(tmpBridgePara.devicePhyId));
     625         2651 :                 outLogInfo.append("/");
     626         2651 :                 outLogInfo.append(tmpBridgePara.nicIp[0].GetReadableAddress());
     627         2651 :                 outLogInfo.append("/");
     628         2651 :                 outLogInfo.append(std::to_string(bridgeRankFlag));
     629         2651 :                 outLogInfo.append("; ");
     630              : 
     631              :                 // 环内填充 aggregatedSubGroup superPodId-> subGroupIndex 用于生成分组信息
     632         2651 :                 if (!calcGroupDone && (deviceType_ == DevType::DEV_TYPE_910_93 || deviceType_ == DevType::DEV_TYPE_910B)) {
     633          539 :                     std::string IdForIndexing = (iterMap->second)[ringIndex].superPodId;
     634          539 :                     auto itIndex = aggregatedSubGroup.find(IdForIndexing);
     635          539 :                     if (itIndex != aggregatedSubGroup.end()) {
     636          166 :                         itIndex->second.push_back(subGroupIndex);
     637              :                     } else {
     638          373 :                         idsForIndexingVector.push_back(IdForIndexing);
     639          373 :                         std::vector<u32> subGroup;
     640          373 :                         subGroup.push_back(subGroupIndex);
     641          373 :                         aggregatedSubGroup.insert(std::make_pair(IdForIndexing, subGroup));
     642          373 :                     }
     643          539 :                     HCCL_INFO("[Set][TopoInfoForLevel1] calc subGroup superPodId[%s] subIndex[%u]",
     644              :                         IdForIndexing.c_str(), subGroupIndex);
     645          539 :                 }
     646              : 
     647         2651 :                 subGroupIndex = subGroupIndex + 1;
     648         2651 :             }
     649              :         }
     650              : 
     651         3266 :         for (auto it = aggregatedSubGroup.begin(); it != aggregatedSubGroup.end(); it++) {
     652         1058 :             HCCL_DEBUG("[Set][TopoInfoForLevel1][AHC_DEBUG] superPodId[%s]", it->first.c_str());
     653         2385 :             for (auto index = it->second.begin(); index != it->second.end(); index++) {
     654         1327 :                 HCCL_DEBUG("[Set][TopoInfoForLevel1][AHC_DEBUG] groupIndex[%u]", (*index));
     655              :             }
     656              :         }
     657              : 
     658         4859 :         for (auto it = tmpBridgeVector.begin(); it != tmpBridgeVector.end(); it++) {
     659         2651 :             HCCL_DEBUG("[Set][TopoInfoForLevel1][AHC_DEBUG] ringIndex[%u] tmpBridgevector userRank[%u]", ringIndex, it->userRank);
     660              :         }
     661              : 
     662              :         // 3、填充bridge_rank_vector_、isBridgeVector_
     663         2208 :         if (!prepareAHC) {
     664         1104 :             isBridgeVector_.push_back(bridgeRankFlag);
     665              :         }
     666         2208 :         CommPlaneVector_[commPlaneLevel1].push_back(tmpBridgeVector);
     667              : 
     668              :         // 4、填充当前 level 的通信域内分组信息(用于层次化算法)
     669         2208 :         if (!calcGroupDone) {
     670          968 :             std::vector<std::vector<u32>> SubGroups;
     671         1341 :             for (u32 i = 0; i < idsForIndexingVector.size(); i++) {
     672          373 :                 std::string idForIndexing = idsForIndexingVector[i];
     673          373 :                 SubGroups.push_back(aggregatedSubGroup[idForIndexing]);
     674          373 :             }
     675          968 :             CommPlaneSubGroupVector_[commPlaneLevel1].push_back(SubGroups);
     676          968 :             calcGroupDone = true;
     677          968 :         }
     678              : 
     679         2208 :         HCCL_INFO("SetTopoInfoForLevel1: topoRankInfo[%s]", outLogInfo.c_str());
     680         2208 :     }
     681              : 
     682         1044 :     HCCL_RUN_INFO("SetTopoInfoForLevel1: identifier[%s], userRank[%u], userRankSize[%u], plane size[%u]",
     683              :         identifier_.c_str(), userRank_, userRankSize_, CommPlaneVector_[commPlaneLevel1].size());
     684         1044 :     return HCCL_SUCCESS;
     685         1044 : }
     686              : 
     687          522 : HcclResult TopoInfoExtractor::SetTopoInfoForLevel2()
     688              : {
     689           33 :     bool isLevel2Support = ((deviceType_ == DevType::DEV_TYPE_910_93) && multiModuleDiffDeviceNumMode_
     690          555 :         && !multiSuperPodDiffDeviceNumMode_);
     691              :     // 对称场景需要初始化多个平面,超节点内rank数一致也可切分平面;其他非对称场景 level1 和 level2 合并无需切分平面
     692          522 :     if (((!multiModuleDiffDeviceNumMode_ && !multiSuperPodDiffServerNumMode_) || isLevel2Support) && !isDiffDeviceType_) {
     693          514 :         HCCL_INFO("[Set][TopoInfoForLevel2] select origin proc");
     694              : 
     695              :         // 找到当前rank在本超节点内部的序号
     696          514 :         auto it = superPodToRank_.find(rankData_.superPodIdx);
     697          514 :         CHK_PRT_RET(it == superPodToRank_.end(),
     698              :             HCCL_ERROR("[Set][TopoInfoForLevel2]superPodIdx[%u] is not exist in superPodRankMap",
     699              :             rankData_.superPodIdx), HCCL_E_INTERNAL);
     700              : 
     701          514 :         u32 index = 0;
     702          829 :         for (; index < it->second.size(); ++index) {
     703          829 :             if (userRank_ == it->second[index].userRank) {
     704          514 :                 break;
     705              :             }
     706              :         }
     707          514 :         CHK_PRT_RET(index >= it->second.size(),
     708              :             HCCL_ERROR("[Set][TopoInfoForLevel2]userRank_[%u] superPodId[%s] superPodIdx[%u] not exist in superPodRankMap",
     709              :             userRank_, rankData_.superPodId.c_str(), rankData_.superPodIdx), HCCL_E_INTERNAL);
     710              : 
     711          514 :         std::vector<RankInfo> tmpRankVec;
     712         1069 :         for (auto iterMap = superPodToRank_.begin(); iterMap != superPodToRank_.end(); iterMap++) {
     713          555 :             CHK_PRT_RET(iterMap->second.size() <= index,
     714              :                 HCCL_ERROR("[Set][TopoInfoForLevel2]index[%u] is bigger than rank vector size[%u]",
     715              :                 index, iterMap->second.size()), HCCL_E_INTERNAL);
     716              : 
     717          555 :             RankInfo& tempRankData = iterMap->second[index];
     718          555 :             tmpRankVec.push_back(tempRankData);
     719              : 
     720              :             // 维护topo输出的信息
     721          555 :             std::string outLogInfo = "userRank/devicePhyId/serverIdx/superPodId: ";
     722          555 :             outLogInfo.append(std::to_string(tempRankData.userRank));
     723          555 :             outLogInfo.append("/");
     724          555 :             outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     725          555 :             outLogInfo.append("/");
     726          555 :             outLogInfo.append(std::to_string(tempRankData.serverIdx));
     727          555 :             outLogInfo.append("/");
     728          555 :             outLogInfo.append(tempRankData.superPodId);
     729          555 :             outLogInfo.append("; ");
     730          555 :             HCCL_INFO("SetTopoInfoForLevel2: topoRankInfo[%s]", outLogInfo.c_str());
     731          555 :         }
     732              : 
     733          514 :         CommPlaneVector_[COMM_LEVEL2].push_back(tmpRankVec);
     734          514 :         HCCL_RUN_INFO("SetTopoInfoForLevel2: identifier[%s], userRank[%u], userRankSize[%u], plane size[%u]",
     735              :             identifier_.c_str(), userRank_, userRankSize_, CommPlaneVector_[COMM_LEVEL2].size());
     736          514 :     }
     737              : 
     738          522 :     return HCCL_SUCCESS;
     739              : }
     740              : 
     741          520 : HcclResult TopoInfoExtractor::SetTopoInfoForMeshL0()
     742              : {
     743              :     // 以MeshAggregation为粒度、MeshAggregation内各设备的mesh建链
     744          520 :     u32 rankSize = meshAggregationRankSize_;
     745          520 :     u32 userRankIndexBegin = userRank_ / meshAggregationRankSize_ * meshAggregationRankSize_;
     746          520 :     u32 userRankIndexEnd = userRankIndexBegin + meshAggregationRankSize_;
     747          520 :     std::vector<RankInfo> paraVector(rankSize);
     748          520 :     u32 rankIndex = 0;
     749          520 :     std::string outLogInfo = "userRank/devicePhyId: "; // 维护topo输出的信息
     750              : 
     751          520 :     CHK_PRT_RET(rankVector_.size() < userRankIndexEnd,
     752              :         HCCL_ERROR("[Set][TopoInfoForMeshL0]rankVector_ size[%u] should be greater than userRankIndexEnd[%u]",
     753              :             rankVector_.size(), userRankIndexEnd), HCCL_E_PARA);
     754              : 
     755         1744 :     for (u32 i = userRankIndexBegin; i < userRankIndexEnd; i ++) {
     756         1224 :         paraVector[rankIndex] = rankVector_[i];
     757         1224 :         outLogInfo.append(std::to_string(paraVector[rankIndex].userRank));
     758         1224 :         outLogInfo.append("/");
     759         1224 :         outLogInfo.append(std::to_string(paraVector[rankIndex].devicePhyId));
     760         1224 :         outLogInfo.append("; ");
     761         1224 :         rankIndex++;
     762              :     }
     763          520 :     CommPlaneVector_[COMM_MESH_L0].push_back(paraVector);
     764          520 :     return HCCL_SUCCESS;
     765          520 : }
     766              : 
     767          520 : HcclResult TopoInfoExtractor::SetTopoInfoForMeshL1()
     768              : {
     769              :     // 以MeshAggregation为粒度、MeshAggregation间各平面的mesh建链
     770          520 :     u32 rankSize = userRankSize_ /  meshAggregationRankSize_; // 1 = 7 / 4
     771          520 :     u32 planeID = userRank_ % meshAggregationRankSize_; // 0
     772          520 :     std::vector<RankInfo> paraVector(rankSize);
     773              : 
     774          520 :     CHK_PRT_RET(rankVector_.size() < userRankSize_,
     775              :         HCCL_ERROR("[Set][TopoInfoForMeshL1]rankVector_ size[%u] should be greater than userRankSize[%u]",
     776              :             rankVector_.size(), userRankSize_), HCCL_E_PARA);
     777              : 
     778         1314 :     for (u32 i = planeID; i < userRankSize_; i += meshAggregationRankSize_) {
     779          794 :         u32 rankIndex = i / meshAggregationRankSize_;
     780          794 :         paraVector[rankIndex] = rankVector_[i];
     781          794 :         std::string outLogInfo = "userRank/devicePhyId"; // 维护topo输出的信息
     782          794 :         outLogInfo.append(std::to_string(paraVector[rankIndex].userRank));
     783          794 :         outLogInfo.append("/");
     784          794 :         outLogInfo.append(std::to_string(paraVector[rankIndex].devicePhyId));
     785          794 :         outLogInfo.append("; ");
     786          794 :         HCCL_INFO("SetTopoInfoForMeshL1: topoRankInfo[%s]", outLogInfo.c_str());
     787          794 :     }
     788          520 :     CommPlaneVector_[COMM_MESH_L1].push_back(paraVector);
     789          520 :     return HCCL_SUCCESS;
     790          520 : }
     791              : 
     792          491 : HcclResult TopoInfoExtractor::SetSingleLevel0()
     793              : {
     794              :     // 填充level0_rank_vector_,该函数处理场景非8P_RING算法
     795          491 :     std::vector<RankInfo> tmpLevel0Vector;
     796          491 :     u32 moduleIdx = 0;
     797          491 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     798          491 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     799          491 :     bool check = (iterRank == serverToRank_.end());
     800          491 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][SingleLevel0]can't find serverId[%s] in rank map", rankData_.serverId.c_str()),
     801              :         HCCL_E_NOT_FOUND);
     802              : 
     803          491 :     std::vector<s32> devicePhyIdVector;
     804         1904 :     for (u32 i = 0; i < rankVector_.size(); i++) {
     805         1413 :         devicePhyIdVector.push_back(rankVector_[i].devicePhyId);
     806              :     }
     807          491 :     s32 maxPhyId = *max_element(devicePhyIdVector.begin(), devicePhyIdVector.end());
     808              :     // 8P满配场景:4PMESH算法 + 8Pfullmesh + 16P仅使用左边module
     809          515 :     if (((iterRank->second).size() == DEVICE_PER_MODULE &&
     810          515 :         maxPhyId < DEVICE_PER_MODULE) &&
     811           24 :         (topoType_ == TopoType::TOPO_TYPE_4P_MESH || topoType_ == TopoType::TOPO_TYPE_NP_MESH)) {
     812            0 :         return SetSingleLevel0For8P(); // 服务器内dev个数相同已在hcom层做过校验
     813              :     }
     814              : 
     815              :     // 维护topo输出的信息
     816          491 :     std::string outLogInfo = "userRank/devicePhyId: ";
     817          491 :     RankInfo tempRankData;
     818              :     // 其他场景 + 16P使用右边module
     819         1617 :     for (u32 startIndex = 0; startIndex < (iterRank->second).size(); startIndex++) {
     820         1126 :         u32 level0StartRank = (iterRank->second)[startIndex].userRank;
     821         1126 :         bool checkError = (rankVector_.size() <= level0StartRank);
     822         1126 :         CHK_PRT_RET(checkError, HCCL_ERROR("[Set][SingleLevel0]level0 userRank[%u] is bigger than rank vector",
     823              :             level0StartRank), HCCL_E_INTERNAL);
     824         1126 :         tempRankData = rankVector_[level0StartRank];
     825              : 
     826         1126 :         outLogInfo.append(std::to_string(tempRankData.userRank));
     827         1126 :         outLogInfo.append("/");
     828         1126 :         outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     829         1126 :         outLogInfo.append("; ");
     830         1126 :         tmpLevel0Vector.push_back(tempRankData);
     831              :     }
     832              : 
     833              :     // NPmesh或4Pmesh场景下,外层拓扑平面为device数量-1
     834          491 :     u32 level0Size = (topoType_ == TopoType::TOPO_TYPE_4P_MESH || topoType_ == TopoType::TOPO_TYPE_NP_MESH) ?
     835          124 :         (ranksOneNode_[static_cast<u32>(topoType_)] - 1) : 1;
     836              : 
     837         1226 :     for (u32 index = 0; index < level0Size; index++) {
     838          735 :         CommPlaneVector_[COMM_LEVEL0].push_back(tmpLevel0Vector);
     839              :     }
     840          491 :     HCCL_RUN_INFO("SetTopoInfoForLevel0: identifier[%s], userRank[%u], userRankSize[%u], topoRankInfo[%s]",
     841              :         identifier_.c_str(), userRank_, userRankSize_, outLogInfo.c_str());
     842          491 :     return HCCL_SUCCESS;
     843          491 : }
     844              : 
     845            0 : HcclResult TopoInfoExtractor::SetSingleLevel0For8P()
     846              : {
     847              :     // 该函数处理场景:8P满配、非8P_RING算法(8P满配下走4PMESH)
     848            0 :     std::vector<RankInfo> tmpLevel0Vector;
     849            0 :     u32 moduleIdx = 0;
     850            0 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     851            0 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     852            0 :     bool check = (iterRank == serverToRank_.end());
     853            0 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][SingleLevel0For8P]can't find serverId[%s] in rank map",
     854              :         rankData_.serverId.c_str()), HCCL_E_NOT_FOUND);
     855              : 
     856            0 :     u32 startIndex = (rankData_.devicePhyId < static_cast<s32>(meshAggregationRankSize_)) ?
     857              :         0 : meshAggregationRankSize_;
     858            0 :     u32 devcount = 0;
     859              :     // 维护topo输出的信息
     860            0 :     std::string outLogInfo = "userRank/devicePhyId: ";
     861            0 :     RankInfo tempRankData;
     862            0 :     while (devcount < meshAggregationRankSize_) {
     863            0 :         u32 level0StartRank = (iterRank->second)[startIndex].userRank;
     864            0 :         bool checkError = (rankVector_.size() <= level0StartRank);
     865            0 :         CHK_PRT_RET(checkError, HCCL_ERROR("[Set][SingleLevel0For8P]level0 userRank[%u] is bigger than rank vector",
     866              :             level0StartRank), HCCL_E_INTERNAL);
     867            0 :         tempRankData = rankVector_[level0StartRank];
     868              : 
     869            0 :         outLogInfo.append(std::to_string(tempRankData.userRank));
     870            0 :         outLogInfo.append("/");
     871            0 :         outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     872            0 :         outLogInfo.append("; ");
     873            0 :         tmpLevel0Vector.push_back(tempRankData);
     874            0 :         startIndex++;
     875            0 :         devcount++;
     876              :     }
     877              : 
     878              :     // 4PMESH场景下,外层拓扑3个平面
     879            0 :     u32 level0Size = ranksOneNode_[static_cast<u32>(topoType_)] -1;
     880            0 :     for (u32 index = 0; index < level0Size; index++) {
     881            0 :         CommPlaneVector_[COMM_LEVEL0].push_back(tmpLevel0Vector);
     882              :     }
     883            0 :     HCCL_RUN_INFO("SetTopoInfoForLevel0: identifier[%s], userRank[%u], userRankSize[%u], topoRankInfo[%s]",
     884              :         identifier_.c_str(), userRank_, userRankSize_, outLogInfo.c_str());
     885            0 :     return HCCL_SUCCESS;
     886            0 : }
     887              : 
     888              : /*
     889              :  * *********************************************************************************
     890              :  * 用来标识集群中是否存在910B A+X形态
     891              :  * **********************************************************************************
     892              :  */
     893         4565 : bool TopoInfoExtractor::IsDiffDeviceModuleInServer() const
     894              : {
     895         4565 :     return deviceType_ == DevType::DEV_TYPE_910B && isDiffAggregation_;
     896              : }
     897              : 
     898           31 : HcclResult TopoInfoExtractor::SetMultiLevel0(u32 ringNum)
     899              : {
     900           31 :     std::vector<u32> tmpLevel0Order;
     901           31 :     u32 moduleIdx = 0;
     902           31 :     RankInfo tempRankData;
     903           31 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     904           31 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     905           31 :     bool check = (iterRank == serverToRank_.end());
     906           31 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][MultiLevel0]can't find serverId[%s] in rank map", rankData_.serverId.c_str()),
     907              :         HCCL_E_NOT_FOUND);
     908              : 
     909              :     // 维护topo输出的信息
     910           31 :     std::string outLogInfo = "";
     911          141 :     for (u32 ringIndex = 0; ringIndex < ringNum; ringIndex++) {
     912          110 :         tmpLevel0Order = multiLevel0Order_[ringIndex]; // 获取每一个环的设备物理ID排序
     913          110 :         std::vector<RankInfo> tmpLevel0Vector;
     914          110 :         outLogInfo = "userRank/devicePhyId: ";
     915          910 :         for (u32 startIndex = 0; startIndex < (iterRank->second).size(); startIndex++) {
     916          800 :             u32 devIndex = tmpLevel0Order[startIndex];
     917          800 :             u32 level0RingUserank = (iterRank->second)[devIndex].userRank;
     918          800 :             bool checkError = (rankVector_.size() <= level0RingUserank);
     919          800 :             CHK_PRT_RET(checkError, HCCL_ERROR("[Set][MultiLevel0]level0 userRank[%u] is bigger than rank vector",
     920              :                 level0RingUserank), HCCL_E_INTERNAL);
     921          800 :             tempRankData = rankVector_[level0RingUserank];
     922          800 :             outLogInfo.append(std::to_string(tempRankData.userRank));
     923          800 :             outLogInfo.append("/");
     924          800 :             outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     925          800 :             outLogInfo.append("; ");
     926          800 :             tmpLevel0Vector.push_back(tempRankData);
     927              :         }
     928          110 :         HCCL_RUN_INFO("SetTopoInfoForLevel0: identifier[%s], userRank[%u], userRankSize[%u], topoRankInfo[%s]",
     929              :             identifier_.c_str(), userRank_, userRankSize_, outLogInfo.c_str());
     930          110 :         CommPlaneVector_[COMM_LEVEL0].push_back(tmpLevel0Vector);
     931          110 :     }
     932           31 :     return HCCL_SUCCESS;
     933           31 : }
     934              : 
     935              : // anypath创建通信域
     936            0 : HcclResult TopoInfoExtractor::SetMultiLevel0AnyPath(std::vector<std::vector<u32> > multiOrder)
     937              : {
     938            0 :     u32 ringNum = multiOrder.size();
     939            0 :     std::vector<u32> tmpLevel0Order;
     940            0 :     u32 moduleIdx = 0;
     941            0 :     CHK_RET(GetModuleIdx(rankData_, moduleIdx));
     942            0 :     auto iterRank = serverToRank_.find(moduleIdx); // 查询本rank所在服务器
     943            0 :     bool check = (iterRank == serverToRank_.end());
     944            0 :     CHK_PRT_RET(check, HCCL_ERROR("[Set][MultiLevel0]can't find serverId[%s] in rank map", rankData_.serverId.c_str()),
     945              :         HCCL_E_NOT_FOUND);
     946              : 
     947              :     // 维护topo输出的信息
     948            0 :     std::string outLogInfo = "";
     949            0 :     RankInfo tempRankData;
     950            0 :     for (u32 ringIndex = 0; ringIndex < ringNum; ringIndex++) {
     951            0 :         tmpLevel0Order = multiOrder[ringIndex]; // 获取每一个环的设备物理ID排序
     952            0 :         std::vector<RankInfo> tmpLevel0Vector;
     953            0 :         outLogInfo = "userRank/devicePhyId: ";
     954            0 :         for (u32 startIndex = 0; startIndex < (iterRank->second).size(); startIndex++) {
     955            0 :             u32 devIndex = tmpLevel0Order[startIndex];
     956            0 :             u32 level0RingUserank = (iterRank->second)[devIndex].userRank;
     957            0 :             bool checkError = (rankVector_.size() <= level0RingUserank);
     958            0 :             CHK_PRT_RET(checkError, HCCL_ERROR("[Set][MultiLevel0]level0 userRank[%u] is bigger than rank vector",
     959              :                 level0RingUserank), HCCL_E_INTERNAL);
     960            0 :             tempRankData = rankVector_[level0RingUserank];
     961            0 :             outLogInfo.append(std::to_string(tempRankData.userRank));
     962            0 :             outLogInfo.append("/");
     963            0 :             outLogInfo.append(std::to_string(tempRankData.devicePhyId));
     964            0 :             outLogInfo.append("; ");
     965            0 :             tmpLevel0Vector.push_back(tempRankData);
     966              :         }
     967            0 :         HCCL_RUN_INFO("[AnyPath]SetTopoInfoForLevel0: identifier[%s], userRank[%u], userRankSize[%u], topoRankInfo[%s]",
     968              :             identifier_.c_str(), userRank_, userRankSize_, outLogInfo.c_str());
     969            0 :         CommPlaneVector_[COMM_LEVEL0_ANYPATH_SDMA].push_back(tmpLevel0Vector);
     970            0 :         CommPlaneVector_[COMM_LEVEL0_ANYPATH_RDMA].push_back(tmpLevel0Vector);
     971            0 :     }
     972              : 
     973            0 :     return HCCL_SUCCESS;
     974            0 : }
     975              : 
     976              : // 集群中存在910B A+X时,0-7卡: moduleIdx = 2 * serverIdx; 8-15卡: moduleIdx = 2 * serverIdx + 1
     977              : // 集群中不存在910B A+X时,moduleIdx = serverIdx
     978         4212 : HcclResult TopoInfoExtractor::GetModuleIdx(const RankInfo &rankInfo, u32 &moduleIdx)
     979              : {
     980              :     // 获取moduleIdx,在16P同时使用左右两个module时,moduleIdx标识当前rank所在的module,其他场景下moduleIdx等同于serverIdx
     981         4212 :     u32 serverIdx = 0;
     982         4212 :     CHK_RET(GetServerIdx(rankInfo, serverIdx));
     983         4212 :     if (isDiffDeviceType_) {
     984            0 :         moduleIdx = rankInfo.userRank / gcdDeviceNumPerAggregation_;
     985            0 :         HCCL_DEBUG("[TopoInfoExtractor][GetModuleIdx]serverIdx [%u] devicePhyId[%u] userRank[%u] moduleIdx[%u] "
     986              :             "gcdDeviceNumPerAggregation[%u]", serverIdx, rankInfo.devicePhyId, rankInfo.userRank, moduleIdx,
     987              :             gcdDeviceNumPerAggregation_);
     988         4212 :     } else if (IsDiffDeviceModuleInServer()) {
     989            0 :         moduleIdx = serverIdx * FACTOR_NUM_TWO + rankInfo.devicePhyId / DEVICE_PER_MODULE;
     990              :     } else {
     991         4212 :         moduleIdx = serverIdx;
     992              :     }
     993         4212 :     return HCCL_SUCCESS;
     994              : }
     995              : 
     996         2651 : HcclResult TopoInfoExtractor::SetBridgeLinkInfo(RankInfo &bridgePara, u32 bridgeUserRank)
     997              : {
     998         2651 :     bool checkSize = (rankVector_.size() <= bridgeUserRank);
     999         2651 :     CHK_PRT_RET(checkSize,
    1000              :         HCCL_ERROR("[Set][BridgeLinkInfo]bridge UserRank %u is bigger than rank vector", bridgeUserRank),
    1001              :         HCCL_E_INTERNAL);
    1002              : 
    1003         2651 :     bridgePara = rankVector_[bridgeUserRank];
    1004         2651 :     return HCCL_SUCCESS;
    1005              : }
    1006              : 
    1007           24 : HcclResult TopoInfoExtractor::SetTopoDefaultInfoFor8P()
    1008              : {
    1009              :     // 填充combined_rank_vector_:不区分board_type,只生成default单层拓扑
    1010           24 :     std::vector<RankInfo> tmpCombinedVector;
    1011              :     // 服务器内排序固定为0, 2, 3, 1, 5, 7, 6, 4,挑选8P多环中适用于combined的一组服务器内排序
    1012           72 :     std::vector<u32> devOrder = { 0, 2, 3, 1, 5, 7, 6, 4 };
    1013              :     // 维护topo输出的信息
    1014           24 :     std::string outLogInfo = "userRank/devicePhyId: ";
    1015              : 
    1016              :     // 填充combined_rank_vector_的内层vector:combined场景只有一条固定的环
    1017           48 :     for (auto iterMap = serverToRank_.begin(); iterMap != serverToRank_.end(); iterMap++) {
    1018              :         /* 服务器内8P满配单环特殊适配逻辑 */
    1019          216 :         for (u32 index = 0; index < devOrder.size(); index++) {
    1020          192 :             u32 devIndex = devOrder[index];
    1021          192 :             u32 combinedUserRank = (iterMap->second)[devIndex].userRank;
    1022              : 
    1023          192 :             bool checkError = (rankVector_.size() <= combinedUserRank);
    1024          192 :             CHK_PRT_RET(checkError,
    1025              :                 HCCL_ERROR("[Set][TopoDefaultInfoFor8P]combined userRank[%u] is bigger than rank vector",
    1026              :                     combinedUserRank), HCCL_E_INTERNAL);
    1027              : 
    1028          192 :             RankInfo tmpCombinedPara = rankVector_[combinedUserRank];
    1029          192 :             outLogInfo.append(std::to_string(tmpCombinedPara.userRank));
    1030          192 :             outLogInfo.append("/");
    1031          192 :             outLogInfo.append(std::to_string(tmpCombinedPara.devicePhyId));
    1032          192 :             outLogInfo.append("; ");
    1033          192 :             tmpCombinedVector.push_back(tmpCombinedPara);
    1034          192 :         }
    1035              :     }
    1036              : 
    1037           24 :     CommPlaneVector_[COMM_COMBINE].push_back(tmpCombinedVector);
    1038           24 :     return HCCL_SUCCESS;
    1039           24 : }
    1040              : 
    1041          520 : HcclResult TopoInfoExtractor::GetCommPlaneRanks(std::vector<std::vector<std::vector<u32>>> &CommPlaneRanks)
    1042              : {
    1043          520 :     CommPlaneRanks.resize(CommPlaneVector_.size());
    1044         8840 :     for (u32 level = 0; level < CommPlaneVector_.size(); level ++) {
    1045         8320 :         u32 ringSize = CommPlaneVector_[level].size();
    1046         8320 :         CommPlaneRanks[level].resize(ringSize);
    1047        14029 :         for (u32 ringIndex = 0 ; ringIndex < ringSize; ringIndex ++) {
    1048         5709 :             u32 rankSize = CommPlaneVector_[level][ringIndex].size();
    1049         5709 :             CommPlaneRanks[level][ringIndex].resize(rankSize);
    1050        17222 :             for (u32 rankIndex = 0 ; rankIndex < rankSize; rankIndex ++) {
    1051        11513 :                 u32 userRank = CommPlaneVector_[level][ringIndex][rankIndex].userRank;
    1052        11513 :                 CommPlaneRanks[level][ringIndex][rankIndex] = userRank;
    1053        11513 :                 HCCL_DEBUG("GetCommPlaneRanks CommPlaneRanks[%u][%u][%u]=%u", level, ringIndex, rankIndex, userRank);
    1054              :             }
    1055              :         }
    1056              :     }
    1057          520 :     return HCCL_SUCCESS;
    1058              : }
    1059              : 
    1060         1047 : void TopoInfoExtractor::GetIsBridgeVector(std::vector<bool> &isBridgeVector)
    1061              : {
    1062         1047 :     isBridgeVector = isBridgeVector_;
    1063         1047 :     return;
    1064              : }
    1065              : 
    1066          520 : HcclResult TopoInfoExtractor::GetIsUsedRdmaMap(std::unordered_map<u32, bool> &isUsedRdmaMap)
    1067              : {
    1068         2143 :     for (const RankInfo &dstRank : rankVector_) {
    1069         1623 :         bool isInterSuperPod = false;
    1070         1623 :         bool isInterServer = false;
    1071         1623 :         uint32_t isConnectedWithPcie = 0;
    1072         1623 :         if (rankData_.superPodId != dstRank.superPodId) { // 跨超节点场景
    1073           51 :             isInterSuperPod = true;
    1074         1572 :         } else if (rankData_.serverIdx != dstRank.serverIdx) { // 不跨超节点, 跨server场景
    1075          252 :             isInterServer = true;
    1076              :         } else { // 同server, PCIE互连场景
    1077         1320 :             HCCL_DEBUG("[TopoInfoExtractor]GetIsUsedRdmaMap for interServer");
    1078         1320 :             auto it = deviceLinkTypeMap_.find(dstRank.devicePhyId);
    1079         1320 :             CHK_PRT_RET(it == deviceLinkTypeMap_.end(),
    1080              :                 HCCL_ERROR("can't find devicePhyId[%d] in deviceLinkTypeMap_", dstRank.devicePhyId),
    1081              :                 HCCL_E_NOT_FOUND);
    1082         1320 :             isConnectedWithPcie = (it->second == LinkTypeInServer::PXI_TYPE) ? true : false;
    1083              :         }
    1084              :         // 使能RDMA的场景: 1.跨超节点  2.跨server且不使能HCCS  3.PCIE连接且使能RDMA开关
    1085         1572 :         bool isUsedRdma = (isInterSuperPod) ||
    1086         3195 :                 (isInterServer && !isUsedInterHccsMode_) || (isConnectedWithPcie && isUsedRdmaLevel0_);
    1087         1623 :         isUsedRdmaMap[dstRank.userRank] = isUsedRdma;
    1088         1623 :         HCCL_DEBUG("[GetIsUsedRdma]isUsedRdma[%u], isInterSuperPod[%u], isInterServer[%u], isUsedInterHccsMode_[%u], "\
    1089              :             "isConnectedWithPcie[%u], isUsedRdmaLevel0_[%u], dstRank[%u]", isUsedRdma, isInterSuperPod, isInterServer,
    1090              :             isUsedInterHccsMode_, isConnectedWithPcie, isUsedRdmaLevel0_, dstRank.userRank);
    1091              :     }
    1092          520 :     return HCCL_SUCCESS;
    1093              : }
    1094              : 
    1095          520 : HcclResult TopoInfoExtractor::GetRankVecInfo(std::vector<std::vector<std::vector<u32>>> &serverAndsuperPodToRank)
    1096              : {
    1097          520 :     std::vector<std::vector<u32>> serverToRank;
    1098          520 :     std::vector<std::vector<u32>> superPodToRank;
    1099          520 :     serverToRank.clear();
    1100          520 :     superPodToRank.clear();
    1101          520 :     u32 firstIdx = 0;
    1102              : 
    1103          520 :     serverToRank.resize(serverToRank_.size());
    1104         1209 :     for (auto iterMap = serverToRank_.begin(); iterMap != serverToRank_.end(); iterMap++) {
    1105          689 :         serverToRank[firstIdx].resize((iterMap->second).size());
    1106          689 :         if (!(iterMap->second).empty()) {
    1107         2261 :             for (u32 i = 0; i < (iterMap->second).size(); i++) {
    1108         1572 :                 serverToRank[firstIdx][i] = (iterMap->second)[i].userRank;
    1109              :             }
    1110              :         }
    1111          689 :         firstIdx++;
    1112              :     }
    1113              : 
    1114          520 :     u32 podFirstIdx = 0;
    1115          520 :     superPodToRank.resize(superPodToRank_.size());
    1116         1081 :     for (auto iterMap = superPodToRank_.begin(); iterMap != superPodToRank_.end(); iterMap++) {
    1117          561 :         if (!(iterMap->second).empty()) {
    1118          561 :             superPodToRank[podFirstIdx].resize((iterMap->second).size());
    1119         2184 :             for (u32 i = 0; i < (iterMap->second).size(); i++) {
    1120         1623 :                 superPodToRank[podFirstIdx][i] = (iterMap->second)[i].userRank;
    1121         1623 :                 HCCL_DEBUG("GetRankVecInfo superPodToRank[%u][%u]=%u", podFirstIdx, i, superPodToRank[podFirstIdx][i]);
    1122              :             }
    1123              :         }
    1124          561 :         podFirstIdx++;
    1125              :     }
    1126          520 :     serverAndsuperPodToRank.push_back(serverToRank);
    1127          520 :     serverAndsuperPodToRank.push_back(superPodToRank);
    1128          520 :     return HCCL_SUCCESS;
    1129          520 : }
    1130          522 : HcclResult TopoInfoExtractor::SetTopoInfoForCombineL1()
    1131              : {
    1132          522 :     if (deviceType_ == DevType::DEV_TYPE_910_93) {
    1133              :         // 按照superPodIdx 划分得所有rank信息
    1134          107 :         for (auto iter = superPodToRank_.begin(); iter != superPodToRank_.end(); iter++) {
    1135           74 :             if (iter->first != rankData_.superPodIdx) {
    1136           41 :                 continue; // 只在自己所在的超节点创建
    1137              :             }
    1138           33 :             CommPlaneVector_[COMM_COMBINE_L1].push_back(iter->second);
    1139           33 :             HCCL_DEBUG("[SetTopoInfoForARS]Superpod rankdSize[%u].", CommPlaneVector_[COMM_COMBINE_L1][0].size());
    1140              :         }
    1141              :     }
    1142          522 :     return HCCL_SUCCESS;
    1143              : }
    1144              : 
    1145          522 : HcclResult TopoInfoExtractor::SetTopoInfoForARS() // 针对ARS特性
    1146              : {
    1147          522 :     if (deviceType_ == DevType::DEV_TYPE_910_93) {
    1148          107 :         for (auto iter = superPodToRank_.begin(); iter != superPodToRank_.end(); iter++) {
    1149           74 :             if (iter->first != rankData_.superPodIdx) {
    1150           41 :                 continue; // 只在自己所在的超节点创建
    1151              :             }
    1152           33 :             CommPlaneVector_[COMM_ARS].push_back(iter->second);
    1153           33 :             HCCL_DEBUG("[SetTopoInfoForARS]Superpod rankdSize[%u].", CommPlaneVector_[COMM_ARS][0].size());
    1154              :         }
    1155              :     }
    1156          522 :     return HCCL_SUCCESS;
    1157              : }
    1158              : 
    1159          527 : void TopoInfoExtractor::GetCommPlaneVector(std::vector<std::vector<std::vector<RankInfo>>> &commPlaneVector)
    1160              : {
    1161          527 :     commPlaneVector = CommPlaneVector_;
    1162          527 :     return;
    1163              : }
    1164              : 
    1165          523 : void TopoInfoExtractor::InitAHCConfig(std::map<HcclCMDType, std::vector<HcclAlgoType>> &algoConfig)
    1166              : {
    1167        54711 :     for (u32 opType = 0; opType < static_cast<u32>(HcclCMDType::HCCL_CMD_MAX); opType++) {
    1168        54190 :         std::vector<HcclAlgoType> algoType = algoConfig[static_cast<HcclCMDType>(opType)];
    1169       108378 :         isConfigAHC_ = (algoType[HCCL_ALGO_LEVEL_1] == HcclAlgoType::HCCL_ALGO_TYPE_AHC ||
    1170        54188 :                         algoType[HCCL_ALGO_LEVEL_1] == HcclAlgoType::HCCL_ALGO_TYPE_AHC_BROKE);
    1171        54190 :         if (isConfigAHC_) {
    1172            2 :             HCCL_INFO("[InitAHCConfig] set AHC alg, opType[%u]", opType);
    1173            2 :             break;
    1174              :         }
    1175        54190 :     }
    1176              : 
    1177        52211 :     for (u32 opType = 0; opType < static_cast<u32>(HcclCMDType::HCCL_CMD_MAX); opType++) {  //没配置算法的情况下默认会走AHC嘛?  给测试用
    1178        51714 :         std::vector<HcclAlgoType> algoType = algoConfig[static_cast<HcclCMDType>(opType)];
    1179        51714 :         isConfigNULL_ = algoType[HCCL_ALGO_LEVEL_0] == HcclAlgoType::HCCL_ALGO_TYPE_NULL;
    1180        51714 :         if (isConfigNULL_) {
    1181           26 :             HCCL_INFO("[InitAHCConfig] set NULL alg, opType[%u]", opType);
    1182           26 :             break;
    1183              :         }
    1184        51714 :     }
    1185          523 :     return;
    1186              : }
    1187              : 
    1188          522 : HcclResult TopoInfoExtractor::SetAHCSubGroupsAndAlgOption()
    1189              : {
    1190              :     // 解析subgroup
    1191          522 :     CHK_RET(SetTopoInfoForLevel1(true));
    1192              :     
    1193              :     // 分组切分
    1194          522 :     CHK_RET(AHCSubGroupInit(COMM_LEVEL1_AHC, CommPlaneSubGroupVector_));
    1195          522 :     if (deviceType_ != DevType::DEV_TYPE_910_93) {
    1196          489 :         CHK_RET(AHCSubGroupInit(COMM_COMBINE, CommPlaneSubGroupVector_));
    1197              :     } else {
    1198           33 :         CHK_RET(AHCSubGroupInit(COMM_COMBINE_ORDER, CommPlaneSubGroupVector_));
    1199              :     }
    1200              : 
    1201              :     //算法配置初始化
    1202          522 :     CommAHCBaseInfo::InitConcAlgOption(ahcAlgOption_);
    1203          522 :     return HCCL_SUCCESS;
    1204              : }
    1205              : 
    1206          522 : void TopoInfoExtractor::AHCCommSubgroupInit()
    1207              : {
    1208          522 :     if (deviceType_ != DevType::DEV_TYPE_910_93) {
    1209              :         // 用于910B AHC COMM_COMBINE 通信域分组场景测试
    1210          489 :         std::map<std::string, std::vector<u32>> serverIDGroup;
    1211          489 :         std::vector<std::string> serverIdsVector;
    1212         1981 :         for (u32 i = 0; i < rankVector_.size(); i++) {
    1213         1492 :             auto itServerID = serverIDGroup.find(rankVector_[i].serverId);
    1214         1492 :             if (itServerID != serverIDGroup.end()) {
    1215          848 :                 itServerID->second.push_back(i);
    1216              :             } else {
    1217          644 :                 serverIdsVector.push_back(rankVector_[i].serverId);
    1218          644 :                 std::vector<u32> subGroup;
    1219          644 :                 subGroup.push_back(i);
    1220          644 :                 serverIDGroup.insert(std::make_pair(rankVector_[i].serverId, subGroup));
    1221          644 :             }
    1222              :         }
    1223          489 :         std::vector<std::vector<u32>> serverSubGroups;
    1224         1133 :         for (u32 i = 0; i < serverIdsVector.size(); i++) {
    1225          644 :             serverSubGroups.push_back(serverIDGroup[serverIdsVector[i]]);
    1226              :         }
    1227          489 :         CommPlaneSubGroupVector_[COMM_COMBINE].push_back(serverSubGroups);
    1228          489 :     } else {
    1229              :         // 用于910_93 AHC COMM_COMBINE_ORDER 通信域分组场景测试
    1230           33 :         std::vector<std::string> idsForIndexingVector;
    1231           33 :         std::map<std::string, std::vector<u32>> superPodIdGroup;
    1232          178 :         for (u32 i = 0; i < rankVector_.size(); i++) {
    1233          145 :             auto itSuperPodID = superPodIdGroup.find(rankVector_[i].superPodId);
    1234          145 :             if (itSuperPodID != superPodIdGroup.end()) {
    1235           67 :                 itSuperPodID->second.push_back(i);
    1236              :             } else {
    1237           78 :                 idsForIndexingVector.push_back(rankVector_[i].superPodId);
    1238           78 :                 std::vector<u32> subGroup;
    1239           78 :                 subGroup.push_back(i);
    1240           78 :                 superPodIdGroup.insert(std::make_pair(rankVector_[i].superPodId, subGroup));
    1241           78 :             }
    1242              :         }
    1243           33 :         std::vector<std::vector<u32>> superPodSubGroups;
    1244          111 :         for (u32 i = 0; i < idsForIndexingVector.size(); i++) {
    1245           78 :             superPodSubGroups.push_back(superPodIdGroup[idsForIndexingVector[i]]);
    1246           78 :             HCCL_DEBUG("[SetTopoInfoForLevel0][AHC_DEBUG 910_93] superPodId[%s]", idsForIndexingVector[i].c_str());
    1247          223 :             for (u32 index = 0; index < superPodIdGroup[idsForIndexingVector[i]].size(); index++) {
    1248          145 :                 HCCL_DEBUG("[SetTopoInfoForLevel0][AHC_DEBUG 910_93] groupIdx[%u]", superPodIdGroup[idsForIndexingVector[i]][index]);
    1249              :             }
    1250              :         }
    1251           33 :         CommPlaneSubGroupVector_[COMM_COMBINE_ORDER].push_back(superPodSubGroups);
    1252           33 :     }
    1253          522 :     return;
    1254              : }
    1255              : 
    1256          520 : void TopoInfoExtractor::GetCommPlaneSubGroupVector(std::vector<std::vector<std::vector<std::vector<u32>>>> &CommPlaneSubGroupVector)
    1257              : {
    1258          520 :     CommPlaneSubGroupVector = CommPlaneSubGroupVector_;
    1259          520 :     return;
    1260              : }
    1261              : 
    1262            0 : void TopoInfoExtractor::SetAHCLevelAlgOption(AHCConcOpType ahcConcOpType,TemplateType templateType)
    1263              : {
    1264            0 :     if (ahcAlgOption_.find(ahcConcOpType) == ahcAlgOption_.end()) {
    1265            0 :         ahcAlgOption_[ahcConcOpType] = templateType;
    1266              :     }
    1267            0 :     return;
    1268              : }
    1269              : 
    1270          520 : void TopoInfoExtractor::GetAHCAlgOption(std::map<AHCConcOpType, TemplateType> &ahcAlgOption)
    1271              : {
    1272          520 :     ahcAlgOption = ahcAlgOption_;
    1273          520 :     return;
    1274              : }
    1275              : 
    1276          527 : void TopoInfoExtractor::GetRankData(RankInfo &rankData)
    1277              : {
    1278          527 :     rankData = rankData_;
    1279          527 :     return;
    1280              : }
    1281              : 
    1282          527 : void TopoInfoExtractor::GetServerToRank(std::map<u32, std::vector<RankInfo>> &serverToRank)
    1283              : {
    1284          527 :     serverToRank = serverToRank_;
    1285          527 :     return;
    1286              : }
    1287              : 
    1288          527 : void TopoInfoExtractor::GetSuperPodToRank(std::map<u32, std::vector<RankInfo>> &superPodToRank)
    1289              : {
    1290          527 :     superPodToRank = superPodToRank_;
    1291          527 :     return;
    1292              : }
    1293              : 
    1294          527 : void TopoInfoExtractor::GetDeviceLinkTypeMap(std::map<s32, LinkTypeInServer> &deviceLinkTypeMap)
    1295              : {
    1296          527 :     deviceLinkTypeMap = deviceLinkTypeMap_;
    1297          527 :     return;
    1298              : }
    1299              : 
    1300         1044 : HcclResult TopoInfoExtractor::AHCSubGroupInit(CommPlane algLevel, std::vector<std::vector<std::vector<std::vector<u32>>>> &CommPlaneSubGroupVector)
    1301              : {
    1302         1044 :     std::vector<std::vector<std::vector<u32>>>  &globalSubGroups = CommPlaneSubGroupVector[algLevel];
    1303              :  
    1304              :     // globalSubGroups 参数检查
    1305         1044 :     if ((globalSubGroups.size() == 0) || (globalSubGroups[0].size() == 0)) {
    1306          358 :         return HCCL_SUCCESS;
    1307              :     }
    1308              : 
    1309          686 :     CHK_RET(CommAHCBaseInfo::CheckGlobalGroups(globalSubGroups));
    1310              : 
    1311          686 :     u32 minSubGroupSize = globalSubGroups[0][0].size();
    1312          686 :     u32 maxSubGroupSize = globalSubGroups[0][0].size();
    1313          686 :     u32 subGroupSizeGCD = globalSubGroups[0][0].size();
    1314          931 :     for (u32 i = 1; i < globalSubGroups[0].size(); ++i) {
    1315          245 :         subGroupSizeGCD = std::__gcd(subGroupSizeGCD, static_cast<u32>(globalSubGroups[0][i].size()));
    1316          245 :         if (globalSubGroups[0][i].size() < minSubGroupSize) {
    1317            0 :             minSubGroupSize = globalSubGroups[0][i].size();
    1318              :         }
    1319          245 :         if (globalSubGroups[0][i].size() > maxSubGroupSize) {
    1320           16 :             maxSubGroupSize = globalSubGroups[0][i].size();
    1321              :         }
    1322              :     }
    1323              :  
    1324          686 :     u32 splitDivisor = minSubGroupSize;
    1325              :  
    1326          686 :     HCCL_DEBUG("[TopoInfoExtractor][AHCSubGroupInit] begin groupSplit algLevel = %u minSubGroupSize = %u maxSubGroupSize = %u SubGroupSizeGCD = %u \
    1327              :         splitDivisor = %u", algLevel, minSubGroupSize, maxSubGroupSize, subGroupSizeGCD, splitDivisor);
    1328              : 
    1329              :     // 切分分组逻辑, 满足整数倍切分,满足最大偏差大于等于最小分组数时切分
    1330          686 :     if ((subGroupSizeGCD == minSubGroupSize) || (maxSubGroupSize / splitDivisor > 1)) {
    1331              :         // 设置为 BROKE 类型
    1332          686 :         maxSubGroupSize = splitDivisor;
    1333              :         // 将所有的分组切分成 splitDivisor 粒度的 subGroup
    1334         1665 :         for (u32 i = 0; i < globalSubGroups[0].size(); ++i) {
    1335          979 :             if (globalSubGroups[0][i].size() / splitDivisor <= 1) {
    1336          963 :                 continue;
    1337              :             }
    1338           16 :             std::vector<u32> originGroup = globalSubGroups[0][i];
    1339           16 :             globalSubGroups[0].erase(globalSubGroups[0].begin() + i);
    1340           16 :             u32 splitGroupsNum = (originGroup.size() / splitDivisor);
    1341           48 :             for (u32 j = 0; j < splitGroupsNum - 1; ++j) {
    1342           64 :                 globalSubGroups[0].insert(globalSubGroups[0].begin() + i + j, std::vector<u32>(originGroup.begin() + j * splitDivisor,
    1343           64 :                                                         originGroup.begin() + (j + 1) * splitDivisor));
    1344              :             }
    1345           32 :             globalSubGroups[0].insert(globalSubGroups[0].begin() + i + splitGroupsNum - 1, std::vector<u32>(originGroup.begin() + (splitGroupsNum - 1) * splitDivisor,
    1346           32 :                                                         originGroup.begin() + originGroup.size()));
    1347           16 :             maxSubGroupSize = std::max(maxSubGroupSize, static_cast<u32>(originGroup.size()) - ((splitGroupsNum - 1) * splitDivisor));
    1348           16 :             i--;
    1349           16 :         }
    1350              :     }
    1351              : 
    1352          686 :     HCCL_DEBUG("[TopoInfoExtractor][AHCSubGroupInit] after groupSplit algLevel = %u minSubGroupSize = %u maxSubGroupSize = %u SubGroupSizeGCD = %u \
    1353              :         splitDivisor = %u", algLevel, minSubGroupSize, maxSubGroupSize, subGroupSizeGCD, splitDivisor);
    1354              : 
    1355          686 :     CHK_RET(CommAHCBaseInfo::CheckGlobalGroups(globalSubGroups));
    1356              : 
    1357          686 :     return HCCL_SUCCESS;
    1358              : }
    1359              : 
    1360         5748 : bool Ascending(const RankInfo &first, const RankInfo &second)
    1361              : {
    1362         5748 :     if (first.serverIdx != second.serverIdx) {
    1363          449 :         return first.serverIdx < second.serverIdx;
    1364              :     } else {
    1365         5299 :         return first.userRank < second.userRank;
    1366              :     }
    1367              : }
    1368              : 
    1369          552 : bool CompareWithUserRankAscend(const RankInfo &left, const RankInfo &right)
    1370              : {
    1371          552 :     return left.userRank < right.userRank;
    1372              : }
    1373              : 
    1374              : // 适配ROH平面网段隔离,奇数rank互通,偶数rank互通,奇偶不通
    1375            1 : bool CheckSdmaWithRohTopo(const std::vector<u32> &nicList, std::vector<u32> &topoList)
    1376              : {
    1377            1 :     std::vector<u32> tmpNicList(nicList);
    1378            1 :     SearchPath searchPath;
    1379            1 :     std::sort(tmpNicList.begin(), tmpNicList.end());
    1380            1 :     topoList = searchPath.Search(tmpNicList);
    1381            1 :     if (topoList.empty()) {
    1382            0 :         return false;
    1383              :     }
    1384            1 :     return true;
    1385            1 : }
    1386              : 
    1387          522 : std::vector<std::vector<u32>> GetRingsOrderByTopoType(u32 ranksSize, TopoType topoType, std::vector<u32> &nicList)
    1388              : {
    1389          522 :     std::vector<std::vector<u32>> multiRingOrder;
    1390          522 :     if (topoType == TopoType::TOPO_TYPE_8P_RING) { // 4 ring 场景
    1391              :         // 每个环的排序是按照设备物理ID进行的
    1392           48 :         std::vector<u32> tmpLevel00 = { 0, 1, 2, 6, 5, 4, 7, 3 }; // 环0
    1393           48 :         std::vector<u32> tmpLevel01 = { 0, 3, 7, 4, 5, 6, 2, 1 }; // 环1
    1394           48 :         std::vector<u32> tmpLevel02 = { 0, 2, 3, 1, 5, 7, 6, 4 }; // 环2
    1395           48 :         std::vector<u32> tmpLevel03 = { 0, 4, 6, 7, 5, 1, 3, 2 }; // 环3
    1396              : 
    1397              :         // 填充8pring 多环的comm level0 四个环的顺序
    1398           24 :         multiRingOrder.push_back(tmpLevel00);
    1399           24 :         multiRingOrder.push_back(tmpLevel01);
    1400           24 :         multiRingOrder.push_back(tmpLevel02);
    1401           24 :         multiRingOrder.push_back(tmpLevel03);
    1402          522 :     } else if (topoType == TopoType::TOPO_TYPE_NP_DOUBLE_RING) { // 2 ring 场景
    1403            7 :         std::vector<u32> tmpLevel00;   // 环0
    1404            7 :         std::vector<u32> tmpLevel01;  // 环1
    1405            7 :         tmpLevel00 = nicList;  // { 0, 1, 2, 3, 4, 5, 6, 7 };
    1406            7 :         tmpLevel01.reserve(ranksSize);
    1407            7 :         tmpLevel01.push_back(nicList[0]);
    1408            7 :         tmpLevel01.insert(tmpLevel01.end(), tmpLevel00.rbegin(), tmpLevel00.rend() - 1);
    1409            7 :         HCCL_INFO("[GetRingsOrderByTopoType] TopoType:TOPO_TYPE_NP_DOUBLE_RING");
    1410              :         // 填充 double ring 两环的comm level0的顺序
    1411            7 :         multiRingOrder.push_back(tmpLevel00);
    1412            7 :         multiRingOrder.push_back(tmpLevel01);
    1413            7 :     } else { // 1 ring 场景
    1414          491 :         std::vector<u32> tmpLevel00 = nicList; // 环0
    1415              : 
    1416              :         // 填充 single ring 单环的comm level0的顺序
    1417          491 :         multiRingOrder.push_back(tmpLevel00);
    1418          491 :     }
    1419              :     // 打印多个环
    1420          522 :     if (UNLIKELY(HcclCheckLogLevel(DLOG_DEBUG))) {
    1421         1123 :         for (size_t i = 0; i < multiRingOrder.size(); i++) {
    1422          601 :             auto ring = multiRingOrder[i];
    1423          601 :             std::ostringstream stringRepresentation;
    1424         2527 :             for (std::vector<uint32_t>::iterator it = ring.begin(); it != ring.end(); it++) {
    1425         1926 :                 stringRepresentation << *it << " ";
    1426              :             }
    1427          601 :             std::string ringString = stringRepresentation.str();
    1428          601 :             const char *charRing = ringString.c_str();
    1429          601 :             HCCL_DEBUG("[GetRingsOrderByTopoType] The No.%zu ring: %s", i, charRing);
    1430          601 :         }
    1431              :     }
    1432          522 :     return multiRingOrder;
    1433            0 : }
    1434              : 
    1435            1 : std::vector<std::vector<u32>> GetRingsOrderForAnyPath(u32 ranksSize, TopoType topoType, std::vector<u32> &nicList)
    1436              : {
    1437            1 :     std::vector<std::vector<u32>> multiRingOrder;
    1438            1 :     if (topoType == TopoType::TOPO_TYPE_NP_DOUBLE_RING) { // 2 ring 场景
    1439            1 :         std::vector<u32> tmpLevel00;   // 环0
    1440            1 :         std::vector<u32> tmpLevel01;  // 环1
    1441            1 :         std::vector<u32> rohLevel0;
    1442            1 :         if (CheckSdmaWithRohTopo(nicList, rohLevel0)) {
    1443            1 :             tmpLevel00 = rohLevel0;          // 环0, 8卡 { 0, 1, 3, 2, 4, 5, 7, 6 };
    1444            1 :             tmpLevel01.reserve(ranksSize);  // 环1, 8卡 { 0, 6, 7, 5, 4, 2, 3, 1 };
    1445            1 :             tmpLevel01.push_back(rohLevel0[0]);
    1446            1 :             tmpLevel01.insert(tmpLevel01.end(), rohLevel0.rbegin(), rohLevel0.rend() - 1);
    1447              :         } else {
    1448            0 :             tmpLevel00 = nicList;  // { 0, 1, 2, 3, 4, 5, 6, 7 };
    1449            0 :             tmpLevel01.reserve(ranksSize);
    1450            0 :             tmpLevel01.push_back(nicList[0]);
    1451            0 :             tmpLevel01.insert(tmpLevel01.end(), tmpLevel00.rbegin(), tmpLevel00.rend() - 1);
    1452              :         }
    1453              :         // 填充 double ring 两环的comm level0的顺序
    1454            1 :         multiRingOrder.push_back(tmpLevel00);
    1455            1 :         multiRingOrder.push_back(tmpLevel01);
    1456            1 :     } else { // 1 ring 场景
    1457            0 :         std::vector<u32> tmpLevel00 = nicList; // 环0
    1458              : 
    1459              :         // 填充 single ring 单环的comm level0的顺序
    1460            0 :         multiRingOrder.push_back(tmpLevel00);
    1461            0 :     }
    1462              :     // 打印多个环
    1463            1 :     HCCL_DEBUG("[GetRingsOrderForAnyPath]print rings:");
    1464            3 :     for (size_t i = 0; i < multiRingOrder.size(); i++) {
    1465            2 :         auto ring = multiRingOrder[i];
    1466            2 :         std::ostringstream stringRepresentation;
    1467           18 :         for (std::vector<uint32_t>::iterator it = ring.begin(); it != ring.end(); it++) {
    1468           16 :             stringRepresentation << *it << " ";
    1469              :         }
    1470            2 :         std::string ringString = stringRepresentation.str();
    1471            2 :         const char *charRing = ringString.c_str();
    1472            2 :         HCCL_INFO("[GetRingsOrderByRdmaSdmaConcurrent] The No.%zu ring: %s.", i, charRing);
    1473            2 :     }
    1474            1 :     return multiRingOrder;
    1475            0 : }
    1476              : 
    1477              : }
        

Generated by: LCOV version 2.0-1