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