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 : #ifndef HCCLV2_VIRTUAL_TOPO_H
12 : #define HCCLV2_VIRTUAL_TOPO_H
13 :
14 : #include <cassert>
15 : #include <map>
16 : #include <set>
17 : #include <cstdint>
18 : #include "port.h"
19 : #include "iterator.h"
20 : #include "dev_type.h"
21 : #include "log.h"
22 : #include "net_instance.h"
23 : #include "rank_gph.h"
24 :
25 : namespace Hccl {
26 :
27 : using namespace std;
28 :
29 : MAKE_ENUM(PeerType, CPU, NPU)
30 :
31 : static constexpr u32 MAX_LINK_PATH_NUM = 2;
32 :
33 : class LinkData {
34 : public:
35 : // 待修改 构造函数不对外开发,LinkData只能由Link生成
36 586 : LinkData(BasePortType portType, RankId localRankId, RankId remoteRankId, u32 localPortId, u32 remotePortId)
37 586 : : type(portType.GetType()),
38 586 : linkProtocol_(ConnProto2LinkProtocol(portType.GetProto())),
39 586 : localRankId_(localRankId),
40 586 : remoteRankId_(remoteRankId),
41 586 : localPortId_(localPortId),
42 586 : remotePortId_(remotePortId) {};
43 234 : LinkData(
44 : PortDeploymentType portDeploymentType, LinkProtocol linkProtocol, RankId localRankId, RankId remoteRankId,
45 : IpAddress localAddr, IpAddress remoteAddr, u32 devicePhyId = 0, u32 remoteDevicePhyId = 0, u32 reuseIdx = 0)
46 234 : : type(portDeploymentType),
47 234 : linkProtocol_(linkProtocol),
48 234 : localRankId_(localRankId),
49 234 : remoteRankId_(remoteRankId),
50 234 : localAddr_(localAddr),
51 234 : remoteAddr_(remoteAddr),
52 234 : localDeviceId_(devicePhyId),
53 234 : remoteDeviceId_(remoteDevicePhyId),
54 234 : reuseIdx_(reuseIdx) {};
55 :
56 44 : explicit LinkData(const NetInstance::Path& path)
57 44 : {
58 44 : if (path.links.size() == 1) {
59 44 : auto link = path.links[0];
60 44 : auto srcPeer = link.GetSourceNode();
61 44 : auto targetPeer = link.GetTargetNode();
62 44 : shared_ptr<NetInstance::ConnInterface> srcConnIface = link.GetSourceIface();
63 44 : auto targetConnIface = link.GetTargetIface();
64 44 : linkProtocol_ = *link.GetLinkProtocols().begin();
65 44 : type = AddrPos2PortDeploymentType(srcConnIface->GetPos(), linkProtocol_);
66 44 : localRankId_ = std::dynamic_pointer_cast<NetInstance::Peer>(srcPeer)->GetRankId();
67 44 : remoteRankId_ = std::dynamic_pointer_cast<NetInstance::Peer>(targetPeer)->GetRankId();
68 44 : localDeviceId_ = std::dynamic_pointer_cast<NetInstance::Peer>(srcPeer)->GetDeviceId();
69 44 : remoteDeviceId_ = std::dynamic_pointer_cast<NetInstance::Peer>(targetPeer)->GetDeviceId();
70 44 : localAddr_ = srcConnIface->GetAddr();
71 44 : remoteAddr_ = targetConnIface->GetAddr();
72 44 : localDieId_ = srcConnIface->GetLocalDieId();
73 44 : hop = path.links[0].GetHop();
74 44 : fullmesh = true; // 单链路场景,标识为fullmesh
75 44 : } else if (path.links.size() == MAX_LINK_PATH_NUM) {
76 0 : auto link0 = path.links[0];
77 0 : auto link1 = path.links[1];
78 0 : auto srcPeer = link0.GetSourceNode();
79 0 : auto targetPeer = link1.GetTargetNode();
80 0 : auto srcConnIface = link0.GetSourceIface();
81 0 : auto targetConnIface = link1.GetTargetIface();
82 0 : linkProtocol_ = *link0.GetLinkProtocols().begin();
83 0 : type = AddrPos2PortDeploymentType(srcConnIface->GetPos(), linkProtocol_);
84 0 : localRankId_ = std::dynamic_pointer_cast<NetInstance::Peer>(srcPeer)->GetRankId();
85 0 : remoteRankId_ = std::dynamic_pointer_cast<NetInstance::Peer>(targetPeer)->GetRankId();
86 0 : localDeviceId_ = std::dynamic_pointer_cast<NetInstance::Peer>(srcPeer)->GetDeviceId();
87 0 : remoteDeviceId_ = std::dynamic_pointer_cast<NetInstance::Peer>(targetPeer)->GetDeviceId();
88 0 : localAddr_ = srcConnIface->GetAddr();
89 0 : remoteAddr_ = targetConnIface->GetAddr();
90 0 : localDieId_ = srcConnIface->GetLocalDieId();
91 0 : hop = path.links[0].GetHop();
92 0 : portGroupSize = static_cast<u8>(srcConnIface->GetPorts().size());
93 0 : auto tgtPortGroupSize = static_cast<u8>(targetConnIface->GetPorts().size());
94 0 : if (portGroupSize != tgtPortGroupSize) {
95 0 : HCCL_WARNING(
96 : "[LinkData][Constructor]srcConnIface.portGroupSize[%u] "
97 : "is not euqal to targetConnIface.portGroupSize[%u]",
98 : static_cast<u32>(portGroupSize), static_cast<u32>(tgtPortGroupSize));
99 : }
100 0 : fullmesh = false; // 多链路场景,非fullmesh
101 0 : } else {
102 0 : HCCL_ERROR("[LinkData][Constructor]path.links.size()[%u] is invalid", path.links.size());
103 0 : fullmesh = false; // 无效场景,默认为false
104 : }
105 44 : UpdateIpAddrWithPCIE();
106 44 : direction = path.direction;
107 :
108 44 : localPortId_ = 0;
109 44 : remotePortId_ = 0;
110 44 : }
111 :
112 : explicit LinkData(vector<char>& data);
113 :
114 : std::vector<char> GetUniqueId() const;
115 :
116 453 : bool operator==(const LinkData& rhs) const
117 : {
118 906 : return type == rhs.type && linkProtocol_ == rhs.linkProtocol_ && localRankId_ == rhs.localRankId_
119 453 : && remoteRankId_ == rhs.remoteRankId_ && localAddr_ == rhs.localAddr_ && remoteAddr_ == rhs.remoteAddr_
120 453 : && hop == rhs.hop && direction == rhs.direction && portGroupSize == rhs.portGroupSize
121 906 : && fullmesh == rhs.fullmesh && reuseIdx_ == rhs.reuseIdx_;
122 : }
123 :
124 : bool operator!=(const LinkData& rhs) const { return !(rhs == *this); }
125 :
126 32 : bool operator<(const LinkData& rhs) const
127 : {
128 32 : if (type < rhs.type) {
129 0 : return true;
130 : }
131 32 : if (rhs.type < type) {
132 0 : return false;
133 : }
134 32 : if (linkProtocol_ < rhs.linkProtocol_) {
135 0 : return true;
136 : }
137 32 : if (rhs.linkProtocol_ < linkProtocol_) {
138 0 : return false;
139 : }
140 32 : if (localRankId_ < rhs.localRankId_) {
141 0 : return true;
142 : }
143 32 : if (rhs.localRankId_ < localRankId_) {
144 0 : return false;
145 : }
146 32 : if (remoteRankId_ < rhs.remoteRankId_) {
147 16 : return true;
148 : }
149 16 : if (rhs.remoteRankId_ < remoteRankId_) {
150 6 : return false;
151 : }
152 10 : if (localAddr_ < rhs.localAddr_) {
153 0 : return true;
154 : }
155 10 : if (rhs.localAddr_ < localAddr_) {
156 0 : return false;
157 : }
158 10 : if (remoteAddr_ < rhs.remoteAddr_) {
159 0 : return true;
160 : }
161 10 : if (rhs.remoteAddr_ < remoteAddr_) {
162 0 : return false;
163 : }
164 10 : if (hop < rhs.hop) {
165 0 : return true;
166 : }
167 10 : if (rhs.hop < hop) {
168 0 : return false;
169 : }
170 10 : if (direction < rhs.direction) {
171 0 : return true;
172 : }
173 10 : if (rhs.direction < direction) {
174 0 : return false;
175 : }
176 10 : if (rhs.portGroupSize < portGroupSize) {
177 0 : return false;
178 : }
179 10 : if (fullmesh == false && rhs.fullmesh == true) {
180 0 : return true;
181 : }
182 10 : if (rhs.fullmesh == false && fullmesh == true) {
183 0 : return false;
184 : }
185 10 : if (localPortId_ < rhs.localPortId_) {
186 0 : return true;
187 : }
188 10 : if (rhs.localPortId_ < localPortId_) {
189 0 : return false;
190 : }
191 10 : if (reuseIdx_ < rhs.reuseIdx_) {
192 0 : return true;
193 : }
194 10 : if (rhs.reuseIdx_ < reuseIdx_) {
195 0 : return false;
196 : }
197 10 : return remotePortId_ < rhs.remotePortId_;
198 : }
199 :
200 1596 : string Describe() const
201 : {
202 : return StringFormat(
203 : "LinkData:type=%s, protocol=%s, localRankId=%d, localAddr=%s, remoteRankId=%d, "
204 : "remoteAddr=%s, reuseIdx=%u",
205 4788 : type.Describe().c_str(), linkProtocol_.Describe().c_str(), localRankId_, localAddr_.Describe().c_str(),
206 6384 : remoteRankId_, remoteAddr_.Describe().c_str(), reuseIdx_);
207 : };
208 :
209 340 : PortData GetLocalPort() const
210 : {
211 340 : return {localRankId_, type, LinkProtocol2LinkProtoType(linkProtocol_), localPortId_, localAddr_};
212 : };
213 :
214 243 : PortData GetRemotePort() const
215 : {
216 243 : return {remoteRankId_, type, LinkProtocol2LinkProtoType(linkProtocol_), remotePortId_, remoteAddr_};
217 : };
218 :
219 : bool IsSymetric(const LinkData& rhs) const
220 : {
221 : return (type == rhs.type) && (linkProtocol_ == rhs.linkProtocol_) && (localRankId_ == rhs.remoteRankId_)
222 : && (remoteRankId_ == rhs.localRankId_) && (localAddr_ == rhs.remoteAddr_)
223 : && (remoteAddr_ == rhs.localAddr_) && (hop == rhs.hop) && (direction == rhs.direction);
224 : };
225 :
226 1383 : const PortDeploymentType& GetType() const { return type; };
227 :
228 1390 : const LinkProtocol& GetLinkProtocol() const { return linkProtocol_; }
229 :
230 2 : u32 GetHop() const { return hop; }
231 :
232 0 : LinkDirection GetDirection() const { return direction; }
233 :
234 2396 : RankId GetLocalRankId() const { return localRankId_; };
235 :
236 2783 : RankId GetRemoteRankId() const { return remoteRankId_; };
237 :
238 0 : DeviceId GetRemoteDeviceId() const { return remoteDeviceId_; };
239 :
240 1175 : u32 GetLocalPortId() const { return localPortId_; };
241 :
242 1175 : u32 GetRemotePortId() const { return remotePortId_; };
243 :
244 2201 : const IpAddress& GetLocalAddr() const { return localAddr_; };
245 :
246 1977 : const IpAddress& GetRemoteAddr() const { return remoteAddr_; };
247 :
248 16 : u32 GetLocalDieId() const { return localDieId_; };
249 :
250 1175 : u8 GetPortGroupSize() const { return portGroupSize; };
251 :
252 : bool Readable() const { return readable; };
253 :
254 : bool Writable() const { return writable; };
255 : void UpdateIpAddrWithPCIE();
256 :
257 1394 : bool GetFullmesh() const { return fullmesh; };
258 :
259 57 : std::string GetReuseIdx() const { return std::to_string(reuseIdx_); };
260 :
261 : private:
262 : PortDeploymentType type;
263 : LinkProtocol linkProtocol_;
264 : RankId localRankId_{0};
265 : RankId remoteRankId_{0};
266 : u32 localPortId_{0};
267 : u32 remotePortId_{0};
268 : IpAddress localAddr_;
269 : IpAddress remoteAddr_;
270 : bool readable{true};
271 : bool writable{true};
272 : u32 hop{0};
273 : LinkDirection direction;
274 : u32 localDieId_{};
275 : u8 portGroupSize{1};
276 : DeviceId localDeviceId_{UINT32_MAX};
277 : DeviceId remoteDeviceId_{UINT32_MAX};
278 : bool fullmesh{false}; // 标识是否为全互联单链路场景
279 : u32 reuseIdx_{0}; // socket复用idx,加在socket建链tag后面
280 : };
281 : } // namespace Hccl
282 :
283 : namespace std {
284 :
285 : template <>
286 : class hash<Hccl::LinkData> {
287 : public:
288 1175 : size_t operator()(const Hccl::LinkData& linkData) const
289 : {
290 1175 : auto typeHash = hash<uint8_t>{}(linkData.GetType());
291 1175 : auto linkProtoHash = hash<uint8_t>{}(linkData.GetLinkProtocol());
292 1175 : auto localRankIdHash = hash<Hccl::RankId>{}(linkData.GetLocalRankId());
293 1175 : auto remoteRankIdHash = hash<Hccl::RankId>{}(linkData.GetRemoteRankId());
294 1175 : auto localPortIdHash = hash<u32>{}(linkData.GetLocalPortId());
295 1175 : auto remotePortIdHash = hash<u32>{}(linkData.GetRemotePortId());
296 1175 : auto localAddrHash = hash<Hccl::IpAddress>{}(linkData.GetLocalAddr());
297 1175 : auto remoteAddrHash = hash<Hccl::IpAddress>{}(linkData.GetRemoteAddr());
298 1175 : auto portGrpSizeHash = hash<uint8_t>{}(linkData.GetPortGroupSize());
299 1175 : auto fullmeshHash = hash<bool>{}(linkData.GetFullmesh());
300 :
301 2350 : return Hccl::HashCombine(
302 : {typeHash, linkProtoHash, localRankIdHash, remoteRankIdHash, localPortIdHash, remotePortIdHash,
303 2350 : localAddrHash, remoteAddrHash, portGrpSizeHash, fullmeshHash});
304 : }
305 : };
306 : } // namespace std
307 :
308 : #endif // HCCLV2_VIRTUAL_TOPO_H
|