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 10632 : MAKE_ENUM(PortDeploymentType, P2P, DEV_NET, HOST_NET)
30 :
31 6673 : MAKE_ENUM(ConnectProtoType, HCCS, PCIE, TCP, RDMA, UB, UBOE, UB_RTP)
32 :
33 3577 : MAKE_ENUM(LinkProtoType, HCCS_PCIE, TCP, RDMA, UB)
34 :
35 284 : inline PortDeploymentType AddrPos2PortDeploymentType(AddrPosition addrPosition, LinkProtocol linkProtocol)
36 : {
37 284 : PortDeploymentType portDeploymentType{};
38 284 : if (addrPosition == AddrPosition::DEVICE) {
39 106 : if (linkProtocol == LinkProtocol::PCIE) {
40 0 : portDeploymentType = PortDeploymentType::P2P;
41 : } else {
42 106 : portDeploymentType = PortDeploymentType::DEV_NET;
43 : }
44 178 : } else if (addrPosition == AddrPosition::HOST) {
45 178 : portDeploymentType = PortDeploymentType::HOST_NET;
46 : } else {
47 0 : THROW<NotSupportException>(
48 0 : StringFormat("[AddrPos2PortDeploymentType] addrPosition[%s].", addrPosition.Describe().c_str()));
49 : }
50 284 : return portDeploymentType;
51 : }
52 :
53 825 : inline LinkProtoType LinkProtocol2LinkProtoType(LinkProtocol linkProtocol)
54 : {
55 825 : LinkProtoType linkType{};
56 1026 : if (linkProtocol == LinkProtocol::UB_CTP || linkProtocol == LinkProtocol::UB_TP
57 201 : || linkProtocol == LinkProtocol::UB_MEM || linkProtocol == LinkProtocol::UBOE
58 1026 : || linkProtocol == LinkProtocol::UB_RTP) {
59 624 : 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(
66 0 : "[LinkProtocol2LinkProtoType] linkProtocol[%s] don't support.", linkProtocol.Describe().c_str()));
67 : }
68 825 : 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 26 : } else if (
81 27 : connType == ConnectProtoType::UB || connType == ConnectProtoType::UBOE
82 27 : || connType == ConnectProtoType::UB_RTP) {
83 25 : linkType = LinkProtoType::UB;
84 : }
85 63 : HCCL_INFO("[ConnProto2LinkProto] linkType is[%s]", linkType.Describe().c_str());
86 47 : return linkType;
87 : }
88 :
89 : // 该函数仅用于内部构造函数,主流程不使用
90 586 : inline LinkProtocol ConnProto2LinkProtocol(ConnectProtoType connType)
91 : {
92 586 : LinkProtocol linkProto{};
93 586 : if (connType == ConnectProtoType::HCCS || connType == ConnectProtoType::PCIE) {
94 124 : linkProto = LinkProtocol::HCCS;
95 462 : } else if (connType == ConnectProtoType::TCP) {
96 2 : linkProto = LinkProtocol::TCP;
97 460 : } else if (connType == ConnectProtoType::RDMA) {
98 24 : linkProto = LinkProtocol::ROCE;
99 436 : } else if (connType == ConnectProtoType::UB) {
100 344 : linkProto = LinkProtocol::UB_CTP;
101 92 : } else if (connType == ConnectProtoType::UBOE) {
102 0 : linkProto = LinkProtocol::UBOE;
103 92 : } else if (connType == ConnectProtoType::UB_RTP) {
104 0 : linkProto = LinkProtocol::UB_RTP;
105 : }
106 1684 : HCCL_INFO("[ConnProto2LinkProtocol] linkProto is[%s]", linkProto.Describe().c_str());
107 586 : return linkProto;
108 : }
109 :
110 : class BasePortType {
111 : public:
112 : BasePortType(const BasePortType&) = default;
113 : BasePortType& operator=(const BasePortType&) = default;
114 :
115 633 : inline PortDeploymentType GetType() const { return type_; };
116 :
117 633 : inline ConnectProtoType GetProto() const { return proto_; };
118 :
119 133 : explicit BasePortType(PortDeploymentType type) : type_(type) {};
120 :
121 : bool operator==(const BasePortType& rhs) const { return type_ == rhs.type_ && proto_ == rhs.proto_; }
122 :
123 : bool operator!=(const BasePortType& rhs) const { return !(rhs == *this); }
124 :
125 : bool operator<(const BasePortType& rhs) const
126 : {
127 : if (type_ < rhs.type_)
128 : return true;
129 : if (rhs.type_ < type_)
130 : return false;
131 : return proto_ < rhs.proto_;
132 : }
133 :
134 3473 : BasePortType(PortDeploymentType type, ConnectProtoType proto) : type_(type), proto_(proto) {};
135 :
136 : string Describe() const
137 : {
138 : return StringFormat("PortType[type=%s, proto=%s]", type_.Describe().c_str(), proto_.Describe().c_str());
139 : }
140 :
141 : protected:
142 : PortDeploymentType type_;
143 : ConnectProtoType proto_;
144 : };
145 :
146 : class P2PPortType : public BasePortType {
147 : public:
148 : P2PPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::P2P)
149 : {
150 : if (proto != ConnectProtoType::HCCS && proto != ConnectProtoType::PCIE) {
151 : THROW<InvalidParamsException>(StringFormat("P2PPortType::P2PPortType proto invalid"));
152 : }
153 : proto_ = proto;
154 : };
155 : };
156 :
157 : class DevNetPortType : public BasePortType {
158 : public:
159 39 : DevNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::DEV_NET)
160 : {
161 39 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
162 0 : THROW<InvalidParamsException>(StringFormat("DevNetPortType::DevNetPortType proto invalid"));
163 : }
164 39 : proto_ = proto;
165 39 : };
166 : };
167 :
168 : class HostNetPortType : public BasePortType {
169 : public:
170 : HostNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::HOST_NET)
171 : {
172 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
173 : THROW<InvalidParamsException>(StringFormat("HostNetPortType::HostNetPortType proto invalid"));
174 : }
175 : proto_ = proto;
176 : };
177 : };
178 :
179 : class PortData {
180 : public:
181 47 : PortData(RankId rankId, BasePortType type, u32 id, const IpAddress& addr)
182 47 : : rankId(rankId),
183 47 : type(type.GetType()),
184 47 : protoType(ConnProto2LinkProto(type.GetProto())),
185 47 : id(id),
186 47 : addr(addr)
187 47 : {}
188 :
189 590 : PortData(RankId rankId, PortDeploymentType type, LinkProtoType protoType, u32 id, const IpAddress& addr)
190 590 : : rankId(rankId),
191 590 : type(type),
192 590 : protoType(protoType),
193 590 : id(id),
194 590 : addr(addr)
195 590 : {}
196 :
197 234 : PortData(RankId rankId, const NetInstance::ConnInterface& connIface)
198 234 : : rankId(rankId),
199 234 : type(AddrPos2PortDeploymentType(connIface.GetPos(), *connIface.GetLinkProtocols().begin())),
200 234 : protoType(LinkProtocol2LinkProtoType(*connIface.GetLinkProtocols().begin())),
201 234 : id(0),
202 234 : addr(connIface.GetAddr())
203 234 : {}
204 :
205 260 : string Describe() const
206 : {
207 : return StringFormat(
208 520 : "PortData[rankId=%d, type=%s, id=%d, addr=%s]", rankId, type.Describe().c_str(), id,
209 780 : addr.Describe().c_str());
210 : }
211 :
212 35 : RankId GetRankId() const { return rankId; }
213 :
214 1199 : const PortDeploymentType& GetType() const { return type; }
215 :
216 1266 : const LinkProtoType& GetProto() const { return protoType; }
217 :
218 8 : u32 GetId() const { return id; }
219 :
220 1394 : const IpAddress& GetAddr() const { return addr; }
221 :
222 0 : bool operator==(const PortData& rhs) const
223 : {
224 0 : return type == rhs.type && id == rhs.id
225 0 : && addr == rhs.addr; // TODO: rankId后面应该要删,rankId == rhs.rankId &&
226 : }
227 :
228 0 : bool operator!=(const PortData& rhs) const { return !(rhs == *this); }
229 :
230 0 : bool operator<(const PortData& rhs) const
231 : {
232 0 : if (rankId < rhs.rankId) {
233 0 : return true;
234 : }
235 0 : if (rhs.rankId < rankId) {
236 0 : return false;
237 : }
238 0 : if (type < rhs.type) {
239 0 : return true;
240 : }
241 0 : if (rhs.type < type)
242 0 : return false;
243 0 : if (addr < rhs.addr) {
244 0 : return true;
245 : }
246 0 : if (rhs.addr < addr) {
247 0 : return false;
248 : }
249 0 : return id < rhs.id;
250 : }
251 :
252 : bool operator>(const PortData& rhs) const { return rhs < *this; }
253 :
254 : bool operator<=(const PortData& rhs) const { return !(rhs < *this); }
255 :
256 : bool operator>=(const PortData& rhs) const { return !(*this < rhs); }
257 :
258 : private:
259 : RankId rankId;
260 : PortDeploymentType type;
261 : LinkProtoType protoType;
262 : u32 id;
263 : IpAddress addr;
264 : };
265 : } // namespace Hccl
266 :
267 : namespace std {
268 :
269 : template <>
270 : class hash<Hccl::PortData> {
271 : public:
272 494 : size_t operator()(const Hccl::PortData& portData) const
273 : {
274 494 : auto typeHash = hash<uint8_t>{}(portData.GetType());
275 494 : auto protoHash = hash<uint8_t>{}(portData.GetProto());
276 494 : auto addrHash = hash<Hccl::IpAddress>{}(portData.GetAddr());
277 :
278 494 : return Hccl::HashCombine({addrHash, typeHash, protoHash});
279 : }
280 : };
281 :
282 : template <>
283 : class equal_to<Hccl::PortData> {
284 : public:
285 217 : bool operator()(const Hccl::PortData& p1, const Hccl::PortData& p2) const
286 : {
287 217 : return p1.GetAddr() == p2.GetAddr() && p1.GetType() == p2.GetType() && p1.GetProto() == p2.GetProto();
288 : }
289 : };
290 : } // namespace std
291 :
292 : #endif // HCCLV2_PORT_H
|