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 HCCL_IMPL_H
12 : #define HCCL_IMPL_H
13 :
14 : #include <functional>
15 : #include <vector>
16 : #include <hccl/hccl_types.h>
17 :
18 : #include "hccl_common.h"
19 : #include "common.h"
20 : #include "comm_factory_pub.h"
21 : #include "parallel_task_loader.h"
22 : #include "dispatcher.h"
23 : #include "ccl_buffer_manager.h"
24 : #include "workspace_resource.h"
25 : #include "hccl_impl_pub.h"
26 : #include "op_base_stream_manager_pub.h"
27 : #include "resource_manager/queue_notify_manager.h"
28 : #include "device_capacity.h"
29 : #include "coll_alg_utils.h"
30 : #include "alg_configurator.h"
31 : #include "workflow_pub.h"
32 : #include "topo_info_extractor.h"
33 :
34 : namespace hccl
35 : {
36 : constexpr s32 COMM_INDEX_0 = 0;
37 : constexpr s32 COMM_INDEX_1 = 1;
38 : constexpr s32 STREAM_INDEX_0 = 0;
39 : constexpr s32 STREAM_INDEX_1 = 1;
40 : constexpr s32 COMM_SIZE_TWO = 2;
41 : constexpr s32 LEVEL1_PLANE_NUM_IN_4PMESH = 4;
42 : constexpr s32 LEVEL0_PLANE_NUM_IN_NPRING_SINGLE = 1;
43 : constexpr s32 LEVEL0_PLANE_NUM_IN_NPRING_DOUBLE = 2;
44 : constexpr s32 RDMA_PLANE_NUM_IN_NPRING_DOUBLE = 2;
45 : constexpr s32 LEVEL0_PLANE_NUM_IN_8PRING = 4;
46 : constexpr s32 LEVEL0_PLANE_NUM_IN_4PMESH = 3;
47 : constexpr s32 STREAM_NUM_FOR_DMAREDUCE_ONE_RING = 2;
48 :
49 : constexpr u32 SLICES_FACTOR = 2;
50 : constexpr u32 RDMA_ADD_STREAMS_NUM = 3;
51 :
52 : constexpr u32 CCE_REDUCE_ALIGN_SIZE = 32;
53 :
54 : constexpr u32 HCCL_INTERNODE_MAX_DATA_RATE = 1; // node间通信的单次通信量最多为node通信量的1倍(R-HD或NHR)
55 :
56 : constexpr u32 DEVICE_EIGHT = 8;
57 : constexpr u32 DEVICE_FOUR = 4;
58 : constexpr u32 DEVICE_TWO = 2;
59 : constexpr u32 DEVICE_ONE = 1;
60 : constexpr u64 KB2B = 1024;
61 : constexpr u64 FACTOR_TWO = 2;
62 : constexpr float BASE_COMM_LATENCY = 13.0; // 通信静态时延(us);
63 : constexpr u64 MULTIPLIER_MS2US = 1000; // 毫秒转换成微秒
64 : constexpr u64 MULTIPLIER_S2MS = 1000; // 秒转换成毫秒
65 :
66 : using ResDeviceMemMap = std::map<std::string, DeviceMem>;
67 :
68 : struct PiplineSliceInfo
69 : {
70 : std::vector<Slice> piplineDataSegsSlice;
71 : std::vector<std::vector<Slice>> piplineMultiStreamSlice;
72 : u64 count{0};
73 : u64 offset{0}; // 记录切分内存段起始地址的相对偏移
74 : };
75 :
76 : class hcclImpl
77 : {
78 : friend class CollAlgOperator;
79 : friend class CollNativeExecutorBase;
80 :
81 : public:
82 : explicit hcclImpl(const HcclDispatcher dispatcher,
83 : const std::unique_ptr<NotifyPool> ¬ifyPool,
84 : std::map<HcclIpAddress, HcclNetDevCtx> &netDevCtxMap,
85 : const std::unique_ptr<QueueNotifyManager> &queueNotifyManager,
86 : std::unique_ptr<WorkspaceResource> &workSpaceRes,
87 : CCLBufferManager &cclBufferManager,
88 : HcclAlgoAttr &algoAttr,
89 : HcclTopoAttr &topoAttr,
90 : std::shared_ptr<AlgConfigurator> algConfigurator,
91 : std::shared_ptr<TopoInfoExtractor> topoInfoEx);
92 : ~hcclImpl();
93 : HcclResult Init(bool isHeterogComm = false);
94 : HcclResult ReleaseCommInfos();
95 : HcclResult CreateMutiStreamRes(const std::string &tag, Stream &stream, AlgType algType,
96 : bool isBatchSendRecv = false, u32 ringNum = 0);
97 :
98 : HcclResult CreateMutiStreamRes(const std::string &tag, Stream &stream, level1StreamInfo_t &streamInfo,
99 : AlgType algType, bool isAicpuModeEn = false, bool isBatchSendRecv = false, u32 ringNum = 0);
100 : HcclResult CreateComm(const std::string &tag, DeviceMem &inputMem, DeviceMem &outputMem, AlgType algType,
101 : std::unique_ptr<CommInfo> &commInfo, u32 root = INVALID_VALUE_RANKID, bool isP2p = false,
102 : bool isAicpuModeEn = false, bool isBatchSendRecv = false, bool meshSinglePlane = false, bool aivMode = false,
103 : std::set<u32> batchSendRecvtargetRanks = std::set<u32>());
104 :
105 : HcclResult CreateComm(const std::string &tag, DeviceMem &inputMem, DeviceMem &outputMem, AlgType algType,
106 : u32 root = INVALID_VALUE_RANKID, bool isP2p = false, bool isBatchSendRecv = false, bool meshSinglePlane = false,
107 : bool aivMode = false, std::set<u32> batchSendRecvtargetRanks = std::set<u32>());
108 : HcclResult ClearOpResource(const std::string &tag);
109 0 : void Break()
110 : {
111 0 : if (Is310P3Common(isHaveCpuRank_, deviceType_))
112 : {
113 0 : HCCL_ERROR("[hcclImpl][Break]Break is not supported.");
114 0 : return;
115 : }
116 0 : for (auto &commInfo : tagCommInfo_)
117 : {
118 0 : for (auto &comm : commInfo.second.commLevel0)
119 : {
120 0 : if (comm == nullptr)
121 : {
122 0 : continue;
123 : }
124 0 : comm->Break();
125 : }
126 0 : for (auto &comm : commInfo.second.commLevel1)
127 : {
128 0 : if (comm == nullptr)
129 : {
130 0 : continue;
131 : }
132 0 : comm->Break();
133 : }
134 0 : for (auto &comm : commInfo.second.commP2P)
135 : {
136 0 : if (comm == nullptr)
137 : {
138 0 : continue;
139 : }
140 0 : comm->Break();
141 : }
142 : }
143 : }
144 :
145 0 : inline bool IsExistCommRes(const std::string &tag)
146 : {
147 0 : std::unique_lock<std::mutex> commLock(commLock_);
148 0 : return (tagCommInfo_.find(tag) != tagCommInfo_.end());
149 0 : }
150 :
151 : void SetHDCModeInfo(
152 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>> &rankDevicePhyIdNicInfoMap,
153 : std::vector<u32> &ranksPort, std::vector<u32> &vnicRanksPort, bool isSetHDCModeInfo, bool isUseRankPort);
154 :
155 : private:
156 : void SetAlgoAttr(HcclAlgoAttr &algoAttr);
157 : void SetTopoAttr(HcclTopoAttr &algoAttr);
158 : HcclResult CreateCommThread(const ErrContextPub &error_context, const std::string &tag,
159 : DeviceMem &inputMem, DeviceMem &outputMem, DeviceMem &expMem, const CommParaInfo &commParaInfo,
160 : std::vector<std::unique_ptr<CommBase>> &commVec, HcclResult &retOut);
161 : HcclResult GetCommTypeInLevel0(const AlgType algType, const TopoType topoType, CommType &commType);
162 : HcclResult GetCommTypeInLevel1(const AlgType algType, CommType &commType);
163 : CommPlane GetCommPlaneInLevel1(CommType &commType);
164 : HcclResult ReplaceCommInfoByTag(const std::string &tag, std::unique_ptr<CommInfo> &commInfo);
165 : HcclResult CreateP2pComm(const std::string &tag, CommInfo &commInfo,
166 : DeviceMem &inOutMem, u32 peerUserRank);
167 : HcclResult CreateCommByAlg(const std::string &tag, const AlgType algType, CommInfo &commInfo, DeviceMem &inputMem,
168 : DeviceMem &outputMem, DeviceMem &expMem, u32 root = INVALID_VALUE_RANKID, bool isAicpuModeEn = false,
169 : bool meshSinglePlane = false, bool isA2MC2MultiServer = false);
170 :
171 : void DestroyLevel1Comm(const std::string &tag);
172 : void DestroyIntraServerComm(const std::string &tag);
173 : void DestroyLevel0Comm(const std::string &tag);
174 : HcclResult ReleaseSignal(level1StreamInfo_t &level1Stream);
175 :
176 : HcclResult InitMultiStreamResource(const std::string &tag, level1StreamInfo_t &streamInfo, AlgType algType,
177 : bool isAicpuModeEn = false, bool isBatchSendRecv = false, u32 ringNum = 0);
178 :
179 : HcclResult WaitCommThread(std::unique_ptr<std::thread> &ThreadPtr) const;
180 : HcclResult SetRankPortInfo(s32 deviceLogicID, bool isUseRankPort, std::vector<u32> &ranksPort);
181 :
182 : /* ---------------以下为私有成员变量定义领域-------------------------- */
183 : TopoType topoType_ = TopoType::TOPO_TYPE_COMMON;
184 : std::mutex commLock_;
185 :
186 : tagCommInfo_t tagCommInfo_; // 以tag为粒度分配comm实例和资源
187 : std::mutex tagStreamInfoLock_;
188 : std::mutex scratchMemLock_;
189 : std::map<std::string, DeviceMem> scratchMemMap_;
190 : std::vector<u32> nicList_;
191 : std::mutex nicSendSizeListLock_;
192 : std::map<std::string, std::vector<u64>> nicSendSizeList_;
193 : std::mutex ringNicListLock_;
194 : std::map<std::string, std::vector<std::vector<u32>>> ringNicList_;
195 : u32 serverNum_;
196 : u32 superPodNum_;
197 : u32 moduleNum_;
198 : OpBaseStreamManager opBaseStreamManager_;
199 : std::vector<Stream> auxRingStreamsDev_;
200 :
201 : std::unique_ptr<std::thread> commThreadPtrLevel0_;
202 : std::unique_ptr<std::thread> commThreadPtrLevel0Rdma_;
203 : std::unique_ptr<std::thread> commThreadPtrLevel1_;
204 : std::unique_ptr<std::thread> commThreadPtrLevel1Rdma_;
205 : std::unique_ptr<std::thread> commThreadPtrLevel2_;
206 :
207 : std::unique_ptr<CommBase> commMeshPtr_; // 单算子alltoallv只建链一次
208 : std::unique_ptr<CommBase> commMeshLevel2_; // 单算子alltoallv只建链一次
209 : std::map<std::string, std::unique_ptr<CommBase>> commMeshMap_; // 图模式alltoallv建链多次
210 : u32 deviceNumPerServer_;
211 : u32 deviceNumPerAggregation_;
212 : static std::array<DeviceMem, MAX_MODULE_DEVICE_NUM> inOutPutTempMem_; // 图模式alltoallv输入为0时用该内存建链
213 : static std::array<std::mutex, MAX_MODULE_DEVICE_NUM> inOutPutTempMemMutex_;
214 : static std::array<Referenced, MAX_MODULE_DEVICE_NUM> instanceRef_; // 实例计数,用于释放静态资源
215 : const u64 tinyMemSizeForTransportCreation{LARGE_PAGE_MEMORY_MIN_SIZE}; // 避免申请小页内存。最小2*1024*1024
216 : bool isAlltoAllZCopyMode_ = false;
217 : bool needRecreateAlltoallComm_ = false;
218 : std::map<std::string, bool> isAlltoAllZCopyModeMap_;
219 : // 按照 tag 记录全局所有卡上 alltoall 算子的中转内存大小
220 : std::unordered_map<std::string, std::unordered_map<u32, u64>> allRankAlltoallScratchMemSize_;
221 : bool isSingleMeshAggregation_ = false;
222 : bool meshSinglePlane_ = false;
223 : bool isAllRankSamePlane_ = false;
224 :
225 : u64 piplineSliceNum_ = 0; // Server间pipline切分数量 0: 不支持; 1: 当前数据量下切1份; 其他: 走pipline模式
226 : const HcclDispatcher dispatcher_; // dispatcher放到最后析构
227 : const std::unique_ptr<NotifyPool> ¬ifyPool_;
228 : std::map<HcclIpAddress, HcclNetDevCtx> &netDevCtxMap_;
229 : const std::unique_ptr<QueueNotifyManager> &queueNotifyManager_;
230 : std::unordered_map<u32, u32> pairLinkCounter_; // server内所有device间的链路类型计数
231 : std::unordered_map<u32, std::unordered_map<int, std::vector<int>>> pairLinkInfo_; // server内所有device间的链路类型
232 : bool isHaveCpuRank_;
233 : u32 userRank_; // 本group中的userrank
234 : u32 realUserRank_; // world group中的userrank
235 : u32 userRankSize_;
236 : std::vector<RankInfo> rankInfoList_; // world group内rank的信息, 按照rank id递增依次排列
237 : bool inlineReduceSwitchOn_;
238 : NICDeployment nicDeployment_;
239 : u32 devicePhyId_;
240 : s32 deviceLogicId_;
241 : bool isUsedRdmaLevel0_;
242 : std::unique_ptr<WorkspaceResource> &workSpaceRes_;
243 : CCLBufferManager &cclBufferManager_;
244 : DevType deviceType_;
245 : std::string collectiveId_;
246 : std::unique_ptr<CommFactory> commFactory_;
247 : WorkMode commWorkMode_;
248 : tagStreamInfo_t tagStreamInfo_;
249 : u32 meshAggregationRankSize_;
250 : std::string identifier_;
251 : bool isDiffDeviceModule_;
252 : bool isStandardCard_;
253 : bool is310PDuoCard_;
254 : bool multiModuleDiffDeviceNumMode_;
255 : bool multiSuperPodDiffServerNumMode_;
256 : bool multiSuperPodDiffDeviceNumMode_;
257 : bool isUsedInterHccsMode_ = false;
258 : bool useSuperPodMode_ = false;
259 : s32 pid_ = 0;
260 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>> rankDevicePhyIdNicInfoMap_{};
261 : std::vector<u32> ranksPort_;
262 : bool isSetHDCModeInfo_{false};
263 : bool isUseRankPort_{false};
264 : std::vector<u32> vnicRanksPort_;
265 : bool isSupportRdmaLite_{false}; // 是否支持rdma lite
266 : bool isSupportHccsAndSio_{false}; // 是否支持hccs sio并发
267 :
268 : HcclWorkflowMode workflowMode_{HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE};
269 : std::shared_ptr<AlgConfigurator> algConfigurator_;
270 : std::shared_ptr<TopoInfoExtractor> topoInfoEx_;
271 : HcclTopoAttr &topoAttr_;
272 : HcclAlgoAttr &algoAttr_;
273 : u32 localNicPort_{0};
274 : bool isNeedInitNic_{false};
275 : };
276 : } // namespace hccl
277 :
278 : #endif /** __HCCL_COMM_H__ */
|