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