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 "all_reduce_operator.h"
12 : #include "device_capacity.h"
13 : #include "coll_alg_utils.h"
14 : #include "hccl_aiv.h"
15 : #include "coll_alg_op_registry.h"
16 :
17 : namespace hccl {
18 :
19 : // 保序规约仅支持多于2卡场景(2卡时收发对端唯一, 无规约顺序差异)
20 : constexpr u32 DETERMINISTIC_MIN_USER_RANK_SIZE = 2;
21 :
22 17 : AllReduceOperator::AllReduceOperator(
23 : AlgConfigurator* algConfigurator, CCLBufferManager& cclBufferManager, HcclDispatcher dispatcher,
24 17 : std::unique_ptr<TopoMatcher>& topoMatcher)
25 17 : : CollAlgOperator(algConfigurator, cclBufferManager, dispatcher, topoMatcher, HcclCMDType::HCCL_CMD_ALLREDUCE)
26 20 : {}
27 :
28 40 : AllReduceOperator::~AllReduceOperator() {}
29 :
30 : // 如果逻辑有修改,需同步修改GetAllReduceScratchMemSize()
31 0 : HcclDataCountType AllReduceOperator::GetCountTypeForDeterAllReduce(const u64 count, const HcclDataType dataType)
32 : {
33 0 : u64 dataSize = SIZE_TABLE[dataType] * count;
34 0 : if ((GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB)) {
35 0 : if (dataSize <= HCCL_SMALL_COUNT_GRAPH_64_KB) {
36 0 : return HcclDataCountType::HCCL_COUNT_SMALL;
37 0 : } else if ((dataSize <= HCCL_MEDIUM_COUNT_GRAPH_4_MB) && (deviceNumPerAggregation_ == DEVICE_EIGHT)) {
38 0 : return HcclDataCountType::HCCL_COUNT_MEDIUM;
39 : } else {
40 0 : return HcclDataCountType::HCCL_COUNT_HUGE;
41 : }
42 : } else {
43 0 : if (dataSize <= HCCL_SMALL_COUNT_128_KB) {
44 0 : return HcclDataCountType::HCCL_COUNT_SMALL;
45 : } else {
46 0 : if (deviceNumPerAggregation_ == DEVICE_EIGHT) {
47 0 : return HcclDataCountType::HCCL_COUNT_MEDIUM;
48 : } else {
49 0 : return HcclDataCountType::HCCL_COUNT_HUGE;
50 : }
51 : }
52 : }
53 : }
54 :
55 : // 如果逻辑有修改,需同步修改GetAllReduceScratchMemSize()
56 0 : HcclResult AllReduceOperator::GetScratchSizeForDeterAllReduce(
57 : const u64 count, const HcclDataType dataType, const u32 rankSize, u64& outScratchSize)
58 : {
59 : // 两卡不需要申请额外内存
60 0 : if (rankSize == DEVICE_TWO) {
61 0 : outScratchSize = 0;
62 0 : return HCCL_SUCCESS;
63 : }
64 :
65 0 : HcclDataCountType countType = GetCountTypeForDeterAllReduce(count, dataType);
66 0 : u64 memSize = SIZE_TABLE[dataType] * count;
67 0 : switch (countType) {
68 0 : case HcclDataCountType::HCCL_COUNT_SMALL:
69 : // 小数据量下,八卡选择HD算法、非八卡选择Reduce-Bcast算法
70 0 : if (rankSize == DEVICE_EIGHT) {
71 : // one shot HD算法,需要额外的(log2(N)-1)倍内存避免读写冲突
72 0 : outScratchSize = 0;
73 : } else {
74 : // Reduce-Bcast算法,需要N-1倍内存来暂存来自其他卡的数据(先收集数据,再本地Reduce到目的内存上)
75 0 : outScratchSize = memSize * (rankSize - 1);
76 : }
77 0 : break;
78 0 : case HcclDataCountType::HCCL_COUNT_MEDIUM:
79 : // 中数据量下,八卡选择Local Reduce算法,非八卡选择MeshChunk算法,都不要额外内存
80 0 : outScratchSize = 0;
81 0 : break;
82 0 : case HcclDataCountType::HCCL_COUNT_HUGE:
83 : // 大数据量下,统一选择MeshChunk算法,不需要额外内存
84 0 : outScratchSize = 0;
85 0 : break;
86 0 : default:
87 0 : return HCCL_E_NOT_SUPPORT;
88 : }
89 :
90 0 : HCCL_DEBUG(
91 : "[GetScratchSizeForDeterAllReduce] countType=%u, rankSize=%u, memSize=%llu, outScratchSize=%llu", countType,
92 : rankSize, memSize, outScratchSize);
93 0 : return HCCL_SUCCESS;
94 : }
95 :
96 0 : HcclResult AllReduceOperator::GetAllReduceScratchSize(const u64 count, const HcclDataType dataType, u64& scratchSize)
97 : {
98 : // 针对 单机、910B、确定性计算、图模式 的特殊优化
99 0 : if (algConfigurator_->SupportDeterministicOptim()) {
100 0 : CHK_RET(GetScratchSizeForDeterAllReduce(count, dataType, deviceNumPerAggregation_, scratchSize));
101 : } else {
102 0 : u64 reservedSize = (userRankSize_ + 1) * (userRankSize_ + 1) * SIZE_TABLE[dataType];
103 :
104 0 : scratchSize = count * SIZE_TABLE[dataType] * DEVICE_TWO + reservedSize;
105 : }
106 :
107 0 : HCCL_INFO("[AllReduceOperator][GetAllReduceScratchSize] scratchSize %llu, count %llu", scratchSize, count);
108 0 : return HCCL_SUCCESS;
109 : }
110 :
111 : HcclResult
112 19 : AllReduceOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName, std::string& newTag)
113 : {
114 19 : if (userRankSize_ == 1) {
115 0 : algName = "AllReduceSingleExecutor";
116 0 : HCCL_INFO("[SelectAlg] AllReduce SelectAlg is algName [%s]", algName.c_str());
117 0 : return HCCL_SUCCESS;
118 : }
119 : HcclResult ret;
120 19 : if (isDiffDeviceType_) {
121 0 : ret = SelectAlgforMix(param, algName);
122 19 : } else if (Is310P3Common(isHaveCpuRank_, deviceType_)) {
123 0 : if (is310PDuoCard_) {
124 0 : ret = SelectAlgfor310P3DUO(param, algName);
125 : } else {
126 0 : ret = SelectAlgfor310P3(param, algName);
127 : }
128 20 : } else if (Is310PDevice()) {
129 0 : ret = SelectAlgfor310PHelper(param, algName);
130 20 : } else if (deviceType_ == DevType::DEV_TYPE_910) {
131 0 : ret = SelectAlgfor910A(param, algName);
132 20 : } else if (deviceType_ == DevType::DEV_TYPE_910B) {
133 4 : ret = SelectAlgfor910B(param, algName);
134 16 : } else if (deviceType_ == DevType::DEV_TYPE_910_93) {
135 16 : ret = SelectAlgfor91093(param, algName);
136 : } else {
137 0 : HCCL_ERROR("[AllReduceOperator][SelectAlg] device type[%d] is out of range for selector.", deviceType_);
138 0 : return HCCL_E_NOT_SUPPORT;
139 : }
140 18 : CHK_PRT_RET(
141 : ret != HCCL_SUCCESS,
142 : HCCL_ERROR("[AllReduceSelector][SelectAlg]tag[%s], AllReduce failed, return[%d]", tag.c_str(), ret), ret);
143 :
144 18 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
145 5 : if (Is310P3Common(isHaveCpuRank_, deviceType_)) {
146 0 : newTag = tag + algName;
147 : } else {
148 5 : AlgTypeLevel1 algType1 = algType_.algoLevel1;
149 5 : auto level1Iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algType1);
150 5 : CHK_PRT_RET(
151 : level1Iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(), HCCL_ERROR("level1: algType1[%u] is invalid.", algType1),
152 : HCCL_E_INTERNAL);
153 5 : newTag = tag + level1Iter->second + algName;
154 : }
155 :
156 5 : bool isInlineReduce = IsSupportSDMAReduce(
157 5 : cclBufferManager_.GetInCCLbuffer().ptr(), cclBufferManager_.GetOutCCLbuffer().ptr(), param.DataDes.dataType,
158 5 : param.reduceType);
159 5 : bool isRdmaReduce = IsSupportRDMAReduce(param.DataDes.dataType, param.reduceType);
160 5 : const std::string ALL_REDUCE_NO_INLINE = "_no_inline";
161 10 : newTag = (!isDiffDeviceType_ || (isDiffDeviceType_ && isInlineReduce && isRdmaReduce)) ?
162 : newTag :
163 5 : newTag + ALL_REDUCE_NO_INLINE;
164 5 : } else {
165 12 : newTag = tag;
166 : }
167 19 : if (algName == "AllReduceARSFor91093Executor") {
168 : u32 ringSize
169 0 : = CalcOptimalIntraRingsize(param.DataDes.count, param.DataDes.dataType, HcclCMDType::HCCL_CMD_ALLREDUCE);
170 0 : newTag += std::to_string(ringSize);
171 : }
172 19 : newTag += (param.aicpuUnfoldMode ? "_device" : "_host");
173 20 : return ret;
174 : }
175 :
176 0 : HcclResult AllReduceOperator::SelectAlgforMix(const OpParam& param, std::string& algName)
177 : {
178 : (void)param;
179 :
180 : // 混合组网场景不支持规约保序
181 0 : if (IsNeedStrictMode(param)) {
182 0 : HCCL_ERROR("[AllReduceOperator][SelectAlgforMix] not support DETERMINISTIC_STRICT mode.");
183 0 : return HCCL_E_NOT_SUPPORT;
184 : }
185 :
186 0 : if (gcdDeviceNumPerAggregation_ > 1) {
187 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
188 0 : HCCL_WARNING("[AllReduceOperator][SelectAlgforMix] only support NHR in AlgoLevel1 yet, "
189 : "default is algType=NHR.");
190 0 : algName = "AllReduceMixExecutor";
191 : } else {
192 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_RING;
193 : ;
194 0 : HCCL_WARNING("[AllReduceOperator][SelectAlgforMix] only support ring in AlgoComm yet, "
195 : "default is algType=ring.");
196 0 : algName = "AllReduceComm";
197 : }
198 :
199 0 : HCCL_INFO("[SelectAlgforMix] AllReduce SelectAlgforMix is algName [%s]", algName.c_str());
200 0 : return HCCL_SUCCESS;
201 : }
202 :
203 0 : HcclResult AllReduceOperator::SelectAlgfor310P3DUO(const OpParam& param, std::string& algName)
204 : {
205 : bool isInlineReduce
206 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
207 0 : u64 dataSize = SIZE_TABLE[param.DataDes.dataType] * param.DataDes.count;
208 :
209 0 : bool isPowOfTwo = ((userRankSize_ - 1) & userRankSize_) == 0;
210 0 : const u32 RANK_SIZE_TWO = 2;
211 0 : const u32 RANK_SIZE_EIGHT = 8;
212 :
213 0 : if (isInlineReduce) {
214 0 : if ((dataSize <= HCCL_SMALL_COUNT_256_KB && isPowOfTwo && userRankSize_ <= RANK_SIZE_EIGHT)
215 0 : || userRankSize_ == RANK_SIZE_TWO) {
216 0 : algType_.algoLevel0 = AlgTypeLevel0::ALG_LEVEL0_NP_HD;
217 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
218 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
219 0 : algName = "AllReduceDoublingDirect";
220 : } else {
221 0 : algName = "AllReduceDoubling";
222 : }
223 : }
224 : }
225 0 : if (algName.empty()) {
226 0 : algType_.algoLevel0 = AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING;
227 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING;
228 0 : algName = "AllReduceRing";
229 : }
230 0 : HCCL_INFO("[SelectAlgfor310P3DUO] AllReduce SelectAlgfor310P3DUO is algName [%s].", algName.c_str());
231 0 : return HCCL_SUCCESS;
232 : }
233 :
234 0 : HcclResult AllReduceOperator::SelectAlgfor310P3(const OpParam& param, std::string& algName)
235 : {
236 0 : bool isPowOfTwo = ((userRankSize_ - 1) & userRankSize_) == 0;
237 0 : u64 dataSize = SIZE_TABLE[param.DataDes.dataType] * param.DataDes.count;
238 :
239 : bool isInlineReduce
240 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
241 0 : if (isInlineReduce) {
242 0 : if (dataSize <= HCCL_SMALL_COUNT_256_KB && isPowOfTwo) {
243 0 : algType_.algoLevel0 = AlgTypeLevel0::ALG_LEVEL0_NP_HD;
244 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
245 0 : algName = "AllReduceDoubling";
246 : }
247 : }
248 0 : if (algName.empty()) {
249 0 : algType_.algoLevel0 = AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING;
250 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING;
251 0 : algName = "AllReduceRing";
252 : }
253 0 : HCCL_INFO("[SelectAlgfor310P3] AllReduce SelectAlgfor310P3 is algName [%s].", algName.c_str());
254 0 : return HCCL_SUCCESS;
255 : }
256 :
257 0 : HcclResult AllReduceOperator::SelectAlgfor310PHelper(const OpParam& param, std::string& algName)
258 : {
259 : (void)param;
260 0 : algName = "AllReduceReducePlusBcast";
261 0 : HCCL_INFO("[SelectAlgfor310PHelper] AllReduce SelectAlgfor310PHelper is algName [%s]", algName.c_str());
262 0 : return HCCL_SUCCESS;
263 : }
264 :
265 0 : HcclResult AllReduceOperator::SelectAlgfor910A(const OpParam& param, std::string& algName)
266 : {
267 0 : const u32 RANK_SIZE_FOUR = 4;
268 0 : const u32 RANK_SIZE_EIGHT = 8;
269 0 : u64 dataSize = SIZE_TABLE[param.DataDes.dataType] * param.DataDes.count;
270 0 : bool isOpbase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
271 : bool isInlineReduce
272 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
273 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_4P_MESH || topoType_ == TopoType::TOPO_TYPE_2P_MESH;
274 0 : bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING || topoType_ == TopoType::TOPO_TYPE_8P_RING;
275 :
276 0 : if (isOpbase && serverNum_ == 1 && dataSize <= HCCL_SMALL_COUNT_1_MB
277 0 : && (userRankSize_ == RANK_SIZE_FOUR || userRankSize_ == RANK_SIZE_EIGHT)) {
278 0 : algType_.algoLevel0 = AlgTypeLevel0::ALG_LEVEL0_NP_HD;
279 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
280 0 : if (isInlineReduce && userRankSize_ == RANK_SIZE_FOUR) {
281 0 : algName = "AllReduceDoublingDirect";
282 0 : } else if (isInlineReduce && userRankSize_ == RANK_SIZE_EIGHT) {
283 0 : algName = "AllReduceDoubling";
284 : } else {
285 0 : algName = "AllReduceSmallCountFor910";
286 : }
287 0 : } else if (isMeshTopo) {
288 0 : algName = "AllReduceMeshExecutor";
289 0 : } else if (isRingTopo) {
290 0 : algName = "AllReduceRingExecutor";
291 : } else {
292 0 : algName = "AllReduceComm";
293 : }
294 0 : HCCL_INFO("[SelectAlgfor910A] AllReduce SelectAlgfor910A is algName [%s]", algName.c_str());
295 0 : return HCCL_SUCCESS;
296 : }
297 :
298 3 : HcclResult AllReduceOperator::SelectAlgfor910B(const OpParam& param, std::string& algName)
299 : {
300 3 : HcclResult ret = HCCL_SUCCESS;
301 3 : u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
302 :
303 3 : bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
304 : bool isInlineReduce
305 2 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
306 2 : bool isRdmaReduce = IsSupportRDMAReduce(param.DataDes.dataType, param.reduceType);
307 :
308 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH
309 2 : || topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
310 2 : bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING;
311 :
312 2 : u64 dataSize = param.DataDes.count * unitSize; // 单位:字节
313 :
314 2 : void* commInputPtr = nullptr;
315 2 : void* commOutputPtr = nullptr;
316 2 : u64 commInputSize = 0;
317 2 : u64 commOutputSize = 0;
318 :
319 2 : CHK_RET(cclBufferManager_.GetInCCLbuffer(commInputPtr, commInputSize));
320 3 : CHK_RET(cclBufferManager_.GetOutCCLbuffer(commOutputPtr, commOutputSize));
321 :
322 : // aiv场景单独判断逻辑,满足AIV模式打开+支持AIVReduce+非确定性场景+外层为mesh+(单机/跨机小数据/跨机中数据)时进入分支
323 2 : bool isOpbase = (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
324 2 : bool isMesh = IsAlgTypeLevel0Mesh(algType_.algoLevel0);
325 3 : u64 rankCountSize = dataSize / deviceNumPerAggregation_;
326 3 : bool isServNumPowOfTwo = (serverNum_ > 0) && ((serverNum_ & (serverNum_ - 1)) == 0);
327 :
328 0 : bool isSupportAivRdmaSmallCount = !isSingleMeshAggregation_ && !multiModuleDiffDeviceNumMode_ && isServNumPowOfTwo
329 3 : && ((rankCountSize <= HCCL_SMALL_COUNT_190_KB || isOnlyAiv));
330 :
331 3 : bool isSupportAivRdmaMidCount
332 3 : = !isSingleMeshAggregation_ && !multiModuleDiffDeviceNumMode_ && (dataSize <= HCCL_MID_COUNT_16_MB);
333 :
334 3 : bool isSupportAivDeter = isSingleMeshAggregation_
335 2 : && (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_ENABLE)
336 3 : && (dataSize <= HCCL_SMALL_COUNT_8_MB);
337 :
338 1 : bool isCCLBufferGE16M
339 1 : = !isOpbase || (commInputSize >= HCCL_MID_COUNT_16_MB && commOutputSize >= HCCL_MID_COUNT_16_MB);
340 :
341 1 : bool isBarrierOp = param.syncMode == SyncMode::UNLIMITED_TIMEWAITSYNCMODE; // Barrier算子不使能AIV
342 1 : bool isAivMode = (topoMatcher_->GetAivModeConfig() && !isBarrierOp)
343 0 : && IsSupportAIVReduce(param.DataDes.dataType, param.reduceType) && isMesh && isCCLBufferGE16M
344 0 : && (isSingleMeshAggregation_ || isSupportAivRdmaSmallCount || isSupportAivRdmaMidCount)
345 1 : && (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE || isSupportAivDeter);
346 1 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
347 0 : std::string algTypeLevel1Tag;
348 0 : CHK_RET(AutoSelectAlgTypeLevel1(
349 : HcclCMDType::HCCL_CMD_ALLREDUCE, dataSize, commInputSize, algTypeLevel1Tag, isInlineReduce, isRdmaReduce,
350 : isAivMode));
351 0 : if (GetExternalInputHcclEnableEntryLog() && param.opBaseAtraceInfo != nullptr) {
352 0 : CHK_RET(param.opBaseAtraceInfo->SavealgtypeTraceInfo(algTypeLevel1Tag, param.tag));
353 : }
354 0 : }
355 :
356 : // AHC 算法选择逻辑
357 1 : if (((algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC)
358 1 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE))) {
359 0 : CHK_RET(SelectAlgforAHC(dataSize, AHCOpType::AHC_OP_TYPE_ALLREDUCE));
360 : }
361 :
362 : // pipeline算法task数量多,如果超出FFTS子图限制,则重定向到HD算法
363 : // 图模式不会重定向到HD算法
364 2 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE
365 1 : && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
366 0 : u32 contextNum = CalcContextNumForPipeline(HcclCMDType::HCCL_CMD_ALLREDUCE);
367 0 : if (contextNum > HCCL_FFTS_CAPACITY) {
368 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
369 0 : HCCL_WARNING(
370 : "[AllReduceOperator][SelectAlgfor910B] context num[%u] is out of capacity of FFTS+ graph[%u], "
371 : "reset algorithm to HD.",
372 : contextNum, HCCL_FFTS_CAPACITY);
373 : }
374 : }
375 :
376 1 : if (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_STRICT && multiModuleDiffDeviceNumMode_) {
377 : // 保序规约场景(多batch一致),当前不支持非对称场景
378 0 : HCCL_ERROR(
379 : "[SelectAlgfor910B] reduce order preservation only support Symmetry("
380 : "multiModuleDiffDeviceNumMode_[%d]).",
381 : multiModuleDiffDeviceNumMode_);
382 0 : return HCCL_E_NOT_SUPPORT;
383 : }
384 :
385 1 : if (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_STRICT
386 0 : && userRankSize_ > DETERMINISTIC_MIN_USER_RANK_SIZE
387 1 : && (param.DataDes.dataType == HCCL_DATA_TYPE_FP16 || param.DataDes.dataType == HCCL_DATA_TYPE_FP32
388 0 : || param.DataDes.dataType == HCCL_DATA_TYPE_BFP16)) {
389 0 : if (param.aicpuUnfoldMode || (topoMatcher_->GetAivModeConfig() && !isBarrierOp)) {
390 : // AIV / AICPU场景,规约保序优先级更高
391 0 : HCCL_WARNING(
392 : "[SelectAlgfor910B]aicpuMode[%d], AivModeConfig[%d], "
393 : "the Aiv/AICPU mode does not support when the reduce order preservation is enabled.",
394 : param.aicpuUnfoldMode, topoMatcher_->GetAivModeConfig());
395 : }
396 : // 只有浮点数存在多batch不一致的可能,整数天然一致
397 0 : algName = "AllReduceOrderPreservedExecutor";
398 1 : } else if (isAivMode) {
399 0 : if (isSupportAivDeter) {
400 0 : if (dataSize <= HCCL_SMALL_COUNT_8_MB) {
401 0 : algName = "AllReduceAivDeterSmallExecutor";
402 : } else {
403 0 : algName = "AllReduceAivDeterExecutor";
404 : }
405 0 : HCCL_INFO("[SelectAlgfor910B] AllReduce SelectAlgfor910B is algName [%s].", algName.c_str());
406 0 : return HCCL_SUCCESS;
407 : }
408 0 : bool isOpbaseBigCount = isOpbase && (dataSize >= AIV_ALL_REDUCE_BIG_SIZE);
409 0 : HCCL_INFO(
410 : "[SelectAlgfor910B] Select AivMode Alg: DataSize[%llu], RankCountSize[%llu], DeviceNumPerAgg [%u]",
411 : dataSize, rankCountSize, deviceNumPerAggregation_);
412 0 : if (isSupportAivRdmaSmallCount) {
413 0 : algName = "AllReduceSmallCountAivRdmaExecutor"; // 多server,满足二次幂,小数据量(单卡190K以内)
414 0 : } else if (isSupportAivRdmaMidCount) {
415 0 : algName = "AllReduceMidCountAivRdmaExecutor"; // 多server,中小数据量(总数据量16M以内)
416 0 : } else if (isOpbaseBigCount || !isOpbase) {
417 0 : algName = "AllReduceMeshAivExecutor"; // 单server,单算子AIV模式大数据 和 图模式AIV 共用一个Executor
418 : } else {
419 0 : algName = "AllReduceMeshAivSmallCountExecutor"; // 单server,单算子AIV模式小数据单独一个Executor
420 : }
421 : // 小于等于两卡场景单独判断逻辑
422 1 : } else if (deviceNumPerAggregation_ <= DEVICE_TWO) {
423 : // 动态图算子融合场景?
424 0 : if ((param.inputPtr == commInputPtr)
425 0 : && (param.outputPtr == commOutputPtr && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE)
426 0 : && isMeshTopo) {
427 0 : algName = "AllReduceMeshExecutor";
428 : // 两卡不存在确定性问题 server内
429 0 : } else if (SingleMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)) {
430 0 : ret = MeshTopoSelector(algName, dataSize);
431 0 : CHK_PRT_RET(
432 : ret != HCCL_SUCCESS,
433 : HCCL_ERROR("[SelectAlgfor910B] AllReduce MeshTopoSelector failed, return[%d]", ret), ret);
434 : // 标卡场景(只有2p)
435 0 : } else if (Is2U2PInfer()) {
436 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && isInlineReduce) {
437 0 : algName = "AllReduceMeshOneshotLoopExecutor";
438 : } else {
439 0 : algName = "AllReduceRingExecutor";
440 : }
441 : // 多机单卡/两卡 pipeline需单独做判断(pipeline无确定性算法,并只支持单算子模式)
442 0 : } else if (
443 0 : topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE
444 0 : && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE
445 0 : && IsMultiMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)) {
446 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
447 0 : algName = "AllReduceMeshOpbasePipelineExecutor";
448 : } else {
449 0 : algName = "AllReduceMeshGraphPipelineExecutor";
450 : }
451 : // 常规910B为mesh拓扑
452 0 : } else if (isMeshTopo) {
453 0 : algName = "AllReduceMeshExecutor";
454 : // 多机单卡topo为ring
455 0 : } else if (isRingTopo) {
456 0 : algName = "AllReduceRingExecutor";
457 : // 通信域打平场景
458 : } else {
459 0 : algName = "AllReduceComm";
460 : }
461 : // 多卡场景
462 : } else {
463 1 : if (isMeshTopo) {
464 2 : if ((param.inputPtr == commInputPtr)
465 1 : && (param.outputPtr == commOutputPtr
466 0 : && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE)) {
467 0 : algName = "AllReduceMeshExecutor";
468 : // 非确定性算法
469 1 : } else if (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE) {
470 1 : ret = NonDeterministicSelector(param, algName, dataSize);
471 : // 确定性算法
472 : } else {
473 0 : ret = DeterministicSelector(param, algName);
474 : }
475 2 : CHK_PRT_RET(
476 : ret != HCCL_SUCCESS,
477 : HCCL_ERROR("[SelectAlgfor910B] AllReduce SelectAlgfor910B failed, return[%d]", ret), ret);
478 2 : if (algName.empty()) {
479 2 : algName = "AllReduceMeshExecutor";
480 : }
481 : } else {
482 0 : algName = "AllReduceComm";
483 : }
484 : }
485 : // 如果配置了aiv only,但是实际没有选择aiv算法,需要通过DFX打印出具体原因
486 4 : if (isOnlyAiv && !isAivMode) {
487 0 : HCCL_ERROR("The current conditions do not meet the aiv only execution criteria because:");
488 0 : CHK_PRT_RET(
489 : !IsSupportAIVReduce(param.DataDes.dataType, param.reduceType),
490 : HCCL_ERROR(
491 : "current data type[%s] or reduceType[%s] not supported, "
492 : "data type support range:[int8, int16, int32, float16, float32, bfloat16] reduce type support "
493 : "range:[sum, max, min]",
494 : GetDataTypeEnumStr(param.DataDes.dataType).c_str(), GetReduceOpEnumStr(param.reduceType).c_str()),
495 : HCCL_E_NOT_SUPPORT);
496 :
497 0 : CHK_PRT_RET(
498 : !isMesh, HCCL_ERROR("current algoLevel0Mesh[%d] not supported", algType_.algoLevel0), HCCL_E_NOT_SUPPORT);
499 :
500 0 : CHK_PRT_RET(
501 : !isCCLBufferGE16M,
502 : HCCL_ERROR(
503 : "current isOpbase[%d] or commInputSize[%llu] or commOutputSize[%llu] not supported", isOpbase,
504 : commInputSize, commOutputSize),
505 : HCCL_E_NOT_SUPPORT);
506 :
507 0 : CHK_PRT_RET(
508 : !isSingleMeshAggregation_ && multiModuleDiffDeviceNumMode_,
509 : HCCL_ERROR(
510 : "The number of cards between servers in a multi-server setup must be consistent. "
511 : "isSingleMeshAggregation_[%d] multiModuleDiffDeviceNumMode_[%d]",
512 : isSingleMeshAggregation_, multiModuleDiffDeviceNumMode_),
513 : HCCL_E_NOT_SUPPORT);
514 :
515 0 : CHK_PRT_RET(!isServNumPowOfTwo, HCCL_ERROR("server num[%u] is pow of two.", serverNum_), HCCL_E_NOT_SUPPORT);
516 :
517 0 : CHK_PRT_RET(
518 : !isSupportAivRdmaMidCount, HCCL_ERROR("current data size[%llu] not support aiv rdma mid count.", dataSize),
519 : HCCL_E_NOT_SUPPORT);
520 :
521 0 : CHK_PRT_RET(
522 : !isSupportAivDeter,
523 : HCCL_ERROR(
524 : "is not support aiv deter.isSingleMeshAggregation_[%d] isOpbase[%d] deterministic config[%u], "
525 : "dataSize[%llu]",
526 : isSingleMeshAggregation_, isOpbase, topoMatcher_->GetDeterministicConfig(), dataSize),
527 : HCCL_E_NOT_SUPPORT);
528 0 : return HCCL_E_NOT_SUPPORT;
529 : }
530 4 : HCCL_INFO("[SelectAlgfor910B] AllReduce SelectAlgfor910B is algName [%s].", algName.c_str());
531 3 : return HCCL_SUCCESS;
532 : }
533 :
534 0 : HcclResult AllReduceOperator::MeshTopoSelector(std::string& algName, u64 unitSize)
535 : {
536 : // 单算子选择逻辑
537 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
538 0 : if (unitSize <= HCCL_SMALL_COUNT_256_KB) {
539 0 : algName = "AllReduceMeshSmallCountExecutor";
540 : } else {
541 0 : algName = "AllReduceMeshOpbaseLoopExecutor";
542 : }
543 : // 图模式选择逻辑
544 : } else {
545 0 : if (unitSize <= HCCL_SMALL_COUNT_GRAPH_64_KB) {
546 0 : algName = "AllReduceMeshSmallCountExecutor";
547 : } else {
548 0 : algName = "AllReduceMeshExecutor";
549 : }
550 : }
551 0 : return HCCL_SUCCESS;
552 : }
553 :
554 4 : HcclResult AllReduceOperator::NonDeterministicSelector(const OpParam& param, std::string& algName, u64 dataSize)
555 : {
556 4 : const bool isOpbase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
557 4 : if (isOpbase) {
558 0 : if (IsMultiMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)
559 0 : && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE) {
560 0 : algName = "AllReduceMeshOpbasePipelineExecutor";
561 0 : } else if (SingleMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)) {
562 0 : if (dataSize <= HCCL_SMALL_COUNT_256_KB) {
563 0 : algName = "AllReduceMeshSmallCountExecutor";
564 : } else {
565 0 : algName = "AllReduceMeshOpbaseLoopExecutor";
566 : }
567 : }
568 2 : } else if (
569 4 : GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB
570 3 : && IsMultiMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)
571 5 : && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE) {
572 0 : algName = "AllReduceMeshGraphPipelineExecutor";
573 : }
574 2 : if (!algName.empty() || !isOpbase) {
575 2 : return HCCL_SUCCESS;
576 : }
577 : const bool isInlineReduce
578 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
579 : // 单算子 + 数据量小于512kB
580 0 : if (dataSize < HCCL_SMALL_COUNT_512_KB && !isSingleMeshAggregation_ && isInlineReduce) {
581 0 : algName = "AllReduceMeshOpbaseSmallCountDeterministicExecutor";
582 : }
583 0 : return HCCL_SUCCESS;
584 : }
585 :
586 0 : HcclResult AllReduceOperator::DeterministicSelector(const OpParam& param, std::string& algName)
587 : {
588 : // 确定性图和单算子归一流程
589 0 : HcclDataCountType countType = GetCountTypeForDeterAllReduce(param.DataDes.count, param.DataDes.dataType);
590 0 : const bool isOpbase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
591 : const bool isInlineReduce
592 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
593 :
594 0 : if (isOpbase && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE
595 0 : && deviceNumPerAggregation_ > DEVICE_TWO) {
596 0 : u64 dataSize = param.DataDes.count * SIZE_TABLE[param.DataDes.dataType];
597 0 : if (dataSize >= deviceNumPerAggregation_ * HCCL_MIN_SLICE_ALIGN) {
598 0 : algName = "AllReduceDeterPipelineExecutor";
599 0 : return HCCL_SUCCESS;
600 : }
601 : }
602 0 : if (SingleMeshInlineReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType)) {
603 0 : if (countType == HcclDataCountType::HCCL_COUNT_SMALL) {
604 0 : algName = "AllReduceMeshSmallCountExecutor";
605 0 : } else if (countType == HcclDataCountType::HCCL_COUNT_MEDIUM) {
606 0 : algName = "AllReduceMeshMidCountLoopExecutor";
607 : } else {
608 0 : algName = "AllReduceMeshOneshotLoopExecutor";
609 : }
610 : } else {
611 0 : u64 dataSize = param.DataDes.count * SIZE_TABLE[param.DataDes.dataType];
612 0 : if (isOpbase && !isSingleMeshAggregation_ && isInlineReduce) {
613 0 : if (dataSize <= HCCL_SMALL_COUNT_512_KB) {
614 : // 单算子 + 确定性 + 数据量小于512kB
615 0 : algName = "AllReduceMeshOpbaseSmallCountDeterministicExecutor";
616 : } else {
617 0 : algName = "AllReduceMeshOpbaseMidCountDeterministicExecutor";
618 : }
619 : }
620 : }
621 0 : return HCCL_SUCCESS;
622 : }
623 :
624 16 : HcclResult AllReduceOperator::SelectAlgfor91093(const OpParam& param, std::string& algName)
625 : {
626 16 : u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
627 16 : u64 dataSize = param.DataDes.count * unitSize; // 单位:字节
628 16 : if (dataSize >= cclBufferManager_.GetInCCLbufferSize()) {
629 16 : HCCL_WARNING(
630 : "The current inCCLbufferSize is [%llu] bytes, change the HCCL_BUFFSIZE environment variable "
631 : "to be greater than the current data volume[%llu] bytes to improve the performance of the 91093 "
632 : "environment.",
633 : cclBufferManager_.GetInCCLbufferSize(), dataSize);
634 : }
635 :
636 16 : u64 dataSizePerRank = dataSize / deviceNumPerAggregation_;
637 16 : bool isOpbase = workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
638 16 : bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
639 : // A3 AIV确定性 超节点内(单机与跨机) 支持单算子与图模式 限制单卡数据量8MB
640 16 : bool isBarrierOp = param.syncMode == SyncMode::UNLIMITED_TIMEWAITSYNCMODE; // Barrier算子不使能AIV
641 0 : bool isSupportAivDeter = (superPodNum_ == 1) && (topoMatcher_->GetAivModeConfig() && !isBarrierOp)
642 0 : && IsSupportAIVReduce(param.DataDes.dataType, param.reduceType)
643 0 : && ((topoMatcher_->GetDeterministicConfig() != DETERMINISTIC_DISABLE) || (serverNum_ > 1))
644 0 : && ((userRankSize_ > DEVICE_EIGHT && dataSize < HCCL_SMALL_COUNT_8_MB)
645 0 : || (userRankSize_ <= DEVICE_EIGHT && dataSize <= HCCL_SMALL_COUNT_512_KB) || isOnlyAiv)
646 0 : && (!retryEnable_) && userRankSize_ > 1 && !multiModuleDiffDeviceNumMode_
647 16 : && ((!GetExternalInputInterHccsDisable()) || (serverNum_ == 1));
648 :
649 16 : bool isAivMode = (topoMatcher_->GetAivModeConfig() && !isBarrierOp)
650 0 : && IsSupportAIVReduce(param.DataDes.dataType, param.reduceType) && serverNum_ == 1
651 0 : && ((isOpbase && (dataSizePerRank <= AIV_ALL_REDUCE_A3_ENTRY_SIZE || isOnlyAiv))
652 0 : || (!isOpbase && (dataSizePerRank <= AIV_ALL_REDUCE_A3_GRAPH_ENTRY_SIZE || isOnlyAiv)))
653 0 : && (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE) && (!retryEnable_)
654 16 : && !multiModuleDiffDeviceNumMode_;
655 :
656 16 : if (isSupportAivDeter) {
657 0 : algName = "AllReduceMeshAivFor91093Executor";
658 0 : HCCL_INFO("[SelectAlgfor91093] allreduce SelectAlgfor91093 algName [%s].", algName.c_str());
659 0 : return HCCL_SUCCESS;
660 : }
661 :
662 16 : if (IsNeedStrictMode(param)) {
663 0 : CHK_PRT_RET(
664 : !CheckStrictCondition(param),
665 : HCCL_ERROR("[AllReduceOperator][SelectAlgfor91093] not support DETERMINISTIC_STRICT mode."),
666 : HCCL_E_NOT_SUPPORT);
667 :
668 0 : algName = "AllReduceOrderPreservedFor91093Executor";
669 0 : HCCL_INFO("[SelectAlgfor91093] allreduce SelectAlgfor91093 algName [%s].", algName.c_str());
670 0 : return HCCL_SUCCESS;
671 : }
672 :
673 16 : if (isAivMode) {
674 0 : HCCL_INFO(
675 : "[SelectAlgfor91093] dataSize[%llu], dataSizePerRank[%llu], deviceNumPerAggregation[%u]", dataSize,
676 : dataSizePerRank, deviceNumPerAggregation_);
677 0 : if ((isOpbase && dataSize < AIV_ALL_REDUCE_BIG_SIZE)
678 0 : || (!isOpbase && dataSize <= AIV_A3_ALL_REDUCE_GRAPH_GUIYI_SIZE)) {
679 0 : algName = "AllReduceMeshAivSmallCountExecutor"; // 单server小数据
680 : } else {
681 0 : algName = "AllReduceMeshAivExecutor"; // 单server大数据
682 : }
683 0 : HCCL_INFO("[SelectAlgfor91093] AllReduce SelectAlgfor91093 is algName [%s].", algName.c_str());
684 0 : return HCCL_SUCCESS;
685 : }
686 : // ARS 算法选择
687 16 : bool isARSAlgo = multiModuleDiffDeviceNumMode_ && !multiSuperPodDiffDeviceNumMode_;
688 16 : if (isARSAlgo) {
689 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB
690 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING)) {
691 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
692 0 : HCCL_WARNING("[AllReduceOperator][SelectAlgfor91093] ARS only support NHR or RING in AlgoLevel1 "
693 : "yet, default is NHR.");
694 : }
695 : }
696 : // AHC 算法选择逻辑
697 16 : if ((algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC)
698 8 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE)) {
699 9 : CHK_RET(SelectAlgforAHC(dataSize, AHCOpType::AHC_OP_TYPE_ALLREDUCE));
700 : }
701 16 : void* commInputPtr = nullptr;
702 16 : u64 commInputSize = 0;
703 16 : CHK_RET(cclBufferManager_.GetInCCLbuffer(commInputPtr, commInputSize));
704 16 : bool cclLimit
705 16 : = (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE)
706 16 : && (param.DataDes.count * SIZE_TABLE[param.DataDes.dataType] > (commInputSize / HCCL_MEMSIZE_HD_FACTOR));
707 :
708 : bool isSupportInlineReduce
709 16 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
710 16 : bool smallCountOptimSingleServer
711 16 : = (!retryEnable_) && (serverNum_ == 1)
712 1 : && ((workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE)
713 0 : || (workflowMode_ != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && !param.aicpuUnfoldMode))
714 1 : && isSupportInlineReduce && (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO)
715 1 : && (param.DataDes.count * SIZE_TABLE[param.DataDes.dataType] <= HCCL_SMALL_COUNT_512_KB * userRankSize_)
716 32 : && !cclLimit;
717 1 : bool smallCountOptimMultiServer = (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO) && (serverNum_ != 1)
718 0 : && (superPodNum_ == 1)
719 17 : && (param.DataDes.count * SIZE_TABLE[param.DataDes.dataType]
720 0 : <= HCCL_SMALL_COUNT_1_MB * deviceNumPerAggregation_);
721 16 : bool useHostComm = !isSupportInlineReduce
722 17 : && ((serverNum_ != 1 && superPodNum_ == 1 && !GetExternalInputInterHccsDisable())
723 1 : || ((superPodNum_ > 1 || GetExternalInputInterHccsDisable()) && !retryEnable_
724 0 : && param.DataDes.count * SIZE_TABLE[param.DataDes.dataType]
725 0 : <= HCCL_SMALL_COUNT_4_MB * deviceNumPerAggregation_));
726 16 : bool is2Pod2ServerTopo = (superPodNum_ == 2 && serverNum_ == 2); // 针对 A3背靠背机型
727 : bool smallCountOptimMultiPod
728 16 : = (superPodNum_ > 1 || (GetExternalInputInterHccsDisable() && serverNum_ > 1)) && !is2Pod2ServerTopo
729 11 : && (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_16_KB * deviceNumPerAggregation_)
730 32 : && !retryEnable_; // 涉及ROCE平面
731 : // 多超节点 的中等数据量
732 16 : bool midCountOptimMultiPod
733 11 : = (superPodNum_ > 1) && isOpbase && !multiSuperPodDiffDeviceNumMode_ && !multiModuleDiffDeviceNumMode_
734 27 : && (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_256_KB) && !retryEnable_; // 涉及ROCE平面
735 :
736 16 : if (multiModuleDiffDeviceNumMode_ && multiSuperPodDiffDeviceNumMode_) {
737 0 : algName = "AllReduceComm";
738 16 : } else if (multiModuleDiffDeviceNumMode_ && !multiSuperPodDiffDeviceNumMode_) {
739 0 : algName = "AllReduceARSFor91093Executor";
740 16 : } else if (midCountOptimMultiPod) {
741 1 : algName = "AllReduceMidCountFor91093Executor";
742 15 : } else if (useHostComm || smallCountOptimMultiServer || smallCountOptimMultiPod) {
743 10 : algName = "AllReduceComm";
744 10 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
745 5 : } else if (smallCountOptimSingleServer) {
746 0 : algName = "AllReduceMeshSmallCountExecutor";
747 5 : } else if (
748 5 : (param.supportSymmetricMemory || param.supportZeroCopy)
749 0 : && (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING
750 0 : || param.DataDes.count * unitSize > HCCL_MID_COUNT_16_MB * serverNum_)) {
751 0 : algName = "AllReduceRingZerocopyExecutor";
752 : } else {
753 5 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD) {
754 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
755 0 : HCCL_WARNING("[AllReduceOperator][SelectAlgfor91093] only support ring, NB and NHR in AlgoLevel1 yet, "
756 : "default is algType=NHR.");
757 : }
758 5 : if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
759 4 : algName = "AllReduceFastDoubleRingFor91093Executor";
760 1 : } else if (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING) {
761 1 : algName = "AllReduceRingFor91093Executor";
762 : } else {
763 0 : algName = "AllReduceComm"; // 支持91093全通信域
764 : }
765 : }
766 : // 如果配置了aiv only,但是实际没有选择aiv算法,需要通过DFX打印出具体原因
767 16 : if (isOnlyAiv && !isAivMode && !isSupportAivDeter) {
768 0 : HCCL_ERROR("The current conditions do not meet the aiv only execution criteria because:");
769 0 : CHK_PRT_RET(
770 : !IsSupportAIVReduce(param.DataDes.dataType, param.reduceType),
771 : HCCL_ERROR(
772 : "current data type[%s] or reduceType[%s] not supported, "
773 : "data type support range:[int8, int16, int32, float16, float32, bfloat16] reduce type support "
774 : "range:[sum, max, min]",
775 : GetDataTypeEnumStr(param.DataDes.dataType).c_str(), GetReduceOpEnumStr(param.reduceType).c_str()),
776 : HCCL_E_NOT_SUPPORT);
777 :
778 0 : CHK_PRT_RET(retryEnable_, HCCL_ERROR("retryEnable [%d] not supported", retryEnable_), HCCL_E_NOT_SUPPORT);
779 :
780 0 : CHK_PRT_RET(
781 : superPodNum_ != 1, HCCL_ERROR("multi superpod [%u] not supported", superPodNum_), HCCL_E_NOT_SUPPORT);
782 :
783 0 : CHK_PRT_RET(
784 : multiModuleDiffDeviceNumMode_,
785 : HCCL_ERROR("multiModuleDiffDeviceNumMode [%d] not supported", multiModuleDiffDeviceNumMode_),
786 : HCCL_E_NOT_SUPPORT);
787 0 : return HCCL_E_NOT_SUPPORT;
788 : }
789 16 : HCCL_INFO("[SelectAlgfor91093] AllReduce SelectAlgfor91093 is algName [%s].", algName.c_str());
790 16 : return HCCL_SUCCESS;
791 : }
792 :
793 : REGISTER_OP(HcclCMDType::HCCL_CMD_ALLREDUCE, AllReduce, AllReduceOperator);
794 :
795 : } // namespace hccl
|