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