LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/topo/new_topo_builder/rank_table_info - rank_table_info.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.7 % 156 140
Test Date: 2026-08-04 10:52:23 Functions: 100.0 % 11 11

            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 "rank_table_info.h"
      12              : 
      13              : #include <unordered_set>
      14              : #include <unordered_map>
      15              : #include <sstream>
      16              : #include <string>
      17              : #include "json_parser.h"
      18              : #include "invalid_params_exception.h"
      19              : #include "exception_util.h"
      20              : #include "adapter_error_manager_pub.h"
      21              : 
      22              : namespace Hccl {
      23              : 
      24           36 : void RankTableInfo::Check()
      25              : {
      26           36 :     if (version != "2.0") {
      27            3 :         HCCL_ERROR("[RankTableInfo::%s] failed with version [%s] is not \"2.0\".", __func__ , version.c_str());
      28            1 :         RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      29              :                             std::vector<std::string>({version, "version", "2.0"}));
      30            1 :         THROW<InvalidParamsException>(
      31            3 :             StringFormat("[RankTableInfo::%s] failed with version is not \"2.0\" in ranktable file.", __func__));
      32              :     }
      33              : 
      34           35 :     if (rankCount > MAX_RANKCOUNT) {
      35            1 :         RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      36              :                             std::vector<std::string>({std::to_string(rankCount), "rankCount", "lower than " + std::to_string(MAX_RANKCOUNT)}));
      37            2 :         THROW<InvalidParamsException>(StringFormat(
      38              :             "[RankTableInfo::%s] failed with rankCount [%u] exceeds maximum limit of [%u]",
      39              :             __func__, rankCount, MAX_RANKCOUNT));
      40              :     }
      41              : 
      42           34 :     if (rankCount == 0) {
      43            1 :         RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      44              :                             std::vector<std::string>({std::to_string(rankCount), "rankCount", "should not be 0"}));
      45            2 :         THROW<InvalidParamsException>(StringFormat(
      46              :             "[RankTableInfo::%s] failed with rankCount [%u] exceeds minimum limit of [%u]",__func__, rankCount, 0));
      47              :     }
      48              : 
      49           33 :     if (rankCount != ranks.size()) {
      50            1 :         RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      51              :                             std::vector<std::string>({std::to_string(rankCount), "rankCount","rankCount is equal to rankSize[" + std::to_string(ranks.size()) + "]"}));
      52            2 :         THROW<InvalidParamsException>(StringFormat("[RankTableInfo::%s] failed with rankCount is not equal "
      53              :                                                    "to rank_list size. version[%s], rankCount[%u], ranks.size[%u]",
      54              :                                                    __func__, version.c_str(), rankCount, ranks.size()));
      55              :     }
      56              : 
      57           32 :     std::unordered_set<u32> rankIdSet;
      58           32 :     std::unordered_set<u32> localIdSet;
      59           32 :     u32 recordedReplaceLocalId{UNDEFIEND_LOCAL_ID};
      60          117 :     for (auto &rank : ranks) {
      61           88 :         if (static_cast<u32>(rank.rankId) >= rankCount) {
      62            1 :             RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      63              :                             std::vector<std::string>({std::to_string(rank.rankId), "rankId", "[0," + std::to_string(rankCount) + ")"}));
      64            2 :             THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::%s] failed with rank_id is "
      65              :                                                        "out of range. version[%s], rankCount[%u], rank_id[%d]",
      66              :                                                        __func__, version.c_str(), rankCount, rank.rankId));
      67              :         }
      68           87 :         if (rankIdSet.count(rank.rankId) > 0) {
      69            1 :             RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      70              :                             std::vector<std::string>({std::to_string(rank.rankId), "rankId", "rank_id is not repeat."}));
      71            2 :             THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::%s] failed with rank_id is "
      72              :                                                        "repeat. version[%s], rankCount[%u], rank_id[%d]",
      73              :                                                        __func__, version.c_str(), rankCount, rank.rankId));
      74              :         }
      75           86 :         rankIdSet.insert(rank.rankId);
      76              : 
      77           86 :         if (rank.localId != BACKUP_LOCAL_ID && rank.localId != rank.replacedLocalId) {
      78            1 :             RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      79              :                             std::vector<std::string>({std::to_string(rank.replacedLocalId), "replacedLocalId", 
      80              :                                 "replacedLocalId equal to locaId[" + std::to_string(rank.localId) + "]"}));
      81            2 :             THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::Check] "
      82              :             "failed with replacedLocalId[%u] not equal to localId[%u].", rank.replacedLocalId, rank.localId));
      83           85 :         } else if (rank.localId == BACKUP_LOCAL_ID) {
      84            3 :             if (recordedReplaceLocalId == UNDEFIEND_LOCAL_ID) {
      85            3 :                 recordedReplaceLocalId = rank.replacedLocalId;
      86              :             } else {
      87            0 :                 RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
      88              :                             std::vector<std::string>({"NA", "NA", "multiple replaced rank is configured."}));
      89            0 :                 THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::Check] "
      90              :                                                            "multiple replaced rank is configured"));
      91              :             }
      92              :         } else {
      93           82 :             localIdSet.emplace(rank.localId);
      94              :         }
      95              :     }
      96              : 
      97          113 :     for (u32 rankRange = 0; rankRange < rankCount; rankRange++) {
      98           84 :         if (rankIdSet.find(rankRange) == rankIdSet.end()) {
      99            0 :             RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     100              :                             std::vector<std::string>({std::to_string(rankRange),"rankId", "rank_id is continuous."}));
     101            0 :             THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::%s] failed with rank_id is "
     102              :                                                        "not continuous. version[%s], rankCount[%u], rankRange[%d]",
     103              :                                                            __func__, version.c_str(), rankCount, rankRange));
     104              :         }
     105              :     }
     106              : 
     107           29 :     std::vector<std::unordered_map<std::string, u32>> verifyRankAddr;
     108          113 :     for (auto &rank : ranks) {
     109          246 :         for (auto &levelInfo : rank.rankLevelInfos) {
     110          162 :             InsertToRank(levelInfo.netInstId, levelInfo.rankAddrs.size(), verifyRankAddr, levelInfo.netLayer);
     111              :         }
     112              :     }
     113              : 
     114           29 :     if(localIdSet.find(recordedReplaceLocalId) != localIdSet.end()) {
     115            0 :         RPT_INPUT_ERR(true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     116              :                             std::vector<std::string>({std::to_string(recordedReplaceLocalId), "recordedReplacedLocalId",
     117              :                                  "failed with configuring same local_id with replaced one simutaneously."}));
     118            0 :         THROW<InvalidParamsException>(StringFormat("[Parse][ClusterInfo][RankTableInfo::%s] failed with configuring "
     119              :                                                    "same local_id[%u] with replaced one simutaneously",
     120              :                                                     __func__, recordedReplaceLocalId));
     121              :     }
     122           35 : }
     123              : 
     124           38 : void RankTableInfo::Deserialize(const nlohmann::json &rankTableInfoJson, bool isCheck)
     125              : {
     126           38 :     std::string msgVersion   = "error occurs when parser object of propName \"version\"";
     127           39 :     TRY_CATCH_THROW(InvalidParamsException, msgVersion, version = GetJsonProperty(rankTableInfoJson, "version"););
     128           37 :     std::string msgStatus    = "error occurs when parser object of propName \"status\"";
     129              : 
     130           37 :     std::string detourStr;
     131           37 :     std::string msgDetour   = "error occurs when parser object of propName \"detour\"";
     132           37 :     TRY_CATCH_THROW(InvalidParamsException, msgDetour, detourStr = GetJsonProperty(rankTableInfoJson, "detour", false););
     133           37 :     if (detourStr == "true") {
     134           23 :         detour = true;
     135           14 :     } else if (detourStr == "false" || detourStr == "") {
     136           13 :         detour = false;
     137              :     } else {
     138            2 :         THROW<InvalidParamsException>(StringFormat("Invalid detour value [%s]", detourStr.c_str()));
     139              :     }
     140              : 
     141           36 :     std::string msgRankcount = "error occurs when parser object of propName \"rank_count\"";
     142           37 :     TRY_CATCH_THROW(InvalidParamsException, msgRankcount, rankCount = GetJsonPropertyUInt(rankTableInfoJson, "rank_count"););
     143              : 
     144           35 :     nlohmann::json rankJsons;
     145           35 :     std::string    msgRanklist = "error occurs when parser object of propName \"rank_list\"";
     146           35 :     TRY_CATCH_THROW(InvalidParamsException, msgRanklist,
     147              :                          GetJsonPropertyList(rankTableInfoJson, "rank_list", rankJsons););
     148          120 :     for (auto &rankJson : rankJsons) {
     149           86 :         NewRankInfo rankInfo;
     150           86 :         rankInfo.Deserialize(rankJson);
     151           85 :         ranks.emplace_back(rankInfo);
     152           86 :     }
     153              :    
     154              :     // check
     155           34 :     if (isCheck) {
     156           33 :         Check();
     157              :     }
     158           87 : }
     159              : 
     160          162 : void RankTableInfo::CheckAndInsert(const std::string &levelId, u32 rankAddrSize,
     161              :                                    std::unordered_map<std::string, u32> &idRankSizeMap) const
     162              : {
     163          162 :     if (idRankSizeMap.find(levelId) != idRankSizeMap.end() && idRankSizeMap[levelId] != rankAddrSize) {
     164            0 :         THROW<InvalidParamsException>(StringFormat("[RankTableInfo::%s] failed with the size of "
     165              :                                                    "rank_addrs with the same id is different. leveId[%s],"
     166              :                                                    "rankAddrSize[%u]",
     167              :                                                    __func__, levelId.c_str(), rankAddrSize));
     168              :     }
     169          162 :     idRankSizeMap[levelId] = rankAddrSize;
     170          162 : }
     171              : 
     172          162 : void RankTableInfo::InsertToRank(const std::string &levelId, u32 rankAddrSize,
     173              :                                  std::vector<std::unordered_map<std::string, u32>> &rankLists, u32 levelNum) const
     174              : {
     175          162 :     if (rankLists.size() <= levelNum) {
     176           49 :         rankLists.resize(levelNum + 1);
     177              :     }
     178          162 :     CheckAndInsert(levelId, rankAddrSize, rankLists[levelNum]);
     179          162 : }
     180              : 
     181           35 : std::string RankTableInfo::Describe() const
     182              : {
     183           35 :     return StringFormat("RankTableInfo[version=%s, rankCount=%u, ranks size=%d]", version.c_str(), rankCount,
     184           35 :                         ranks.size());
     185              : }
     186              : 
     187           18 : void RankTableInfo::Dump() const
     188              : {
     189           54 :     HCCL_DEBUG("RankTableInfo Dump:");
     190           54 :     HCCL_DEBUG("%s", Describe().c_str());
     191           54 :     HCCL_DEBUG("ranks:");
     192           41 :     for (const auto& rank : ranks) {
     193           69 :         HCCL_DEBUG("%s", rank.Describe().c_str());
     194           62 :         for (const auto& levelInfo : rank.rankLevelInfos) {
     195          117 :             HCCL_DEBUG("    %s", levelInfo.Describe().c_str());
     196              :         }
     197              :     }
     198           18 : }
     199              : 
     200            6 : RankTableInfo::RankTableInfo(BinaryStream& binaryStream){
     201            6 :     binaryStream >> version >> rankCount;
     202            6 :     size_t ranksSize = 0;
     203            6 :     binaryStream >> ranksSize;
     204           18 :     HCCL_INFO("[%s] version[%s] rankCount[%u] ranks size[%u]", __func__, version.c_str(), rankCount, ranksSize);
     205           13 :     for(u32 i = 0; i < ranksSize; i++){
     206            7 :         NewRankInfo rankInfo(binaryStream);
     207            7 :         ranks.emplace_back(rankInfo);
     208            7 :     }
     209            6 :     binaryStream>>detour;
     210            6 : }
     211              : 
     212           13 : void RankTableInfo::GetBinStream(bool isContainLocId, BinaryStream& binaryStream) const{
     213           13 :     if(ranks.size() == 0) {
     214            0 :         std::string msg = StringFormat("ranks size is zero.");
     215            0 :         THROW<InvalidParamsException>(msg);
     216            0 :     }
     217           39 :     HCCL_INFO("[%s] version[%s] rankCount[%u] ranks size[%u]", __func__, version.c_str(), rankCount, ranks.size());
     218              : 
     219           13 :     binaryStream << version  << rankCount;
     220           13 :     binaryStream << ranks.size();
     221           42 :     for(auto& it: ranks){
     222           29 :         it.GetBinStream(isContainLocId, binaryStream);
     223              :     }
     224           13 :     binaryStream<<detour;
     225           13 : }
     226              : 
     227            1 : vector<char> RankTableInfo::GetUniqueId(bool isContainLocId) const
     228              : {
     229            1 :     if(ranks.size() == 0) {
     230            0 :         std::string msg = StringFormat("ranks size is zero.");
     231            0 :         THROW<InvalidParamsException>(msg);
     232            0 :     }
     233            1 :     std::vector<char> result(0);
     234              : 
     235            1 :     BinaryStream binaryStream;
     236            1 :     binaryStream << version << rankCount;
     237              : 
     238            1 :     u32 ranksSize = ranks.size();
     239            1 :     binaryStream << ranksSize;
     240            2 :     for(auto& it: ranks) {
     241            1 :         it.GetBinStream(isContainLocId, binaryStream);
     242              :     }
     243              : 
     244            1 :     binaryStream.Dump(result);
     245            1 :     return result; 
     246            1 : }
     247              : 
     248            1 : void RankTableInfo::UpdateRankTable(const RankTableInfo &localRankInfo)
     249              : {
     250              :     // version
     251            1 :     if (detour) {
     252            0 :         CHK_PRT_THROW(localRankInfo.detour != true,
     253              :             HCCL_ERROR("[%s] detour cfg is not same with other ranks.", __func__),
     254              :             InvalidParamsException, 
     255              :             "updateRankTableInfo error");
     256              :     }
     257            1 :     detour = localRankInfo.detour; 
     258            1 :     if (rankCount == 0) {
     259            1 :         version = localRankInfo.version;
     260              :     } else {
     261            0 :         CHK_PRT_THROW(version != localRankInfo.version, 
     262              :             HCCL_ERROR("[%s] version[%s] error, local version[%s] .", __func__, version.c_str(), localRankInfo.version.c_str()), 
     263              :             InvalidParamsException, "updateRankTableInfo error");
     264              :     }
     265              : 
     266              :     // ranks size
     267            1 :     CHK_PRT_THROW(localRankInfo.ranks.size() == 0, HCCL_ERROR("[%s] ranks size is zero.", __func__), 
     268              :             InvalidParamsException, "updateRankTableInfo error");
     269              : 
     270            1 :     ranks.insert(ranks.end(), localRankInfo.ranks.begin(), localRankInfo.ranks.end());
     271            1 :     rankCount++;
     272              : 
     273            3 :     HCCL_INFO("[%s] success, current rankTableInfo[%s]", __func__, Describe().c_str());
     274            1 : }
     275              : 
     276            5 : std::unordered_map<u32, std::unordered_map<IpAddress, u32>> RankTableInfo::GetRankDeviceListenPortMap() 
     277              : {
     278            5 :     std::unordered_map<u32, std::unordered_map<IpAddress, u32>> ranklListenPortMap;
     279           25 :     for (auto &rankinfo : ranks) {
     280           20 :         std::unordered_map<IpAddress, u32> listenPortMap;
     281           80 :         for (auto &rankLevelInfo : rankinfo.rankLevelInfos) {
     282          160 :             for (auto &rankAddr : rankLevelInfo.rankAddrs) {
     283          100 :                 listenPortMap.insert(std::make_pair(rankAddr.addr, rankAddr.socketPort_));
     284              :             }
     285              :         }
     286           20 :         listenPortMap.insert(std::make_pair(DEVICE_PORT_KEY_IPADDRESS, rankinfo.devicePort));
     287           20 :         ranklListenPortMap.insert(std::make_pair(rankinfo.rankId, listenPortMap));
     288           20 :     }
     289            5 :     return ranklListenPortMap;
     290            0 : }
     291              : 
     292              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1