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