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