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 : #include <memory>
12 : #include "hccl_impl.h"
13 : #include "alltoall_operator.h"
14 : #include "all_reduce_operator.h"
15 : #include "coll_alg_op_registry.h"
16 : #include "topo_matcher.h"
17 : #include "topo_info_extractor.h"
18 : #include "alg_configurator.h"
19 : #include "hccl_alg.h"
20 :
21 : namespace hccl {
22 : constexpr u32 TINY_MEMORY_SIZE = 32; // sendBuff或recvBuff为空时, 使用的DeviceMem大小
23 :
24 532 : HcclAlg::HcclAlg(CCLBufferManager &cclBufferManager, const HcclDispatcher dispatcher, const HcclDispatcher vDispatcher):
25 532 : cclBufferManager_(cclBufferManager), dispatcher_(dispatcher), vDispatcher_(vDispatcher)
26 : {
27 532 : }
28 :
29 1062 : HcclAlg::~HcclAlg()
30 : {
31 : #ifndef OPEN_HCCL_TEST
32 531 : pimpl_ = nullptr;
33 : #endif
34 1062 : }
35 :
36 521 : HcclResult HcclAlg::Init(std::unique_ptr<WorkspaceResource> &workSpaceRes,
37 : const std::unique_ptr<NotifyPool> ¬ifyPool, std::map<HcclIpAddress, HcclNetDevCtx> &netDevCtxMap,
38 : const std::unique_ptr<QueueNotifyManager> &queueNotifyManager,
39 : HcclAlgoAttr &algoAttr, HcclTopoAttr &topoAttr, bool isHeterogComm)
40 : {
41 521 : CHK_RET(Init(algoAttr, topoAttr, isHeterogComm));
42 :
43 : #ifndef OPEN_HCCL_TEST
44 : // 老流程使用,新流程的LLT不编译相关的代码
45 520 : pimpl_.reset((new (std::nothrow) hcclImpl(dispatcher_, notifyPool, netDevCtxMap, queueNotifyManager,
46 520 : workSpaceRes, cclBufferManager_, algoAttr_, topoAttr_,
47 1040 : algConfigurator_, topoInfoEx_)));
48 520 : CHK_SMART_PTR_NULL(pimpl_);
49 520 : CHK_RET(pimpl_->Init(isHeterogComm));
50 : #endif
51 520 : return HCCL_SUCCESS;
52 : }
53 :
54 521 : HcclResult HcclAlg::Init(HcclAlgoAttr &algoAttr, HcclTopoAttr &topoAttr, bool isHeterogComm)
55 : {
56 521 : algoAttr_ = algoAttr;
57 521 : topoAttr_ = topoAttr;
58 521 : algConfigurator_.reset(new (std::nothrow) AlgConfigurator(algoAttr_, topoAttr_));
59 521 : CHK_SMART_PTR_NULL(algConfigurator_);
60 521 : CHK_RET(algConfigurator_->Init(isHeterogComm));
61 :
62 520 : TopoType topoType = TopoType::TOPO_TYPE_RESERVED;
63 520 : algConfigurator_->GetTopoType(topoType);
64 520 : topoInfoEx_.reset(new (std::nothrow) TopoInfoExtractor(algoAttr_, topoAttr_, topoType));
65 520 : CHK_SMART_PTR_NULL(topoInfoEx_);
66 520 : CHK_RET(topoInfoEx_->Init(algoAttr_.commAlgoConfig));
67 :
68 520 : std::vector<std::vector<std::vector<u32>>> CommPlaneRanks;
69 520 : CHK_RET(topoInfoEx_->GetCommPlaneRanks(CommPlaneRanks));
70 :
71 520 : std::vector<bool> isBridgeVector;
72 520 : topoInfoEx_->GetIsBridgeVector(isBridgeVector);
73 :
74 520 : std::vector<std::vector<std::vector<u32>>> serverAndsuperPodToRank;
75 520 : CHK_RET(topoInfoEx_->GetRankVecInfo(serverAndsuperPodToRank));
76 :
77 520 : HcclTopoInfo topoInfo;
78 520 : CHK_RET(InitTopoInfo(topoInfo, topoAttr_));
79 :
80 520 : HcclAlgoInfo algoInfo;
81 520 : CHK_RET(InitAlgoInfo(algoInfo, algoAttr_));
82 :
83 520 : HcclExternalEnable externalEnable;
84 520 : CHK_RET(InitExternalEnable(externalEnable));
85 :
86 520 : topoMatcher_.reset((new (std::nothrow) TopoMatcher(CommPlaneRanks, isBridgeVector, topoInfo, algoInfo,
87 1040 : externalEnable, serverAndsuperPodToRank)));
88 520 : CHK_SMART_PTR_NULL(topoMatcher_);
89 :
90 520 : parallelTaskLoader_.reset(static_cast<ParallelTaskLoader *>(new (std::nothrow) ParallelTaskLoader(
91 520 : topoAttr_.deviceLogicId, dispatcher_)));
92 520 : CHK_SMART_PTR_NULL(parallelTaskLoader_);
93 :
94 : #ifndef OPEN_HCCL_TEST
95 520 : if (static_cast<s32>(topoAttr_.devicePhyId) != HOST_DEVICE_ID) {
96 520 : CHK_RET(DeviceMem::alloc(tinySendRecvMem_, TINY_MEMORY_SIZE));
97 : }
98 : #endif
99 520 : return HCCL_SUCCESS;
100 520 : }
101 :
102 83 : std::unique_ptr<CollAlgOperator> HcclAlg::GetAlgOperator(const HcclCMDType &opType, HcclWorkflowMode workflowMode)
103 : {
104 : (void) workflowMode;
105 83 : if (!topoMatcher_) {
106 0 : HCCL_ERROR("[HcclAlg][GetAlgOperator] topoMatcher ptr is null, get algorithm operator failed.");
107 0 : return nullptr;
108 : }
109 80 : std::unique_ptr<CollAlgOperator> operation = CollAlgOpRegistry::Instance().GetAlgOp(
110 78 : opType, algConfigurator_.get(), cclBufferManager_, dispatcher_, topoMatcher_);
111 81 : CHK_PRT_RET(operation == nullptr,
112 : HCCL_ERROR("[HcclAlg][GetAlgOperator] GetAlgOp return nullptr, opType[%d]", opType), nullptr);
113 80 : if (opType == HcclCMDType::HCCL_CMD_ALLTOALL || opType == HcclCMDType::HCCL_CMD_ALLTOALLV ||
114 73 : opType == HcclCMDType::HCCL_CMD_ALLTOALLVC) {
115 8 : AlltoAllOperator* alltoAllOperator = dynamic_cast<AlltoAllOperator *>(operation.get());
116 8 : alltoAllOperator->SetVirtualDispatcher(vDispatcher_);
117 8 : alltoAllOperator->SetParallelTaskLoader(parallelTaskLoader_.get());
118 : }
119 80 : HCCL_INFO("[AIG][GetAlgOperator] GetAlgOperator done");
120 84 : return operation;
121 80 : }
122 :
123 0 : HcclResult HcclAlg::GetAlltoAllStagedWorkSpaceMemSize(
124 : std::vector<SendRecvInfo> &allMeshAggregationSendRecvInfo, u64 &memSize)
125 : {
126 0 : AlltoAllOperator operation(algConfigurator_.get(), cclBufferManager_, dispatcher_, topoMatcher_);
127 0 : operation.SetVirtualDispatcher(vDispatcher_);
128 0 : operation.SetParallelTaskLoader(parallelTaskLoader_.get());
129 0 : return operation.GetAlltoAllStagedWorkSpaceMemSize(allMeshAggregationSendRecvInfo, memSize);
130 0 : }
131 :
132 0 : HcclResult HcclAlg::GetAllReduceScratchSize(const u64 count, const HcclDataType dataType, u64 &scratchSize)
133 : {
134 0 : AllReduceOperator operation(algConfigurator_.get(), cclBufferManager_, dispatcher_, topoMatcher_);
135 0 : return operation.GetAllReduceScratchSize(count, dataType, scratchSize);
136 0 : }
137 :
138 0 : HcclResult HcclAlg::GetTopoType(TopoType &topoType)
139 : {
140 0 : algConfigurator_->GetTopoType(topoType);
141 0 : return HCCL_SUCCESS;
142 : }
143 :
144 0 : HcclResult HcclAlg::SetAlgType(AlgType algType, HcclCMDType opType)
145 : {
146 0 : return algConfigurator_->SetAlgType(algType, opType);
147 : }
148 :
149 233 : HcclResult HcclAlg::GetAlgType(AlgType &algType, HcclCMDType opType)
150 : {
151 233 : return algConfigurator_->GetAlgType(algType, opType);
152 : }
153 :
154 0 : HcclResult HcclAlg::SupportDeterministicOptim(bool &isDeterministicOptim)
155 : {
156 0 : isDeterministicOptim = algConfigurator_->SupportDeterministicOptim();
157 0 : return HCCL_SUCCESS;
158 : }
159 :
160 82 : u8 HcclAlg::GetDeterministicConfig() const
161 : {
162 82 : return topoMatcher_->GetDeterministicConfig();
163 : }
164 :
165 234 : HcclResult HcclAlg::SetDeterministicConfig(const u8 deterministic)
166 : {
167 234 : CHK_RET(topoMatcher_->SetDeterministicConfig(deterministic));
168 234 : return HCCL_SUCCESS;
169 : }
170 :
171 234 : HcclResult HcclAlg::SetAivModeConfig(const bool aivMode)
172 : {
173 234 : CHK_RET(topoMatcher_->SetAivModeConfig(aivMode));
174 234 : return HCCL_SUCCESS;
175 : }
176 :
177 0 : bool HcclAlg::GetAicpuUnfoldConfig() const
178 : {
179 0 : return topoMatcher_->GetAicpuUnfoldConfig();
180 : }
181 :
182 93 : bool HcclAlg::GetAivModeConfig() const
183 : {
184 93 : return topoMatcher_->GetAivModeConfig();
185 : }
186 :
187 234 : HcclResult HcclAlg::SetAicpuUnfoldConfig(const bool aicpuUnfold)
188 : {
189 234 : CHK_RET(topoMatcher_->SetAicpuUnfoldConfig(aicpuUnfold));
190 234 : return HCCL_SUCCESS;
191 : }
192 :
193 234 : HcclResult HcclAlg::SetExecTimeOutConfig(const s32 execTimeOut)
194 : {
195 234 : CHK_RET(topoMatcher_->SetExecTimeOutConfig(execTimeOut));
196 234 : return HCCL_SUCCESS;
197 : }
198 :
199 234 : HcclResult HcclAlg::SetAlgoConfig(const std::map<HcclCMDType, std::vector<HcclAlgoType>>& algoMap)
200 : {
201 234 : CHK_RET(topoMatcher_->SetAlgoConfig(algoMap));
202 234 : return HCCL_SUCCESS;
203 : }
204 :
205 0 : HcclResult HcclAlg::GetRankVecInfo(std::vector<std::vector<std::vector<u32>>> &serverAndsuperPodToRank)
206 : {
207 0 : CHK_RET(topoInfoEx_->GetRankVecInfo(serverAndsuperPodToRank));
208 0 : return HCCL_SUCCESS;
209 : }
210 :
211 0 : HcclResult HcclAlg::GetIsBridgeVector(std::vector<bool> &isBridgeVector)
212 : {
213 0 : topoInfoEx_->GetIsBridgeVector(isBridgeVector);
214 0 : return HCCL_SUCCESS;
215 : }
216 0 : HcclResult HcclAlg::GetCommPlaneRanks(std::vector<std::vector<std::vector<u32>>> &commPlaneRanks)
217 : {
218 0 : CHK_RET(topoInfoEx_->GetCommPlaneRanks(commPlaneRanks));
219 0 : return HCCL_SUCCESS;
220 : }
221 :
222 0 : void HcclAlg::GetCommPlaneVector(std::vector<std::vector<std::vector<RankInfo>>> &commPlaneVector)
223 : {
224 0 : topoInfoEx_->GetCommPlaneVector(commPlaneVector);
225 0 : }
226 :
227 234 : HcclResult HcclAlg::SetOnlyAivModeConfig(const bool isOnlyAiv)
228 : {
229 234 : CHK_RET(topoMatcher_->SetOnlyAivModeConfig(isOnlyAiv));
230 234 : return HCCL_SUCCESS;
231 : }
232 :
233 0 : HcclResult HcclAlg::GetCommPlaneSubGroupVector(std::vector<std::vector<std::vector<std::vector<u32>>>> &commPlaneSubGroupVector)
234 : {
235 0 : topoMatcher_->GetCommPlaneSubGroupVector(commPlaneSubGroupVector);
236 0 : return HCCL_SUCCESS;
237 : }
238 :
239 0 : HcclResult HcclAlg::GetAHCAlgOption(std::map<AHCConcOpType, TemplateType> &ahcAlgOption)
240 : {
241 0 : topoMatcher_->GetAHCAlgOption(ahcAlgOption);
242 0 : return HCCL_SUCCESS;
243 : }
244 :
245 0 : HcclResult HcclAlg::GetIsUsedRdmaMap(std::unordered_map<u32, bool> &isUsedRdmaMap)
246 : {
247 0 : CHK_RET(topoInfoEx_->GetIsUsedRdmaMap(isUsedRdmaMap));
248 0 : return HCCL_SUCCESS;
249 : }
250 :
251 5 : HcclResult HcclAlg::GetTinyMem(DeviceMem &tinySendRecvMem)
252 : {
253 5 : tinySendRecvMem = tinySendRecvMem_;
254 5 : return HCCL_SUCCESS;
255 : }
256 :
257 520 : HcclResult HcclAlg::InitExternalEnable(HcclExternalEnable& externalEnable)
258 : {
259 520 : externalEnable.enableFfts = GetExternalInputHcclEnableFfts();
260 520 : externalEnable.deterministic = GetExternalInputHcclDeterministicV2();
261 520 : externalEnable.intraRoceSwitch = GetExternalInputIntraRoceSwitch();
262 520 : externalEnable.dumpDebug = GetExternalInputHcclDumpDebug();
263 520 : externalEnable.aivMode = GetExternalInputHcclAivMode();
264 520 : externalEnable.aicpuUnfold = GetExternalInputHcclAicpuUnfold();
265 520 : externalEnable.execTimeOut = GetInternalExecTimeOut();
266 520 : return HCCL_SUCCESS;
267 : }
268 :
269 520 : HcclResult HcclAlg::InitTopoInfo(HcclTopoInfo& topoInfo, HcclTopoAttr &topoAttr)
270 : {
271 520 : topoInfo.userRank = topoAttr.userRank;
272 520 : topoInfo.userRankSize = topoAttr.userRankSize;
273 520 : topoInfo.devicePhyId = topoAttr.devicePhyId;
274 520 : topoInfo.deviceLogicId = topoAttr.deviceLogicId;
275 520 : topoInfo.nicList = topoAttr.nicList;
276 520 : topoInfo.isSingleMeshAggregation = topoAttr.isSingleMeshAggregation;
277 520 : topoInfo.deviceNumPerAggregation = topoAttr.deviceNumPerAggregation;
278 520 : topoInfo.superPodNum = topoAttr.superPodNum;
279 520 : topoInfo.deviceType = topoAttr.deviceType;
280 520 : topoInfo.serverNum = topoAttr.serverNum;
281 520 : topoInfo.meshAggregationRankSize = topoAttr.meshAggregationRankSize;
282 520 : topoInfo.multiModuleDiffDeviceNumMode = topoAttr.multiModuleDiffDeviceNumMode;
283 520 : topoInfo.multiSuperPodDiffServerNumMode = topoAttr.multiSuperPodDiffServerNumMode;
284 520 : topoInfo.multiSuperPodDiffDeviceNumMode = topoAttr.multiSuperPodDiffDeviceNumMode;
285 520 : topoInfo.isDiffDeviceType = topoAttr.isDiffDeviceType;
286 520 : topoInfo.gcdDeviceNumPerAggregation = topoAttr.gcdDeviceNumPerAggregation;
287 520 : topoInfo.pairLinkCounter = topoAttr.pairLinkCounter;
288 520 : topoInfo.isDiffDeviceModule = topoAttr.isDiffDeviceModule;
289 520 : topoInfo.realUserRank = topoAttr.realUserRank;
290 520 : topoInfo.moduleNum = topoAttr.moduleNum;
291 520 : topoInfo.useSuperPodMode = topoAttr.useSuperPodMode;
292 520 : topoInfo.isARSDoubleRing = topoAttr.isARSDoubleRing;
293 :
294 520 : topoInfoEx_->GetCommPlaneSubGroupVector(topoInfo.CommPlaneSubGroupVector);
295 520 : topoInfoEx_->GetAHCAlgOption(topoInfo.ahcAlgOption);
296 :
297 520 : algConfigurator_->GetTopoType(topoInfo.topoType);
298 520 : topoInfo.is310P3Common = Is310P3Common(algoAttr_.isHaveCpuRank, topoAttr_.deviceType);
299 520 : std::unordered_map<u32, bool> isUsedRdmaMap;
300 520 : CHK_RET(topoInfoEx_->GetIsUsedRdmaMap(isUsedRdmaMap));
301 520 : topoInfo.isUsedRdmaMap = isUsedRdmaMap;
302 520 : return HCCL_SUCCESS;
303 520 : }
304 :
305 520 : HcclResult HcclAlg::InitAlgoInfo(HcclAlgoInfo& algoInfo, HcclAlgoAttr &algoAttr)
306 : {
307 520 : algoInfo.identifier = algoAttr.identifier;
308 520 : algoInfo.inlineReduceSwitchOn = algoAttr.inlineReduceSwitchOn;
309 520 : algoInfo.isUsedRdmaLevel0 = algoAttr.isUsedRdmaLevel0;
310 520 : algoInfo.isSupportAtomicWrite = false; // 涉及到任务编排,当前不能只判断本机驱动版本是否支持
311 520 : return HCCL_SUCCESS;
312 : }
313 :
314 : #ifndef OPEN_HCCL_TEST
315 : // 上层保证,以下方法在初始化成功后才会调用,所以未对pimpl_进行保护判断
316 0 : HcclResult HcclAlg::ReleaseCommInfos()
317 : {
318 0 : return pimpl_->ReleaseCommInfos();
319 : }
320 :
321 16 : HcclResult HcclAlg::ClearOpResource(const std::string &tag)
322 : {
323 16 : return pimpl_->ClearOpResource(tag);
324 : }
325 :
326 1 : HcclResult HcclAlg::CreateMutiStreamRes(const std::string &tag, Stream &stream, level1StreamInfo_t &streamInfo,
327 : AlgType algType, bool isAicpuModeEn)
328 : {
329 1 : return pimpl_->CreateMutiStreamRes(tag, stream, streamInfo, algType, isAicpuModeEn);
330 : }
331 :
332 1 : HcclResult HcclAlg::CreateComm(const std::string &tag, DeviceMem &inputMem, DeviceMem &outputMem, AlgType algType,
333 : std::unique_ptr<CommInfo> &commInfo, u32 root, bool isP2p, bool isAicpuModeEn)
334 : {
335 1 : return pimpl_->CreateComm(tag, inputMem, outputMem, algType, commInfo, root, isP2p, isAicpuModeEn);
336 : }
337 :
338 0 : HcclResult HcclAlg::CreateComm(
339 : const std::string &tag, DeviceMem &inputMem, DeviceMem &outputMem, AlgType algType, u32 root, bool isP2p)
340 : {
341 0 : return pimpl_->CreateComm(tag, inputMem, outputMem, algType, root, isP2p);
342 : }
343 :
344 0 : void HcclAlg::Break()
345 : {
346 0 : pimpl_->Break();
347 0 : }
348 :
349 144 : HcclResult HcclAlg::SetHDCModeInfo(
350 : std::unordered_map<std::string, std::map<u32, HcclIpAddress>> &rankDevicePhyIdNicInfoMap,
351 : std::vector<u32> &ranksPort, std::vector<u32> &vnicRanksPort, bool isSetHDCModeInfo, bool isUseRankPort)
352 : {
353 144 : pimpl_->SetHDCModeInfo(rankDevicePhyIdNicInfoMap, ranksPort, vnicRanksPort, isSetHDCModeInfo, isUseRankPort);
354 141 : return HCCL_SUCCESS;
355 : }
356 : #endif
357 : }
|