LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/common/src/topo - topoinfo_ranktable_partition.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.8 % 132 108
Test Date: 2026-07-28 12:11:00 Functions: 100.0 % 9 9

            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 "topoinfo_ranktable_partition.h"
      12              : 
      13              : #include <vector>
      14              : #include <string>
      15              : #include <unordered_map>
      16              : #include <unordered_set>
      17              : 
      18              : namespace hccl {
      19              : 
      20            1 : TopoinfoRanktablePartition::TopoinfoRanktablePartition(hccl::HcclCommParams &globalParams,
      21            1 :     hccl::RankTable_t &globalRankTable)
      22            1 :     : globalParams_(globalParams), globalRankTable_(globalRankTable)
      23              : {
      24            1 : }
      25              : 
      26            1 : TopoinfoRanktablePartition::~TopoinfoRanktablePartition()
      27              : {
      28            1 : }
      29              : 
      30            1 : HcclResult TopoinfoRanktablePartition::GenerateSubRankTable(const uint32_t rankNum, const uint32_t *rankIds,
      31              :     hccl::RankTable_t &subRankTable)
      32              : {
      33            1 :     subRankTable.nicDeploy = globalRankTable_.nicDeploy;
      34            1 :     std::unordered_map<uint32_t, size_t> rankInfoMap;
      35            2 :     for (size_t i = 0; i < globalRankTable_.rankList.size(); i++) {
      36            1 :         auto rankId = globalRankTable_.rankList[i].rankId;
      37            1 :         rankInfoMap[rankId] = i;
      38              :     }
      39            1 :     std::unordered_map<std::string, u32> serverIdMap;
      40            1 :     std::unordered_map<std::string, u32> superPodIdMap;
      41            1 :     std::unordered_set<uint32_t> rankIdSet;
      42            1 :     subRankTable.deviceNum = 0;
      43            2 :     for (size_t i = 0; i < rankNum; i++) {
      44            1 :         CHK_PTR_NULL(rankIds + i);
      45            1 :         uint32_t rankId = rankIds[i];
      46            1 :         CHK_PRT_RET(
      47              :             rankIdSet.find(rankId) != rankIdSet.end(),
      48              :             HCCL_ERROR("[TopoinfoRanktablePartition][GenerateSubRankTable]errNo[0x%016llx], " \
      49              :                 "duplicated rankId[%u] in rankIds.", HCCL_ERROR_CODE(HCCL_E_PARA), rankId),
      50              :             HCCL_E_PARA);
      51              : 
      52            1 :         auto iter = rankInfoMap.find(rankId);
      53            1 :         CHK_PRT_RET(
      54              :             iter == rankInfoMap.end(),
      55              :             HCCL_ERROR("[TopoinfoRanktablePartition][GenerateSubRankTable]errNo[0x%016llx], " \
      56              :                 "fail to find target rank[%u] in the global communicator.", HCCL_ERROR_CODE(HCCL_E_PARA), rankId),
      57              :             HCCL_E_PARA);
      58              : 
      59            1 :         hccl::RankInfo_t rankInfo = globalRankTable_.rankList[iter->second];
      60            1 :         serverIdMap.emplace(rankInfo.serverId, serverIdMap.size());
      61            1 :         superPodIdMap.emplace(rankInfo.superPodId, superPodIdMap.size());
      62              : 
      63            1 :         rankInfo.rankId = i;
      64            1 :         rankInfo.serverIdx = serverIdMap[rankInfo.serverId];
      65            1 :         rankInfo.superPodIdx = superPodIdMap[rankInfo.superPodId];
      66            1 :         subRankTable.rankList.emplace_back(rankInfo);
      67              : 
      68            1 :         if (rankInfo.deviceInfo.devicePhyId != HOST_DEVICE_ID) {
      69            1 :             subRankTable.deviceNum++;
      70              :         }
      71            1 :         HCCL_INFO(
      72              :             "[TopoinfoRanktablePartition][GenerateSubRankTable]" \
      73              :             "Pick rank[%u] from global comm as rank[%u] in sub comm, " \
      74              :             "severId[%s], serverIdx[%u], superPodId[%s], superDeviceId[%u], devicePhyId[%d].",
      75              :             rankId, i, rankInfo.serverId.c_str(), rankInfo.serverIdx, rankInfo.superPodId.c_str(),
      76              :             rankInfo.superDeviceId, rankInfo.deviceInfo.devicePhyId);
      77            1 :     }
      78            1 :     CHK_RET(GenerateSubSuperPodId(subRankTable));
      79            1 :     subRankTable.serverNum = serverIdMap.size();
      80            1 :     subRankTable.superPodNum = superPodIdMap.size();
      81            1 :     subRankTable.rankNum = rankNum;
      82            1 :     subRankTable.version = globalRankTable_.version;
      83            1 :     return HCCL_SUCCESS;
      84            1 : }
      85              : 
      86            1 : HcclResult TopoinfoRanktablePartition::GenerateSubSuperPodId(hccl::RankTable_t &subRankTable)
      87              : {
      88            1 :     std::map<std::string, std::vector<RankInfo_t*>> podGroupClusters;
      89            2 :     for (auto& rankInfo : subRankTable.rankList) {
      90            1 :         podGroupClusters[rankInfo.originalSuperPodId].emplace_back(&rankInfo);
      91              :     }
      92            1 :     std::set<std::string> superPodIdSet;
      93            1 :     std::map<std::string, std::pair<u32, u32>> superPodIdRanges; // 记录每个逻辑超节点的rank id范围
      94            2 :     for (auto& subCluster : podGroupClusters) {
      95            1 :         auto& subClusterInfo = subCluster.second;
      96            1 :         if (subClusterInfo.size() <= 1) {
      97            1 :             continue;
      98              :         }
      99            0 :         u32 groupId = 0;
     100            0 :         superPodIdSet.insert(subCluster.first);
     101            0 :         RankInfo_t preRank = *(subClusterInfo[0]);
     102            0 :         superPodIdRanges[preRank.superPodId] = {preRank.rankId, preRank.rankId}; // 初始化范围
     103            0 :         for (u32 i = 1; i < subClusterInfo.size(); ++i) {
     104            0 :             RankInfo_t& curRank = *(subClusterInfo[i]);
     105              :             // 当前的curRank和上一个preRank的rankId不连续,分配新的逻辑超节点ID
     106            0 :             if (curRank.rankId != preRank.rankId + 1) {
     107            0 :                 std::string newSuperPodId = curRank.originalSuperPodId + "_HCCLSPLIT_" + std::to_string(groupId);
     108            0 :                 curRank.superPodId = newSuperPodId;
     109            0 :                 groupId++;
     110            0 :                 superPodIdRanges[curRank.superPodId] = {curRank.rankId, curRank.rankId}; // 初始化新的范围
     111            0 :             } else {
     112              :                 // 同一个sub通信域两个rank原始逻辑超节点是一致的
     113              :                 // rankId连续 上一个rank的superPodId可能已经重新分配,需要更新当前superPodId为上一个rank的
     114            0 :                 curRank.superPodId = preRank.superPodId;
     115            0 :                 superPodIdRanges[curRank.superPodId].second = curRank.rankId; // 更新最大rank id
     116              :             }
     117            0 :             superPodIdSet.insert(curRank.superPodId);
     118            0 :             preRank = curRank;
     119              :         }
     120            0 :     }
     121              :     // 打印每个逻辑超节点的rank id范围,只打印包含_HCCLSPLIT_的逻辑超节点
     122            1 :     for (const auto& entry : superPodIdRanges) {
     123            0 :         auto superPodId = entry.first;
     124            0 :         if (superPodId.find("_HCCLSPLIT_") != std::string::npos) {
     125            0 :             auto range = entry.second;
     126            0 :             HCCL_RUN_INFO("[TopoinfoRanktablePartition][%s]Split superPod, ID[%s], rank range[%u, %u]", __func__,
     127              :                 superPodId.c_str(), range.first, range.second);
     128              :         }
     129            0 :     }
     130            1 :     subRankTable.superPodNum = superPodIdSet.size();
     131            1 :     return HCCL_SUCCESS;
     132            1 : }
     133              : 
     134            1 : HcclResult TopoinfoRanktablePartition::GenerateSubParams(const hccl::RankTable_t &subRankTable,
     135              :     const uint32_t subCommRankId, hccl::HcclCommParams &subParams)
     136              : {
     137            1 :     subParams.rank = subCommRankId;
     138            1 :     subParams.userRank = subRankTable.rankList[subCommRankId].rankId;
     139            1 :     subParams.totalRanks = subRankTable.rankList.size();
     140            1 :     subParams.logicDevId = globalParams_.logicDevId;
     141            1 :     subParams.serverId = subRankTable.rankList[subCommRankId].serverId;
     142            1 :     subParams.deviceType = globalParams_.deviceType;
     143            1 :     subParams.commPortConfig.devPortSwitchOn = globalParams_.commPortConfig.devPortSwitchOn;
     144            1 :     return HCCL_SUCCESS;
     145              : }
     146              : 
     147            1 : HcclResult TopoinfoRanktablePartition::GetRankTableStr(const hccl::RankTable_t &subRankTable, std::string &rankTableStr)
     148              : {
     149            1 :     nlohmann::json basicJson;
     150            1 :     HcclResult ret = Struct2JsonRankTable(subRankTable, globalParams_.deviceType, basicJson);
     151            1 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_RUN_WARNING("cluster info to json failed, ret[%d].", ret), HCCL_E_INTERNAL);
     152            1 :     rankTableStr = std::move(basicJson.dump());
     153            1 :     return HCCL_SUCCESS;
     154            1 : }
     155              : 
     156            1 : HcclResult TopoinfoRanktablePartition::TransformRankInfo(const RankTable_t &clusterInfo,
     157              :     nlohmann::json &perRankJson, u32 rankIndex)
     158              : {
     159            1 :     auto rankInfo = clusterInfo.rankList[rankIndex];
     160            1 :     perRankJson[PROP_HOST_IP] = std::string(rankInfo.hostIp.GetReadableIP());
     161            1 :     perRankJson[PROP_DEV_ID] = std::to_string(rankInfo.deviceInfo.devicePhyId);
     162            1 :     perRankJson[PROP_DEV_NIC_PORT] = std::to_string(rankInfo.deviceInfo.port);
     163            1 :     perRankJson[PROP_DEV_VNIC_PORT] = std::to_string(rankInfo.deviceInfo.vnicPort);
     164            1 :     perRankJson[PROP_BACKUP_DEV_PORT] = std::to_string(rankInfo.deviceInfo.backupPort);
     165            1 :     perRankJson[PROP_RANK_ID] = std::to_string(rankInfo.rankId);
     166            1 :     perRankJson[PROP_SERVER_ID] = rankInfo.serverId;
     167            1 :     perRankJson[PROP_SUPER_POD_ID] = rankInfo.superPodId;
     168            1 :     perRankJson[PROP_SUPER_DEVICE_ID] = std::to_string(rankInfo.superDeviceId);
     169            1 :     if (rankInfo.deviceInfo.deviceIp.size() != 0 && !rankInfo.deviceInfo.deviceIp[0].IsInvalid()) {
     170            2 :         perRankJson[PROP_DEV_IP] = std::string(rankInfo.deviceInfo.deviceIp[0].GetReadableIP());
     171              :     }
     172            1 :     if (clusterInfo.nicDeploy == NICDeployment::NIC_DEPLOYMENT_DEVICE &&
     173            2 :         rankInfo.deviceInfo.backupDeviceIp.size() != 0 && !rankInfo.deviceInfo.backupDeviceIp[0].IsInvalid()) {
     174            0 :         perRankJson[PROP_BACKUP_DEV_IP] = std::string(rankInfo.deviceInfo.backupDeviceIp[0].GetReadableIP());
     175              :     }
     176            1 :     return HCCL_SUCCESS;
     177            1 : }
     178              : 
     179            1 : HcclResult TopoinfoRanktablePartition::TransformServerList(const RankTable_t &clusterInfo,
     180              :     nlohmann::json &rankListJson)
     181              : {
     182            2 :     for (size_t i = 0; i < clusterInfo.rankList.size(); i++) {
     183            1 :         nlohmann::json perRankJson;
     184            1 :         CHK_RET(TransformRankInfo(clusterInfo, perRankJson, i));
     185            1 :         perRankJson[PROP_RANK_ID] = perRankJson;
     186            1 :         rankListJson.push_back(perRankJson);
     187            1 :     }
     188            1 :     return HCCL_SUCCESS;
     189              : }
     190              : 
     191            1 : HcclResult TopoinfoRanktablePartition::Struct2JsonRankTable(const RankTable_t &clusterInfo, const DevType deviceType,
     192              :     nlohmann::json& ClusterJson)
     193              : {
     194            1 :     ClusterJson[PROP_SERVER_COUNT] = std::to_string(clusterInfo.serverNum);
     195            1 :     ClusterJson[PROP_SUPER_POD_NUM] = std::to_string(clusterInfo.superPodNum);
     196            1 :     ClusterJson[PROP_RANK_NUM] = std::to_string(clusterInfo.rankNum);
     197            1 :     ClusterJson[PROP_DEV_NUM] = std::to_string(clusterInfo.deviceNum);
     198              : 
     199            1 :     nlohmann::json rankListJson;
     200            1 :     CHK_RET(TransformServerList(clusterInfo, rankListJson));
     201            1 :     ClusterJson[PROP_RANK_LIST] = rankListJson;
     202              : 
     203            1 :     ClusterJson[PROP_STATUS] = "completed";
     204            1 :     if (!clusterInfo.version.empty()) {
     205            1 :         ClusterJson[PROP_VERSION] = clusterInfo.version;
     206              :     } else {
     207            0 :         ClusterJson[PROP_VERSION] = (deviceType == DevType::DEV_TYPE_910_93) ? "1.2" : "1.0";
     208              :     }
     209              : 
     210            1 :     return HCCL_SUCCESS;
     211            1 : }
     212              : }  // namespace hccl
        

Generated by: LCOV version 2.0-1