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 "ins_v2_all_to_all_sole_executor.h"
12 : #include "log.h"
13 : #include "ins_coll_alg_registry.h"
14 : #include "topo_match_mesh.h"
15 : #include "topo_match_concurr_mesh.h"
16 : #include "ins_temp_all_to_all_mesh_2D.h"
17 : #ifndef CCL_KERNEL_AICPU
18 : #include "aiv_temp_all_to_all_mesh_1D.h"
19 : #include "ccu_temp_all_to_all_mesh_1D_2Die.h"
20 : #endif
21 :
22 : namespace Hccl {
23 : constexpr u64 MAX_OFFLOAD_SCRATCH_SIZE = 200 * 1024 * 1024; // 200M
24 :
25 : template <typename AlgTopoMatch, typename InsAlgTemplate>
26 0 : InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InsV2AlltoAllSoleExecutor() : InsCollAlgBase()
27 0 : {}
28 :
29 : template <typename AlgTopoMatch, typename InsAlgTemplate>
30 0 : InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::~InsV2AlltoAllSoleExecutor()
31 0 : {}
32 :
33 : template <typename AlgTopoMatch, typename InsAlgTemplate>
34 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitParams(
35 : const CollAlgOperator& op, const CollAlgParams& params)
36 : {
37 0 : op_ = op;
38 0 : opMode_ = params.opMode;
39 0 : maxTmpMemSize_ = params.maxTmpMemSize;
40 0 : CHK_PRT_RET(
41 : (maxTmpMemSize_ == 0), HCCL_ERROR("[InitParams] maxTmpMemSize equals to zero."), HcclResult::HCCL_E_PARA);
42 :
43 0 : CHK_PRT_RET(
44 : (op.opType != OpType::ALLTOALL), HCCL_ERROR("[InitParams] opType is invalid."), HcclResult::HCCL_E_PARA);
45 :
46 0 : dataType_ = op.all2AllDataDes.sendType;
47 0 : dataCount_ = op.all2AllDataDes.sendCount; // 本卡数据量/rankSize
48 0 : outputDataType_ = op.all2AllDataDes.sendType;
49 0 : dataTypeSize_ = DataTypeSizeGet(dataType_);
50 0 : dataSize_ = dataCount_ * dataTypeSize_;
51 :
52 0 : HCCL_DEBUG("dataType_ is [%u], dataCount_ is [%u]", dataType_, dataCount_);
53 :
54 0 : CHK_PRT_RET(
55 : InitOpInfo(op, opType_, redOp_, root_), HCCL_ERROR("[InitParams] unable to init OpInfo."),
56 : HcclResult::HCCL_E_PARA);
57 0 : return HcclResult::HCCL_SUCCESS;
58 : }
59 :
60 : template <typename AlgTopoMatch, typename InsAlgTemplate>
61 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const RankGraph* rankGraph)
62 : {
63 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
64 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
65 0 : return HcclResult::HCCL_SUCCESS;
66 0 : }
67 :
68 : template <typename AlgTopoMatch, typename InsAlgTemplate>
69 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const AlgTopoInfo& topoInfo)
70 : {
71 0 : CHK_PRT_RET(
72 : (topoInfo.vTopo.empty()), HCCL_ERROR("[InsV2AlltoAllSoleExecutor][InitCommInfo], topoInfo.vTopo is empty"),
73 : HcclResult::HCCL_E_PARA);
74 0 : CHK_PRT_RET(
75 : (topoInfo.virtRankMap.empty()),
76 : HCCL_ERROR("[InsV2AlltoAllSoleExecutor][InitCommInfo], topoInfo.virtRankMap is empty"),
77 : HcclResult::HCCL_E_PARA);
78 0 : CHK_PRT_RET(
79 : (topoInfo.virtRanks.empty()),
80 : HCCL_ERROR("[InsV2AlltoAllSoleExecutor][InitCommInfo], topoInfo.virtRanks is empty"), HcclResult::HCCL_E_PARA);
81 :
82 0 : vTopo_ = topoInfo.vTopo[0]; // 本通信域内的通信平面
83 0 : virtRankMap_ = topoInfo.virtRankMap[0]; // 本通信域内的 rank 映射表
84 0 : virtRanks_ = topoInfo.virtRanks[0]; // 本通信域内的 rank 集合
85 0 : return HcclResult::HCCL_SUCCESS;
86 : }
87 :
88 : template <typename AlgTopoMatch, typename InsAlgTemplate>
89 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CreateTemplates(
90 : std::shared_ptr<InsAlgTemplate>& algTemplatePtr)
91 : {
92 0 : HCCL_DEBUG("[InsV2AlltoAllSoleExecutor][CreateTemplates]");
93 0 : algTemplatePtr = std::make_shared<InsAlgTemplate>(myRank_, rankSize_, vTopo_, virtRankMap_);
94 0 : CHK_PTR_NULL(algTemplatePtr); // 检查是否成功分配内存
95 0 : algTemplatePtr->SetDmaMode(dmaMode_);
96 0 : algTemplatePtr->SetDataType(dataType_);
97 0 : algTemplatePtr->SetCollOp(op_);
98 0 : return HcclResult::HCCL_SUCCESS;
99 : }
100 :
101 : template <typename AlgTopoMatch, typename InsAlgTemplate>
102 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
103 : const RankGraph* rankGraph, std::shared_ptr<InsAlgTemplate>& algTemplate, AlgTempResReq& tempResReq) const
104 : {
105 0 : if (enableDetour_) {
106 0 : CHK_RET(algTemplate->CalcResDetour(rankGraph, tempResReq));
107 : } else {
108 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
109 : }
110 :
111 0 : return HcclResult::HCCL_SUCCESS;
112 : }
113 :
114 : template <typename AlgTopoMatch, typename InsAlgTemplate>
115 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
116 : ConnectedLinkMgr* linkMgr, std::shared_ptr<InsAlgTemplate>& algTemplate, AlgTempResReq& tempResReq) const
117 : {
118 0 : if (enableDetour_) {
119 0 : CHK_RET(algTemplate->CalcResDetour(linkMgr, tempResReq));
120 : } else {
121 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
122 : }
123 0 : return HcclResult::HCCL_SUCCESS;
124 : }
125 :
126 : template <typename AlgTopoMatch, typename InsAlgTemplate>
127 : HcclResult
128 0 : InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalNumBlocks(u32& numBlocks, u64 dataSize, u32 numBlocksLimit)
129 : {
130 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
131 0 : CHK_RET(CreateTemplates(algTemplate));
132 0 : CHK_RET(algTemplate->CalNumBlocks(numBlocks, dataSize, numBlocksLimit));
133 0 : return HcclResult::HCCL_SUCCESS;
134 0 : }
135 :
136 : // HOST 侧算法入口
137 : template <typename AlgTopoMatch, typename InsAlgTemplate>
138 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(
139 : const RankGraph* rankGraph, const CollAlgOperator& op, const CollAlgParams& params, InsQuePtr insQue)
140 : {
141 0 : HCCL_DEBUG("[InsV2AlltoAllSoleExecutor][Orchestrate] Orchestrate HOST Start");
142 0 : CHK_RET(Init(op, params, insQue));
143 0 : CHK_RET(InitCommInfo(rankGraph));
144 :
145 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
146 0 : CHK_RET(CreateTemplates(algTemplate));
147 :
148 0 : AlgTempResReq tempResReq;
149 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
150 :
151 0 : HCCL_DEBUG(
152 : "[InsV2AlltoAllSoleExecutor][Orchestrate] Rank[%d], template [%s], requiredQue Num [%u].", myRank_,
153 : algTemplate->Describe().c_str(), tempResReq.queNum);
154 0 : CHK_RET(InitQueue(tempResReq.queNum, tempInsQue_));
155 0 : CHK_RET(PrepResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, tempResLinks_));
156 :
157 0 : CHK_RET(OrchestrateLoop(algTemplate));
158 0 : HCCL_DEBUG("[InsV2AlltoAllSoleExecutor][Orchestrate] Orchestrate HOST End");
159 0 : return HcclResult::HCCL_SUCCESS;
160 0 : }
161 :
162 : // AICPU 侧算法入口
163 : template <typename AlgTopoMatch, typename InsAlgTemplate>
164 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(
165 : const AlgTopoInfo& topoInfo, const CollAlgOperator& op, const CollAlgParams& params, ConnectedLinkMgr* linkMgr,
166 : InsQuePtr insQue)
167 : {
168 0 : CHK_RET(Init(op, params, insQue));
169 0 : CHK_RET(InitCommInfo(topoInfo));
170 :
171 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
172 0 : CHK_RET(CreateTemplates(algTemplate));
173 :
174 0 : AlgTempResReq tempResReq;
175 0 : CHK_RET(GetTemplateResRequest(linkMgr, algTemplate, tempResReq));
176 :
177 0 : CHK_RET(InitQueue(tempResReq.queNum, tempInsQue_));
178 0 : CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
179 :
180 0 : CHK_RET(OrchestrateLoop(algTemplate));
181 0 : return HcclResult::HCCL_SUCCESS;
182 0 : }
183 :
184 : // 切分数据并调用 template
185 : template <typename AlgTopoMatch, typename InsAlgTemplate>
186 : HcclResult
187 0 : InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::OrchestrateLoop(std::shared_ptr<InsAlgTemplate> algTemplate)
188 : {
189 0 : u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
190 0 : HCCL_INFO("[InsV2AlltoAllSoleExecutor][Orchestrate] Start, template[%s]", algTemplate->Describe().c_str());
191 0 : dataSize_ = dataCount_ * dataSizePerVolume;
192 :
193 0 : TemplateDataParams tempAlgParams;
194 0 : tempAlgParams.repeatNum = 1; // 不需要重复
195 0 : tempAlgParams.inputRepeatStride = 0;
196 0 : tempAlgParams.outputRepeatStride = 0;
197 0 : tempAlgParams.buffInfo.outBuffType = BufferType::OUTPUT;
198 0 : tempAlgParams.buffInfo.scratBuffType = BufferType::SCRATCH;
199 0 : tempAlgParams.buffInfo.inBuffType = BufferType::INPUT;
200 :
201 0 : TempFuncs tempFuncs;
202 0 : tempFuncs.opMode = opMode_;
203 0 : tempFuncs.enableCounterNotify = IsEnableCounterNotify();
204 0 : tempFuncs.isBottom = true;
205 0 : tempFuncs.isForepart = true;
206 :
207 0 : u64 maxDataSizePerLoop = 0;
208 0 : u64 transportBoundDataSize_ = UB_MAX_DATA_SIZE;
209 0 : u32 templateScratchMultiplier = algTemplate->CalcScratchMultiple(BufferType::INPUT, BufferType::OUTPUT);
210 0 : if (templateScratchMultiplier != 0) {
211 0 : u64 scratchBoundDataSize = maxTmpMemSize_ / templateScratchMultiplier;
212 0 : maxDataSizePerLoop = std::min(transportBoundDataSize_, scratchBoundDataSize);
213 : } else {
214 0 : maxDataSizePerLoop = transportBoundDataSize_;
215 : }
216 :
217 : // 先将cclBuffer切块,看每一块大小
218 0 : u64 scratchDataCountPerLoopPerRank = maxDataSizePerLoop / dataTypeSize_ / rankSize_;
219 0 : HCCL_DEBUG(
220 : "[InsV2AlltoAllSoleExecutor][OrchestrateLoop] maxTmpMemSize_[%llu], templateScratchMultiplier[%llu], "
221 : "maxDataSizePerLoop[%llu], "
222 : "transportBoundDataSize_[%llu], scratchDataCountPerLoopPerRank[%llu]",
223 : maxTmpMemSize_, templateScratchMultiplier, maxDataSizePerLoop, transportBoundDataSize_,
224 : scratchDataCountPerLoopPerRank);
225 0 : CHK_PRT_RET(
226 : scratchDataCountPerLoopPerRank == 0,
227 : HCCL_ERROR("[InsV2AlltoAllSoleExecutor][OrchestrateLoop] scratchDataCountPerLoopPerRank is 0"),
228 : HCCL_E_INTERNAL);
229 :
230 : // 将usrIn数据切块,看每一块大小,这里要保障是能整除的
231 0 : u64 dataCountPerRank = dataCount_;
232 0 : u64 allToAllProcessedDataCount = 0;
233 0 : u64 loopTimes = dataCountPerRank / scratchDataCountPerLoopPerRank
234 0 : + static_cast<u64>(dataCountPerRank % scratchDataCountPerLoopPerRank != 0);
235 0 : for (u64 loop = 0; loop < loopTimes; loop++) {
236 0 : u64 currDataCount
237 0 : = (loop == loopTimes - 1) ? dataCountPerRank - allToAllProcessedDataCount : scratchDataCountPerLoopPerRank;
238 :
239 0 : tempAlgParams.buffInfo.inBuffBaseOff = allToAllProcessedDataCount * dataTypeSize_;
240 0 : tempAlgParams.buffInfo.outBuffBaseOff = allToAllProcessedDataCount * dataTypeSize_;
241 0 : tempAlgParams.buffInfo.scratchBuffBaseOff = 0;
242 0 : tempAlgParams.sliceSize = currDataCount * dataTypeSize_; // 这里就是 cclbuf 一块数据的大小
243 0 : tempAlgParams.inputSliceStride = dataCountPerRank * dataTypeSize_;
244 0 : tempAlgParams.outputSliceStride = dataCountPerRank * dataTypeSize_;
245 :
246 0 : CHK_RET(algTemplate->GenExtIns(tempFuncs, tempAlgParams, tempResLinks_, tempInsQue_));
247 0 : allToAllProcessedDataCount += currDataCount;
248 : }
249 :
250 0 : HCCL_INFO("[InsV2AlltoAllSoleExecutor][Orchestrate] End, template[%s]", algTemplate->Describe().c_str());
251 :
252 0 : return HcclResult::HCCL_SUCCESS;
253 0 : }
254 :
255 : template <typename AlgTopoMatch, typename InsAlgTemplate>
256 : HcclResult
257 0 : InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcRes(const RankGraph* rankGraph, CollAlgResReq& algResReq)
258 : {
259 : // Topo Match
260 0 : CHK_RET(InitCommInfo(rankGraph));
261 :
262 : // instantiate a template
263 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
264 :
265 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
266 0 : CHK_RET(CreateTemplates(algTemplate));
267 :
268 0 : AlgTempResReq tempResReq;
269 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
270 :
271 0 : CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
272 0 : algResReq.primQueueNum = tempResReq.streamNum;
273 0 : algResReq.queueNotifys = tempResReq.queNotifys;
274 0 : algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
275 0 : algResReq.localBcastPostCntNotify = tempResReq.localBcastPostCntNotify;
276 0 : algResReq.localWaitGroupCntNotify = tempResReq.localWaitGroupCntNotify;
277 0 : CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
278 :
279 0 : return HcclResult::HCCL_SUCCESS;
280 0 : }
281 :
282 : template <typename AlgTopoMatch, typename InsAlgTemplate>
283 0 : HcclResult InsV2AlltoAllSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcResOffload(
284 : const RankGraph* rankGraph, const u64& dataSize, CollOffloadOpResReq& resReq)
285 : {
286 : (void)dataSize;
287 : // Topo Match
288 0 : CHK_RET(InitCommInfo(rankGraph));
289 :
290 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
291 0 : CHK_RET(CreateTemplates(algTemplate));
292 :
293 0 : AlgTempResReq tempResReq;
294 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
295 0 : resReq.requiredScratchMemSize = MAX_OFFLOAD_SCRATCH_SIZE; // 最大 200M
296 0 : resReq.requiredSubQueNum = tempResReq.streamNum - 1;
297 :
298 0 : return HcclResult::HCCL_SUCCESS;
299 0 : }
300 :
301 : INS_REGISTER_IMPL_BY_TEMP(
302 : OpType::ALLTOALL, InsAlltoAllMesh2D, InsV2AlltoAllSoleExecutor, TopoMatchConcurrMesh, InsTempAlltoAllMesh2D);
303 : #ifndef CCL_KERNEL_AICPU
304 : INS_REGISTER_IMPL_BY_TEMP(
305 : OpType::ALLTOALL, AivAlltoAllMesh1D, InsV2AlltoAllSoleExecutor, TopoMatchMesh, AivTempAlltoAllMesh1D);
306 : INS_REGISTER_IMPL_BY_TEMP(
307 : OpType::ALLTOALL, CcuAlltoAllMesh1D2Die, InsV2AlltoAllSoleExecutor, TopoMatchMesh, CcuTempAllToAllMesh1D2Die);
308 : #endif
309 : } // namespace Hccl
|