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_broadcast_sole_executor.h"
12 : #include "log.h"
13 : #include "ins_coll_alg_registry.h"
14 :
15 : #include "topo_match_mesh.h"
16 : #include "topo_match_nhr.h"
17 : #include "topo_match_concurr_mesh.h"
18 : #include "ccu_temp_broadcast_mesh_1D_mem2mem.h"
19 : #include "ins_temp_broadcast_mesh1D_oneshot.h"
20 : #include "ins_temp_broadcast_mesh_2D_two_shot.h"
21 : #include "ins_temp_broadcast_mesh_1D_two_shot.h"
22 : #include "ins_temp_broadcast_nhr.h"
23 :
24 : #ifndef CCL_KERNEL_AICPU
25 : #include "ccu_temp_broadcast_mesh_2D_mem2mem.h"
26 : #include "aiv_temp_broadcast_mesh_1D.h"
27 : #include "ccu_temp_broadcast_nhr_1D_mem2mem.h"
28 : #endif
29 :
30 : namespace Hccl {
31 : constexpr u64 MAX_OFFLOAD_SCRATCH_SIZE = 200 * 1024 * 1024; // 200M
32 : template <typename AlgTopoMatch, typename InsAlgTemplate>
33 0 : InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InsV2BroadcastSoleExecutor() : InsCollAlgBase()
34 0 : {}
35 :
36 : template <typename AlgTopoMatch, typename InsAlgTemplate>
37 0 : InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::~InsV2BroadcastSoleExecutor()
38 0 : {}
39 :
40 : template <typename AlgTopoMatch, typename InsAlgTemplate>
41 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const RankGraph* rankGraph)
42 : {
43 0 : AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
44 0 : CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
45 0 : return HcclResult::HCCL_SUCCESS;
46 0 : }
47 :
48 : template <typename AlgTopoMatch, typename InsAlgTemplate>
49 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InitCommInfo(const AlgTopoInfo& topoInfo)
50 : {
51 0 : CHK_PRT_RET(
52 : topoInfo.vTopo.size() == 0, HCCL_ERROR("[InsV2BroadcastSoleExecutor] [Orchestrate] vTopo size is 0."),
53 : HcclResult::HCCL_E_INTERNAL);
54 0 : vTopo_ = topoInfo.vTopo[0]; // 本通信域内的通信平面
55 0 : virtRankMap_ = topoInfo.virtRankMap[0]; // 本通信域内的 rank 映射表
56 0 : virtRanks_ = topoInfo.virtRanks[0]; // 本通信域内的 rank 集合
57 0 : return HcclResult::HCCL_SUCCESS;
58 : }
59 :
60 : template <typename AlgTopoMatch, typename InsAlgTemplate>
61 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
62 : const RankGraph* rankGraph, std::shared_ptr<InsAlgTemplate>& algTemplate, AlgTempResReq& tempResReq) const
63 : {
64 0 : if (enableDetour_) {
65 0 : HCCL_DEBUG("[InsV2BroadcastSoleExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
66 0 : CHK_RET(algTemplate->CalcResDetour(rankGraph, tempResReq));
67 : } else {
68 0 : HCCL_DEBUG("[InsV2BroadcastSoleExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
69 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
70 : }
71 0 : return HcclResult::HCCL_SUCCESS;
72 : }
73 :
74 : template <typename AlgTopoMatch, typename InsAlgTemplate>
75 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GetTemplateResRequest(
76 : ConnectedLinkMgr* linkMgr, std::shared_ptr<InsAlgTemplate>& algTemplate, AlgTempResReq& tempResReq) const
77 : {
78 0 : if (enableDetour_) {
79 0 : HCCL_DEBUG("[%s] Rank[%d]. CalcRes with detouring enabled.", __func__, myRank_);
80 0 : CHK_RET(algTemplate->CalcResDetour(linkMgr, tempResReq));
81 : } else {
82 0 : HCCL_DEBUG("[%s] Rank[%d], CalcRes with detouring disabled.", __func__, myRank_);
83 0 : CHK_RET(algTemplate->CalcRes(tempResReq));
84 : }
85 0 : return HcclResult::HCCL_SUCCESS;
86 : }
87 :
88 : template <typename AlgTopoMatch, typename InsAlgTemplate>
89 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcResOffload(
90 : const RankGraph* rankGraph, const u64& dataSize, CollOffloadOpResReq& resReq)
91 : {
92 : (void)dataSize;
93 0 : resReq.requiredScratchMemSize = 0;
94 :
95 : // Topo Match
96 0 : CHK_RET(InitCommInfo(rankGraph));
97 :
98 0 : std::shared_ptr<InsAlgTemplate> algTemplate = nullptr;
99 0 : CHK_RET(CreateTemplates(algTemplate));
100 0 : AlgTempResReq tempResReq;
101 0 : CHK_RET(GetTemplateResRequest(rankGraph, algTemplate, tempResReq));
102 0 : resReq.requiredScratchMemSize = MAX_OFFLOAD_SCRATCH_SIZE;
103 0 : resReq.requiredSubQueNum = tempResReq.streamNum - 1;
104 :
105 0 : return HcclResult::HCCL_SUCCESS;
106 0 : }
107 :
108 : template <typename AlgTopoMatch, typename InsAlgTemplate>
109 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CreateTemplates(
110 : std::shared_ptr<InsAlgTemplate>& algTemplatePtr)
111 : {
112 0 : algTemplatePtr = std::make_shared<InsAlgTemplate>(myRank_, rankSize_, vTopo_, virtRankMap_);
113 0 : CHK_PTR_NULL(algTemplatePtr); // 检查是否成功分配内存
114 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
115 0 : algTemplatePtr->SetDmaMode(dmaMode_);
116 0 : algTemplatePtr->SetCollOp(op_); // CCU template需要传递op信息
117 0 : algTemplatePtr->SetRoot(root_);
118 0 : algTemplatePtr->SetDataType(dataType_);
119 0 : return HCCL_SUCCESS;
120 0 : }
121 :
122 : template <typename AlgTopoMatch, typename InsAlgTemplate>
123 : HcclResult
124 0 : InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcRes(const RankGraph* rankGraph, CollAlgResReq& algResReq)
125 : {
126 : // Topo Match
127 0 : CHK_RET(InitCommInfo(rankGraph));
128 0 : algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
129 :
130 : // instantiate a template
131 0 : InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
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(rankGraph, algTemplate, tempResReq));
138 0 : CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
139 0 : algResReq.primQueueNum = tempResReq.streamNum;
140 0 : algResReq.queueNotifys = tempResReq.queNotifys;
141 0 : algResReq.localWaitGroupCntNotify = tempResReq.localWaitGroupCntNotify;
142 0 : algResReq.localBcastPostCntNotify = tempResReq.localBcastPostCntNotify;
143 0 : HCCL_DEBUG(
144 : "[InsV2BroadcastSoleExecutor][InsCollAlgFactory] Rank[%d], requiredQueNum [%u].", myRank_,
145 : algResReq.primQueueNum);
146 0 : CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
147 :
148 0 : return HcclResult::HCCL_SUCCESS;
149 0 : }
150 :
151 : // host
152 : template <typename AlgTopoMatch, typename InsAlgTemplate>
153 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(
154 : const RankGraph* rankGraph, const CollAlgOperator& op, const CollAlgParams& params, InsQuePtr insQue)
155 : {
156 0 : HCCL_INFO("[InsCollAlgFactory] [InsV2BroadcastSoleExecutor] Host Orchestrate begins.");
157 : // init and check params
158 0 : CHK_RET(Init(op, params, insQue));
159 :
160 : // Topo Match
161 0 : CHK_RET(InitCommInfo(rankGraph));
162 0 : dataTypeSize_ = DataTypeSizeGet(dataType_);
163 0 : dataSize_ = dataCount_ * dataTypeSize_;
164 0 : CHK_PRT_RET(
165 : dataTypeSize_ == 0,
166 : HCCL_ERROR(
167 : "[InsV2BroadcastSoleExecutor] [CollAlgFactory] Rank [%d], Invalid dataTypeSize_ [%u].", myRank_,
168 : dataTypeSize_),
169 : HcclResult::HCCL_E_INTERNAL);
170 :
171 : // 实例化算法模板类
172 0 : HCCL_DEBUG(
173 : "[InsV2BroadcastSoleExecutor] Rank[%d], Init insAlgTemplate with rankSize [%u] and dmaMode [%s].", myRank_,
174 : rankSize_, dmaMode_.Describe().c_str());
175 0 : std::shared_ptr<InsAlgTemplate> tempAlg = nullptr;
176 0 : CHK_RET(CreateTemplates(tempAlg));
177 :
178 0 : AlgTempResReq tempResReq;
179 0 : CHK_RET(GetTemplateResRequest(rankGraph, tempAlg, tempResReq));
180 : // 申请算法模板所需资源
181 0 : CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
182 0 : CHK_RET(PrepResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, tempResLinks_));
183 :
184 0 : CHK_RET(OrchestrateLoop(tempAlg));
185 :
186 0 : return HcclResult::HCCL_SUCCESS;
187 0 : }
188 :
189 : // 算子执行aicpu接口
190 : template <typename AlgTopoMatch, typename InsAlgTemplate>
191 0 : HcclResult InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(
192 : const AlgTopoInfo& topoInfo, const CollAlgOperator& op, const CollAlgParams& params, ConnectedLinkMgr* linkMgr,
193 : InsQuePtr insQue)
194 : {
195 0 : HCCL_INFO("[InsCollAlgFactory] [InsV2BroadcastSoleExecutor] AiCpu Orchestrate begins.");
196 : // 参数校验和初始化
197 0 : CHK_RET(Init(op, params, insQue));
198 : // soleEsecutor 只支持单层拓扑, 所以只取第 0 级通信域的信息
199 0 : CHK_RET(InitCommInfo(topoInfo));
200 0 : dataTypeSize_ = DataTypeSizeGet(dataType_);
201 0 : dataSize_ = dataCount_ * dataTypeSize_;
202 0 : CHK_PRT_RET(
203 : dataTypeSize_ == 0,
204 : HCCL_ERROR(
205 : "[InsV2BroadcastSoleExecutor] [CollAlgFactory] Rank [%d], Invalid dataTypeSize_ [%u].", myRank_,
206 : dataTypeSize_),
207 : HcclResult::HCCL_E_INTERNAL);
208 :
209 : // 实例化算法模板类
210 0 : HCCL_DEBUG(
211 : "[InsV2BroadcastSoleExecutor] Rank[%d], Init insAlgTemplate with rankSize [%u] and dmaMode [%s].", myRank_,
212 : rankSize_, dmaMode_.Describe().c_str());
213 0 : std::shared_ptr<InsAlgTemplate> tempAlg = nullptr;
214 0 : CHK_RET(CreateTemplates(tempAlg));
215 :
216 0 : AlgTempResReq tempResReq;
217 0 : CHK_RET(GetTemplateResRequest(linkMgr, tempAlg, tempResReq));
218 :
219 : // 申请算法模板所需资源
220 0 : CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
221 0 : CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
222 :
223 0 : CHK_RET(OrchestrateLoop(tempAlg));
224 :
225 0 : return HcclResult::HCCL_SUCCESS;
226 0 : }
227 :
228 : template <typename AlgTopoMatch, typename InsAlgTemplate>
229 : HcclResult
230 0 : InsV2BroadcastSoleExecutor<AlgTopoMatch, InsAlgTemplate>::OrchestrateLoop(std::shared_ptr<InsAlgTemplate>& tempAlg)
231 : {
232 : // 基本参数配置
233 0 : TempFuncs tempFuncs;
234 0 : tempFuncs.opMode = opMode_;
235 0 : tempFuncs.enableCounterNotify = IsEnableCounterNotify();
236 0 : tempFuncs.isForepart = true; // Usr Buff to CCL Buff required
237 0 : tempFuncs.isBottom = true; // CCL Buff to Usr Buff required
238 :
239 0 : TemplateDataParams tempAlgParams;
240 0 : tempAlgParams.buffInfo.inBuffType = BufferType::INPUT;
241 0 : tempAlgParams.buffInfo.outBuffType = BufferType::INPUT;
242 0 : tempAlgParams.buffInfo.scratBuffType = BufferType::SCRATCH;
243 0 : tempAlgParams.buffInfo.scratchBuffBaseOff = 0;
244 0 : tempAlgParams.inputSliceStride = 0;
245 0 : tempAlgParams.outputSliceStride = 0;
246 : // 不需要重复
247 0 : tempAlgParams.repeatNum = 1;
248 0 : tempAlgParams.inputRepeatStride = 0;
249 0 : tempAlgParams.outputRepeatStride = 0;
250 :
251 : // 根据CCL Buffer大小和UB_MAX_DATA_SIZE,计算出一轮中最多能输出多少数据
252 0 : u64 maxDataSizePerLoop = 0;
253 0 : u64 transportBoundDataSize = UB_MAX_DATA_SIZE; // algTemplate->CalcLoopMaxCount();
254 0 : u32 templateScratchMultiplier = tempAlg->CalcScratchMultiple(BufferType::INPUT, BufferType::INPUT);
255 0 : if (templateScratchMultiplier != 0) {
256 0 : u64 scratchBoundDataSize = maxTmpMemSize_ / templateScratchMultiplier;
257 0 : maxDataSizePerLoop = min(transportBoundDataSize, scratchBoundDataSize);
258 : } else {
259 0 : maxDataSizePerLoop = transportBoundDataSize;
260 : }
261 0 : u64 maxDataCountPerLoop = maxDataSizePerLoop / dataTypeSize_;
262 :
263 0 : u64 dataSize = dataCount_ * dataTypeSize_;
264 :
265 0 : u64 maxLoopOutputSize = maxDataCountPerLoop * dataTypeSize_;
266 :
267 0 : u64 loopTimes = dataSize / maxLoopOutputSize + static_cast<u64>(dataSize % maxLoopOutputSize != 0);
268 :
269 0 : for (u64 loop = 0; loop < loopTimes; loop++) {
270 0 : u64 currloopOffset = loop * maxLoopOutputSize;
271 0 : u64 currSize = (loop == (loopTimes - 1)) ? dataSize - currloopOffset : maxLoopOutputSize;
272 : // 当前搬运的数据片
273 0 : tempAlgParams.buffInfo.inBuffBaseOff = currloopOffset;
274 0 : tempAlgParams.buffInfo.outBuffBaseOff = currloopOffset;
275 :
276 0 : tempAlgParams.sliceSize = currSize;
277 0 : tempAlgParams.tailSize = tempAlgParams.sliceSize;
278 :
279 0 : CHK_RET(tempAlg->GenExtIns(tempFuncs, tempAlgParams, tempResLinks_, requiredQue_));
280 0 : HCCL_DEBUG(
281 : "[InsCollAlgFactory] Rank[%d], done generating instruction queues, currSize[%llu], currOffset[%llu].",
282 : myRank_, currSize, currloopOffset);
283 : }
284 :
285 0 : return HcclResult::HCCL_SUCCESS;
286 0 : }
287 :
288 : INS_REGISTER_IMPL_BY_TEMP(
289 : OpType::BROADCAST, InsBroadcastMesh1DOneShot, InsV2BroadcastSoleExecutor, TopoMatchMesh,
290 : InsTempBroadcastMesh1DOneShot);
291 : INS_REGISTER_IMPL_BY_TEMP(
292 : OpType::BROADCAST, InsBroadcastMesh1DTwoShot, InsV2BroadcastSoleExecutor, TopoMatchMesh,
293 : InsTempBroadcastMesh1DTwoShot);
294 : INS_REGISTER_IMPL_BY_TEMP(
295 : OpType::BROADCAST, InsBroadcastMesh2DTwoShot, InsV2BroadcastSoleExecutor, TopoMatchConcurrMesh,
296 : InsTempBroadcastMesh2DTwoShot);
297 : INS_REGISTER_IMPL_BY_TEMP(
298 : OpType::BROADCAST, InsBroadcastNHR, InsV2BroadcastSoleExecutor, TopoMatchNHR, InsTempBroadcastNHR);
299 : #ifndef CCL_KERNEL_AICPU
300 : INS_REGISTER_IMPL_BY_TEMP(
301 : OpType::BROADCAST, CcuBroadcastMeshMem2Mem1D, InsV2BroadcastSoleExecutor, TopoMatchMesh,
302 : CcuTempBroadcastMesh1DMem2Mem);
303 : INS_REGISTER_IMPL_BY_TEMP(
304 : OpType::BROADCAST, CcuBroadcastMeshMem2Mem2D, InsV2BroadcastSoleExecutor, TopoMatchConcurrMesh,
305 : CcuTempBroadcastMeshMem2Mem2D);
306 : INS_REGISTER_IMPL_BY_TEMP(
307 : OpType::BROADCAST, AivBroadcastMesh1D, InsV2BroadcastSoleExecutor, TopoMatchMesh, AivTempBroadcastMesh1D);
308 : INS_REGISTER_IMPL_BY_TEMP(
309 : OpType::BROADCAST, CcuBroadcastNHRMem2Mem1D, InsV2BroadcastSoleExecutor, TopoMatchMesh,
310 : CcuTempBroadcastNHRMem2Mem1D);
311 : #endif
312 : } // namespace Hccl
|