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 "topo_match_concurr_mesh.h"
14 : #include "ins_temp_reduce_mesh_1D.h"
15 : #include "ins_temp_reduce_mesh_1D_two_shot.h"
16 : #include "ins_temp_reduce_mesh_2D.h"
17 : #include "ins_temp_reduce_aicpu_reduce.h"
18 : #include "ins_temp_reduce_aicpu_reduce_mesh_2D.h"
19 : #include "topo_match_mesh.h"
20 : #include "topo_match_nhr.h"
21 : #include "ins_temp_reduce_nhr.h"
22 : #include "ins_v2_reduce_sole_executor.h"
23 : #ifndef CCL_KERNEL_AICPU
24 : #include "aiv_temp_reduce_mesh_1D.h"
25 : #include "ccu_temp_reduce_mesh_1D.h"
26 : #include "ccu_temp_reduce_nhr_1D_mem2mem.h"
27 : #include "ccu_temp_reduce_mesh_1D_mem2mem.h"
28 : #include "ccu_temp_reduce_mesh_2D_mem2mem.h"
29 : #include "ccu_temp_reduce_mesh_1D_two_shot_mem2mem.h"
30 : #endif
31 :
32 : namespace Hccl {
33 :
34 : template <typename AlgTopoMatch, typename InsAlgTemplate>
35 0 : InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InsV2ReduceSoleExecutor() : InsCollAlgBase()
36 0 : {}
37 :
38 : template <typename AlgTopoMatch, typename InsAlgTemplate>
39 0 : InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::~InsV2ReduceSoleExecutor()
40 0 : {}
41 :
42 : template <typename AlgTopoMatch, typename InsAlgTemplate>
43 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const RankGraph *rankGraph)
44 : {
45 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
46 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
47 0 : return HcclResult::HCCL_SUCCESS;
48 0 : }
49 :
50 : template <typename AlgTopoMatch, typename InsAlgTemplate>
51 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const AlgTopoInfo &topoInfo)
52 : {
53 0 : CHK_PRT_RET(topoInfo.vTopo.empty(),
54 : HCCL_ERROR("[InsV2ReduceSoleExecutor][InitCommInfo] vTopo size is invalid"), HCCL_E_PARA);
55 0 : CHK_PRT_RET(topoInfo.virtRankMap.empty(),
56 : HCCL_ERROR("[InsV2ReduceSoleExecutor][InitCommInfo] virtRankMap size is invalid"), HCCL_E_PARA);
57 0 : CHK_PRT_RET(topoInfo.virtRanks.empty(),
58 : HCCL_ERROR("[InsV2ReduceSoleExecutor][InitCommInfo] virtRanks size is invalid"), HCCL_E_PARA);
59 0 : vTopo_ = topoInfo.vTopo[0]; // 本通信域内的通信平面
60 0 : virtRankMap_ = topoInfo.virtRankMap[0]; // 本通信域内的 rank 映射表
61 0 : virtRanks_ = topoInfo.virtRanks[0]; // 本通信域内的 rank 集合
62 0 : return HcclResult::HCCL_SUCCESS;
63 : }
64 :
65 : template <typename AlgTopoMatch, typename InsAlgTemplate>
66 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CreateTemplates(
67 : std::shared_ptr<InsAlgTemplate> &algTemplatePtr)
68 : {
69 0 : algTemplatePtr = std::make_shared<InsAlgTemplate>(myRank_, rankSize_, vTopo_, virtRankMap_);
70 0 : CHK_PTR_NULL(algTemplatePtr); // 检查是否成功分配内存
71 0 : algTemplatePtr->SetDmaMode(dmaMode_);
72 0 : algTemplatePtr->InitReduceInfo(redOp_, dataType_);
73 0 : algTemplatePtr->SetCollOp(op_);
74 0 : algTemplatePtr->SetRoot(op_.root);
75 0 : return HcclResult::HCCL_SUCCESS;
76 : }
77 :
78 : template <typename AlgTopoMatch, typename InsAlgTemplate>
79 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
80 : const RankGraph *rankGraph, std::shared_ptr<InsAlgTemplate> &algTemplate, AlgTempResReq &tempResReq) const
81 : {
82 0 : if (enableDetour_) {
83 0 : HCCL_DEBUG("[InsV2ReduceSoleExecutor] [%s] Rank[%d], CalcRes with detouring enabled.", __func__, myRank_);
84 0 : CHK_RET(algTemplate->CalcResDetour(rankGraph, tempResReq));
85 : } else {
86 0 : HCCL_DEBUG("[InsV2ReduceSoleExecutor] [%s] Rank[%d], CalcRes with detouring disabled.", __func__, myRank_);
87 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
88 : }
89 0 : return HcclResult::HCCL_SUCCESS;
90 : }
91 :
92 : template <typename AlgTopoMatch, typename InsAlgTemplate>
93 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
94 : ConnectedLinkMgr *linkMgr, std::shared_ptr<InsAlgTemplate> &algTemplate, AlgTempResReq &tempResReq) const
95 : {
96 0 : if (enableDetour_) {
97 0 : HCCL_DEBUG("[%s] Rank[%d], CalcRes with detouring enabled.", __func__, myRank_);
98 0 : CHK_RET(algTemplate->CalcResDetour(linkMgr, tempResReq));
99 : } else {
100 0 : HCCL_DEBUG("[%s] Rank[%d], CalcRes with detouring disabled.", __func__, myRank_);
101 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
102 : }
103 0 : return HcclResult::HCCL_SUCCESS;
104 : }
105 :
106 : // HOST 侧算法入口
107 : template <typename AlgTopoMatch, typename InsAlgTemplate>
108 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(
109 : const RankGraph *rankGraph, const CollAlgOperator &op, const CollAlgParams ¶ms, InsQuePtr insQue)
110 : {
111 0 : CHK_RET(Init(op, params, insQue));
112 0 : CHK_RET(InitCommInfo(rankGraph));
113 :
114 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
115 0 : CHK_RET(CreateTemplates(algTemplate));
116 :
117 0 : AlgTempResReq tempResReq;
118 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
119 0 : CHK_RET(InitQueue(tempResReq.queNum, tempInsQue_));
120 0 : CHK_RET(PrepResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, tempResLinks_));
121 0 : CHK_RET(OrchestrateLoop(algTemplate));
122 0 : return HcclResult::HCCL_SUCCESS;
123 0 : }
124 :
125 : // AICPU 侧算法入口
126 : template <typename AlgTopoMatch, typename InsAlgTemplate>
127 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(const AlgTopoInfo &topoInfo,
128 : const CollAlgOperator &op, const CollAlgParams ¶ms, ConnectedLinkMgr *linkMgr, InsQuePtr insQue)
129 : {
130 0 : CHK_RET(Init(op, params, insQue));
131 0 : CHK_RET(InitCommInfo(topoInfo));
132 :
133 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
134 0 : CHK_RET(CreateTemplates(algTemplate));
135 :
136 0 : AlgTempResReq tempResReq;
137 0 : CHK_RET(GetTemplateResRequest(linkMgr, algTemplate, tempResReq));
138 0 : CHK_RET(InitQueue(tempResReq.queNum, tempInsQue_));
139 0 : CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
140 0 : CHK_RET(OrchestrateLoop(algTemplate));
141 0 : return HcclResult::HCCL_SUCCESS;
142 0 : }
143 :
144 : // 切分数据并调用 template
145 : template <typename AlgTopoMatch, typename InsAlgTemplate>
146 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::OrchestrateLoop(
147 : std::shared_ptr<InsAlgTemplate> algTemplate)
148 : {
149 0 : HCCL_INFO("[InsReduceSoleExecutor][OrchestrateLoop] Start, template[%s]", algTemplate->Describe().c_str());
150 0 : u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
151 0 : dataSize_ = dataCount_ * dataSizePerVolume;
152 :
153 0 : TemplateDataParams tempAlgParams;
154 0 : tempAlgParams.buffInfo.inBuffType = BufferType::INPUT;
155 0 : tempAlgParams.buffInfo.outBuffType = BufferType::OUTPUT;
156 0 : tempAlgParams.buffInfo.scratBuffType = BufferType::SCRATCH;
157 0 : tempAlgParams.repeatNum = 1; // 不需要重复
158 0 : tempAlgParams.outputRepeatStride = 0;
159 0 : tempAlgParams.inputRepeatStride = 0;
160 :
161 0 : TempFuncs tempFuncs;
162 0 : tempFuncs.opMode = opMode_;
163 0 : tempFuncs.isForepart = true;
164 0 : tempFuncs.enableCounterNotify = IsEnableCounterNotify();
165 0 : tempFuncs.isBottom = true;
166 :
167 0 : u64 maxDataSizePerLoop = 0;
168 0 : u64 transportBoundDataSize = UB_MAX_DATA_SIZE; // algTemplate->CalcLoopMaxCount();
169 0 : u32 templateScratchMultiplier = algTemplate->CalcScratchMultiple(BufferType::INPUT, BufferType::OUTPUT);
170 0 : if (templateScratchMultiplier != 0) {
171 0 : u64 scratchBoundDataSize = maxTmpMemSize_ / templateScratchMultiplier;
172 0 : maxDataSizePerLoop = std::min(transportBoundDataSize, scratchBoundDataSize);
173 : } else {
174 0 : maxDataSizePerLoop = transportBoundDataSize;
175 : }
176 0 : u64 maxDataCountPerLoop = maxDataSizePerLoop / dataTypeSize_;
177 0 : HCCL_INFO("[InsReduceSoleExecutor][OrchestrateLoop] maxDataCountPerLoop[%llu], maxDataSizePerLoop[%llu], "
178 : "transportBoundDataSize[%llu], templateScratchMultiplier[%llu]",
179 : maxDataCountPerLoop,
180 : maxDataSizePerLoop,
181 : transportBoundDataSize,
182 : templateScratchMultiplier);
183 0 : CHK_PRT_RET(maxDataCountPerLoop == 0,
184 : HCCL_ERROR("[InsReduceSoleExecutor][OrchestrateLoop] maxDataCountPerLoop is 0"),
185 : HCCL_E_INTERNAL);
186 :
187 0 : tempAlgParams.buffInfo.scratchBuffBaseOff = 0;
188 0 : tempAlgParams.inputSliceStride = 0; // 输入数据仅有 1 个 slice, 不需要 stride
189 0 : tempAlgParams.outputSliceStride = dataSize_; // 每张卡的数据间隔为算子输入大小
190 :
191 0 : u64 processedDataCount = 0;
192 0 : u64 loopTimes = dataCount_ / maxDataCountPerLoop + static_cast<u64>(dataCount_ % maxDataCountPerLoop != 0);
193 0 : for (u64 loop = 0; loop < loopTimes; loop++) {
194 0 : u64 currDataCount = (loop == loopTimes - 1) ? dataCount_ - processedDataCount : maxDataCountPerLoop;
195 0 : tempAlgParams.buffInfo.outBuffBaseOff = processedDataCount * dataTypeSize_;
196 0 : tempAlgParams.buffInfo.inBuffBaseOff = processedDataCount * dataTypeSize_;
197 0 : tempAlgParams.sliceSize = currDataCount * dataTypeSize_;
198 0 : tempAlgParams.tailSize = tempAlgParams.sliceSize;
199 :
200 0 : CHK_RET(algTemplate->GenExtIns(tempFuncs, tempAlgParams, tempResLinks_, tempInsQue_));
201 0 : processedDataCount += currDataCount;
202 : }
203 :
204 0 : return HcclResult::HCCL_SUCCESS;
205 0 : }
206 :
207 : template <typename AlgTopoMatch, typename InsAlgTemplate>
208 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcRes(
209 : const RankGraph *rankGraph, CollAlgResReq &algResReq)
210 : {
211 : // Topo Match
212 0 : CHK_RET(InitCommInfo(rankGraph));
213 :
214 : // instantiate a template
215 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
216 :
217 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
218 0 : CHK_RET(CreateTemplates(algTemplate));
219 :
220 0 : AlgTempResReq tempResReq;
221 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
222 :
223 0 : CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
224 0 : algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
225 0 : algResReq.queueNotifys = tempResReq.queNotifys;
226 0 : algResReq.localWaitGroupCntNotify = tempResReq.localWaitGroupCntNotify;
227 0 : algResReq.primQueueNum = tempResReq.streamNum;
228 0 : algResReq.localBcastPostCntNotify = tempResReq.localBcastPostCntNotify;
229 0 : CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
230 :
231 0 : return HcclResult::HCCL_SUCCESS;
232 0 : }
233 :
234 : template <typename AlgTopoMatch, typename InsAlgTemplate>
235 0 : HcclResult InsV2ReduceSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcResOffload(
236 : const RankGraph *rankGraph, const u64 &dataSize, CollOffloadOpResReq &resReq)
237 : {
238 : // Topo Match
239 0 : CHK_RET(InitCommInfo(rankGraph));
240 :
241 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
242 0 : CHK_RET(CreateTemplates(algTemplate));
243 :
244 0 : AlgTempResReq tempResReq;
245 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
246 0 : u32 templateScratchMultiplier = algTemplate->CalcScratchMultiple(BufferType::INPUT, BufferType::OUTPUT);
247 0 : u64 transportBoundDataSize = UB_MAX_DATA_SIZE;
248 0 : resReq.requiredScratchMemSize =
249 0 : std::min(dataSize * templateScratchMultiplier, transportBoundDataSize);
250 0 : resReq.requiredSubQueNum = tempResReq.streamNum - 1;
251 :
252 0 : return HcclResult::HCCL_SUCCESS;
253 0 : }
254 :
255 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceMesh1D, InsV2ReduceSoleExecutor,
256 : TopoMatchMesh, InsTempReduceMesh1D);
257 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceMesh1DTwoShot, InsV2ReduceSoleExecutor,
258 : TopoMatchMesh, InsTempReduceMesh1DTwoShot);
259 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceMesh2D, InsV2ReduceSoleExecutor,
260 : TopoMatchConcurrMesh, InsTempReduceMesh2D);
261 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceAicpuReduce, InsV2ReduceSoleExecutor,
262 : TopoMatchMesh, InsTempReduceAicpuReduce);
263 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceAicpuReduceMesh2D, InsV2ReduceSoleExecutor,
264 : TopoMatchConcurrMesh, InsTempReduceAicpuReduceMesh2D);
265 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, InsReduceNHR, InsV2ReduceSoleExecutor, TopoMatchNHR,
266 : InsTempReduceNHR);
267 : #ifndef CCL_KERNEL_AICPU
268 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, CcuReduceMesh1D, InsV2ReduceSoleExecutor,
269 : TopoMatchMesh, CcuTempReduceMesh1D);
270 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, CcuReduceNHR1D, InsV2ReduceSoleExecutor,
271 : TopoMatchMesh, CcuTempReduceNHRMem2Mem1D);
272 : INS_REGISTER_IMPL_BY_TEMP(
273 : OpType::REDUCE, CcuReduceMeshMem2Mem1D, InsV2ReduceSoleExecutor, TopoMatchMesh, CcuTempReduceMeshMem2Mem1D);
274 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, AivReduceMesh1D, InsV2ReduceSoleExecutor,
275 : TopoMatchMesh, AivTempReduceMesh1D);
276 : INS_REGISTER_IMPL_BY_TEMP(
277 : OpType::REDUCE, CcuReduceMeshMem2Mem2D, InsV2ReduceSoleExecutor, TopoMatchConcurrMesh, CcuTempReduceMeshMem2Mem2D);
278 : INS_REGISTER_IMPL_BY_TEMP(OpType::REDUCE, CcuReduceMeshTwoShotMem2Mem1D, InsV2ReduceSoleExecutor,
279 : TopoMatchMesh, CcuTempReduceMeshTwoShotMem2Mem1D);
280 : #endif
281 : } // namespace Hccl
|