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_auto_selector.h"
12 : #include "selector_registry.h"
13 : #include "coll_operator.h"
14 :
15 : namespace Hccl {
16 :
17 : constexpr u64 REDUCE_AICPU_1D_MAX_DATA_SIZE = 16 * 1024 * 1024;
18 : constexpr u64 REDUCE_CCU_1D_MAX_DATA_SIZE = 64 * 1024 * 1024;
19 : constexpr u64 REDUCE_CCU_1D_MAX_DATA_SIZE_INT8 = 16 * 1024 * 1024;
20 :
21 0 : SelectorStatus ReduceAutoSelector::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("[ReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
27 : // MS 模式不支持 int8
28 0 : CHK_PRT_RET(
29 : op.dataType == DataType::INT8,
30 : HCCL_WARNING(
31 : "[Algo][ReduceAutoSelector] dataType[%s] is not supported yet for ccu_ms mode.",
32 : op.dataType.Describe().c_str()),
33 : SelectorStatus::NOT_MATCH);
34 :
35 : // MS 模式不支持 PROD
36 0 : CHK_PRT_RET(
37 : op.reduceOp == ReduceOp::PROD,
38 : HCCL_WARNING(
39 : "[Algo][ReduceAutoSelector] ReduceOp[%s] is not supported yet for ccu_ms mode.",
40 : op.reduceOp.Describe().c_str()),
41 : SelectorStatus::NOT_MATCH);
42 :
43 0 : CHK_PRT_RET(
44 : op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64,
45 : HCCL_WARNING("[Algo][ReduceAutoSelector] ccu_ms mode not support INT64, UINT64, FP64."),
46 : SelectorStatus::NOT_MATCH);
47 :
48 0 : if (topoInfo.levelNum > 1) {
49 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] levelNum > 1 is not supported yet for ccu_ms mode.");
50 0 : return SelectorStatus::NOT_MATCH;
51 : } else {
52 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
53 0 : if (IsInputOutputOverlap(op.inputMem, op.outputMem) == true) {
54 : // 不支持 inplace 场景
55 0 : return SelectorStatus::NOT_MATCH;
56 : }
57 0 : if (Is2DieFullMesh()) {
58 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] 2DieFullMesh is not supported yet for ccu_ms mode.");
59 0 : return SelectorStatus::NOT_MATCH;
60 0 : } else if (dataSize_ >= REDUCE_AICPU_1D_MAX_DATA_SIZE) {
61 0 : HCCL_INFO("[Algo][ReduceAutoSelector] Mesh1D dataSize[%llu] >= 8MB, fallback to aicpu.", dataSize_);
62 0 : return SelectorStatus::NOT_MATCH;
63 : } else {
64 0 : primQueueGenName = "CcuReduceMesh1D";
65 : }
66 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
67 0 : primQueueGenName = "CcuReduceMesh2D";
68 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D_CLOS) {
69 0 : if (IsLayerAllConnetedWithTopo(topoInfo, 0, TopoType::MESH_1D)) {
70 : // MESH_1D 即可链接所有卡, 使用 MESH_1D 算法
71 0 : if (dataSize_ >= REDUCE_AICPU_1D_MAX_DATA_SIZE) {
72 0 : HCCL_INFO("[Algo][ReduceAutoSelector] Mesh1D dataSize[%llu] >= 8MB, fallback to aicpu.", dataSize_);
73 0 : return SelectorStatus::NOT_MATCH;
74 : } else {
75 0 : primQueueGenName = "CcuReduceMesh1D";
76 : }
77 0 : } else if (topoInfo.level0PcieMix) {
78 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] level0 PCIE mix is not supported yet for ccu_ms mode.");
79 0 : return SelectorStatus::NOT_MATCH;
80 : } else { // MS 不支持
81 0 : HCCL_WARNING(
82 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
83 : topoInfo.level0Shape);
84 0 : return SelectorStatus::NOT_MATCH;
85 : }
86 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
87 0 : HCCL_WARNING(
88 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
89 : topoInfo.level0Shape);
90 0 : return SelectorStatus::NOT_MATCH;
91 : } else {
92 0 : HCCL_WARNING(
93 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu_ms mode.",
94 : topoInfo.level0Shape);
95 0 : return SelectorStatus::NOT_MATCH;
96 : }
97 : }
98 0 : HCCL_INFO("[Algo][ReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
99 0 : return SelectorStatus::MATCH;
100 : }
101 :
102 0 : SelectorStatus ReduceAutoSelector::SelectCcuScheduleAlgo(
103 : const TopoInfo& topoInfo, const CollAlgOperator& op,
104 : const std::map<OpType, std::vector<HcclAlgoType>>& configAlgMap, std::string& primQueueGenName) const
105 : {
106 : (void)configAlgMap;
107 0 : HCCL_DEBUG("[ReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
108 : // ccu 模式不支持 inplace 场景
109 0 : CHK_PRT_RET(
110 : IsInputOutputOverlap(op.inputMem, op.outputMem) == true,
111 : HCCL_WARNING("[Algo][ReduceAutoSelector] ccu schedule does not support inplace allreduce."),
112 : SelectorStatus::NOT_MATCH);
113 :
114 : // ccu 模式不支持 PROD
115 0 : CHK_PRT_RET(
116 : op.reduceOp == ReduceOp::PROD,
117 : HCCL_WARNING(
118 : "[Algo][ReduceAutoSelector] ReduceOp[%s] is not supported yet for ccu schedule mode.",
119 : op.reduceOp.Describe().c_str()),
120 : SelectorStatus::NOT_MATCH);
121 :
122 0 : CHK_PRT_RET(
123 : op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64,
124 : HCCL_WARNING("[Algo][ReduceAutoSelector] ccu_ms mode not support INT64, UINT64, FP64."),
125 : SelectorStatus::NOT_MATCH);
126 :
127 0 : HCCL_DEBUG("[ReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
128 :
129 0 : if (topoInfo.levelNum > 1) {
130 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
131 0 : if (topoInfo.netLayerDetails.localNetInsSizeOfLayer[0] == 1) {
132 : // 每框出 1 卡
133 0 : primQueueGenName = "CcuReduceNHR1D";
134 0 : } else if (Is2DieFullMesh()) {
135 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] 2DieFullMesh is not supported yet for schedule mode.");
136 0 : return SelectorStatus::NOT_MATCH;
137 : } else {
138 0 : primQueueGenName = "CcuReduceParallelMesh1DNHR";
139 : }
140 : } else {
141 0 : HCCL_WARNING(
142 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
143 : topoInfo.level0Shape);
144 0 : return SelectorStatus::NOT_MATCH;
145 : }
146 : } else {
147 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
148 : double ratio;
149 0 : if (rankSize_ == 0) {
150 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] the selector is not set RankSize_");
151 0 : ratio = 1;
152 : } else {
153 0 : if (op.dataType == DataType::INT8) {
154 0 : ratio = DEFAULT_RANK_SIZE / rankSize_;
155 : } else {
156 0 : ratio = (DEFAULT_RANK_SIZE / rankSize_) * (DEFAULT_RANK_SIZE / rankSize_);
157 : }
158 : }
159 0 : if (Is2DieFullMesh()) {
160 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] 2DieFullMesh is not supported yet for ccu schedule mode.");
161 0 : return SelectorStatus::NOT_MATCH;
162 : }
163 0 : if (op.dataType == DataType::INT8) {
164 0 : if (dataSize_ * ratio >= REDUCE_CCU_1D_MAX_DATA_SIZE_INT8) {
165 0 : HCCL_INFO("[Algo][ReduceAutoSelector] fallback to aicpu.");
166 0 : return SelectorStatus::NOT_MATCH;
167 : } else {
168 0 : primQueueGenName = "CcuReduceMeshMem2Mem1D";
169 : }
170 : } else {
171 0 : if (dataSize_ * ratio >= REDUCE_CCU_1D_MAX_DATA_SIZE) {
172 0 : HCCL_INFO("[Algo][ReduceAutoSelector] fallback to aicpu.");
173 0 : return SelectorStatus::NOT_MATCH;
174 : } else {
175 0 : primQueueGenName = "CcuReduceMeshTwoShotMem2Mem1D";
176 : }
177 : }
178 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
179 0 : primQueueGenName = "CcuReduceMeshMem2Mem2D";
180 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_1D_CLOS) {
181 0 : if (IsLayerAllConnetedWithTopo(topoInfo, 0, TopoType::MESH_1D)) {
182 : // MESH_1D 即可链接所有卡, 使用 MESH_1D 算法
183 : double ratio;
184 0 : if (rankSize_ == 0) {
185 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] the selector is not set RankSize_");
186 0 : ratio = 1;
187 : } else {
188 0 : if (op.dataType == DataType::INT8) {
189 0 : ratio = DEFAULT_RANK_SIZE / rankSize_;
190 : } else {
191 0 : ratio = (DEFAULT_RANK_SIZE / rankSize_) * (DEFAULT_RANK_SIZE / rankSize_);
192 : }
193 : }
194 0 : if (op.dataType == DataType::INT8) {
195 0 : if (dataSize_ * ratio >= REDUCE_CCU_1D_MAX_DATA_SIZE_INT8) {
196 0 : HCCL_INFO("[Algo][ReduceAutoSelector] fallback to aicpu.");
197 0 : return SelectorStatus::NOT_MATCH;
198 : } else {
199 0 : primQueueGenName = "CcuReduceMeshMem2Mem1D";
200 : }
201 : } else {
202 0 : if (dataSize_ * ratio >= REDUCE_CCU_1D_MAX_DATA_SIZE) {
203 0 : HCCL_INFO("[Algo][ReduceAutoSelector] fallback to aicpu.");
204 0 : return SelectorStatus::NOT_MATCH;
205 : } else {
206 0 : primQueueGenName = "CcuReduceMeshTwoShotMem2Mem1D";
207 : }
208 : }
209 0 : } else if (topoInfo.level0PcieMix) {
210 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] level0 PCIE mix is not supported yet for ccu schedule mode.");
211 0 : return SelectorStatus::NOT_MATCH;
212 : } else {
213 0 : primQueueGenName = "CcuReduceNHR1D";
214 : }
215 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
216 0 : HCCL_WARNING(
217 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
218 : topoInfo.level0Shape);
219 0 : return SelectorStatus::NOT_MATCH;
220 : } else {
221 0 : HCCL_WARNING(
222 : "[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet for ccu schedule mode.",
223 : topoInfo.level0Shape);
224 0 : return SelectorStatus::NOT_MATCH;
225 : }
226 : }
227 0 : HCCL_INFO("[Algo][ReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
228 0 : return SelectorStatus::MATCH;
229 : }
230 :
231 0 : SelectorStatus ReduceAutoSelector::SelectAicpuAlgo(
232 : const TopoInfo& topoInfo, const CollAlgOperator& op,
233 : const std::map<OpType, std::vector<HcclAlgoType>>& configAlgMap, std::string& primQueueGenName) const
234 : {
235 : (void)configAlgMap;
236 0 : HCCL_DEBUG("[ReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
237 :
238 0 : if (topoInfo.levelNum > 1) {
239 0 : CHK_PRT_RET(
240 : op.reduceOp == ReduceOp::PROD,
241 : HCCL_WARNING(
242 : "[Algo][ReduceAutoSelector] ReduceOp[%s] is not supported yet for aicpu levelNum > 1.",
243 : op.reduceOp.Describe().c_str()),
244 : SelectorStatus::NOT_MATCH);
245 :
246 0 : CHK_PRT_RET(
247 : op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64,
248 : HCCL_WARNING("[Algo][ReduceAutoSelector] aicpu levelNum > 1 not support INT64, UINT64, FP64."),
249 : SelectorStatus::NOT_MATCH);
250 :
251 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
252 0 : if (topoInfo.netLayerDetails.localNetInsSizeOfLayer[0] == 1) {
253 0 : primQueueGenName = "InsReduceNHR";
254 : } else {
255 0 : primQueueGenName = "InsReduceParallelMesh1DNHR";
256 : }
257 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
258 0 : primQueueGenName = "InsReduceNHR";
259 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
260 0 : primQueueGenName = "InsReduceNHR";
261 : } else {
262 0 : return SelectorStatus::NOT_MATCH;
263 : }
264 : } else {
265 0 : if (topoInfo.level0Shape == Level0Shape::MESH_1D) {
266 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64
267 0 : || op.reduceOp == ReduceOp::PROD) {
268 0 : primQueueGenName = "InsReduceAicpuReduce";
269 0 : } else if (dataSize_ >= REDUCE_AICPU_1D_MAX_DATA_SIZE) {
270 0 : primQueueGenName = "InsReduceMesh1DTwoShot";
271 : } else {
272 0 : primQueueGenName = "InsReduceMesh1D";
273 : }
274 0 : } else if (topoInfo.level0Shape == Level0Shape::MESH_2D) {
275 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64
276 0 : || op.reduceOp == ReduceOp::PROD) {
277 0 : primQueueGenName = "InsReduceAicpuReduceMesh2D";
278 : } else {
279 0 : primQueueGenName = "InsReduceMesh2D";
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 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64
285 0 : || op.reduceOp == ReduceOp::PROD) {
286 0 : primQueueGenName = "InsReduceAicpuReduce";
287 : } else {
288 0 : primQueueGenName = "InsReduceParallelMesh1DNHR";
289 : }
290 : } else {
291 0 : if (topoInfo.level0PcieMix) {
292 : // 预留PCIE mix入口,如果要更新算法可以直接改
293 0 : primQueueGenName = "InsReduceParallelMesh1DNHRPcie";
294 : }
295 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64
296 0 : || op.reduceOp == ReduceOp::PROD) {
297 0 : primQueueGenName = "InsReduceAicpuReduce";
298 : } else {
299 0 : primQueueGenName = "InsReduceNHR";
300 : }
301 : }
302 0 : } else if (topoInfo.level0Shape == Level0Shape::CLOS) {
303 0 : if (op.dataType == DataType::INT64 || op.dataType == DataType::UINT64 || op.dataType == DataType::FP64
304 0 : || op.reduceOp == ReduceOp::PROD) {
305 0 : primQueueGenName = "InsReduceAicpuReduce";
306 : } else {
307 0 : primQueueGenName = "InsReduceNHR";
308 : }
309 : } else {
310 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] level0Shape[%d] is not supported yet.", topoInfo.level0Shape);
311 0 : return SelectorStatus::NOT_MATCH;
312 : }
313 : }
314 0 : HCCL_INFO("[Algo][ReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
315 0 : return SelectorStatus::MATCH;
316 : }
317 :
318 0 : SelectorStatus ReduceAutoSelector::SelectAivAlgo(
319 : const TopoInfo& topoInfo, const CollAlgOperator& op,
320 : const std::map<OpType, std::vector<HcclAlgoType>>& configAlgMap, std::string& primQueueGenName) const
321 : {
322 : (void)configAlgMap;
323 0 : HCCL_DEBUG("[ReduceAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo.levelNum);
324 :
325 : // aiv 模式不支持 PROD
326 0 : CHK_PRT_RET(
327 : op.reduceOp == ReduceOp::PROD,
328 : HCCL_WARNING(
329 : "[Algo][ReduceAutoSelector] ReduceOp[%s] is not supported yet for aiv mode.",
330 : op.reduceOp.Describe().c_str()),
331 : SelectorStatus::NOT_MATCH);
332 :
333 0 : if (op.dataType == DataType::UINT64 || op.dataType == DataType::FP64) {
334 0 : HCCL_WARNING("[Algo][ReduceAutoSelector] aiv mode not support INT64, UINT64, FP64.");
335 0 : return SelectorStatus::NOT_MATCH;
336 : }
337 :
338 : // aiv 直接走打平 mesh
339 0 : primQueueGenName = "AivReduceMesh1D";
340 :
341 0 : HCCL_INFO("[Algo][ReduceAutoSelector][%s] Algo match [%s]", __func__, primQueueGenName.c_str());
342 0 : return SelectorStatus::MATCH;
343 : }
344 :
345 : REGISTER_SELECTOR_BY_OPTYPE(OpType::REDUCE, 18, ReduceAutoSelector);
346 : } // namespace Hccl
|