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 COMM_BASE_PUB_H
12 : #define COMM_BASE_PUB_H
13 :
14 : #include <memory>
15 : #include <mutex>
16 : #include <map>
17 : #include <sys/types.h>
18 : #include <hccl/hccl_types.h>
19 :
20 : #include "hccl_common.h"
21 : #include "hccl_socket_manager.h"
22 : #include "transport_pub.h"
23 : #include "alg_template_base_pub.h"
24 : #include "workflow_pub.h"
25 : #include "common.h"
26 :
27 : namespace hccl {
28 : constexpr u32 HCCL_RANK_SIZE_EQ_TWO = 2;
29 : constexpr u32 HCCL_RANK_ZERO = 0;
30 : constexpr u32 HCCL_RANK_OFFSET = 1;
31 :
32 : constexpr u32 FACTOR_NUM_TWO = 2;
33 : constexpr s32 DEVICE_PER_MODULE = 8; // 单module支持最大device数量
34 : constexpr u32 MC2_PLANE_MODE_HOST = 0; // HOST调度RoCE模式
35 : constexpr u32 MC2_PLANE_MODE_COMBINE = 1; // 非分层建链模式
36 : constexpr u32 MC2_PLANE_MODE_HIERARCHY = 2; // 分层建链模式
37 :
38 : constexpr u32 GROUP_MAX_CONCURRENT = 8;
39 :
40 : class CommBase {
41 : public:
42 : explicit CommBase(
43 : const std::string& collectiveId, const u32 userRank, const u32 userRankSize, const u32 rank, const u32 rankSize,
44 : const std::vector<RankInfo> paraVector, const TopoType topoFlag, const HcclDispatcher dispatcher,
45 : const std::unique_ptr<NotifyPool>& notifyPool, std::map<HcclIpAddress, HcclNetDevCtx>& netDevCtxMap,
46 : const IntraExchanger& exchanger, const DeviceMem& inputMem, const DeviceMem& outputMem,
47 : const bool isUsedRdmaLevel0, const std::string& tag = "",
48 : const NICDeployment nicDeployInner = NICDeployment::NIC_DEPLOYMENT_DEVICE, bool isAlltoAllCommMesh = false,
49 : const bool useOneDoorbell = false, const bool isAicpuModeEn = false, const u32 rankRoot = INVALID_UINT,
50 : const bool isHaveCpuRank = false, const bool useSuperPodMode = false, DeviceMem expMem = DeviceMem());
51 : virtual ~CommBase();
52 :
53 : inline const std::string& CollectiveId() const { return collectiveId_; }
54 :
55 0 : inline const std::vector<LINK>& TransportInfo() const { return transportInfo_; }
56 :
57 1 : inline u32 UserRank() const { return userRank_; }
58 :
59 : inline u32 UserRankSize() const { return userRankSize_; }
60 :
61 1 : inline u32 Rank() const { return rank_; }
62 :
63 1 : inline u32 RankSize() const { return rankSize_; }
64 :
65 0 : inline const std::string& Tag() const { return tag_; }
66 :
67 0 : inline void SetHeterogP2PType() { isNeedHeterogP2P_ = true; }
68 :
69 : inline void SetHostUseDevNic() { isHostUseDevNic_ = true; }
70 :
71 : virtual HcclResult Init(); // 初始化必要信息
72 : virtual HcclResult DeInit();
73 :
74 : std::shared_ptr<Transport>& GetTransportByRank(const u32 dstRank); // 获取当前rank与dst rank的link信息
75 : HcclResult GetRankByUserRank(const u32 userRank, u32& rank) const; // 获取当前userrank在重新排序后的rank
76 : HcclResult GetUserRankByRank(const u32 rank, u32& userRank) const; // 获取当前rank的userrank
77 : HcclResult GetRaSocket(const u32 role, HcclSocketInfo conn[], const u32 num);
78 : HcclResult CreateIntraThread(
79 : const u32 role, u32 dstRank,
80 : const std::vector<std::shared_ptr<HcclSocket>>& sockets); // 节点内建链起线程
81 : HcclResult CreateInterThread(
82 : const u32 role, u32 dstRank,
83 : const std::vector<std::shared_ptr<HcclSocket>>& sockets); // 节点间建链起线程
84 : HcclResult RunTemplateAlg(const std::unique_ptr<AlgTemplateBase>& tempAlg);
85 : HcclResult RunTemplateAlgStaged(const std::unique_ptr<AlgTemplateBase>& tempAlg, const RunStage& stage);
86 : std::shared_ptr<Transport>& GetTrasportInfoByVTransportInfoIndex(u32 index);
87 : HcclResult BuildAsync(u32& status);
88 : HcclResult BuildQuerry(u32& status);
89 : HcclResult SetHDCModeInfo(
90 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>>& rankDevicePhyIdNicInfoMap,
91 : std::vector<u32>& ranksPort, std::vector<u32>& vnicRanksPort, bool isSetHDCModeInfo, bool isUseRankPort);
92 : u32 IsSupportMC2(const std::string& tag);
93 0 : void Break()
94 : {
95 0 : for (auto& ptr : transportInfo_) {
96 0 : if (ptr == nullptr) {
97 0 : continue;
98 : }
99 0 : ptr->Break();
100 : }
101 0 : }
102 :
103 : std::shared_ptr<Transport> linkDummy_; // 用于无效的link返回
104 : protected:
105 : // 创建当前rank与其他rank之间的link:ring\mesh\H-D分别在对应派生类实现
106 : virtual HcclResult CreateLinks();
107 : // 计算当前rank与其他rank之间的link个数:server/client两种角色,ring\mesh\H-D分别在对应派生类实现
108 : virtual HcclResult CalcLink();
109 : // 获取每个 link 需要的 socket 数量
110 : virtual u32 GetSocketsPerLink();
111 : virtual bool NeedDataReceivedAck();
112 : virtual void SetMachineLinkMode(MachinePara& machinePara);
113 : virtual HcclResult CreateIntraLinks(); // 当前rank在服务器内与对端的建链
114 : virtual HcclResult CreateInterLinks(); // 当前rank在服务期间与对端的建链
115 : virtual HcclResult SetMachinePara(
116 : MachineType machineType, const std::string& serverId, u32 dstRank,
117 : const std::vector<std::shared_ptr<HcclSocket>>& sockets, MachinePara& machinePara);
118 : virtual void SetTransportParam(TransportPara& para, MachinePara& machinePara);
119 : virtual HcclResult MakeClientInfo(const u32 dstRank, RankInfo& dstRankInfo, bool isInterRdma, bool isInterHccs);
120 : virtual HcclResult MakeServerInfo(const u32 dstRank, RankInfo& dstRankInfo, bool isInterRdma, bool isInterHccs);
121 :
122 : virtual HcclResult CreateExchangerNetwork(); // server间HCCS通信模式下,创建节点间的建链关系
123 : HcclResult GetRankLinkInfo(bool& isInterServer, bool& isInterHccs, std::map<u32, HcclSocketRole>& rankRole);
124 :
125 : HcclResult CalcLinksNum(
126 : const MachineType machineType,
127 : const u32 dstRank); // 填充dst_inter_server_num_/dst_inter_client_num_
128 : HcclResult CreateDestLink(
129 : const ErrContextPub& error_context, const MachineType machineType, const std::string& serverId,
130 : const u32 dstRank, const std::string& threadStr,
131 : const std::vector<std::shared_ptr<HcclSocket>>& sockets); // 创建transhport
132 : HcclResult TransportInit(const u32 dstRank, MachinePara& machinePara);
133 : HcclResult SetRankMap(); // 获取rank->userrank以及userrank->rank的映射关系
134 : HcclResult GetBuildStatus(u32& status);
135 : HcclResult TransportBuildAsync(
136 : const MachineType machineType, const std::string& serverId, u32 dstRank,
137 : const std::vector<std::shared_ptr<HcclSocket>>& sockets, u32& status);
138 : HcclResult TransportBuildQuerry(u32 dstRank, u32& status);
139 :
140 : const std::string collectiveId_; /* * 本节点所在的通信域ID */
141 :
142 : const u32 userRank_; /* * 本节点的用户原始rank号 */
143 : const u32 userRankSize_; /* * 本节点所在的用户通信域rank size */
144 :
145 : const u32 rank_; /* * 本节点在子通信域的rank号 */
146 : const u32 rankSize_; /* * 本节点所在的子通信域的rank size */
147 : std::vector<RankInfo> paraVector_; // 子通信域内各个rank的基本信息
148 : // 与link_info_中每个link类型对应的vector:默认值均为-1,建链成功后填入对应type
149 : std::vector<TransportType> transportType_;
150 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>> rankDevicePhyIdNicInfoMap_;
151 : std::vector<u32> ranksPort_;
152 : std::vector<u32> vnicRanksPort_;
153 :
154 : s32 deviceLogicId_;
155 : u32 devicePhyId_;
156 : std::map<u32, std::unique_ptr<HcclSocketManager>> pyhIdResourseSockets_{};
157 :
158 : protected:
159 : const TopoType topoFlag_; // 当前通信域内服务器间拓扑组合类型
160 :
161 : const std::string tag_; /* * 多stream是的tag信息 */
162 : std::vector<std::shared_ptr<Transport>> transportInfo_; // 当前rank与其他rank对应的link信息
163 : std::vector<std::shared_ptr<Transport>> vTransportInfo_; // 当前rank与其他rank对应的virtual link信息
164 :
165 : std::vector<u32> rankMap_; // rank->userrank的映射关系:vector下标是user_rank,存的数据是rank
166 : std::vector<u32> userRankMap_; // userrank->rank的映射关系:vector下标是rank,存的数据是user_rank
167 :
168 : const HcclDispatcher dispatcher_; // signal调度句柄(event/notify机制)
169 : const std::unique_ptr<NotifyPool>& notifyPool_;
170 : std::map<HcclIpAddress, HcclNetDevCtx>& netDevCtxMap_;
171 : const IntraExchanger& exchanger_;
172 : std::map<u32, std::vector<std::shared_ptr<HcclSocket>>> intraSocketsMap_;
173 : const DeviceMem inputMem_;
174 : const DeviceMem outputMem_;
175 : const bool isUsedRdmaLevel0_;
176 :
177 : // 当前rank作为client端,需要连接的节点间server端的集合:键为rank 号,value为 HcclRankLinkInfo
178 : // 当前rank作为client端, 需要连接的节点间server端的集合
179 : std::map<u32, HcclRankLinkInfo> dstInterServerMap_;
180 : // 当前rank作为server端, 需要连接的节点间client端的集合
181 : std::map<u32, HcclRankLinkInfo> dstInterClientMap_;
182 :
183 : // 当前rank作为client端,需要连接的节点内server端的集合
184 : std::vector<u32> dstIntraServerVec_;
185 : // 当前rank作为server端,需要连接的节点内client端的集合
186 : std::vector<u32> dstIntraClientVec_;
187 :
188 : std::vector<std::unique_ptr<std::thread>> linkThreads_; // 建链所需线程
189 : u32 threadsRapplyNum_; // 线程使用计数器
190 :
191 : dev_t shmDev_; // dev_t 为u32类型
192 : bool isAlltoAllCommMesh_;
193 : NICDeployment nicDeployInner_;
194 : std::vector<u32> transportStatus_;
195 : std::vector<bool> checkStatus_;
196 : bool isNeedHeterogP2P_;
197 : bool useOneDoorbell_;
198 :
199 : // 获取当前rank和目的rank之间的link type
200 : HcclResult SetTransportType(const u32 dstRank);
201 : HcclResult CheckLinks() const; // 校验当前rank与dst rank建链的链路有效性
202 : HcclResult CreateVirturalTransport();
203 :
204 : // 统一接口
205 : HcclResult GetRankIPInfo(
206 : bool isInterServer, bool isInterHccs, bool& isSupportReuse, std::map<u32, HcclSocketRole>& rankRole,
207 : HcclIpAddress& localIP, std::map<u32, HcclRankLinkInfo>& dstServerMap,
208 : std::map<u32, HcclRankLinkInfo>& dstClientMap, std::shared_ptr<HcclSocketManager>& socketManager);
209 :
210 : // server内使用
211 : HcclResult GetIntraRankIPInfo(
212 : std::map<u32, HcclSocketRole>& rankRole, HcclIpAddress& localIP, std::map<u32, HcclRankLinkInfo>& dstServerMap,
213 : std::map<u32, HcclRankLinkInfo>& dstClientMap);
214 :
215 : // 310p device侧、isHaveCpuRank_ 业务场景使用
216 : HcclResult GetIntraRankIPInfo(
217 : std::vector<u32>& dstIntraVec, HcclIpAddress& localIP, std::map<u32, HcclRankLinkInfo>& dstServerMap,
218 : std::map<u32, HcclRankLinkInfo>& dstClientMap);
219 :
220 : // 超节点server间HCCS场景使用
221 : HcclResult GetSuperNodeIntraRankIPInfo(
222 : std::map<u32, HcclSocketRole>& rankRole, HcclIpAddress& localIP, std::map<u32, HcclRankLinkInfo>& dstServerMap,
223 : std::map<u32, HcclRankLinkInfo>& dstClientMap);
224 :
225 : bool IsSupportInterHccs(const u32 dstRank); // 是否支持走节点间HCCS通信
226 : u32 GetInterRemotePort(s32 devicePhyId, u32 dstUserRank);
227 : void PrintCreateInterLinksInfo(); // 打印当前rank在服务器间建链通信topo对
228 : HcclResult CheckExchangeInfo(const std::shared_ptr<Transport>& link, const s32 deviceId);
229 : const bool isAicpuModeEn_;
230 : std::unique_ptr<HcclSocketManager> interSocketManager_;
231 : const u32 subUserRankRoot_;
232 : bool isHostUseDevNic_{false};
233 : bool isSetHDCModeInfo_{false};
234 : bool isUseRankPort_{false};
235 : bool isHaveCpuRank_{false};
236 : bool useSuperPodMode_{false};
237 : const DeviceMem expMem_;
238 : std::shared_ptr<HcclSocketManager> socketManager_{nullptr};
239 : HcclWorkflowMode workflowMode_{HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE};
240 : };
241 : } // namespace hccl
242 :
243 : #endif /* COMM_BASE_PUB_H */
|