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