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 <iostream>
12 : #include <string>
13 : #include <map>
14 :
15 : #include "log.h"
16 : #include "execute_selector.h"
17 : #include "coll_alg_component.h"
18 : #include "data_type.h"
19 :
20 : namespace Hccl {
21 426 : CollAlgComponent::CollAlgComponent(RankGraph *rankGraph, DevType devType, u32 myRank, u32 rankSize)
22 426 : : rankGraph_(rankGraph), devType_(devType), myRank_(myRank), rankSize_(rankSize)
23 :
24 : {
25 1278 : collAlgSelector_ = std::make_shared<ExecuteSelector>(ExecuteSelector().SetVirtualTopo(rankGraph)
26 426 : .SetRankSize(rankSize)
27 426 : .SetMyRank(myRank));
28 426 : }
29 :
30 : constexpr u64 HCCLV2_DEFAULT_TASK_NUM = 30;
31 : constexpr u32 ALLTOALLV_DIRECT_FULLMESH_CONCURRENT_SIZE = 8;
32 : constexpr u64 SMALL_COUNT_512KB = 512*1024;
33 : constexpr u64 TASK_NUM_CONST_TWO = 2;
34 :
35 226 : void CollAlgComponent::EnableDetour(bool enableDetour)
36 : {
37 226 : enableDetour_ = enableDetour;
38 226 : return;
39 : }
40 :
41 226 : void CollAlgComponent::EnableDataAllign(bool enableAllign)
42 : {
43 226 : enableAllign_ = enableAllign;
44 226 : return;
45 : }
46 :
47 226 : void CollAlgComponent::SetAllignSize(u64 allignSize)
48 : {
49 226 : allignSize_ = allignSize;
50 226 : return;
51 : }
52 :
53 226 : void CollAlgComponent::SetMaxQueue(u32 maxQueue)
54 : {
55 226 : maxQueue_ = maxQueue;
56 226 : return;
57 : }
58 :
59 226 : void CollAlgComponent::SetMaxLink(u32 maxLink)
60 : {
61 226 : maxLink_ = maxLink;
62 226 : return;
63 : }
64 :
65 226 : void CollAlgComponent::SetMaxDepQueuePairs(u32 maxDepQueuePairs)
66 : {
67 226 : maxDepQueuePairs_ = maxDepQueuePairs;
68 226 : return;
69 : }
70 :
71 226 : void CollAlgComponent::SetDmaMode(const DmaMode dmaMode)
72 : {
73 226 : dmaMode_ = dmaMode;
74 226 : return;
75 : }
76 :
77 0 : AlgorithmType CollAlgComponent::GetAlgorithmTypeForMC2CCU(const std::string& name)
78 : {
79 0 : return collAlgSelector_->GetAlgorithmTypeForMC2CCU(name);
80 : }
81 :
82 0 : HcclResult CollAlgComponent::ExecAlgSelect(const CollAlgOperator &op, const CollAlgParams ¶ms,std::string &algName, OpExecuteConfig &opExecuteConfig)
83 : {
84 0 : HCCL_INFO("CollAlgComponent::ExecAlgSelect currentCollOperator dataType[%s]", op.dataType.Describe().c_str());
85 0 : CollAlgParams paramsTmp = params;
86 0 : paramsTmp.dataSize = op.dataCount * DataTypeSizeGet(op.dataType);
87 0 : CHK_RET(collAlgSelector_->Run(op, paramsTmp, algName));
88 0 : opExecuteConfig = paramsTmp.opExecuteConfig;
89 0 : return HcclResult::HCCL_SUCCESS;
90 0 : }
91 :
92 : // 临时函数:由于资源回退时无法重新申请资源,所以暂时统一按照最大资源需求量申请资源
93 0 : HcclResult TmpStubCalcResOffload(CollOffloadOpResReq &resReq)
94 : {
95 0 : u64 stubRequiredSubQueNum = 16;
96 0 : u64 stubRequiredScratchMemSize = 256 * 1024 * 1024; // 256 * 1024 * 1024 = 256 M
97 :
98 0 : HCCL_INFO("[TmpStubCalcResOffload] original requiredSubQueNum is [%llu], stubRequiredSubQueNum[%llu]",
99 : resReq.requiredSubQueNum,
100 : stubRequiredSubQueNum);
101 0 : HCCL_INFO("[TmpStubCalcResOffload] original requiredScratchMemSize is [%llu], stubRequiredScratchMemSize[%llu]",
102 : resReq.requiredScratchMemSize,
103 : stubRequiredScratchMemSize);
104 :
105 0 : resReq.requiredSubQueNum = max(stubRequiredSubQueNum, resReq.requiredSubQueNum);
106 0 : resReq.requiredScratchMemSize = max(stubRequiredScratchMemSize, resReq.requiredScratchMemSize);
107 :
108 0 : HCCL_INFO("[TmpStubCalcResOffload] updated requiredSubQueNum[%llu], requiredScratchMemSize[%llu]",
109 : resReq.requiredSubQueNum,
110 : resReq.requiredScratchMemSize);
111 0 : return HcclResult::HCCL_SUCCESS;
112 : }
113 :
114 0 : HcclResult CollAlgComponent::CalcResOffload(const OpType &opType, const u64 &dataSize, const HcclDataType &dataType, const OpExecuteConfig &opExecuteConfig,
115 : CollOffloadOpResReq &resReq)
116 : {
117 0 : bool isAlltoAll = (opType == OpType::ALLTOALL) || (opType == OpType::ALLTOALLV) || (opType == OpType::ALLTOALLVC);
118 0 : if ((rankSize_ == 1) && (!isAlltoAll)) {
119 0 : resReq.requiredScratchMemSize = 0;
120 0 : resReq.requiredSubQueNum = 0;
121 0 : HCCL_INFO("[CollAlgComponent] rankSize = 1, requiredSubQueNum and requiredScratchMemSize set to [0].");
122 0 : return HcclResult::HCCL_SUCCESS;
123 : }
124 :
125 0 : CollAlgOperator op;
126 0 : op.opType = opType;
127 0 : op.dataType = HcclDataTypeToDataType(dataType);
128 0 : op.dataCount = dataSize / DataTypeSizeGet(op.dataType);
129 0 : CollAlgParams params;
130 0 : params.opExecuteConfig = opExecuteConfig;
131 0 : params.opMode = OpMode::OFFLOAD;
132 0 : params.dataSize = dataSize;
133 0 : std::string collAlgName;
134 0 : CHK_RET(collAlgSelector_->Run(op, params, collAlgName));
135 0 : CHK_PRT_RET(collAlgName.empty(),
136 : HCCL_ERROR("[CollAlgComponent] Please assign a collAlgName by env variable!"),
137 : HcclResult::HCCL_E_PARA);
138 :
139 0 : std::shared_ptr<InsCollAlgBase> insGenFunc = InsCollAlgRegistry::Global()->GetAlgImpl(opType, collAlgName);
140 0 : CHK_PTR_NULL(insGenFunc);
141 :
142 0 : CHK_PRT_RET(SetInsCollAlgExecutor(insGenFunc) != HcclResult::HCCL_SUCCESS,
143 : HCCL_ERROR("[CollAlgComponent] Unable to Set InsCollAlgExecutor, please check params!"),
144 : HcclResult::HCCL_E_PARA);
145 0 : CHK_RET(insGenFunc->CalcResOffload(rankGraph_, dataSize, resReq));
146 0 : if(opExecuteConfig.accState == AcceleratorState::CCU_MS || opExecuteConfig.accState == AcceleratorState::CCU_SCHED){
147 0 : CHK_RET(TmpStubCalcResOffload(resReq));
148 : }
149 :
150 0 : HCCL_INFO("[CollAlgComponent][CalcResOffload] requiredSubQueNum[%llu], requiredScratchMemSize[%llu]",
151 : resReq.requiredSubQueNum, resReq.requiredScratchMemSize);
152 0 : return HcclResult::HCCL_SUCCESS;
153 0 : }
154 :
155 0 : std::vector<std::string> CollAlgComponent::GetOpAlgNames(const OpType &opType, const OrchestMode &orchestMode)
156 : {
157 0 : if (orchestMode == OrchestMode::INSTRUCTION) {
158 0 : return (InsCollAlgRegistry::Global()->GetAvailAlgs()).at(opType);
159 : }
160 :
161 0 : return (CollAlgRegistry::Global()->GetAvailAlgs()).at(opType);
162 : }
163 :
164 0 : CollAlgResReq CollAlgComponent::GetCollAlgResReqByName(const OpType &opType, const std::string &algName,
165 : const OrchestMode &orchestMode)
166 : {
167 0 : if (algName2Res.find(algName) != algName2Res.end()) {
168 0 : return algName2Res[algName];
169 : }
170 0 : CollAlgResReq algResReq;
171 0 : if (orchestMode == OrchestMode::PRIMITIVE) {
172 0 : HCCL_DEBUG("[CollAlgComponent] Primitive based algorithm.");
173 0 : std::shared_ptr<CollAlgBase> primGenFunc = CollAlgRegistry::Global()->GetAlgImpl(opType, algName);
174 0 : if (primGenFunc == nullptr) {
175 0 : return algResReq;
176 : }
177 0 : SetCollAlgExecutor(primGenFunc);
178 0 : primGenFunc->CalcRes(rankGraph_, algResReq);
179 0 : algName2Res[algName] = algResReq;
180 0 : } else if (orchestMode == OrchestMode::INSTRUCTION) {
181 0 : HCCL_DEBUG("[CollAlgComponent] Instruction based algorithm.");
182 0 : std::shared_ptr<InsCollAlgBase> insGenFunc = InsCollAlgRegistry::Global()->GetAlgImpl(opType, algName);
183 0 : if (insGenFunc == nullptr) {
184 0 : return algResReq;
185 : }
186 0 : SetInsCollAlgExecutor(insGenFunc);
187 0 : insGenFunc->CalcRes(rankGraph_, algResReq);
188 0 : algName2Res[algName] = algResReq;
189 0 : }
190 :
191 0 : HCCL_DEBUG("[CollAlgComponent] Finish CollAlgComponent::CalcRes for AICPU Mode.");
192 0 : return algResReq;
193 0 : }
194 :
195 0 : CollAlgOpReq CollAlgComponent::GetCollAlgOpReq(const CollAlgOperator &op, const std::string &collAlgName)
196 : {
197 0 : CollAlgOpReq collAlgOpReq;
198 :
199 0 : collAlgOpReq.algName = collAlgName;
200 0 : if (algName2Res.find(collAlgName) != algName2Res.end() && op.opType != OpType::BATCHSENDRECV && op.opType != OpType::SEND && op.opType != OpType::RECV) {
201 0 : collAlgOpReq.resReq = algName2Res[collAlgName];
202 0 : return collAlgOpReq;
203 : }
204 :
205 0 : CHK_PRT_RET(collAlgOpReq.algName.empty(),
206 : HCCL_WARNING("[CollAlgComponent] Please assign a collAlgName by env variable!"),
207 : collAlgOpReq);
208 :
209 : std::shared_ptr<InsCollAlgBase> insGenFunc
210 0 : = InsCollAlgRegistry::Global()->GetAlgImpl(op.opType, collAlgOpReq.algName);
211 0 : if (insGenFunc == nullptr) {
212 0 : return collAlgOpReq;
213 : }
214 :
215 0 : SetInsCollAlgExecutor(insGenFunc);
216 0 : insGenFunc->SetOp(op);
217 0 : insGenFunc->SetSendRecvRemoteRank(op.sendRecvRemoteRank);
218 0 : auto req = insGenFunc->CalcRes(rankGraph_, collAlgOpReq.resReq);
219 0 : if (req != HcclResult::HCCL_SUCCESS) {
220 0 : THROW<InvalidParamsException>(StringFormat("CollAlgComponent::CalcRes failed"));
221 : }
222 0 : algName2Res[collAlgOpReq.algName] = collAlgOpReq.resReq;
223 :
224 0 : if (rankSize_ == 1) {
225 0 : collAlgOpReq.resReq.primQueueNum = 1;
226 0 : HCCL_DEBUG("[CollAlgComponent] rankSize = 1, algName %s.", collAlgOpReq.algName.c_str());
227 : }
228 :
229 0 : HCCL_DEBUG("[CollAlgComponent] Finish CollAlgComponent::CalcRes for AICPU Mode.");
230 0 : return collAlgOpReq;
231 0 : }
232 :
233 2 : std::vector<char> CollAlgComponent::GetPackedData() const
234 : {
235 2 : BinaryStream binaryStream;
236 2 : binaryStream << dmaMode_;
237 2 : std::vector<char> result;
238 2 : binaryStream.Dump(result);
239 2 : return result;
240 2 : }
241 :
242 0 : HcclResult CollAlgComponent::Orchestrate(const CollAlgOperator &op, const CollAlgParams ¶ms,const string &algName, PrimQuePtr queue)
243 : {
244 0 : HCCL_DEBUG("[CollAlgComponent] Primitive based algorithm.");
245 :
246 0 : CHK_PRT_RET(algName.empty(), HCCL_ERROR("[CollAlgComponent] Empty collAlgName, please check envVar settings."),
247 : HcclResult::HCCL_E_PARA);
248 0 : std::shared_ptr<CollAlgBase> primGenFunc = CollAlgRegistry::Global()->GetAlgImpl(op.opType, algName);
249 0 : if (primGenFunc == nullptr) {
250 0 : HCCL_ERROR("[CollAlgComponent] Invalid opType and invalid collAlgName, [%s].", algName.c_str());
251 0 : return HcclResult::HCCL_E_PARA;
252 : }
253 :
254 0 : CHK_PRT_RET(enableDetour_
255 : && ((algName != "AllGatherMesh") && (algName != "ReduceScatterMesh")
256 : && (algName != "AllReduceMesh")),
257 : HCCL_ERROR("[CollAlgComponent] Current algorithm can not support detouring, please check!"),
258 : HcclResult::HCCL_E_NOT_SUPPORT);
259 :
260 0 : if (rankSize_ == 1) {
261 0 : u64 dataSize = op.dataCount * DataTypeSizeGet(op.dataType);
262 0 : DataSlice usrInSlice = DataSlice(BufferType::INPUT, 0, dataSize);
263 0 : DataSlice usrOutSlice = DataSlice(BufferType::OUTPUT, 0, dataSize);
264 0 : std::unique_ptr<Primitive> primLocalCopy = std::make_unique<PrimLocalCopy>(usrInSlice, usrOutSlice);
265 0 : queue->Append(std::move(primLocalCopy));
266 :
267 0 : HCCL_DEBUG("[CollAlgComponent] rankSize = 1.");
268 0 : } else {
269 0 : CHK_PRT_RET(SetCollAlgExecutor(primGenFunc) != HcclResult::HCCL_SUCCESS,
270 : HCCL_ERROR("[CollAlgComponent] Unable to Set CollAlgExecutor, please check params!"),
271 : HcclResult::HCCL_E_PARA);
272 0 : primGenFunc->GenPrimQues(rankGraph_, op, params, queue);
273 : }
274 :
275 0 : HCCL_DEBUG("[CollAlgComponent] Primitive based algorithm: finish CollAlgComponent::Orchestrate.");
276 0 : return HcclResult::HCCL_SUCCESS;
277 0 : }
278 :
279 0 : HcclResult CollAlgComponent::SetCollAlgExecutor(std::shared_ptr<CollAlgBase> collAlgExecutor) const
280 : {
281 0 : if (collAlgExecutor == nullptr) {
282 0 : HCCL_ERROR("CollAlgComponent::SetCollAlgExecutor ptr is null");
283 0 : return HcclResult::HCCL_E_PTR;
284 : }
285 0 : collAlgExecutor->SetMyRank(myRank_);
286 0 : collAlgExecutor->SetRankSize(rankSize_);
287 0 : collAlgExecutor->EnableDetour(enableDetour_);
288 0 : collAlgExecutor->EnableDataAllign(enableAllign_);
289 0 : collAlgExecutor->SetAllignSize(allignSize_);
290 0 : collAlgExecutor->SetDmaMode(dmaMode_);
291 0 : collAlgExecutor->SetDevType(devType_);
292 :
293 0 : return HcclResult::HCCL_SUCCESS;
294 : }
295 :
296 0 : HcclResult CollAlgComponent::CalNumBlocks(u32& numBlocks, u64 dataSize, OpType opType, string &algName, u32 numBlocksLimit) const
297 : {
298 0 : std::string insCollAlgName;
299 :
300 0 : if (algName.empty()) {
301 0 : HCCL_ERROR("[CollAlgComponent] algName is empty");
302 0 : return HcclResult::HCCL_E_INTERNAL;
303 : } else {
304 : // 上层测试用例指定算法名字
305 0 : insCollAlgName = algName;
306 : }
307 0 : std::shared_ptr<InsCollAlgBase> insGenFunc = InsCollAlgRegistry::Global()->GetAlgImpl(opType, insCollAlgName);
308 0 : CHK_RET(insGenFunc->CalNumBlocks(numBlocks, dataSize, numBlocksLimit));
309 0 : return HcclResult::HCCL_SUCCESS;
310 0 : }
311 :
312 2 : HcclResult CollAlgComponent::Orchestrate(const CollAlgOperator &op, const CollAlgParams ¶ms, const string &algName, InsQuePtr queue)
313 : {
314 6 : HCCL_DEBUG("[CollAlgComponent] Instruction based algorithm.");
315 :
316 2 : std::string insCollAlgName;
317 :
318 2 : if (algName.empty()) {
319 6 : HCCL_ERROR("[CollAlgComponent] algName is empty");
320 2 : return HcclResult::HCCL_E_INTERNAL;
321 : } else {
322 : // 上层测试用例指定算法名字
323 0 : insCollAlgName = algName;
324 : }
325 0 : std::shared_ptr<InsCollAlgBase> insGenFunc = InsCollAlgRegistry::Global()->GetAlgImpl(op.opType, insCollAlgName);
326 :
327 0 : if (insGenFunc == nullptr) {
328 0 : HCCL_ERROR("[CollAlgComponent] Invalid opType and invalid insCollAlgName, [%s].", algName.c_str());
329 0 : return HcclResult::HCCL_E_PARA;
330 : }
331 :
332 : bool isAlltoAll =
333 0 : (op.opType == OpType::ALLTOALL) || (op.opType == OpType::ALLTOALLV) || (op.opType == OpType::ALLTOALLVC);
334 0 : if ((rankSize_ == 1) && (op.inputMem == nullptr || op.outputMem == nullptr)) {
335 0 : HCCL_INFO("[CollAlgComponent] rankSize = 1 and inputMem or outputMem is nullptr. Do nothing.");
336 0 : return HcclResult::HCCL_SUCCESS;
337 0 : } else if ((rankSize_ == 1) && (!isAlltoAll)) {
338 0 : HCCL_INFO("[CollAlgComponent] rankSize = 1, copy from input to output.");
339 0 : u64 dataSize = op.dataCount * DataTypeSizeGet(op.dataType);
340 0 : u64 inputOffset = 0;
341 0 : u64 outputOffset = 0;
342 0 : if (op.opType == OpType::ALLGATHERV) {
343 0 : CHK_PTR_NULL(op.vDataDes.displs);
344 0 : outputOffset = static_cast<u64 *>(op.vDataDes.displs)[0];
345 0 : } else if (op.opType == OpType::REDUCESCATTERV) {
346 0 : CHK_PTR_NULL(op.vDataDes.displs);
347 0 : inputOffset = static_cast<u64 *>(op.vDataDes.displs)[0];
348 : }
349 0 : DataSlice usrInSlice = DataSlice(BufferType::INPUT, inputOffset, dataSize);
350 0 : DataSlice usrOutSlice = DataSlice(BufferType::OUTPUT, outputOffset, dataSize);
351 0 : std::unique_ptr<Instruction> insLocalCopy = std::make_unique<InsLocalCopy>(usrInSlice, usrOutSlice);
352 0 : queue->Append(std::move(insLocalCopy));
353 0 : } else {
354 0 : HCCL_INFO(
355 : "[CollAlgComponent] Orchestrate, opType[%s], rankSize[%llu].", op.opType.Describe().c_str(), rankSize_);
356 0 : CHK_PRT_RET(SetInsCollAlgExecutor(insGenFunc) != HcclResult::HCCL_SUCCESS,
357 : HCCL_ERROR("[CollAlgComponent] Unable to Set InsCollAlgExecutor, please check params!"),
358 : HcclResult::HCCL_E_PARA);
359 0 : CHK_RET(insGenFunc->Orchestrate(rankGraph_, op, params, queue));
360 : }
361 0 : HCCL_DEBUG("[CollAlgComponent] Instruction based algorithm: finish CollAlgComponent::Orchestrate.");
362 0 : return HcclResult::HCCL_SUCCESS;
363 2 : }
364 :
365 0 : HcclResult CollAlgComponent::SetInsCollAlgExecutor(std::shared_ptr<InsCollAlgBase> insCollAlgExecutor) const
366 : {
367 0 : if (insCollAlgExecutor == nullptr) {
368 0 : THROW<NullPtrException>(StringFormat("CollAlgComponent::SetInsCollAlgExecutor ptr is null"));
369 : }
370 0 : insCollAlgExecutor->SetMyRank(myRank_);
371 0 : insCollAlgExecutor->SetRankSize(rankSize_);
372 0 : insCollAlgExecutor->EnableDetour(enableDetour_);
373 0 : insCollAlgExecutor->EnableDataAllign(enableAllign_);
374 0 : insCollAlgExecutor->SetAllignSize(allignSize_);
375 0 : insCollAlgExecutor->SetDmaMode(dmaMode_);
376 0 : insCollAlgExecutor->SetDevType(devType_);
377 :
378 0 : return HcclResult::HCCL_SUCCESS;
379 : }
380 :
381 0 : void CollAlgComponent::GetNHRStepNum(u32 &nSteps) const
382 : {
383 0 : for (u32 tmp = rankSize_ - 1; tmp != 0; tmp >>= 1, nSteps++) {
384 : }
385 0 : return;
386 : }
387 :
388 0 : void CollAlgComponent::GetRoundByBufferSize(OpType opType, u64 dataSize, u64 scratchBufSize, u32 &roundNum, u32 &extraNum) const
389 : {
390 0 : if (opType == OpType::ALLREDUCE || opType == OpType::REDUCE || opType == OpType::BROADCAST) {
391 0 : roundNum = (dataSize + scratchBufSize - 1) / scratchBufSize;
392 0 : extraNum = 0;
393 0 : } else if (opType == OpType::ALLGATHER || opType == OpType::REDUCESCATTER) {
394 0 : u32 oneSliceSize = scratchBufSize / rankSize_;
395 0 : roundNum = (dataSize + oneSliceSize - 1) / oneSliceSize;
396 0 : extraNum = (rankSize_ - 1) * roundNum;
397 0 : } else if (opType == OpType::SCATTER) {
398 0 : u32 oneSliceSize = scratchBufSize / rankSize_;
399 0 : roundNum = (dataSize + oneSliceSize - 1) / oneSliceSize;
400 0 : extraNum = 0;
401 : } else {
402 0 : roundNum = 1;
403 0 : extraNum = 0;
404 : }
405 0 : return;
406 : }
407 :
408 0 : HcclResult CollAlgComponent::CalcTaskNumMesh(OpType opType, u64 dataSize, u64 scratchBufSize, u32 &taskNum)
409 : {
410 0 : if (opType == OpType::ALLGATHER) {
411 0 : taskNum += 5 * (rankSize_ - 1) + 4 * (rankSize_ - TASK_NUM_CONST_TWO) + rankSize_; // 每个对端5次同步+拷贝,每个queue 4次同步,ranksize个localCopy
412 0 : } else if (opType == OpType::ALLREDUCE) {
413 0 : if (dataSize < SMALL_COUNT_512KB) {
414 0 : taskNum += 5 * (rankSize_ - 1) + 4 * (rankSize_ - TASK_NUM_CONST_TWO) + rankSize_; // 每个对端5次同步+拷贝,每个queue 4次同步
415 : } else {
416 0 : taskNum += TASK_NUM_CONST_TWO * 5 * (rankSize_ - 1) + TASK_NUM_CONST_TWO * 4 * (rankSize_ - TASK_NUM_CONST_TWO) + rankSize_; // 每个对端5次同步+拷贝,每个queue 4次同步
417 : }
418 0 : } else if (opType == OpType::REDUCESCATTER) {
419 0 : taskNum += 5 * (rankSize_ - 1) + 4 * (rankSize_ - TASK_NUM_CONST_TWO) + rankSize_; // 每个对端5次同步+拷贝,每个queue 4次同步,ranksize个localCopy、localReduce
420 0 : } else if (opType == OpType::ALLTOALL || opType == OpType::ALLTOALLV) {
421 0 : u32 numSubStep = (dataSize + scratchBufSize - 1) / scratchBufSize;
422 0 : u32 concurrentSendRecvNum = (rankSize_ > ALLTOALLV_DIRECT_FULLMESH_CONCURRENT_SIZE) ?
423 0 : ALLTOALLV_DIRECT_FULLMESH_CONCURRENT_SIZE : rankSize_;
424 0 : u64 commLoops = (rankSize_ + concurrentSendRecvNum - 1) / concurrentSendRecvNum;
425 0 : taskNum += numSubStep * commLoops * (6 * concurrentSendRecvNum); // 每步6次同步拷贝task
426 0 : } else if (opType == OpType::BROADCAST) {
427 0 : if (dataSize < SMALL_COUNT_512KB) {
428 0 : taskNum += 3 * (rankSize_ - 1 ) + 4 * (rankSize_ - TASK_NUM_CONST_TWO); // 每个对端3次同步+拷贝,每个queue 4次同步
429 : } else {
430 0 : taskNum += 6 * (rankSize_ - TASK_NUM_CONST_TWO ) + 4 * (rankSize_ - TASK_NUM_CONST_TWO); // 每个对端6次同步+拷贝,每个queue 4次同步
431 : }
432 0 : } else if (opType == OpType::SCATTER) {
433 0 : taskNum += 3 * (rankSize_ - 1) + 4 * (rankSize_ - TASK_NUM_CONST_TWO); // 每片数据3个Task,每个que同步4个Task
434 : } else {
435 0 : taskNum += HCCLV2_DEFAULT_TASK_NUM;
436 : }
437 0 : return HCCL_SUCCESS;
438 : }
439 :
440 0 : HcclResult CollAlgComponent::CalcTaskNumNHR(OpType opType, u32 &taskNum) const
441 : {
442 0 : u32 nSteps = 0;
443 0 : GetNHRStepNum(nSteps);
444 0 : if (opType == OpType::ALLGATHER) {
445 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // 每步4个卡间同步task
446 0 : } else if (opType == OpType::ALLREDUCE) {
447 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // AllGather, 每步4个卡间同步task
448 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // ReduceScatter, 每步4个卡间同步task
449 0 : } else if (opType == OpType::REDUCESCATTER) {
450 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // 每步4个卡间同步, task+数据搬运
451 0 : } else if (opType == OpType::BROADCAST) {
452 : // scatter + allgather
453 0 : taskNum += TASK_NUM_CONST_TWO * nSteps + (rankSize_ - 1) + (rankSize_ + 1);
454 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // 每步4个卡间同步task
455 0 : } else if (opType == OpType::SCATTER) {
456 0 : taskNum += TASK_NUM_CONST_TWO * nSteps + (rankSize_ - 1) + (rankSize_ + 1); // 同步+分片数据拷贝,rankSize + 1次localCopy
457 0 : } else if (opType == OpType::REDUCE) {
458 0 : taskNum += 4 * nSteps + (1LL << nSteps) + 1; // 每步4个卡间同步task
459 : } else {
460 0 : taskNum += HCCLV2_DEFAULT_TASK_NUM;
461 : }
462 0 : return HCCL_SUCCESS;
463 : }
464 :
465 2 : HcclResult CollAlgComponent::CalcTaskNum(OpType opType, DataType dataType, u32 count, u32 &taskNum)
466 : {
467 2 : if (rankSize_ == 0) {
468 6 : HCCL_ERROR("[CalcTaskNum]errNo[0x%016llx], invalid rankSize zero",
469 : HCCL_ERROR_CODE(HCCL_E_INTERNAL));
470 2 : return HCCL_E_INTERNAL;
471 : }
472 0 : std::map<OpType, std::vector<HcclAlgoType>> configAlgMap = EnvConfig::GetInstance().GetAlgoConfig().GetAlgoConfig();
473 : std::vector<HcclAlgoType> algos =
474 0 : std::vector<HcclAlgoType>(HCCL_ALGO_LEVEL_NUM, HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT);
475 0 : auto it = configAlgMap.find(opType);
476 0 : if (it != configAlgMap.end()) {
477 0 : algos = it->second;
478 : }
479 0 : u32 dataSizePerVolume = DataTypeSizeGet(dataType);
480 0 : u64 dataSize = dataSizePerVolume * count;
481 0 : u64 scratchBufSize = EnvConfig::GetInstance().GetAlgoConfig().GetBuffSize();
482 0 : HCCL_DEBUG("[CollAlgComponent][CalcTaskNum] dataSize[%llu], scratchBufSize[%llu]", dataSize, scratchBufSize);
483 0 : if (algos[0] == HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH) {
484 0 : CalcTaskNumMesh(opType, dataSize, scratchBufSize, taskNum);
485 : } else {
486 0 : CalcTaskNumNHR(opType, taskNum);
487 : }
488 :
489 0 : u32 roundNum = 0;
490 0 : u32 extraNum = 0;
491 0 : GetRoundByBufferSize(opType, dataSize, scratchBufSize, roundNum, extraNum);
492 0 : taskNum = roundNum * taskNum + extraNum;
493 0 : HCCL_DEBUG("[CollAlgComponent][CalcTaskNum] taskNum is %llu", taskNum);
494 0 : return HCCL_SUCCESS;
495 0 : }
496 : } // namespace Hccl
|