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_auto_selector.h"
12 : #include "selector_registry.h"
13 : #include "coll_operator.h"
14 :
15 : namespace Hccl {
16 : constexpr u64 AR_M2M_1D_MAX_DATA_SIZE = 8 * 1024 * 1024;
17 : constexpr u64 AR_AICPU_1D_SMALL_DATA_SIZE = 8 * 1024 * 1024;
18 : constexpr u64 AR_AICPU_1D_MAX_DATA_SIZE = 16 * 1024 * 1024;
19 : constexpr u64 AR_ONESHOT_1D_MAX_DATA_SIZE = 16 * 1024;
20 :
21 0 : SelectorStatus AllReduceAutoSelector::SelectCcuMsAlgo(const TopoInfo &topoInfo,
22 : const CollAlgOperator &op,
23 : const std::map<OpType, std::vector<HcclAlgoType>> &configAlgMap,
24 : std::string &primQueueGenName) const
25 : {
26 : (void)configAlgMap;
27 0 : HCCL_DEBUG("[AllReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
28 0 : u32 rankSize_2P = 2;
29 0 : u32 rankSize_4P = 4;
30 : // MS 模式不支持 int8
31 0 : CHK_PRT_RET(op.dataType == DataType::INT8,
32 : HCCL_WARNING("[Algo][AllReduceAutoSelector] dataType[%s] is not supported yet for ccu_ms mode.",
33 : op.dataType.Describe().c_str()),
34 : SelectorStatus::NOT_MATCH);
35 :
36 : // MS 模式不支持 PROD
37 0 : CHK_PRT_RET(op.reduceOp == ReduceOp::PROD,
38 : HCCL_WARNING("[Algo][AllReduceAutoSelector] ReduceOp[%s] is not supported yet for ccu_ms mode.",
39 : op.reduceOp.Describe().c_str()),
40 : SelectorStatus::NOT_MATCH);
41 :
42 0 : CHK_PRT_RET(op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64,
43 : HCCL_WARNING("[Algo][AllReduceAutoSelector] ccu_ms mode not support INT64, UINT64, FP64."),
44 : SelectorStatus::NOT_MATCH);
45 :
46 0 : HcclDetourType detourType = EnvConfig::GetInstance().GetDetourConfig().GetDetourType();
47 0 : CHK_PRT_RET((detourType == HcclDetourType::HCCL_DETOUR_ENABLE_2P && rankSize_ != rankSize_2P)||
48 : (detourType == HcclDetourType::HCCL_DETOUR_ENABLE_4P && rankSize_ != rankSize_4P),
49 : HCCL_WARNING("[Algo][AllReduceAutoSelector] detourType not match for rankSize."),
50 : SelectorStatus::NOT_MATCH);
51 :
52 0 : CHK_PRT_RET(detourType == HcclDetourType::HCCL_DETOUR_ENABLE_2P_AND_4P,
53 : HCCL_WARNING("[Algo][AllReduceAutoSelector] HCCL_DETOUR_ENABLE_2P_AND_4P is not supported yet."),
54 : SelectorStatus::NOT_MATCH);
55 :
56 0 : if (topoInfo.levelNum > 1) {
57 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] levelNum > 1 is not supported yet for ccu_ms mode.");
58 0 : return SelectorStatus::NOT_MATCH;
59 : } else {
60 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
61 0 : if (IsInputOutputOverlap(op.inputMem, op.outputMem) == true) {
62 : // 不支持 inplace 场景
63 0 : return SelectorStatus::NOT_MATCH;
64 : }
65 0 : if (Is2DieFullMesh()) {
66 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] 2DieFullMesh is not supported yet for ccu_ms mode.");
67 0 : return SelectorStatus::NOT_MATCH;
68 0 : } else if ((detourType == HcclDetourType::HCCL_DETOUR_ENABLE_2P && rankSize_ == rankSize_2P)||
69 0 : (detourType == HcclDetourType::HCCL_DETOUR_ENABLE_4P && rankSize_ == rankSize_4P)) {
70 0 : primQueueGenName = "CcuAllReduceMeshDetour1D";
71 0 : } else if (dataSize_ / rankSize_ > AR_ONESHOT_1D_MAX_DATA_SIZE) {
72 0 : primQueueGenName = "CcuAllReduceMesh1D";
73 : } else {
74 0 : primQueueGenName = "CcuAllReduceMesh1DOneShot";
75 : }
76 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
77 0 : if (IsSmallData(dataSize_) && IsInputOutputOverlap(op.inputMem, op.outputMem) != true) {
78 0 : primQueueGenName = "CcuAllReduceMesh2DOneShot";
79 : } else {
80 0 : primQueueGenName = "CcuAllReduceMesh2DTwoShot";
81 : }
82 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D_CLOS) {
83 0 : if (IsLayerAllConnetedWithTopo(topoInfo, 0, TopoType::MESH_1D)) {
84 : // MESH_1D 即可链接所有卡, 使用 MESH_1D 算法
85 0 : if (IsInputOutputOverlap(op.inputMem, op.outputMem) == true) {
86 : // 不支持 inplace 场景
87 0 : return SelectorStatus::NOT_MATCH;
88 : }
89 0 : if ((detourType == HcclDetourType::HCCL_DETOUR_ENABLE_2P && rankSize_ == rankSize_2P)||
90 0 : (detourType == HcclDetourType::HCCL_DETOUR_ENABLE_4P && rankSize_ == rankSize_4P)) {
91 0 : primQueueGenName = "CcuAllReduceMeshDetour1D";
92 0 : } else if (dataSize_ / rankSize_ > AR_ONESHOT_1D_MAX_DATA_SIZE) {
93 0 : primQueueGenName = "CcuAllReduceMesh1D";
94 : } else {
95 0 : primQueueGenName = "CcuAllReduceMesh1DOneShot";
96 : }
97 0 : } else if (topoInfo.level0PcieMix) {
98 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0 PCIE mix is not supported yet for ccu_ms mode.");
99 0 : return SelectorStatus::NOT_MATCH;
100 : } else { // MS 不支持
101 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
102 : topoInfo.level0Shape);
103 0 : return SelectorStatus::NOT_MATCH;
104 : }
105 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
106 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
107 : topoInfo.level0Shape);
108 0 : return SelectorStatus::NOT_MATCH;
109 : } else {
110 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
111 : topoInfo.level0Shape);
112 0 : return SelectorStatus::NOT_MATCH;
113 : }
114 : }
115 0 : HCCL_INFO("[Algo][AllReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
116 0 : return SelectorStatus::MATCH;
117 : }
118 :
119 0 : SelectorStatus AllReduceAutoSelector::SelectCcuScheduleAlgo(const TopoInfo &topoInfo, const CollAlgOperator &op,
120 : const std::map<OpType, std::vector<HcclAlgoType>> &configAlgMap, std::string &primQueueGenName) const
121 : {
122 : (void)configAlgMap;
123 0 : HCCL_DEBUG("[AllReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
124 : // ccu 模式不支持 PROD
125 0 : CHK_PRT_RET(op.reduceOp == ReduceOp::PROD,
126 : HCCL_WARNING("[Algo][AllReduceAutoSelector] ReduceOp[%s] is not supported yet for ccu schedule mode.",
127 : op.reduceOp.Describe().c_str()),
128 : SelectorStatus::NOT_MATCH);
129 :
130 0 : CHK_PRT_RET(op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64,
131 : HCCL_WARNING("[Algo][AllReduceAutoSelector] ccu_ms mode not support INT64, UINT64, FP64."),
132 : SelectorStatus::NOT_MATCH);
133 :
134 0 : if (topoInfo.levelNum > 1) {
135 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
136 0 : if (topoInfo.netLayerDetails.localNetInsSizeOfLayer[0] == 1) {
137 : // 每框出 1 卡
138 0 : primQueueGenName = "CcuAllReduceNHR1D";
139 0 : } else if (Is2DieFullMesh()) {
140 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] 2DieFullMesh is not supported yet for schedule mode.");
141 0 : return SelectorStatus::NOT_MATCH;
142 : } else {
143 0 : CHK_PRT_RET(op.dataType == DataType::INT8,
144 : HCCL_WARNING("[Algo][AllReduceAutoSelector] dataType[%s] is not supported yet for ccu schedule "
145 : "mode with ms reduce. levelNum[%u]",
146 : op.dataType.Describe().c_str(),
147 : topoInfo.levelNum),
148 : SelectorStatus::NOT_MATCH);
149 0 : if(IsSmallDataCCU(dataSize_, rankSize_)){
150 0 : primQueueGenName = "CcuAllReduceParallelMesh1DNHR";//64M以下跑ccu
151 : } else {
152 0 : return SelectorStatus::NOT_MATCH;//64M以上切为aicpu
153 : }
154 : }
155 : } else {
156 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
157 : topoInfo.level0Shape);
158 0 : return SelectorStatus::NOT_MATCH;
159 : }
160 : } else {
161 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
162 0 : CHK_PRT_RET(op.dataType == DataType::INT8,
163 : HCCL_WARNING("[Algo][AllReduceAutoSelector] dataType[%s] is not supported yet for ccu schedule mode "
164 : "with ms reduce.",
165 : op.dataType.Describe().c_str()),
166 : SelectorStatus::NOT_MATCH);
167 : double ratio; // 以8卡为基线确定ratio,用来表示不同卡数对下发的影响系数
168 0 : if (rankSize_ == 0) {
169 0 : HCCL_WARNING("[AllReduceAutoSelector]the selector is not set RankSize_]");
170 0 : ratio = 1;
171 : } else {
172 0 : ratio = DEFAULT_RANK_SIZE / rankSize_ / rankSize_;
173 : }
174 0 : if (Is2DieFullMesh()) {
175 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] 2DieFullMesh is not supported yet for schedule mode.");
176 0 : return SelectorStatus::NOT_MATCH;
177 0 : } else if (dataSize_ * ratio > AR_M2M_1D_MAX_DATA_SIZE) {
178 0 : return SelectorStatus::NOT_MATCH;
179 : }
180 0 : primQueueGenName = "CcuAllReduceMeshMem2Mem1D";
181 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
182 0 : primQueueGenName = "CcuAllReduceMeshTwoShotMem2Mem2D";
183 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D_CLOS) {
184 0 : CHK_PRT_RET(op.dataType == DataType::INT8,
185 : HCCL_WARNING("[Algo][AllReduceAutoSelector] dataType[%s] is not supported yet for ccu schedule mode "
186 : "with ms reduce.",
187 : op.dataType.Describe().c_str()),
188 : SelectorStatus::NOT_MATCH);
189 0 : if (IsLayerAllConnetedWithTopo(topoInfo, 0, TopoType::MESH_1D)) {
190 : // MESH_1D 即可链接所有卡, 使用 MESH_1D 算法
191 : double ratio; // 以8卡为基线确定ratio,用来表示不同卡数对下发的影响系数
192 0 : if (rankSize_ == 0) {
193 0 : HCCL_WARNING("[AllReduceAutoSelector]the selector is not set RankSize_]");
194 0 : ratio = 1;
195 : } else {
196 0 : ratio = DEFAULT_RANK_SIZE / rankSize_ / rankSize_;
197 : }
198 0 : if (dataSize_ * ratio > AR_M2M_1D_MAX_DATA_SIZE) {
199 0 : return SelectorStatus::NOT_MATCH;
200 : }
201 0 : primQueueGenName = "CcuAllReduceMeshMem2Mem1D";
202 0 : } else if (topoInfo.level0PcieMix) {
203 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0 PCIE mix is not supported yet for ccu schedule mode.");
204 0 : return SelectorStatus::NOT_MATCH;
205 : } else {
206 0 : if(IsSmallDataCCU(dataSize_, rankSize_)){
207 0 : primQueueGenName = "CcuAllReduceParallelMesh1DNHR";//64M以下跑ccu
208 : } else {
209 0 : return SelectorStatus::NOT_MATCH;//64M以上切为aicpu
210 : }
211 : }
212 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
213 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
214 : topoInfo.level0Shape);
215 0 : return SelectorStatus::NOT_MATCH;
216 : } else {
217 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
218 : topoInfo.level0Shape);
219 0 : return SelectorStatus::NOT_MATCH;
220 : }
221 : }
222 :
223 0 : HCCL_INFO("[Algo][AllReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
224 0 : return SelectorStatus::MATCH;
225 : }
226 :
227 0 : SelectorStatus AllReduceAutoSelector::SelectAicpuAlgo(const TopoInfo &topoInfo, const CollAlgOperator &op,
228 : const std::map<OpType, std::vector<HcclAlgoType>> &configAlgMap, std::string &primQueueGenName) const
229 : {
230 : (void)configAlgMap;
231 0 : HCCL_DEBUG("[AllReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
232 :
233 0 : if (topoInfo.levelNum > 1) {
234 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64 || op.reduceOp == ReduceOp::PROD) {
235 0 : HCCL_ERROR("[SelectAicpuAlgo] INT64, UINT64, FP64 and reduceop::prod only support in-box fullmesh algo type now.");
236 0 : return SelectorStatus::NOT_MATCH;
237 : }
238 0 : if (topoInfo.Level1Nhr) {
239 0 : primQueueGenName = "InsAllReduceNHR";
240 0 : } else if (topoInfo.Level0Nhr) {
241 0 : primQueueGenName = "InsAllReduceParallelNHRNHR";
242 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
243 0 : if (topoInfo.netLayerDetails.localNetInsSizeOfLayer[0] == 1) {
244 0 : primQueueGenName = "InsAllReduceNHR";
245 : } else {
246 0 : primQueueGenName = "InsAllReduceFourTemplateMesh1DNHR";
247 : }
248 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
249 0 : primQueueGenName = "InsAllReduceParallelMesh2DNHR";
250 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
251 0 : primQueueGenName = "InsAllReduceParallelNHRNHR";
252 : } else {
253 0 : return SelectorStatus::NOT_MATCH;
254 : }
255 : } else {
256 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
257 : double ratio; // 以8卡为基线确定ratio,用来表示不同卡数对下发的影响系数
258 0 : if (rankSize_ == 0) {
259 0 : HCCL_WARNING("[AllReduceAutoSelector]the selector is not set RankSize_]");
260 0 : ratio = 1;
261 : } else {
262 0 : ratio = DEFAULT_RANK_SIZE / rankSize_ / rankSize_;
263 : }
264 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64 ||
265 0 : op.reduceOp == ReduceOp::PROD) {
266 0 : primQueueGenName = "InsAllReduceAicpuReduce";
267 0 : } else if (dataSize_ <= AR_AICPU_1D_SMALL_DATA_SIZE) {
268 0 : primQueueGenName = "InsAllReduceMesh1DOneShot";
269 0 : } else if (dataSize_ * ratio > AR_AICPU_1D_MAX_DATA_SIZE) {
270 0 : primQueueGenName = "InsAllReduceMesh1DTwoShotMeshChunk";
271 : } else {
272 0 : primQueueGenName = "InsAllReduceMesh1DTwoShot";
273 : }
274 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
275 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 ||
276 0 : op.dataType == DataType::FP64 || op.reduceOp == ReduceOp::PROD) {
277 0 : primQueueGenName = "InsAllReduceAicpuReduceMesh2D";
278 : } else {
279 0 : primQueueGenName = "InsAllReduceMesh2DTwoShot";
280 : }
281 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D_CLOS) {
282 0 : if (IsLayerAllConnetedWithTopo(topoInfo, 0, TopoType::MESH_1D)) {
283 : // MESH_1D 即可链接所有卡, 使用 MESH_1D 算法
284 : double ratio; // 以8卡为基线确定ratio,用来表示不同卡数对下发的影响系数
285 0 : if (rankSize_ == 0) {
286 0 : HCCL_WARNING("[AllReduceAutoSelector]the selector is not set RankSize_]");
287 0 : ratio = 1;
288 : } else {
289 0 : ratio = DEFAULT_RANK_SIZE / rankSize_ / rankSize_;
290 : }
291 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 ||
292 0 : op.dataType == DataType::FP64 || op.reduceOp == ReduceOp::PROD) {
293 0 : primQueueGenName = "InsAllReduceAicpuReduce";
294 0 : } else if (dataSize_ <= AR_AICPU_1D_SMALL_DATA_SIZE) {
295 0 : primQueueGenName = "InsAllReduceMesh1DOneShot";
296 0 : } else if (dataSize_ * ratio > AR_AICPU_1D_MAX_DATA_SIZE) {
297 0 : primQueueGenName = "InsAllReduceMesh1DTwoShotMeshChunk";
298 : } else {
299 0 : primQueueGenName = "InsAllReduceMesh1DTwoShot";
300 : }
301 : } else {
302 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 ||
303 0 : op.dataType == DataType::FP64 || op.reduceOp == ReduceOp::PROD) {
304 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] INT64, UINT64, FP64, ReduceOp::PROD level0Shape[%d] is "
305 : "not supported "
306 : "yet for aicpu mode.",
307 : topoInfo.level0Shape);
308 0 : return SelectorStatus::NOT_MATCH;
309 0 : } else if (topoInfo.level0PcieMix) {
310 0 : primQueueGenName = "InsAllReduceParallelMesh1DNHRPcie";
311 : } else {
312 0 : primQueueGenName = "InsAllReduceParallelMesh1DNHR";
313 : }
314 : }
315 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
316 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64 ||
317 0 : op.reduceOp == ReduceOp::PROD) {
318 0 : primQueueGenName = "InsAllReduceAicpuReduce";
319 : } else {
320 0 : primQueueGenName = "InsAllReduceNHR";
321 : }
322 : } else {
323 0 : HCCL_WARNING("[AllReduceAutoSelector] topo not match");
324 0 : return SelectorStatus::NOT_MATCH;
325 : }
326 : }
327 0 : HCCL_INFO("[Algo][AllReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
328 0 : return SelectorStatus::MATCH;
329 : }
330 :
331 0 : SelectorStatus AllReduceAutoSelector::SelectAivAlgo(const TopoInfo &topoInfo,
332 : const CollAlgOperator &op,
333 : const std::map<OpType, std::vector<HcclAlgoType>> &configAlgMap,
334 : std::string &primQueueGenName) const
335 : {
336 : (void)configAlgMap;
337 0 : HCCL_DEBUG("[AllReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
338 :
339 : //aiv 模式不支持 PROD
340 0 : CHK_PRT_RET(op.reduceOp == ReduceOp::PROD,
341 : HCCL_WARNING("[Algo][AllReduceAutoSelector] ReduceOp[%s] is not supported yet for aiv mode.",
342 : op.reduceOp.Describe().c_str()),
343 : SelectorStatus::NOT_MATCH);
344 :
345 0 : if (op.dataType == DataType::UINT64 || op.dataType == DataType::FP64) {
346 0 : HCCL_WARNING("[Algo][AllReduceAutoSelector] aiv mode not support INT64, UINT64, FP64.");
347 0 : return SelectorStatus::NOT_MATCH;
348 : }
349 :
350 : // aiv 直接走打平 mesh
351 0 : if (dataSize_ <= AIV_ALL_REDUCE_SMALL_COUNT) {
352 0 : primQueueGenName = "AivAllReduceMesh1DOneShot";
353 : } else {
354 0 : primQueueGenName = "AivAllReduceMesh1DTwoShot";
355 : }
356 :
357 0 : HCCL_INFO("[Algo][AllReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
358 0 : return SelectorStatus::MATCH;
359 : }
360 :
361 : REGISTER_SELECTOR_BY_OPTYPE(OpType::ALLREDUCE, 18, AllReduceAutoSelector);
362 : } // namespace Hccl
|