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_gather_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 : constexpr u32 MODULE_NUM_FOUR = 4;
18 : constexpr u32 HCCL_310P_DATA_SIZE_MID_COUNT = 320 * 1024;
19 : constexpr u32 HCCL_310P_DATA_SIZE_SMALL_COUNT = 1024;
20 : constexpr u32 HCCL_310P_SLIM_RING_MAX_SIZE = 8;
21 : constexpr u32 HCCL_91093_TOTAL_DATA_SIZE_FOR_PIPELINE = 637534208; // 608M
22 : constexpr u64 ALLGATHER_PIPELINE_THRESHOLD = 4194304; // 4MB
23 :
24 : namespace hccl {
25 10 : AllGatherOperator::AllGatherOperator(AlgConfigurator* algConfigurator, CCLBufferManager &cclBufferManager,
26 10 : HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher> &topoMatcher)
27 10 : : CollAlgOperator(algConfigurator, cclBufferManager, dispatcher, topoMatcher, HcclCMDType::HCCL_CMD_ALLGATHER)
28 : {
29 10 : }
30 :
31 22 : AllGatherOperator::~AllGatherOperator()
32 : {
33 22 : }
34 :
35 11 : HcclResult AllGatherOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName,
36 : std::string& newTag)
37 : {
38 11 : if (userRankSize_ == 1) {
39 0 : algName = "AllGatherSingleExecutor";
40 0 : HCCL_INFO("[SelectAlg] AllGather SelectAlg is algName [%s]", algName.c_str());
41 0 : return HCCL_SUCCESS;
42 : }
43 : HcclResult ret;
44 :
45 11 : if (isDiffDeviceType_) {
46 0 : ret = SelectAlgforMix(param, algName);
47 11 : } else if (deviceType_ == DevType::DEV_TYPE_310P3) {
48 4 : ret = SelectAlgfor310P3(param, algName);
49 7 : } else if (deviceType_ == DevType::DEV_TYPE_910) {
50 0 : ret = SelectAlgfor910A(param, algName);
51 7 : } else if (deviceType_ == DevType::DEV_TYPE_910B) {
52 4 : ret = SelectAlgfor910B(param, algName);
53 3 : } else if (deviceType_ == DevType::DEV_TYPE_910_93) {
54 3 : ret = SelectAlgfor91093(param, algName);
55 : } else {
56 0 : HCCL_ERROR("[AllGatherSelector][SelectAlg] device type[%d] is out of range for selector.", deviceType_);
57 0 : return HCCL_E_NOT_SUPPORT;
58 : }
59 11 : CHK_PRT_RET(ret != HCCL_SUCCESS,
60 : HCCL_ERROR("[AllGatherSelector][SelectAlg]tag[%s], AllGather failed, return[%d]", tag.c_str(), ret), ret);
61 11 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
62 4 : newTag = tag;
63 7 : } else if (deviceType_ == DevType::DEV_TYPE_310P3) {
64 4 : newTag = tag + algName;
65 : } else {
66 3 : AlgTypeLevel1 algType1 = algType_.algoLevel1;
67 3 : auto level1Iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algType1);
68 3 : CHK_PRT_RET(level1Iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(),
69 : HCCL_ERROR("[AllGatherSelector]level1: algType1[%u] is invalid.", algType1), HCCL_E_INTERNAL);
70 3 : newTag = tag + level1Iter->second + algName;
71 : }
72 11 : if (algName == "AllGatherARSFor91093Executor") {
73 0 : u32 ringSize = CalcOptimalIntraRingsize(param.DataDes.count, param.DataDes.dataType, HcclCMDType::HCCL_CMD_ALLGATHER);
74 0 : newTag += std::to_string(ringSize);
75 : }
76 10 : newTag += (param.aicpuUnfoldMode ? "_device" : "_host");
77 11 : HCCL_DEBUG("[AllGatherSelector][SelectAlg]newTag is [%s].", newTag.c_str());
78 11 : return ret;
79 : }
80 :
81 0 : HcclResult AllGatherOperator::SelectAlgforMix(const OpParam& param, std::string& algName)
82 : {
83 : (void) param;
84 0 : if (gcdDeviceNumPerAggregation_ > 1) {
85 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
86 0 : HCCL_WARNING("[AllGatherOperator][SelectAlgforMix]only support NHR in AlgoLevel1 yet, "\
87 : "default is algType=NHR.");
88 0 : algName = "AllGatherMixExecutor";
89 : } else {
90 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_RING;
91 0 : HCCL_WARNING("[AllGatherOperator][SelectAlgforMix]only support ring in AlgoComm yet, "\
92 : "default is algType=ring.");
93 0 : algName = "AllGatherComm";
94 : }
95 :
96 0 : HCCL_INFO("[SelectAlgforMix] AllGather SelectAlgforMix is algName [%s]", algName.c_str());
97 0 : return HCCL_SUCCESS;
98 : }
99 :
100 4 : HcclResult AllGatherOperator::SelectAlgfor310P3(const OpParam& param, std::string& algName)
101 : {
102 4 : if(HCCL_310P_DATA_SIZE_SMALL_COUNT< param.DataDes.count &¶m.DataDes.count <= HCCL_310P_DATA_SIZE_MID_COUNT && userRankSize_ <= HCCL_310P_SLIM_RING_MAX_SIZE){
103 0 : algName = "AllGatherSlimRingFor310PExecutor";
104 : } else {
105 4 : algName = "AllGatherFor310PExecutor";
106 : }
107 4 : HCCL_INFO("[SelectAlgfor310P3] AllGather SelectAlgfor310P3 is algName [%s].", algName.c_str());
108 4 : return HCCL_SUCCESS;
109 : }
110 :
111 0 : HcclResult AllGatherOperator::SelectAlgfor910A(const OpParam& param, std::string& algName)
112 : {
113 : (void) param;
114 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_4P_MESH || topoType_ == TopoType::TOPO_TYPE_2P_MESH;
115 0 : bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING || topoType_ == TopoType::TOPO_TYPE_8P_RING;
116 :
117 0 : if (isMeshTopo) {
118 0 : algName = "AllGatherMeshExecutor";
119 0 : } else if (isRingTopo) {
120 0 : algName = "AllGatherRingExecutor";
121 : } else {
122 0 : algName = "AllGatherComm";
123 : }
124 0 : HCCL_INFO("[SelectAlgfor910A] AllGather SelectAlgfor910A is algName [%s]", algName.c_str());
125 0 : return HCCL_SUCCESS;
126 : }
127 :
128 4 : HcclResult AllGatherOperator::SelectAlgfor910B(const OpParam& param, std::string& algName)
129 : {
130 4 : u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
131 4 : u64 dataSize = param.DataDes.count * unitSize; // 单位:字节
132 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH ||
133 4 : topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
134 4 : bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING;
135 4 : bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
136 4 : bool isAivMode = topoMatcher_->GetAivModeConfig()
137 0 : && isSingleMeshAggregation_
138 0 : && IsSupportAIVCopy(param.DataDes.dataType)
139 4 : && (dataSize <= AIV_BIG_SIZE || isOnlyAiv);
140 4 : bool isA2APreAG = (param.tag == HCCL_ALLTOALL_PARA_ALLGATHER);
141 4 : if (isAivMode && !isA2APreAG) {
142 0 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && dataSize <= AIV_ALL_GATHER_SMALL_SIZE) {
143 0 : algName = "AllGatherMeshAivSmallCountExecutor";
144 0 : HCCL_INFO("[SelectAlgfor910BAIV] AllGather SelectAlgfor910B is algName [%s]", algName.c_str());
145 : } else {
146 0 : algName = "AllGatherMeshAivExecutor";
147 0 : HCCL_INFO("[SelectAlgfor910BAIV] AllGather SelectAlgfor910B is algName [%s]", algName.c_str());
148 : }
149 0 : return HCCL_SUCCESS;
150 : }
151 :
152 4 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && !isSingleMeshAggregation_) {
153 0 : u64 cclBufferSize = cclBufferManager_.GetOutCCLbufferSize() / userRankSize_;
154 0 : std::string algTypeLevel1Tag;
155 0 : CHK_RET(AutoSelectAlgTypeLevel1(HcclCMDType::HCCL_CMD_ALLGATHER, dataSize, cclBufferSize, algTypeLevel1Tag));
156 0 : if (GetExternalInputHcclEnableEntryLog() && param.opBaseAtraceInfo != nullptr) {
157 0 : CHK_RET(param.opBaseAtraceInfo->SavealgtypeTraceInfo(algTypeLevel1Tag, param.tag));
158 : }
159 0 : }
160 :
161 : // AHC 算法选择逻辑
162 4 : if (((algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC) ||
163 4 : (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE))) {
164 0 : CHK_RET(SelectAlgforAHC(dataSize, AHCOpType::AHC_OP_TYPE_ALLGATHER));
165 : }
166 :
167 : // pipeline算法task数量多,如果超出FFTS子图限制,则重定向到HD算法
168 4 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE) {
169 0 : u32 contextNum = CalcContextNumForPipeline(HcclCMDType::HCCL_CMD_ALLGATHER);
170 0 : if (contextNum > HCCL_FFTS_CAPACITY) {
171 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
172 0 : HCCL_WARNING("[AllGatherOperator][SelectAlgfor910B] context num[%u] is out of capacity of FFTS+ graph[%u], "
173 : "reset algorithm to HD.", contextNum, HCCL_FFTS_CAPACITY);
174 : }
175 : }
176 :
177 : // 多机场景下aiv支持情况
178 4 : void *commInputPtr = nullptr;
179 4 : void *commOutputPtr = nullptr;
180 4 : u64 commInputSize = 0;
181 4 : u64 commOutputSize = 0;
182 :
183 4 : CHK_RET(cclBufferManager_.GetInCCLbuffer(commInputPtr, commInputSize));
184 4 : CHK_RET(cclBufferManager_.GetOutCCLbuffer(commOutputPtr, commOutputSize));
185 4 : bool isServNumPowOfTwo = (serverNum_ > 0) && ((serverNum_ & (serverNum_ - 1)) == 0);
186 8 : bool isSupportAivRdmaCount = !isSingleMeshAggregation_
187 0 : && !multiModuleDiffDeviceNumMode_
188 4 : && (((isServNumPowOfTwo || dataSize <= HCCL_SMALL_COUNT_128_KB)
189 0 : && dataSize * userRankSize_ <= HCCL_MID_COUNT_16_MB
190 0 : && dataSize <= HCCL_SMALL_COUNT_256_KB) || isOnlyAiv);
191 :
192 4 : bool isOpbase = (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
193 : // 暂只支持单算子模式
194 4 : bool isCCLBufferGE16M = isOpbase && commInputSize >= HCCL_MID_COUNT_16_MB && commOutputSize >= HCCL_MID_COUNT_16_MB;
195 :
196 4 : bool isAivRdmaMode = topoMatcher_->GetAivModeConfig()
197 0 : && IsSupportAIVCopy(param.DataDes.dataType)
198 0 : && isMeshTopo
199 0 : && isCCLBufferGE16M
200 4 : && isSupportAivRdmaCount;
201 4 : if (isAivRdmaMode && !isA2APreAG) {
202 0 : algName = "AllGatherAivRdmaExecutor";
203 4 : } else if (isMeshTopo) {
204 4 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
205 0 : if (isSingleMeshAggregation_) {
206 0 : algName = "AllGatherMeshOpbaseExecutor";
207 0 : } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE) {
208 0 : algName = "AllGatherMeshOpbasePipelineExecutor";
209 : }
210 : }
211 4 : if (algName.empty()) {
212 4 : if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB && moduleNum_ > 1 &&
213 0 : deviceNumPerAggregation_ > 1 &&
214 0 : (dataSize > HCCL_SMALL_COUNT_1_MB || moduleNum_ <= MODULE_NUM_FOUR ||
215 0 : algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE)) {
216 0 : algName = "AllGatherMeshGraphPipelineExecutor";
217 4 : } else if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE ||
218 : dataSize > HCCL_SMALL_COUNT_1_MB) {
219 0 : algName = "AllGatherMeshExecutor";
220 4 : } else if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
221 4 : algName = "AllGatherMeshGraphExecutor";
222 : }
223 : }
224 0 : } else if (isRingTopo) {
225 0 : algName = "AllGatherRingExecutor";
226 : } else {
227 0 : algName = "AllGatherComm";
228 : }
229 : // 如果配置了aiv only,但是实际没有选择aiv算法,需要通过DFX打印出具体原因
230 4 : if (isOnlyAiv && !isAivRdmaMode) {
231 0 : HCCL_ERROR("The current conditions do not meet the aiv only execution criteria because:");
232 0 : CHK_PRT_RET(!IsSupportAIVCopy(param.DataDes.dataType), HCCL_ERROR("current data type[%s] not supported, support range: "\
233 : "[int8, int16, int32, uint8, uint16, uint32, float16, float32, bfloat16]",
234 : GetDataTypeEnumStr(param.DataDes.dataType).c_str()), HCCL_E_NOT_SUPPORT);
235 0 : CHK_PRT_RET(!isMeshTopo, HCCL_ERROR("current topo type[%d] not supported", topoType_), HCCL_E_NOT_SUPPORT);
236 0 : CHK_PRT_RET(!isCCLBufferGE16M, HCCL_ERROR("current isOpbase[%d] or commInputSize[%llu] or commOutputSize[%llu] not supported",
237 : isOpbase, commInputSize, commOutputSize), HCCL_E_NOT_SUPPORT);
238 0 : CHK_PRT_RET(!isSingleMeshAggregation_ && multiModuleDiffDeviceNumMode_,
239 : HCCL_ERROR("The number of cards between servers in a multi-server setup must be consistent. "\
240 : "isSingleMeshAggregation_[%d] multiModuleDiffDeviceNumMode_[%d]",
241 : isSingleMeshAggregation_, multiModuleDiffDeviceNumMode_), HCCL_E_NOT_SUPPORT);
242 0 : return HCCL_E_NOT_SUPPORT;
243 : }
244 4 : HCCL_INFO("[SelectAlgfor910B] AllGather SelectAlgfor910B is algName [%s], current mode is [%u].", algName.c_str(), workflowMode_);
245 4 : return HCCL_SUCCESS;
246 : }
247 :
248 3 : bool AllGatherOperator::SmallCountOptimSinglePod(const OpParam& param)
249 : {
250 3 : u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
251 3 : u64 totalSize = param.DataDes.count * unitSize * userRankSize_;
252 3 : void *commInputPtr = nullptr;
253 3 : u64 commInputSize = 0;
254 3 : CHK_RET(cclBufferManager_.GetInCCLbuffer(commInputPtr, commInputSize));
255 :
256 3 : bool smallCountOptimSingleServer = (serverNum_ == 1) &&
257 0 : ((workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && commInputSize >= totalSize) ||
258 0 : (workflowMode_ != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && !param.aicpuUnfoldMode)) &&
259 0 : (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_512_KB) &&
260 3 : (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO) && !GetExternalInputInterHccsDisable();
261 :
262 6 : bool dmaReduceLimit= (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) &&
263 3 : (((deviceNumPerAggregation_ % HCCL_DEVICE_NUM_FOUR == 0) && (commInputSize * HCCL_DEVICE_NUM_FOUR < totalSize)) ||
264 3 : ((deviceNumPerAggregation_ % HCCL_DEVICE_NUM_TWO == 0) && (commInputSize * HCCL_DEVICE_NUM_TWO < totalSize)) ||
265 1 : ((deviceNumPerAggregation_ % HCCL_DEVICE_NUM_TWO != 0) && (commInputSize < totalSize)));
266 : bool smallCountOptimMultiServer =
267 0 : (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO) && (serverNum_ != 1) && (superPodNum_ == 1) &&
268 0 : (((deviceNumPerAggregation_ % HCCL_DEVICE_NUM_FOUR == 0) && (param.DataDes.count * unitSize * serverNum_ <= HCCL_SMALL_COUNT_1_MB)) ||
269 0 : ((deviceNumPerAggregation_ % HCCL_DEVICE_NUM_FOUR != 0) && (param.DataDes.count * unitSize * serverNum_ <= HCCL_SMALL_COUNT_512_KB))) &&
270 3 : !dmaReduceLimit && !GetExternalInputInterHccsDisable();
271 3 : return smallCountOptimSingleServer || smallCountOptimMultiServer;
272 : }
273 :
274 3 : HcclResult AllGatherOperator::SelectAlgfor91093(const OpParam& param, std::string& algName)
275 : {
276 3 : u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
277 3 : u64 dataSize = param.DataDes.count * unitSize; // 单位:字节
278 3 : if (dataSize >= cclBufferManager_.GetInCCLbufferSize()) {
279 2 : HCCL_WARNING("The current inCCLbufferSize is [%llu] bytes, change the HCCL_BUFFSIZE environment variable "\
280 : "to be greater than the current data volume[%llu] bytes to improve the performance of the 91093 environment.",
281 : cclBufferManager_.GetInCCLbufferSize(), dataSize);
282 : }
283 3 : bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
284 3 : bool isOpbase = workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
285 :
286 3 : bool isAivCrossNode = superPodNum_ == 1
287 0 : && serverNum_ > 1
288 0 : && !GetExternalInputInterHccsDisable()
289 3 : && ((
290 0 : (userRankSize_ <= ONE_EIGHTH_MAX_NUM_BLOCKS && dataSize <= AIV_ALL_GATHER_A3_SMALL_RANKSIZE_ENTRY_SIZE) ||
291 0 : (userRankSize_ <= ONE_THIRD_MAX_NUM_BLOCKS && dataSize <= AIV_ALL_GATHER_A3_MID_RANKSIZE_ENTRY_SIZE) ||
292 : (dataSize <= AIV_ALL_GATHER_A3_LARGE_RANKSIZE_ENTRY_SIZE)
293 0 : ) || isOnlyAiv);
294 :
295 6 : bool isAivSingleNode = (serverNum_ == 1)
296 3 : && (
297 0 : (isOpbase && (dataSize <= AIV_ALL_GATHER_A3_ENTRY_SIZE || isOnlyAiv)) ||
298 0 : (!isOpbase && (dataSize <= AIV_ALL_GATHER_A3_GRAPH_ENTRY_SIZE || isOnlyAiv))
299 : );
300 :
301 3 : bool isAivMode = topoMatcher_->GetAivModeConfig()
302 0 : && IsSupportAIVCopy(param.DataDes.dataType)
303 0 : && (isAivSingleNode || isAivCrossNode)
304 0 : && !retryEnable_
305 3 : && !multiModuleDiffDeviceNumMode_;
306 3 : if (isAivMode) {
307 0 : if (isAivCrossNode) {
308 0 : algName = "AllGatherMeshAivFor91093Executor";
309 0 : } else if ((isOpbase && dataSize <= AIV_ALL_GATHER_SMALL_SIZE)
310 0 : || (!isOpbase && dataSize <= AIV_A3_ALL_GATHER_GRAPH_GUIYI_SIZE)) {
311 0 : algName = "AllGatherMeshAivSmallCountExecutor"; // 目前a3 aivmode下单算子模式正好全走小数据
312 : } else {
313 0 : algName = "AllGatherMeshAivExecutor";
314 : }
315 0 : HCCL_INFO("[SelectAlgfor91093] AllGather SelectAlgfor91093 is algName [%s].", algName.c_str());
316 0 : return HCCL_SUCCESS;
317 : }
318 :
319 3 : bool smallCountOptimSinglePod = SmallCountOptimSinglePod(param);
320 3 : bool is2Pod2ServerTopo = (superPodNum_ == 2 && serverNum_ == 2);// 针对 A3背靠背机型
321 3 : bool smallCountOptimMultiPod = (superPodNum_ > 1 || (GetExternalInputInterHccsDisable() && serverNum_ > 1)) && !is2Pod2ServerTopo &&
322 6 : (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_16_KB) && !retryEnable_; // 涉及ROCE平面
323 : // 多超节点的中等数据量
324 0 : bool midCountOptimMultiPod = (superPodNum_ > 1) && isOpbase &&
325 3 : (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_256_KB) && !retryEnable_; // 涉及ROCE平面
326 :
327 : // ARS 算法选择
328 3 : bool isARSAlgo = multiModuleDiffDeviceNumMode_ && !multiSuperPodDiffDeviceNumMode_;
329 3 : if (isARSAlgo) {
330 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB || algType_.algoLevel1 ==
331 : AlgTypeLevel1::ALG_LEVEL1_RING)) {
332 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
333 0 : HCCL_WARNING("[AllGatherOperator][SelectAlgfor91093] ARS only support NHR or RING in AlgoLevel1 "\
334 : "yet, default is NHR.");
335 : }
336 : }
337 : // AHC 算法选择逻辑
338 3 : bool isAHCAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC) || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE);
339 3 : if (isAHCAlgo) {
340 0 : CHK_RET(SelectAlgforAHC(dataSize, AHCOpType::AHC_OP_TYPE_ALLGATHER));
341 : }
342 :
343 3 : u64 maxSizePerLoop = cclBufferManager_.GetInCCLbufferSize() / HCCL_DEVICE_NUM_TWO / userRankSize_
344 3 : / HCCL_MIN_SLICE_ALIGN * HCCL_MIN_SLICE_ALIGN;
345 :
346 3 : bool isHccsPlusSio = userRankSize_ == 2 && pairLinkCounter_[static_cast<u32>(LinkTypeInServer::SIO_TYPE)] == 2 &&
347 0 : pairLinkCounter_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)] == 0;
348 3 : isHccsPlusSio = false;
349 3 : if (isHccsPlusSio && isSupportHccsAndSio_) {
350 0 : algName = "AllGatherHccsSioExecutor";
351 3 : } else if (multiModuleDiffDeviceNumMode_ && multiSuperPodDiffDeviceNumMode_) {
352 0 : algName = "AllGatherComm";
353 3 : } else if (multiModuleDiffDeviceNumMode_ && !multiSuperPodDiffDeviceNumMode_) {
354 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB || algType_.algoLevel1 ==
355 : AlgTypeLevel1::ALG_LEVEL1_RING)) {
356 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
357 0 : HCCL_WARNING("[AllGatherOperator][SelectAlgfor91093] ARS only support NHR or RING in AlgoLevel1 "\
358 : "yet, default is NHR.");
359 : }
360 0 : algName = "AllGatherARSFor91093Executor";
361 3 : } else if (smallCountOptimMultiPod) {
362 0 : algName = "AllGatherComm";
363 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
364 3 : } else if (smallCountOptimSinglePod) {
365 0 : algName = "AllGatherSmallCount";
366 3 : } else if (midCountOptimMultiPod) {
367 0 : algName = "AllGatherMidCountFor91093Executor";
368 3 : } else if ((param.supportSymmetricMemory || param.supportZeroCopy) &&
369 0 : (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING || param.DataDes.count * unitSize * deviceNumPerAggregation_ > HCCL_MID_COUNT_16_MB)) {
370 0 : const u32 SEVER_NUM_FOUR = 4;
371 0 : constexpr u64 RING_EXCHANGE_PIPELINE_DATA_SIZE_MIN = 2 * 1024 * 1024;
372 0 : HcclAlgoType configAlgTypeLevel2 = topoMatcher_->GetAlgoConfig(HcclCMDType::HCCL_CMD_ALLGATHER)[HCCL_ALGO_LEVEL_2];
373 0 : bool setPipelineAlgo = ((configAlgTypeLevel2 == HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE) ||
374 0 : (configAlgTypeLevel2 == HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT && dataSize >= RING_EXCHANGE_PIPELINE_DATA_SIZE_MIN));
375 0 : if (superPodNum_ > 1 && userRankSize_ / superPodNum_ > 1 && setPipelineAlgo) {
376 0 : algName = "AllGatherRingZerocopyPipelineExecutor"; // 连续数据通信+额外的数据交换,Level2和level0+1并发流水
377 0 : algType_.algoLevel2 = AlgTypeLevel2::ALG_LEVEL2_PIPELINE;
378 0 : } else if (serverNum_ < SEVER_NUM_FOUR || isAHCAlgo) {
379 0 : algName = "AllGatherRingZerocopyExecutor"; // 非连续数据通信(限制Server数,避免数据切太碎)
380 : } else {
381 0 : algName = "AllGatherRingZerocopyExchangeExecutor"; // 连续数据通信+额外的数据交换(AHC不支持)
382 : }
383 3 : } else if (superPodNum_ > 1 && maxSizePerLoop >= ALLGATHER_PIPELINE_THRESHOLD && dataSize * userRankSize_ > HCCL_91093_TOTAL_DATA_SIZE_FOR_PIPELINE
384 0 : && isOpbase && !isAHCAlgo && !multiModuleDiffDeviceNumMode_
385 0 : && (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING
386 0 : || topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING)) {
387 0 : algName = "AllGatherPipelineFor91093Executor";
388 : } else {
389 3 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB ||
390 1 : algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC ||
391 1 : algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE )) {
392 1 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
393 1 : HCCL_WARNING("[AllGatherOperator][SelectAlgfor91093] only support ring, NB AHC and NHR in AlgoLevel1 yet, "\
394 : "default is algType=NHR.");
395 : }
396 3 : if (IsSupportUnifiedMarch(param, topoType_, serverNum_, superPodNum_)) {
397 0 : algName = "AllGatherSemiRingExecutor";
398 3 : } else if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
399 2 : algName = "AlignedAllGatherDoubleRingFor91093Executor";
400 1 : } else if (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING){
401 1 : algName = "AllGatherRingFor91093Executor";
402 : } else {
403 0 : algName = "AllGatherComm";
404 : }
405 : }
406 : // 如果配置了aiv only,但是实际没有选择aiv算法,需要通过DFX打印出具体原因
407 3 : if (isOnlyAiv && !isAivMode) {
408 0 : HCCL_ERROR("The current conditions do not meet the aiv only execution criteria because:");
409 0 : CHK_PRT_RET(!IsSupportAIVCopy(param.DataDes.dataType), HCCL_ERROR("current data type[%s] not supported, support range: "\
410 : "[int8, int16, int32, uint8, uint16, uint32, float16, float32, bfloat16]",
411 : GetDataTypeEnumStr(param.DataDes.dataType).c_str()), HCCL_E_NOT_SUPPORT);
412 0 : CHK_PRT_RET(!isAivSingleNode && !isAivCrossNode,
413 : HCCL_ERROR("not is aiv single or cross node. serverNum_[%u] isOpbase[%d] superPodNum_[%u]",
414 : serverNum_, isOpbase, superPodNum_), HCCL_E_NOT_SUPPORT);
415 0 : CHK_PRT_RET(retryEnable_, HCCL_ERROR("retryEnable_[%d] is true.", retryEnable_), HCCL_E_NOT_SUPPORT);
416 0 : CHK_PRT_RET(multiModuleDiffDeviceNumMode_, HCCL_ERROR("multiModuleDiffDeviceNumMode [%d] not supported", multiModuleDiffDeviceNumMode_), HCCL_E_NOT_SUPPORT);
417 0 : return HCCL_E_NOT_SUPPORT;
418 : }
419 3 : HCCL_INFO("[SelectAlgfor91093] AllGather SelectAlgfor91093 is algName [%s]", algName.c_str());
420 3 : return HCCL_SUCCESS;
421 : }
422 :
423 : REGISTER_OP(HcclCMDType::HCCL_CMD_ALLGATHER, AllGather, AllGatherOperator);
424 :
425 : }
|