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 10589 : MAKE_ENUM(PortDeploymentType, P2P, DEV_NET, HOST_NET)
30 :
31 6641 : MAKE_ENUM(ConnectProtoType, HCCS, PCIE, TCP, RDMA, UB, UBOE, UBG)
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::UBG) {
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 26 : connType == ConnectProtoType::UB || connType == ConnectProtoType::UBOE || 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 585 : inline LinkProtocol ConnProto2LinkProtocol(ConnectProtoType connType)
90 : {
91 585 : LinkProtocol linkProto{};
92 585 : if (connType == ConnectProtoType::HCCS || connType == ConnectProtoType::PCIE) {
93 124 : linkProto = LinkProtocol::HCCS;
94 461 : } else if (connType == ConnectProtoType::TCP) {
95 2 : linkProto = LinkProtocol::TCP;
96 459 : } else if (connType == ConnectProtoType::RDMA) {
97 24 : linkProto = LinkProtocol::ROCE;
98 435 : } else if (connType == ConnectProtoType::UB) {
99 344 : linkProto = LinkProtocol::UB_CTP;
100 91 : } else if (connType == ConnectProtoType::UBOE) {
101 0 : linkProto = LinkProtocol::UBOE;
102 91 : } else if (connType == ConnectProtoType::UBG) {
103 0 : linkProto = LinkProtocol::UBG;
104 : }
105 1681 : HCCL_INFO("[ConnProto2LinkProtocol] linkProto is[%s]", linkProto.Describe().c_str());
106 585 : return linkProto;
107 : }
108 :
109 : class BasePortType {
110 : public:
111 : BasePortType(const BasePortType&) = default;
112 : BasePortType& operator=(const BasePortType&) = default;
113 :
114 632 : inline PortDeploymentType GetType() const { return type_; };
115 :
116 632 : inline ConnectProtoType GetProto() const { return proto_; };
117 :
118 132 : explicit BasePortType(PortDeploymentType type) : type_(type) {};
119 :
120 : bool operator==(const BasePortType& rhs) const { return type_ == rhs.type_ && proto_ == rhs.proto_; }
121 :
122 : bool operator!=(const BasePortType& rhs) const { return !(rhs == *this); }
123 :
124 : bool operator<(const BasePortType& rhs) const
125 : {
126 : if (type_ < rhs.type_)
127 : return true;
128 : if (rhs.type_ < type_)
129 : return false;
130 : return proto_ < rhs.proto_;
131 : }
132 :
133 3449 : BasePortType(PortDeploymentType type, ConnectProtoType proto) : type_(type), proto_(proto) {};
134 :
135 : string Describe() const
136 : {
137 : return StringFormat("PortType[type=%s, proto=%s]", type_.Describe().c_str(), proto_.Describe().c_str());
138 : }
139 :
140 : protected:
141 : PortDeploymentType type_;
142 : ConnectProtoType proto_;
143 : };
144 :
145 : class P2PPortType : public BasePortType {
146 : public:
147 : P2PPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::P2P)
148 : {
149 : if (proto != ConnectProtoType::HCCS && proto != ConnectProtoType::PCIE) {
150 : THROW<InvalidParamsException>(StringFormat("P2PPortType::P2PPortType proto invalid"));
151 : }
152 : proto_ = proto;
153 : };
154 : };
155 :
156 : class DevNetPortType : public BasePortType {
157 : public:
158 39 : DevNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::DEV_NET)
159 : {
160 39 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
161 0 : THROW<InvalidParamsException>(StringFormat("DevNetPortType::DevNetPortType proto invalid"));
162 : }
163 39 : proto_ = proto;
164 39 : };
165 : };
166 :
167 : class HostNetPortType : public BasePortType {
168 : public:
169 : HostNetPortType(ConnectProtoType proto) : BasePortType(PortDeploymentType::HOST_NET)
170 : {
171 : if (proto != ConnectProtoType::TCP && proto != ConnectProtoType::RDMA && proto != ConnectProtoType::UB) {
172 : THROW<InvalidParamsException>(StringFormat("HostNetPortType::HostNetPortType proto invalid"));
173 : }
174 : proto_ = proto;
175 : };
176 : };
177 :
178 : class PortData {
179 : public:
180 47 : PortData(RankId rankId, BasePortType type, u32 id, const IpAddress& addr)
181 47 : : rankId(rankId),
182 47 : type(type.GetType()),
183 47 : protoType(ConnProto2LinkProto(type.GetProto())),
184 47 : id(id),
185 47 : addr(addr)
186 47 : {}
187 :
188 590 : PortData(RankId rankId, PortDeploymentType type, LinkProtoType protoType, u32 id, const IpAddress& addr)
189 590 : : rankId(rankId),
190 590 : type(type),
191 590 : protoType(protoType),
192 590 : id(id),
193 590 : addr(addr)
194 590 : {}
195 :
196 234 : PortData(RankId rankId, const NetInstance::ConnInterface& connIface)
197 234 : : rankId(rankId),
198 234 : type(AddrPos2PortDeploymentType(connIface.GetPos(), *connIface.GetLinkProtocols().begin())),
199 234 : protoType(LinkProtocol2LinkProtoType(*connIface.GetLinkProtocols().begin())),
200 234 : id(0),
201 234 : addr(connIface.GetAddr())
202 234 : {}
203 :
204 260 : string Describe() const
205 : {
206 : return StringFormat(
207 520 : "PortData[rankId=%d, type=%s, id=%d, addr=%s]", rankId, type.Describe().c_str(), id,
208 780 : addr.Describe().c_str());
209 : }
210 :
211 35 : RankId GetRankId() const { return rankId; }
212 :
213 1199 : const PortDeploymentType& GetType() const { return type; }
214 :
215 1266 : const LinkProtoType& GetProto() const { return protoType; }
216 :
217 8 : u32 GetId() const { return id; }
218 :
219 1394 : const IpAddress& GetAddr() const { return addr; }
220 :
221 0 : bool operator==(const PortData& rhs) const
222 : {
223 0 : return type == rhs.type && id == rhs.id
224 0 : && addr == rhs.addr; // TODO: rankId后面应该要删,rankId == rhs.rankId &&
225 : }
226 :
227 0 : bool operator!=(const PortData& rhs) const { return !(rhs == *this); }
228 :
229 0 : bool operator<(const PortData& rhs) const
230 : {
231 0 : if (rankId < rhs.rankId) {
232 0 : return true;
233 : }
234 0 : if (rhs.rankId < rankId) {
235 0 : return false;
236 : }
237 0 : if (type < rhs.type) {
238 0 : return true;
239 : }
240 0 : if (rhs.type < type)
241 0 : return false;
242 0 : if (addr < rhs.addr) {
243 0 : return true;
244 : }
245 0 : if (rhs.addr < addr) {
246 0 : return false;
247 : }
248 0 : return id < rhs.id;
249 : }
250 :
251 : bool operator>(const PortData& rhs) const { return rhs < *this; }
252 :
253 : bool operator<=(const PortData& rhs) const { return !(rhs < *this); }
254 :
255 : bool operator>=(const PortData& rhs) const { return !(*this < rhs); }
256 :
257 : private:
258 : RankId rankId;
259 : PortDeploymentType type;
260 : LinkProtoType protoType;
261 : u32 id;
262 : IpAddress addr;
263 : };
264 : } // namespace Hccl
265 :
266 : namespace std {
267 :
268 : template <>
269 : class hash<Hccl::PortData> {
270 : public:
271 494 : size_t operator()(const Hccl::PortData& portData) const
272 : {
273 494 : auto typeHash = hash<uint8_t>{}(portData.GetType());
274 494 : auto protoHash = hash<uint8_t>{}(portData.GetProto());
275 494 : auto addrHash = hash<Hccl::IpAddress>{}(portData.GetAddr());
276 :
277 494 : return Hccl::HashCombine({addrHash, typeHash, protoHash});
278 : }
279 : };
280 :
281 : template <>
282 : class equal_to<Hccl::PortData> {
283 : public:
284 217 : bool operator()(const Hccl::PortData& p1, const Hccl::PortData& p2) const
285 : {
286 217 : return p1.GetAddr() == p2.GetAddr() && p1.GetType() == p2.GetType() && p1.GetProto() == p2.GetProto();
287 : }
288 : };
289 : } // namespace std
290 :
291 : #endif // HCCLV2_PORT_H
|