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 "log.h"
12 : #include "ins_coll_alg_registry.h"
13 : #include "ins_all_reduce_sole_executor.h"
14 : #ifndef CCL_KERNEL_AICPU
15 : #include "ccu_temp_all_reduce_mesh_1D.h"
16 : #include "ccu_temp_all_reduce_mesh_1D_one_shot.h"
17 : #include "ccu_temp_all_reduce_mesh_2D_one_shot.h"
18 : #include "ccu_temp_all_reduce_mesh_2D_two_shot.h"
19 : #include "ccu_temp_all_reduce_mesh_detour_1D.h"
20 : #include "ccu_temp_all_reduce_mesh_2D_two_shot_mem2mem.h"
21 : #endif
22 : #include "topo_match_mesh.h"
23 : #include "topo_match_concurr_mesh.h"
24 :
25 : namespace Hccl {
26 : template <typename AlgTopoMatch, typename InsAlgTemplate>
27 0 : InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InsAllReduceSoleExecutor() : InsCollAlgBase()
28 : {
29 0 : }
30 :
31 : template <typename AlgTopoMatch, typename InsAlgTemplate>
32 0 : InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::~InsAllReduceSoleExecutor()
33 : {
34 0 : }
35 :
36 : template <typename AlgTopoMatch, typename InsAlgTemplate>
37 0 : HcclResult InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcResOffload(const RankGraph *rankGraph,
38 : const u64 &dataSize,
39 : CollOffloadOpResReq &resReq)
40 : {
41 : (void)dataSize;
42 0 : constexpr u64 needScratchSize = 200 * 1024 * 1024; // 需要申请200MB临时内存
43 0 : resReq.requiredScratchMemSize = needScratchSize;
44 :
45 : // Topo Match
46 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
47 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
48 :
49 : // instantiate a template
50 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
51 0 : tempAlg.InitReduceInfo(redOp_, dataType_);
52 :
53 : // calculate required insQues and prepare queue
54 0 : AlgTempResReq tempResReq;
55 0 : if (enableDetour_) {
56 0 : HCCL_DEBUG("[CalcResOffload] Rank[%d], CalcRes with detouring enabled.", myRank_);
57 0 : CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
58 : } else {
59 0 : HCCL_DEBUG("[CalcResOffload] Rank[%d], CalcRes with detouring disabled.", myRank_);
60 0 : CHK_RET(tempAlg.CalcRes(tempResReq));
61 : }
62 :
63 0 : resReq.requiredSubQueNum = tempResReq.streamNum - 1;
64 :
65 0 : return HcclResult::HCCL_SUCCESS;
66 0 : }
67 :
68 : // 算子执行aicpu接口
69 : template <typename AlgTopoMatch, typename InsAlgTemplate>
70 0 : HcclResult InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(const AlgTopoInfo &topoInfo,
71 : const CollAlgOperator &op,
72 : const CollAlgParams ¶ms,
73 : ConnectedLinkMgr *linkMgr,
74 : InsQuePtr insQue)
75 : {
76 0 : HCCL_INFO("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Host Orchestrate begins.");
77 : // init and check params
78 0 : CHK_RET(Init(op, params, insQue));
79 :
80 : // soleEsecutor 只支持单层拓扑, 所以只取第 0 级通信域的信息
81 0 : vTopo_ = topoInfo.vTopo[0]; // 本通信域内的通信平面
82 0 : virtRankMap_ = topoInfo.virtRankMap[0]; // 本通信域内的 rank 映射表
83 0 : virtRanks_ = topoInfo.virtRanks[0]; // 本通信域内的 rank 集合
84 0 : dataTypeSize_ = DataTypeSizeGet(dataType_);
85 0 : dataSize_ = dataCount_ * dataTypeSize_;
86 0 : CHK_PRT_RET(dataTypeSize_ == 0,
87 : HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid dataTypeSize_ [%u] for AICPU.", myRank_, dataTypeSize_),
88 : HcclResult::HCCL_E_INTERNAL);
89 :
90 : // 实例化算法模板类
91 0 : HCCL_DEBUG("[InsAllReduceSoleExecutor] Rank[%d], Init insAlgTemplate with rankSize [%u] and dmaMode [%s] for AICPU.",
92 : myRank_, rankSize_, dmaMode_.Describe().c_str());
93 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
94 0 : tempAlg.SetDmaMode(dmaMode_);
95 0 : tempAlg.InitReduceInfo(redOp_, dataType_);
96 0 : tempAlg.SetCollOp(op); // CCU template需要传递op信息
97 :
98 : // 计算算法模板所需资源
99 0 : AlgTempResReq tempResReq;
100 0 : if (enableDetour_) {
101 0 : HCCL_DEBUG("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
102 0 : CHK_RET(tempAlg.CalcResDetour(linkMgr, tempResReq));
103 : } else {
104 0 : HCCL_DEBUG("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
105 0 : CHK_RET(tempAlg.CalcRes(tempResReq));
106 : }
107 :
108 : // 申请算法模板所需资源
109 0 : CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
110 0 : CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
111 :
112 0 : ParamPool paramPool = {op, params};
113 0 : HCCL_DEBUG("[InsAllReduceSoleExecutor] Rank[%d], Generating Instruction Queues for AICPU.",
114 : myRank_);
115 0 : CHK_RET(OrchestrateCommon(tempAlg, paramPool));
116 :
117 0 : return HcclResult::HCCL_SUCCESS;
118 0 : }
119 :
120 : template <typename AlgTopoMatch, typename InsAlgTemplate>
121 0 : HcclResult InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcRes(const RankGraph *rankGraph,
122 : CollAlgResReq &algResReq)
123 : {
124 : // Topo Match
125 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
126 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
127 0 : algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
128 :
129 : // instantiate a template
130 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
131 0 : tempAlg.InitReduceInfo(redOp_, dataType_);
132 :
133 : // calculate required insQues and prepare queue
134 0 : AlgTempResReq tempResReq;
135 0 : if (enableDetour_) {
136 0 : HCCL_DEBUG("[CalcRes] Rank[%d], CalcRes with detouring enabled.", myRank_);
137 0 : CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
138 : } else {
139 0 : HCCL_DEBUG("[CalcRes] Rank[%d], CalcRes with detouring disabled.", myRank_);
140 0 : CHK_RET(tempAlg.CalcRes(tempResReq));
141 : }
142 0 : CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
143 0 : algResReq.primQueueNum= tempResReq.streamNum;
144 0 : algResReq.queueNotifys = tempResReq.queNotifys;
145 0 : algResReq.localWaitGroupCntNotify = tempResReq.localWaitGroupCntNotify;
146 0 : algResReq.localBcastPostCntNotify = tempResReq.localBcastPostCntNotify;
147 0 : HCCL_DEBUG("[CalcRes] Rank[%d], requiredQueNum [%u].", myRank_, algResReq.primQueueNum);
148 0 : CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
149 :
150 0 : return HcclResult::HCCL_SUCCESS;
151 0 : }
152 :
153 : // dataSize_ as input
154 : template <typename AlgTopoMatch, typename InsAlgTemplate>
155 0 : HcclResult InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(const RankGraph *rankGraph,
156 : const CollAlgOperator &op,
157 : const CollAlgParams ¶ms,
158 : InsQuePtr insQue)
159 : {
160 0 : HCCL_INFO("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Host Orchestrate begins.");
161 : // init and check params
162 0 : CHK_RET(Init(op, params, insQue));
163 :
164 : // Topo Match
165 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
166 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
167 0 : HCCL_DEBUG("[InsCollAlgFactory] Rank[%d], [%s].", myRank_, topoMatch.Describe().c_str());
168 0 : dataTypeSize_ = DataTypeSizeGet(dataType_);
169 0 : dataSize_ = dataCount_ * dataTypeSize_;
170 0 : CHK_PRT_RET(dataTypeSize_ == 0,
171 : HCCL_ERROR("Allreduce_[CollAlgFactory] Rank [%d], Invalid dataTypeSize_ [%u].", myRank_, dataTypeSize_),
172 : HcclResult::HCCL_E_INTERNAL);
173 :
174 : // 实例化算法模板类
175 0 : HCCL_DEBUG("[InsAllReduceSoleExecutor] Rank[%d], Init insAlgTemplate with rankSize [%u] and dmaMode [%s].",
176 : myRank_, rankSize_, dmaMode_.Describe().c_str());
177 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
178 0 : tempAlg.SetDmaMode(dmaMode_);
179 0 : tempAlg.InitReduceInfo(redOp_, dataType_);
180 0 : tempAlg.SetCollOp(op); // CCU template需要传递op信息
181 :
182 : // 计算算法模板所需资源
183 0 : AlgTempResReq tempResReq;
184 0 : if (enableDetour_) {
185 0 : HCCL_DEBUG("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
186 0 : CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
187 : } else {
188 0 : HCCL_DEBUG("[InsCollAlgFactory] [InsAllReduceSoleExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
189 0 : CHK_RET(tempAlg.CalcRes(tempResReq));
190 : }
191 : // 申请算法模板所需资源
192 0 : CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
193 0 : CHK_RET(PrepResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, tempResLinks_));
194 :
195 0 : ParamPool paramPool = {op, params};
196 0 : HCCL_DEBUG("[InsCollAlgFactory] Rank[%d], Generating Instruction Queues for HOST.", myRank_);
197 0 : CHK_RET(tempAlg.GetScratchBufferInfo(maxTmpMemSize_, dataType_));
198 0 : CHK_RET(OrchestrateCommon(tempAlg, paramPool));
199 :
200 0 : return HcclResult::HCCL_SUCCESS;
201 0 : }
202 :
203 : template <typename AlgTopoMatch, typename InsAlgTemplate>
204 0 : HcclResult InsAllReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::OrchestrateCommon(InsAlgTemplate &tempAlg,
205 : const ParamPool ¶mPool)
206 : {
207 : (void)paramPool;
208 0 : BuffInfo buffInfo;
209 0 : buffInfo.scratBuffType = BufferType::SCRATCH;
210 0 : buffInfo.inBuffBaseOff = 0;
211 0 : buffInfo.outBuffBaseOff = 0;
212 0 : buffInfo.scratchBuffBaseOff = 0;
213 : // 基本参数配置
214 0 : AllignInfo allignInfo = {enableAllign_, allignSize_, dataType_};
215 0 : TempFuncs tempFuncs;
216 0 : tempFuncs.opMode = opMode_;
217 0 : tempFuncs.enableCounterNotify = IsEnableCounterNotify();
218 0 : if (opMode_ == OpMode::OFFLOAD) {
219 0 : buffInfo.inBuffType = BufferType::INPUT;
220 0 : buffInfo.outBuffType = BufferType::OUTPUT;
221 : } else {
222 0 : tempFuncs.isForepart = true; // Usr Buff to CCL Buff required
223 0 : tempFuncs.isBottom = true; // CCL Buff to Usr Buff required
224 0 : buffInfo.inBuffType = BufferType::SCRATCH;
225 0 : buffInfo.outBuffType = BufferType::SCRATCH;
226 : }
227 :
228 0 : u64 outputCount = dataCount_;
229 : // 计算出一轮中最多能输出多少数据
230 0 : u64 maxLoopOutputCount = 0;
231 0 : if (opMode_ == OpMode::OFFLOAD) {
232 0 : maxLoopOutputCount = static_cast<u64>(UB_MAX_DATA_SIZE) / dataTypeSize_;
233 : } else {
234 0 : maxLoopOutputCount = maxTmpMemSize_ / (rankSize_ * dataTypeSize_);
235 : }
236 0 : CHK_PRT_RET(maxLoopOutputCount == 0,
237 : HCCL_ERROR("[OrchestrateCommon] maxLoopOutputCount is zero, dataType[%s]", dataType_.Describe().c_str()),
238 : HcclResult::HCCL_E_PARA);
239 0 : u64 loopTimes = outputCount / maxLoopOutputCount + static_cast<u64>(outputCount % maxLoopOutputCount != 0);
240 :
241 0 : for (u32 loop = 0; loop < loopTimes; loop++) {
242 : // loopOffsetCount 是已经处理过的数据量
243 0 : u64 loopOffsetCount = loop * maxLoopOutputCount;
244 0 : u64 loopOffsetSize = loopOffsetCount * dataTypeSize_;
245 :
246 : // 本轮需要处理的数据量
247 0 : u64 currOutputCount = (loop == (loopTimes - 1)) ? outputCount - loopOffsetCount : maxLoopOutputCount;
248 0 : u64 currDataSize = currOutputCount * dataTypeSize_;
249 :
250 0 : UsrData usrData;
251 : // 将整块数据一次性从 UserIn 搬运到 CclIn 上
252 0 : usrData.usrInSlices.emplace_back(BufferType::INPUT, loopOffsetSize, currDataSize);
253 0 : usrData.scratchInSlices.emplace_back(BufferType::SCRATCH, 0, currDataSize);
254 0 : if (opMode_ == OpMode::OPBASE) {
255 : // 将整块数据一次性从 CclOut 搬运到 UserOut 上
256 0 : usrData.scratchOutSlices.emplace_back(BufferType::SCRATCH, 0, currDataSize);
257 : }
258 0 : usrData.usrOutSlices.emplace_back(BufferType::OUTPUT, loopOffsetSize, currDataSize);
259 0 : tempFuncs.usrData = usrData;
260 :
261 0 : RankSliceInfo sliceInfoVec;
262 0 : CHK_RET(tempAlg.CalcSliceInfo(allignInfo, currDataSize, sliceInfoVec));
263 0 : CHK_RET(tempAlg.Run(tempFuncs, sliceInfoVec, buffInfo, tempResLinks_, requiredQue_));
264 : }
265 0 : return HcclResult::HCCL_SUCCESS;
266 0 : }
267 :
268 : // === CCU 算法注册 ===
269 : #ifndef CCL_KERNEL_AICPU
270 : INS_REGISTER_IMPL_BY_TEMP(
271 : OpType::ALLREDUCE, CcuAllReduceMesh1D, InsAllReduceSoleExecutor, TopoMatchMesh, CcuTempAllReduceMesh1D);
272 : INS_REGISTER_IMPL_BY_TEMP(OpType::ALLREDUCE, CcuAllReduceMesh1DOneShot, InsAllReduceSoleExecutor, TopoMatchMesh,
273 : CcuTempAllReduceMesh1DOneShot);
274 : INS_REGISTER_IMPL_BY_TEMP(OpType::ALLREDUCE, CcuAllReduceMesh2DOneShot, InsAllReduceSoleExecutor, TopoMatchConcurrMesh,
275 : CcuTempAllReduceMesh2DOneShot);
276 : INS_REGISTER_IMPL_BY_TEMP(OpType::ALLREDUCE, CcuAllReduceMesh2DTwoShot, InsAllReduceSoleExecutor, TopoMatchConcurrMesh,
277 : CcuTempAllReduceMesh2DTwoShot);
278 : INS_REGISTER_IMPL_BY_TEMP(
279 : OpType::ALLREDUCE, CcuAllReduceMeshDetour1D, InsAllReduceSoleExecutor, TopoMatchMesh, CcuTempAllReduceMeshDetour1D);
280 : INS_REGISTER_IMPL_BY_TEMP(OpType::ALLREDUCE, CcuAllReduceMeshTwoShotMem2Mem2D, InsAllReduceSoleExecutor,
281 : TopoMatchConcurrMesh, CcuTempAllReduceMeshTwoShotMem2Mem2D);
282 : #endif
283 :
284 : } // namespace Hccl
|