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

Generated by: LCOV version 2.0-1