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