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