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_PORT_H
12 : #define HCCLV2_PORT_H
13 :
14 : #include <memory>
15 : #include <string>
16 : #include <vector>
17 :
18 : #include "types.h"
19 : #include "ip_address.h"
20 : #include "hash_utils.h"
21 : #include "invalid_params_exception.h"
22 : #include "topo_common_types.h"
23 : #include "net_instance.h"
24 :
25 : namespace Hccl {
26 :
27 : using namespace std;
28 :
29 10026 : MAKE_ENUM(PortDeploymentType, P2P, DEV_NET, HOST_NET)
30 :
31 6193 : MAKE_ENUM(ConnectProtoType, HCCS, PCIE, TCP, RDMA, UB, UBOE, UBG)
32 :
33 3527 : MAKE_ENUM(LinkProtoType, HCCS_PCIE, TCP, RDMA, UB)
34 :
35 293 : inline PortDeploymentType AddrPos2PortDeploymentType(AddrPosition addrPosition, LinkProtocol linkProtocol)
36 : {
37 293 : PortDeploymentType portDeploymentType{};
38 293 : if (addrPosition == AddrPosition::DEVICE) {
39 104 : if (linkProtocol == LinkProtocol::PCIE) {
40 0 : portDeploymentType = PortDeploymentType::P2P;
41 : } else {
42 104 : portDeploymentType = PortDeploymentType::DEV_NET;
43 : }
44 189 : } else if (addrPosition == AddrPosition::HOST) {
45 189 : portDeploymentType = PortDeploymentType::HOST_NET;
46 : } else {
47 0 : THROW<NotSupportException>(StringFormat("[AddrPos2PortDeploymentType] addrPosition[%s].",
48 0 : addrPosition.Describe().c_str()));
49 : }
50 293 : return portDeploymentType;
51 : }
52 :
53 836 : inline LinkProtoType LinkProtocol2LinkProtoType(LinkProtocol linkProtocol)
54 : {
55 836 : LinkProtoType linkType{};
56 1037 : if (linkProtocol == LinkProtocol::UB_CTP || linkProtocol == LinkProtocol::UB_TP
57 201 : || linkProtocol == LinkProtocol::UB_MEM || linkProtocol == LinkProtocol::UBOE
58 1037 : || linkProtocol == LinkProtocol::UBG) {
59 635 : linkType = LinkProtoType::UB;
60 201 : } else if (linkProtocol == LinkProtocol::ROCE) {
61 201 : linkType = LinkProtoType::RDMA;
62 0 : } else if (linkProtocol == LinkProtocol::PCIE) {
63 0 : linkType = LinkProtoType::HCCS_PCIE;
64 : } else {
65 0 : THROW<NotSupportException>(StringFormat("[LinkProtocol2LinkProtoType] linkProtocol[%s] don't support.",
66 0 : linkProtocol.Describe().c_str()));
67 : }
68 836 : return linkType;
69 : }
70 :
71 47 : inline LinkProtoType ConnProto2LinkProto(ConnectProtoType connType)
72 : {
73 47 : LinkProtoType linkType{};
74 47 : if (connType == ConnectProtoType::HCCS || connType == ConnectProtoType::PCIE) {
75 0 : linkType = LinkProtoType::HCCS_PCIE;
76 47 : } else if (connType == ConnectProtoType::TCP) {
77 1 : linkType = LinkProtoType::TCP;
78 46 : } else if (connType == ConnectProtoType::RDMA) {
79 20 : linkType = LinkProtoType::RDMA;
80 27 : } else if (connType == ConnectProtoType::UB || connType == ConnectProtoType::UBOE
81 27 : || connType == ConnectProtoType::UBG) {
82 25 : linkType = LinkProtoType::UB;
83 : }
84 63 : HCCL_INFO("[ConnProto2LinkProto] linkType is[%s]", linkType.Describe().c_str());
85 47 : return linkType;
86 : }
87 :
88 : // 该函数仅用于内部构造函数,主流程不使用
89 577 : inline LinkProtocol ConnProto2LinkProtocol(ConnectProtoType connType)
90 : {
91 577 : LinkProtocol linkProto{};
92 577 : if (connType == ConnectProtoType::HCCS || connType == ConnectProtoType::PCIE) {
93 124 : linkProto = LinkProtocol::HCCS;
94 453 : } else if (connType == ConnectProtoType::TCP) {
95 2 : linkProto = LinkProtocol::TCP;
96 451 : } else if (connType == ConnectProtoType::RDMA) {
97 24 : linkProto = LinkProtocol::ROCE;
98 427 : } else if (connType == ConnectProtoType::UB) {
99 340 : linkProto = LinkProtocol::UB_CTP;
100 87 : } else if (connType == ConnectProtoType::UBOE) {
101 0 : linkProto = LinkProtocol::UBOE;
102 87 : } else if (connType == ConnectProtoType::UBG) {
103 0 : linkProto = LinkProtocol::UBG;
104 : }
105 1657 : HCCL_INFO("[ConnProto2LinkProtocol] linkProto is[%s]", linkProto.Describe().c_str());
106 577 : return linkProto;
107 : }
108 :
109 : class BasePortType {
110 : public:
111 : BasePortType(const BasePortType &) = default;
112 : BasePortType &operator=(const BasePortType &) = default;
113 :
114 624 : inline PortDeploymentType GetType() const
115 : {
116 624 : return type_;
117 : };
118 :
119 624 : inline ConnectProtoType GetProto() const
120 : {
121 624 : return proto_;
122 : };
123 :
124 128 : explicit BasePortType(PortDeploymentType type) : type_(type){};
125 :
126 : bool operator==(const BasePortType &rhs) const
127 : {
128 : return type_ == rhs.type_ && proto_ == rhs.proto_;
129 : }
130 :
131 : bool operator!=(const BasePortType &rhs) const
132 : {
133 : return !(rhs == *this);
134 : }
135 :
136 : bool operator<(const BasePortType &rhs) const
137 : {
138 : if (type_ < rhs.type_)
139 : return true;
140 : if (rhs.type_ < type_)
141 : return false;
142 : return proto_ < rhs.proto_;
143 : }
144 :
145 3053 : BasePortType(PortDeploymentType type, ConnectProtoType proto) : type_(type), proto_(proto){};
146 :
147 : string Describe() const
148 : {
149 : return StringFormat("PortType[type=%s, proto=%s]", type_.Describe().c_str(), proto_.Describe().c_str());
150 : }
151 :
152 : protected:
153 : PortDeploymentType type_;
154 : ConnectProtoType proto_;
155 : };
156 :
157 : class P2PPortType : public BasePortType {
158 : public:
159 : P2PPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::P2P)
160 : {
161 : if (proto != ConnectProtoType::HCCS && proto != ConnectProtoType::PCIE) {
162 : THROW<InvalidParamsException>(StringFormat("P2PPortType::P2PPortType proto invalid"));
163 : }
164 : proto_ = proto;
165 : };
166 : };
167 :
168 : class DevNetPortType : public BasePortType {
169 : public:
170 39 : DevNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::DEV_NET)
171 : {
172 39 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
173 0 : THROW<InvalidParamsException>(StringFormat("DevNetPortType::DevNetPortType proto invalid"));
174 : }
175 39 : proto_ = proto;
176 39 : };
177 : };
178 :
179 : class HostNetPortType : public BasePortType {
180 : public:
181 : HostNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::HOST_NET)
182 : {
183 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
184 : THROW<InvalidParamsException>(StringFormat("HostNetPortType::HostNetPortType proto invalid"));
185 : }
186 : proto_ = proto;
187 : };
188 : };
189 :
190 : class PortData {
191 : public:
192 47 : PortData(RankId rankId, BasePortType type, u32 id, const IpAddress &addr)
193 47 : : rankId(rankId), type(type.GetType()), protoType(ConnProto2LinkProto(type.GetProto())), id(id), addr(addr)
194 : {
195 47 : }
196 :
197 590 : PortData(RankId rankId, PortDeploymentType type, LinkProtoType protoType, u32 id, const IpAddress &addr)
198 590 : : rankId(rankId), type(type), protoType(protoType), id(id), addr(addr)
199 : {
200 590 : }
201 :
202 245 : PortData(RankId rankId, const NetInstance::ConnInterface &connIface)
203 245 : : rankId(rankId), type(AddrPos2PortDeploymentType(connIface.GetPos(), *connIface.GetLinkProtocols().begin())),
204 245 : protoType(LinkProtocol2LinkProtoType(*connIface.GetLinkProtocols().begin())), id(0), addr(connIface.GetAddr())
205 : {
206 245 : }
207 :
208 271 : string Describe() const
209 : {
210 542 : return StringFormat("PortData[rankId=%d, type=%s, id=%d, addr=%s]", rankId, type.Describe().c_str(), id,
211 813 : addr.Describe().c_str());
212 : }
213 :
214 35 : RankId GetRankId() const
215 : {
216 35 : return rankId;
217 : }
218 :
219 1210 : const PortDeploymentType &GetType() const
220 : {
221 1210 : return type;
222 : }
223 :
224 1277 : const LinkProtoType &GetProto() const
225 : {
226 1277 : return protoType;
227 : }
228 :
229 8 : u32 GetId() const
230 : {
231 8 : return id;
232 : }
233 :
234 1398 : const IpAddress &GetAddr() const
235 : {
236 1398 : return addr;
237 : }
238 :
239 0 : bool operator==(const PortData &rhs) const
240 : {
241 0 : return type == rhs.type && id == rhs.id && addr == rhs.addr; // TODO: rankId后面应该要删,rankId == rhs.rankId &&
242 : }
243 :
244 0 : bool operator!=(const PortData &rhs) const
245 : {
246 0 : return !(rhs == *this);
247 : }
248 :
249 0 : bool operator<(const PortData &rhs) const
250 : {
251 0 : if (rankId < rhs.rankId) {
252 0 : return true;
253 : }
254 0 : if (rhs.rankId < rankId) {
255 0 : return false;
256 : }
257 0 : if (type < rhs.type) {
258 0 : return true;
259 : }
260 0 : if (rhs.type < type)
261 0 : return false;
262 0 : if (addr < rhs.addr) {
263 0 : return true;
264 : }
265 0 : if (rhs.addr < addr) {
266 0 : return false;
267 : }
268 0 : return id < rhs.id;
269 : }
270 :
271 : bool operator>(const PortData &rhs) const
272 : {
273 : return rhs < *this;
274 : }
275 :
276 : bool operator<=(const PortData &rhs) const
277 : {
278 : return !(rhs < *this);
279 : }
280 :
281 : bool operator>=(const PortData &rhs) const
282 : {
283 : return !(*this < rhs);
284 : }
285 :
286 : private:
287 : RankId rankId;
288 : PortDeploymentType type;
289 : LinkProtoType protoType;
290 : u32 id;
291 : IpAddress addr;
292 : };
293 : } // namespace Hccl
294 :
295 : namespace std {
296 :
297 : template <> class hash<Hccl::PortData> {
298 : public:
299 494 : size_t operator()(const Hccl::PortData &portData) const
300 : {
301 494 : auto typeHash = hash<uint8_t>{}(portData.GetType());
302 494 : auto protoHash = hash<uint8_t>{}(portData.GetProto());
303 494 : auto addrHash = hash<Hccl::IpAddress>{}(portData.GetAddr());
304 :
305 494 : return Hccl::HashCombine({addrHash, typeHash, protoHash});
306 : }
307 : };
308 :
309 : template <> class equal_to<Hccl::PortData> {
310 : public:
311 217 : bool operator()(const Hccl::PortData &p1, const Hccl::PortData &p2) const
312 : {
313 434 : return p1.GetAddr() == p2.GetAddr() && p1.GetType() == p2.GetType()
314 434 : && p1.GetProto() == p2.GetProto();
315 : }
316 : };
317 : } // namespace std
318 :
319 : #endif // HCCLV2_PORT_H
|