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 "topo_info.h"
12 : #include "json_parser.h"
13 : #include "invalid_params_exception.h"
14 : #include "exception_util.h"
15 :
16 : namespace Hccl {
17 :
18 : using namespace std;
19 :
20 19 : void TopoInfo::Deserialize(const nlohmann::json& topoInfoJson)
21 : {
22 38 : std::string msgVersion = "[TopoInfo::Deserialize] error occurs when parser object of propName \"version\"";
23 38 : std::string msgPc = "[TopoInfo::Deserialize] error occurs when parser object of propName \"peer_count\"";
24 19 : std::string msgEc = "[TopoInfo::Deserialize] error occurs when parser object of propName \"edge_count\"";
25 20 : TRY_CATCH_THROW(InvalidParamsException, msgVersion, version = GetJsonProperty(topoInfoJson, "version"););
26 18 : TRY_CATCH_THROW(InvalidParamsException, msgPc, peerCount = GetJsonPropertyUInt(topoInfoJson, "peer_count"););
27 18 : TRY_CATCH_THROW(InvalidParamsException, msgEc, edgeCount = GetJsonPropertyUInt(topoInfoJson, "edge_count"););
28 :
29 18 : if (version != "2.0") {
30 1 : HCCL_ERROR("[TopoInfo::%s] failed with version[%s] is not \"2.0\".", __func__, version.c_str());
31 2 : THROW<InvalidParamsException>(StringFormat(
32 : "[TopoInfo::%s] failed with version[%s] is not \"2.0\" in topo file.", __func__, version.c_str()));
33 : }
34 :
35 17 : if (peerCount == 0 || peerCount > MAX_PEER_COUNT) {
36 0 : THROW<InvalidParamsException>(
37 : "[TopoInfo::%s] the range for the prop peer_count is [1, %u] while peer_count is %u", __func__,
38 : MAX_PEER_COUNT, peerCount);
39 : }
40 :
41 17 : if (edgeCount == 0) {
42 4 : HCCL_WARNING("[TopoInfo::%s]: edge_count is zero", __func__);
43 : }
44 :
45 17 : if (peerCount == 0 || peerCount > MAX_PEER_COUNT) {
46 0 : THROW<InvalidParamsException>(
47 : "[TopoInfo::%s] the range for the prop peer_count is [1, 65] while peer_count is %u", __func__, peerCount);
48 : }
49 :
50 17 : DeserializePeers(topoInfoJson);
51 15 : DeserializeEdges(topoInfoJson);
52 37 : }
53 :
54 17 : void TopoInfo::DeserializePeers(const nlohmann::json& topoInfoJson)
55 : {
56 17 : nlohmann::json peerJsons;
57 17 : std::string msgPl = "[TopoInfo::DeserializePeers] error occurs when parser object of propName \"peer_list\"";
58 17 : TRY_CATCH_THROW(InvalidParamsException, msgPl, GetJsonPropertyList(topoInfoJson, "peer_list", peerJsons););
59 128 : for (auto& peerJson : peerJsons) {
60 112 : PeerInfo peer;
61 112 : peer.Deserialize(peerJson);
62 :
63 112 : if (idSet.count(peer.localId) > 0) {
64 1 : THROW<InvalidParamsException>(
65 3 : StringFormat("[TopoInfo::%s] in peers exist duplicate localId = %u.", __func__, peer.localId));
66 : }
67 :
68 111 : peers.emplace_back(peer);
69 111 : idSet.insert(peer.localId);
70 112 : }
71 :
72 16 : if (peerCount != peers.size()) {
73 2 : THROW<InvalidParamsException>(StringFormat(
74 : "[TopoInfo::%s] Value of peer_count[%u] is inconsistent with the size of the peer_list[%zu].", __func__,
75 : peerCount, peers.size()));
76 : }
77 19 : }
78 :
79 132 : void TopoInfo::VerifyEdges(EdgeInfo& edge)
80 : {
81 132 : if (idSet.count(edge.localA) == 0 || idSet.count(edge.localB) == 0) {
82 2 : THROW<InvalidParamsException>(StringFormat(
83 : "[TopoInfo::%s] endpoint localId [%u] or [%u] is not exist in peers[%zu].", __func__, edge.localA,
84 : edge.localB, idSet.size()));
85 : }
86 : // 检查edge.netLayer这一层级是否存在,不存在则初始化
87 131 : if (edges.find(edge.netLayer) == edges.end()) {
88 17 : edges[edge.netLayer] = vector<EdgeInfo>();
89 : }
90 : // 判断edge.netLayer该层级是否存在重复edge
91 131 : if (find(edges[edge.netLayer].begin(), edges[edge.netLayer].end(), edge) != edges[edge.netLayer].end()) {
92 2 : THROW<InvalidParamsException>(StringFormat(
93 : "[TopoInfo::%s] exist duplicate edges. Location information:{edge.netLayer=%u, edge.linkType=%s, "
94 : "edge.topoType=%s, edge.topoInstanceId=%u, localA=%u, localB=%u}",
95 5 : __func__, edge.netLayer, edge.linkType.Describe().c_str(), edge.topoType.Describe().c_str(),
96 : edge.topoInstId, edge.localA, edge.localB));
97 : }
98 :
99 130 : edges[edge.netLayer].emplace_back(edge);
100 130 : }
101 :
102 15 : void TopoInfo::DeserializeEdges(const nlohmann::json& topoInfoJson)
103 : {
104 15 : nlohmann::json edgeJsons;
105 15 : std::string msgPe = "[TopoInfo::DeserializeEdges] error occurs when parser object of propName \"edge_list\"";
106 15 : TRY_CATCH_THROW(InvalidParamsException, msgPe, GetJsonPropertyList(topoInfoJson, "edge_list", edgeJsons););
107 15 : if (edgeJsons.empty()) {
108 2 : if (edgeCount != 0) {
109 0 : THROW<InvalidParamsException>(StringFormat(
110 : "[TopoInfo::%s] Value of edge_count[%u] is inconsistent with the size of edge_list[0].", __func__,
111 : edgeCount));
112 : } else {
113 2 : HCCL_WARNING("[TopoInfo::%s] edge count is zero", __func__);
114 2 : return;
115 : }
116 : }
117 143 : for (auto& edgeJson : edgeJsons) {
118 134 : EdgeInfo edge;
119 134 : edge.Deserialize(edgeJson);
120 132 : VerifyEdges(edge);
121 134 : }
122 :
123 9 : size_t sumEdge = 0;
124 24 : for (const auto& entry : edges) {
125 15 : sumEdge += entry.second.size();
126 : }
127 9 : if (sumEdge != edgeCount) {
128 2 : THROW<InvalidParamsException>(StringFormat(
129 : "[TopoInfo::%s] Value of edge_count[%u] is inconsistent with the size of edge_list[%zu].", __func__,
130 : edgeCount, sumEdge));
131 : }
132 22 : }
133 :
134 13 : string TopoInfo::Describe() const
135 : {
136 13 : string description = "TopoInfo{";
137 13 : description += StringFormat("version=%s", version.c_str());
138 13 : description += StringFormat(", peer_count=%u", peerCount);
139 13 : description += StringFormat(", edge_count=%u", edgeCount);
140 13 : description += StringFormat(", Peers.size=%u", peers.size());
141 13 : description += StringFormat(", Edges.size=%u", edges.size());
142 13 : description += "}";
143 13 : return description;
144 0 : }
145 :
146 0 : void TopoInfo::Dump() const
147 : {
148 0 : HCCL_DEBUG("TopoInfo Dump:");
149 0 : HCCL_DEBUG("%s", Describe().c_str());
150 0 : HCCL_DEBUG("peers:");
151 0 : for (const auto& peer : peers) {
152 0 : HCCL_DEBUG("%s", peer.Describe().c_str());
153 : }
154 0 : HCCL_DEBUG("edges:");
155 0 : for (const auto& itor : edges) {
156 0 : HCCL_DEBUG("netLayer[%u]:", itor.first);
157 0 : for (const auto& edge : itor.second) {
158 0 : HCCL_DEBUG(" %s", edge.Describe().c_str());
159 : }
160 : }
161 0 : }
162 :
163 3 : TopoInfo::TopoInfo(BinaryStream& binaryStream)
164 : {
165 3 : binaryStream >> version >> peerCount >> edgeCount;
166 3 : size_t peersSize = 0;
167 3 : binaryStream >> peersSize;
168 72 : for (u32 i = 0; i < peersSize; i++) {
169 69 : PeerInfo peer(binaryStream);
170 69 : peers.emplace_back(peer);
171 69 : }
172 3 : size_t edgesSize = 0;
173 3 : binaryStream >> edgesSize;
174 :
175 5 : HCCL_INFO(
176 : "[TopoInfo] version is [%s], peerCount is [%u], edgeCount is [%u], peers size is [%u], edges size is [%u]",
177 : version.c_str(), peerCount, edgeCount, peers.size(), edgesSize);
178 9 : for (u32 i = 0; i < edgesSize; i++) {
179 6 : u32 edgeInfoIndex = 0;
180 6 : binaryStream >> edgeInfoIndex; // key
181 6 : size_t edgeSize = 0;
182 6 : binaryStream >> edgeSize;
183 10 : HCCL_INFO("[TopoInfo] edges key is [%u], value size is [%u]", edgeInfoIndex, edgeSize);
184 78 : for (u32 j = 0; j < edgeSize; j++) { // value
185 72 : EdgeInfo edge(binaryStream);
186 72 : edges[edgeInfoIndex].emplace_back(edge);
187 72 : }
188 : }
189 3 : }
190 :
191 8 : void TopoInfo::GetBinStream(BinaryStream& binaryStream) const
192 : {
193 8 : binaryStream << version << peerCount << edgeCount;
194 8 : binaryStream << peers.size();
195 97 : for (auto& it : peers) {
196 89 : it.GetBinStream(binaryStream);
197 : }
198 8 : binaryStream << edges.size();
199 20 : HCCL_INFO(
200 : "[TopoInfo::GetBinStream] version is [%s], peerCount is [%u], edgeCount is [%u], peers size is [%u], edges "
201 : "size is [%u]",
202 : version.c_str(), peerCount, edgeCount, peers.size(), edges.size());
203 29 : for (auto& it : edges) {
204 21 : binaryStream << it.first;
205 21 : binaryStream << it.second.size();
206 55 : HCCL_INFO("[TopoInfo::GetBinStream] edges key is [%u], value size is [%u]", it.first, it.second.size());
207 163 : for (auto& edge : it.second) {
208 142 : edge.GetBinStream(binaryStream);
209 : }
210 : }
211 8 : }
212 :
213 : } // namespace Hccl
|