LCOV - code coverage report
Current view: top level - coll_communicator_mgr/rank_graph/topo_info - edge_info.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.7 % 188 180
Test Date: 2026-08-25 19:18:03 Functions: 100.0 % 14 14

            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 "edge_info.h"
      12              : #include "json_parser.h"
      13              : #include "invalid_params_exception.h"
      14              : #include "exception_util.h"
      15              : 
      16              : namespace Hccl {
      17              : 
      18              : const unordered_map<string, LinkProtocol> EdgeInfo::strToLinkProtocol = (unordered_map<string, LinkProtocol>{
      19              :     {"UB_CTP", LinkProtocol::UB_CTP},
      20              :     {"UB_TP", LinkProtocol::UB_TP},
      21              :     {"ROCE", LinkProtocol::ROCE},
      22              :     {"HCCS", LinkProtocol::HCCS},
      23              :     {"PCIE", LinkProtocol::PCIE},
      24              :     {"TCP", LinkProtocol::TCP},
      25              :     {"UB_MEM", LinkProtocol::UB_MEM},
      26              :     {"UBOE", LinkProtocol::UBOE},
      27              :     {"UB_RTP", LinkProtocol::UB_RTP},
      28              :     {"UBG", LinkProtocol::UB_RTP}});
      29              : 
      30              : const unordered_map<std::string, TopoType> EdgeInfo::strToTopoType = (unordered_map<string, TopoType>{
      31              :     {"CLOS", TopoType::CLOS},
      32              :     {"1DMESH", TopoType::MESH_1D},
      33              :     {"2DMESH", TopoType::MESH_2D},
      34              :     {"A3_SERVER", TopoType::A3_SERVER},
      35              :     {"A2_AX_SERVER", TopoType::A2_AX_SERVER}});
      36              : 
      37              : const unordered_map<string, LinkType> EdgeInfo::strToLinkType
      38              :     = (unordered_map<string, LinkType>{{"PEER2PEER", LinkType::PEER2PEER}, {"PEER2NET", LinkType::PEER2NET}});
      39              : 
      40              : const unordered_map<string, AddrPosition> EdgeInfo::strToAddrPosition
      41              :     = (unordered_map<string, AddrPosition>{{"DEVICE", AddrPosition::DEVICE}, {"HOST", AddrPosition::HOST}});
      42              : 
      43          169 : void EdgeInfo::Deserialize(const nlohmann::json& edgeInfoJson)
      44              : {
      45              :     // net_layer 不再解析,物理边只保留连接属性。
      46          169 :     DeserializeProtocol(edgeInfoJson);
      47              : 
      48          167 :     if (edgeInfoJson.contains("topo_type")) {
      49           91 :         std::string topoTypeStr;
      50           91 :         std::string msgtopoType = "[EdgeInfo::Deserialize] error occurs when parser object of propName \"topo_type\"";
      51           91 :         TRY_CATCH_THROW(InvalidParamsException, msgtopoType, topoTypeStr = GetJsonProperty(edgeInfoJson, "topo_type"););
      52           93 :         topoType = GetTopoType(topoTypeStr);
      53           93 :     } else {
      54          220 :         HCCL_WARNING("[EdgeInfo::%s] topo_type not found, [default]topo_type=TopoType::CLOS", __func__);
      55           76 :         topoType = TopoType::CLOS; // topo_type字段不存在时,取默认值CLOS
      56              :     }
      57              : 
      58              :     std::string msgtopoInstIdType
      59          165 :         = "[EdgeInfo::Deserialize] error occurs when parser object of propName \"topo_instance_id\"";
      60          165 :     if (edgeInfoJson.contains("topo_instance_id")) {
      61          134 :         TRY_CATCH_THROW(InvalidParamsException, msgtopoInstIdType,
      62              :                         topoInstId = GetJsonPropertyUInt(edgeInfoJson, "topo_instance_id"););
      63              :     } else {
      64           88 :         HCCL_WARNING("[EdgeInfo::%s] topo_instance_id not found, [default]topo_instance_id=0", __func__);
      65           32 :         topoInstId = 0;
      66              :     }
      67              : 
      68              :     // 解析localA 和 localB
      69          164 :     DeserializeEndpoint(edgeInfoJson);
      70          165 : }
      71              : 
      72          169 : void EdgeInfo::DeserializeProtocol(const nlohmann::json& edgeInfoJson)
      73              : {
      74          169 :     nlohmann::json jsonProtocols;
      75              :     std::string msgProtocols
      76          169 :         = "[EdgeInfo::DeserializeProtocol] error occurs when parser object of propName \"protocols\"";
      77          169 :     TRY_CATCH_THROW(InvalidParamsException, msgProtocols,
      78              :                     GetJsonPropertyList(edgeInfoJson, "protocols", jsonProtocols););
      79          336 :     for (auto& protocolEle : jsonProtocols) {
      80          168 :         auto protocolStr = protocolEle.get<std::string>();
      81          169 :         LinkProtocol protocol = GetLinkProtocol(protocolStr);
      82          167 :         if (protocols.count(protocol) == 0) {
      83          167 :             protocols.emplace(protocol);
      84              :         } else {
      85            0 :             HCCL_WARNING("[EdgeInfo::%s] repeat member[%s] in \"protocols\"", __func__, protocolStr.c_str());
      86              :         }
      87          168 :     }
      88              : 
      89          168 :     if (protocols.empty()) {
      90            1 :         THROW<InvalidParamsException>("[EdgeInfo::%s] \"protocols\" is empty", __func__);
      91              :     }
      92          171 : }
      93              : 
      94          164 : void EdgeInfo::DeserializeEndpoint(const nlohmann::json& edgeInfoJson)
      95              : {
      96          164 :     std::string linkTypeStr;
      97              :     std::string msglinkType
      98          164 :         = "[EdgeInfo::DeserializeEndpoint] error occurs when parser object of propName \"link_type\"";
      99          164 :     TRY_CATCH_THROW(InvalidParamsException, msglinkType, linkTypeStr = GetJsonProperty(edgeInfoJson, "link_type"););
     100          165 :     linkType = GetLinkType(linkTypeStr);
     101              : 
     102          163 :     std::string msgLocalA = "[EdgeInfo::DeserializeEndpoint] error occurs when parser object of propName \"local_a\"";
     103          164 :     TRY_CATCH_THROW(InvalidParamsException, msgLocalA, localA = GetJsonPropertyUInt(edgeInfoJson, "local_a"););
     104              : 
     105          326 :     DeserializePort(edgeInfoJson, "local_a_ports", localAPorts);
     106          160 :     if (localAPorts.empty()) {
     107            0 :         THROW<InvalidParamsException>("[EdgeInfo::%s] local_a_ports can not be empty", __func__);
     108              :     }
     109              : 
     110          160 :     if (linkType == LinkType::PEER2PEER) {
     111              :         std::string msgLocalB
     112           34 :             = "[EdgeInfo::DeserializeEndpoint] error occurs when parser object of propName \"local_b\"";
     113           35 :         TRY_CATCH_THROW(InvalidParamsException, msgLocalB, localB = GetJsonPropertyUInt(edgeInfoJson, "local_b"););
     114              : 
     115           33 :         if (localA == localB) { // localA 和 localB 不能是同一个点
     116            1 :             THROW<InvalidParamsException>(
     117              :                 "[EdgeInfo::%s] local_a and local_b can not be the same Endpoint id[%u].", __func__, localA);
     118              :         }
     119              : 
     120           64 :         DeserializePort(edgeInfoJson, "local_b_ports", localBPorts);
     121           32 :         if (localBPorts.empty()) {
     122            0 :             THROW<InvalidParamsException>("[EdgeInfo::%s] local_b_ports can not be empty when PEER2PEER", __func__);
     123              :         }
     124           34 :     } else {
     125          126 :         if (edgeInfoJson.contains("local_b") || edgeInfoJson.contains("local_b_ports")) {
     126            1 :             HCCL_WARNING("[EdgeInfo::%s] local_b and local_b_ports are not need when PEER2NET", __func__);
     127              :         }
     128              :     }
     129              : 
     130          158 :     if (edgeInfoJson.contains("position")) {
     131          134 :         string positionStr;
     132              :         std::string msgPosition
     133          134 :             = "[EdgeInfo::DeserializeEndpoint] error occurs when parser object of propName \"position\"";
     134          134 :         TRY_CATCH_THROW(InvalidParamsException, msgPosition, positionStr = GetJsonProperty(edgeInfoJson, "position"););
     135          135 :         position = GetAddrPosition(positionStr);
     136          135 :     } else {
     137           72 :         HCCL_WARNING("[EdgeInfo::%s] position not found, [default]position=DEVICE", __func__);
     138           24 :         position = AddrPosition::DEVICE;
     139              :     }
     140          177 : }
     141              : 
     142          194 : void EdgeInfo::DeserializePort(const nlohmann::json& edgeInfoJson, std::string propName, std::set<std::string>& ports)
     143              : {
     144          194 :     nlohmann::json jsonPorts;
     145              :     std::string msgPort
     146          194 :         = StringFormat("[EdgeInfo::%s] error occurs when parser object of propName \"%s\"", __func__, propName.c_str());
     147          194 :     TRY_CATCH_THROW(InvalidParamsException, msgPort, GetJsonPropertyList(edgeInfoJson, propName.c_str(), jsonPorts));
     148          194 :     if (jsonPorts.empty() || jsonPorts.size() > MAX_PORTS_SIZE) {
     149            1 :         THROW<InvalidParamsException>(
     150              :             "[EdgeInfo::%s] ports[%s].size=[%zu] out of range[1, %u]", __func__, propName.c_str(), jsonPorts.size(),
     151              :             MAX_PORTS_SIZE);
     152              :     }
     153          597 :     for (auto& portEle : jsonPorts) {
     154          405 :         string port = portEle.get<string>();
     155          405 :         if (!port.empty() && port.size() <= PORT_MAX_LENGTH) {
     156          404 :             if (ports.count(port) == 0) {
     157          404 :                 ports.emplace(port);
     158              :             } else {
     159            0 :                 HCCL_WARNING("[EdgeInfo::%s] Repeat port:[%s]", __func__, port.c_str());
     160              :             }
     161              :         } else {
     162            1 :             THROW<InvalidParamsException>(
     163              :                 "[EdgeInfo::%s] Invalid port[%s], length[%zu] out of range[1, %u]", __func__, port.c_str(), port.size(),
     164              :                 PORT_MAX_LENGTH);
     165              :         }
     166          405 :     }
     167          196 : }
     168              : 
     169         4561 : bool EdgeInfo::operator==(const EdgeInfo& other) const
     170              : {
     171         8951 :     return linkType == other.linkType && protocols == other.protocols && topoType == other.topoType
     172         8951 :            && topoInstId == other.topoInstId && CompareEndpoints(other) && position == other.position;
     173              : }
     174              : 
     175              : // 比较EndpointA和B
     176         4157 : bool EdgeInfo::CompareEndpoints(const EdgeInfo& other) const
     177              : {
     178              :     // 无论什么情况,A=other.A && B=other.B时,可视为相同的连接关系
     179           27 :     if (localA == other.localA && localB == other.localB && localAPorts == other.localAPorts
     180         4184 :         && localBPorts == other.localBPorts) {
     181           16 :         return true;
     182              :     }
     183              : 
     184              :     // 当连接类型是PEER2PEER时,A=other.B && B=other.A时,可视为相同的连接关系
     185         8282 :     if (linkType == other.linkType && linkType == LinkType::PEER2PEER && localA == other.localB
     186         8282 :         && localAPorts == other.localBPorts && localB == other.localA && localBPorts == other.localAPorts) {
     187            1 :         return true;
     188              :     }
     189              : 
     190         4140 :     return false;
     191              : }
     192              : 
     193          170 : LinkProtocol EdgeInfo::GetLinkProtocol(string str) const
     194              : {
     195          170 :     if (strToLinkProtocol.count(str) == 0) {
     196            1 :         THROW<InvalidParamsException>(
     197              :             "[EdgeInfo::%s] string['%s'] is not type of LinkProtocol.", __func__, str.c_str());
     198              :     }
     199          169 :     return strToLinkProtocol.at(str);
     200              : }
     201              : 
     202           91 : TopoType EdgeInfo::GetTopoType(std::string topoTypeStr) const
     203              : {
     204           91 :     if (topoTypeStr.empty()) {
     205            0 :         return TopoType::CLOS; // 不填写时,取默认值
     206              :     }
     207           91 :     if (strToTopoType.count(topoTypeStr) == 0) {
     208            2 :         THROW<InvalidParamsException>(
     209              :             "[EdgeInfo::%s] string['%s'] is not type of TopoType.", __func__, topoTypeStr.c_str());
     210              :     }
     211           89 :     return strToTopoType.at(topoTypeStr);
     212              : }
     213              : 
     214          164 : LinkType EdgeInfo::GetLinkType(std::string linkTypeStr) const
     215              : {
     216          164 :     if (strToLinkType.count(linkTypeStr) == 0) {
     217            1 :         THROW<InvalidParamsException>(
     218              :             "[EdgeInfo::%s] string['%s'] is not type of LinkType.", __func__, linkTypeStr.c_str());
     219              :     }
     220          163 :     return strToLinkType.at(linkTypeStr);
     221              : }
     222              : 
     223          134 : AddrPosition EdgeInfo::GetAddrPosition(string str) const
     224              : {
     225          134 :     if (str.empty()) {
     226            0 :         HCCL_WARNING("[EdgeInfo::%s] position is null, [default]position=DEVICE", __func__);
     227            0 :         return AddrPosition::DEVICE; //  默认取值为DEVICE
     228              :     }
     229          134 :     if (strToAddrPosition.count(str) == 0) {
     230            1 :         THROW<InvalidParamsException>(StringFormat("string ['%s'] is not type of AddrPosition.", str.c_str()));
     231              :     }
     232          133 :     return strToAddrPosition.at(str);
     233              : }
     234              : 
     235           10 : std::string EdgeInfo::Describe() const
     236              : {
     237           10 :     stringstream protocolStr;
     238           10 :     protocolStr << "[";
     239           20 :     for (auto it = protocols.begin(); it != protocols.end(); ++it) {
     240           10 :         if (it != protocols.begin()) {
     241            0 :             protocolStr << ", ";
     242              :         }
     243           10 :         protocolStr << it->Describe();
     244              :     }
     245           10 :     protocolStr << "]";
     246              : 
     247           10 :     string localAPortsStr = DescribePorts(localAPorts);
     248           10 :     string localBPortsStr = DescribePorts(localBPorts);
     249              : 
     250           10 :     std::string description = "EdgeInfo{";
     251           10 :     description += StringFormat("topoType=%s", topoType.Describe().c_str());
     252           10 :     description += StringFormat(", topoInstanceId=%u", topoInstId);
     253           10 :     description += StringFormat(", protocols=%s", protocolStr.str().c_str());
     254           10 :     description += StringFormat(", linkType=%s", linkType.Describe().c_str());
     255           10 :     description += StringFormat(", localA=%u", localA);
     256           10 :     description += StringFormat(", localAPortsStr=%s", localAPortsStr.c_str());
     257           10 :     description += StringFormat(", localB=%u", localB);
     258           10 :     description += StringFormat(", localBPortsStr=%s", localBPortsStr.c_str());
     259           10 :     description += StringFormat(", position=%s", position.Describe().c_str());
     260           10 :     description += "}";
     261           10 :     return description;
     262           10 : }
     263              : 
     264           20 : std::string EdgeInfo::DescribePorts(std::set<std::string> ports) const
     265              : {
     266           20 :     stringstream portsStr;
     267           20 :     portsStr << "[";
     268           38 :     for (auto it = ports.begin(); it != ports.end(); ++it) {
     269           18 :         if (it != ports.begin()) {
     270            2 :             portsStr << ", ";
     271              :         }
     272           18 :         portsStr << *it;
     273              :     }
     274           20 :     portsStr << "]";
     275           40 :     return portsStr.str();
     276           20 : }
     277              : 
     278          149 : void EdgeInfo::GetBinStream(BinaryStream& binaryStream) const
     279              : {
     280              :     // 保留旧快照占位字段,不参与拓扑语义。
     281          149 :     binaryStream << LEGACY_BINARY_LAYER << static_cast<u32>(linkType) << static_cast<u32>(topoType) << topoInstId;
     282          149 :     binaryStream << protocols.size();
     283          298 :     for (LinkProtocol protocol : protocols) {
     284          149 :         binaryStream << static_cast<u32>(protocol);
     285              :     }
     286              : 
     287          149 :     binaryStream << localA << localB;
     288              : 
     289          149 :     binaryStream << localAPorts.size();
     290          532 :     for (string port : localAPorts) {
     291          383 :         binaryStream << port;
     292          383 :     }
     293              : 
     294          149 :     binaryStream << localBPorts.size();
     295          188 :     for (string port : localBPorts) {
     296           39 :         binaryStream << port;
     297           39 :     }
     298              : 
     299          149 :     binaryStream << static_cast<u32>(position);
     300          149 : }
     301              : 
     302           77 : EdgeInfo::EdgeInfo(BinaryStream& binaryStream)
     303              : {
     304              :     u32 ignoredBinaryLayer;
     305           77 :     binaryStream >> ignoredBinaryLayer;
     306              :     u32 linkTypeTmp;
     307           77 :     binaryStream >> linkTypeTmp;
     308           77 :     linkType = static_cast<LinkType::Value>(linkTypeTmp);
     309              :     u32 topoTypeTmp;
     310           77 :     binaryStream >> topoTypeTmp;
     311           77 :     topoType = static_cast<TopoType::Value>(topoTypeTmp);
     312           77 :     binaryStream >> topoInstId;
     313              :     size_t protocolSize;
     314           77 :     binaryStream >> protocolSize;
     315           77 :     protocols.clear();
     316          154 :     for (size_t i = 0; i < protocolSize; i++) {
     317              :         u32 protocolTmp;
     318           77 :         binaryStream >> protocolTmp;
     319           77 :         LinkProtocol protocol = static_cast<LinkProtocol::Value>(protocolTmp);
     320           77 :         protocols.emplace(protocol);
     321              :     }
     322              : 
     323           77 :     binaryStream >> localA >> localB;
     324              : 
     325              :     size_t localAPortsSize;
     326           77 :     binaryStream >> localAPortsSize;
     327           77 :     localAPorts.clear();
     328          347 :     for (size_t i = 0; i < localAPortsSize; i++) {
     329          270 :         string port;
     330          270 :         binaryStream >> port;
     331          270 :         localAPorts.emplace(port);
     332          270 :     }
     333              : 
     334              :     size_t localBPortsSize;
     335           77 :     binaryStream >> localBPortsSize;
     336           77 :     localBPorts.clear();
     337           85 :     for (size_t i = 0; i < localBPortsSize; i++) {
     338            8 :         string port;
     339            8 :         binaryStream >> port;
     340            8 :         localBPorts.emplace(port);
     341            8 :     }
     342              : 
     343              :     u32 positionTmp;
     344           77 :     binaryStream >> positionTmp;
     345           77 :     position = static_cast<AddrPosition::Value>(positionTmp);
     346           77 : }
     347              : 
     348              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1