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

Generated by: LCOV version 2.0-1