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_v_operator.h"
12 : #include "device_capacity.h"
13 : #include "hccl_aiv.h"
14 :
15 : namespace hccl {
16 :
17 : constexpr u64 MAX_310P_RANK_SIZE = 4;
18 :
19 0 : ReduceScatterVOperator::ReduceScatterVOperator(
20 : AlgConfigurator* algConfigurator, CCLBufferManager& cclBufferManager, HcclDispatcher dispatcher,
21 0 : std::unique_ptr<TopoMatcher>& topoMatcher)
22 : : CollAlgOperator(
23 0 : algConfigurator, cclBufferManager, dispatcher, topoMatcher, HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V)
24 0 : {}
25 :
26 0 : ReduceScatterVOperator::~ReduceScatterVOperator() {}
27 :
28 0 : HcclResult ReduceScatterVOperator::SelectAlg(
29 : const std::string& tag, const OpParam& param, std::string& algName, std::string& newTag)
30 : {
31 : HcclResult ret;
32 :
33 0 : if (isDiffDeviceType_) {
34 0 : HCCL_ERROR("[ReduceScatterVOperator][SelectAlg] ReduceScatterV not support diffDeviceType");
35 0 : return HCCL_E_NOT_SUPPORT;
36 0 : } else if (deviceType_ == DevType::DEV_TYPE_910_93) {
37 0 : ret = SelectAlgfor91093(param, algName);
38 0 : } else if (deviceType_ == DevType::DEV_TYPE_910B) {
39 0 : ret = SelectAlgfor910B(param, algName);
40 0 : } else if (deviceType_ == DevType::DEV_TYPE_310P3) {
41 0 : ret = SelectAlgfor310P3(param, algName);
42 : } else {
43 0 : HCCL_ERROR("[ReduceScatterVOperator][SelectAlg] ReduceScatterV only support A3, A2 and 310P.");
44 0 : return HCCL_E_NOT_SUPPORT;
45 : }
46 0 : CHK_PRT_RET(
47 : ret != HCCL_SUCCESS,
48 : HCCL_ERROR("[ReduceScatterVOperator][SelectAlg]tag[%s], ReduceScatterV failed, return[%d]", tag.c_str(), ret),
49 : ret);
50 :
51 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
52 0 : newTag = tag;
53 : } else {
54 0 : if (deviceType_ == DevType::DEV_TYPE_310P3) {
55 0 : newTag = tag + algName;
56 : } else {
57 0 : AlgTypeLevel1 algType1 = algType_.algoLevel1;
58 0 : auto level1Iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algType1);
59 0 : CHK_PRT_RET(
60 : level1Iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(), HCCL_ERROR("level1: algType1[%u] is invalid.", algType1),
61 : HCCL_E_INTERNAL);
62 0 : newTag = tag + level1Iter->second + algName;
63 : }
64 :
65 0 : bool isInlineReduce = IsSupportSDMAReduce(
66 0 : cclBufferManager_.GetInCCLbuffer().ptr(), cclBufferManager_.GetOutCCLbuffer().ptr(),
67 0 : param.VDataDes.dataType, param.reduceType);
68 0 : const std::string REDUCE_SCATTER_V_NO_INLINE = "_no_inline";
69 0 : newTag = isInlineReduce ? newTag : newTag + REDUCE_SCATTER_V_NO_INLINE;
70 0 : }
71 :
72 0 : newTag += (param.aicpuUnfoldMode ? "_device" : "_host");
73 0 : return ret;
74 : }
75 :
76 0 : HcclResult ReduceScatterVOperator::SelectAlgfor91093(const OpParam& param, std::string& algName)
77 : {
78 0 : const auto* countsPtr = static_cast<const u64*>(param.VDataDes.counts);
79 0 : auto countsPerRank = std::vector<u64>(countsPtr, countsPtr + userRankSize_);
80 0 : u64 maxCount = *std::max_element(countsPerRank.begin(), countsPerRank.end());
81 0 : u32 unitSize = SIZE_TABLE[param.VDataDes.dataType];
82 0 : u64 dataSize = maxCount * unitSize; // 单位:字节
83 0 : if (dataSize >= cclBufferManager_.GetInCCLbufferSize()) {
84 0 : HCCL_WARNING(
85 : "The current inCCLbufferSize is [%llu] bytes, change the HCCL_BUFFSIZE environment variable to "
86 : "be greater than the current data volume[%llu] bytes to improve the performance of the 91093 environment.",
87 : cclBufferManager_.GetInCCLbufferSize(), dataSize);
88 : }
89 :
90 0 : if (multiModuleDiffDeviceNumMode_ || multiSuperPodDiffServerNumMode_) {
91 0 : HCCL_ERROR(
92 : "[ReduceScatterVOperator][SelectAlgfor91093] not support mode, multiModuleDiffDeviceNumMode_[%u], "
93 : "multiSuperPodDiffServerNumMode_[%u]",
94 : multiModuleDiffDeviceNumMode_, multiSuperPodDiffServerNumMode_);
95 0 : return HCCL_E_NOT_SUPPORT;
96 : } else {
97 0 : if (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING) {
98 0 : algName = "ReduceScatterVRingFor91093Executor";
99 0 : } else if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
100 0 : const s32 HCCS_PORT_NUM_910_93_7 = 7;
101 0 : if (hccsPortNum_ == HCCS_PORT_NUM_910_93_7) {
102 0 : algName = "ReduceScatterVFastDoubleRingFor91093Executor";
103 : } else {
104 0 : algName = "AlignedReduceScatterVDoubleRingFor91093Executor";
105 : }
106 : } else {
107 0 : HCCL_ERROR("[ReduceScatterVOperator][SelectAlgfor91093] not support topoType_[%u]", topoType_);
108 0 : return HCCL_E_NOT_SUPPORT;
109 : }
110 : }
111 :
112 0 : const bool isWholeRing = (algType_.algoLevel0 == AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING)
113 0 : && (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING);
114 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING || isWholeRing
115 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB)) {
116 : // 910_93超节点只支持server间ring,NB和NHR,默认需继续使用NHR
117 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
118 0 : HCCL_WARNING("[ReduceScatterVOperator][SelectAlgfor91093] only support ring, NB and NHR in AlgoLevel1 yet,"
119 : " default algType is NHR.");
120 : }
121 :
122 0 : HCCL_INFO("[SelectAlgfor91093] ReduceScatterV SelectAlgfor91093 is algName [%s]", algName.c_str());
123 0 : return HCCL_SUCCESS;
124 0 : }
125 :
126 0 : HcclResult ReduceScatterVOperator::SelectAlgfor910B(const OpParam& param, std::string& algName)
127 : {
128 : // 图模式切入确定性
129 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB && !isSingleMeshAggregation_) {
130 0 : if (!multiModuleDiffDeviceNumMode_) {
131 0 : algName = "ReduceScatterVDeterExecutor"; // 多机图模式当前默认选中确定性算法
132 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING
133 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB
134 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR)) {
135 : // 只支持server间ring,NB和NHR,默认使能NHR
136 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
137 0 : HCCL_WARNING(
138 : "[ReduceScatterVOperator][SelectAlgfor910B] only support ring, NB and NHR in AlgoLevel1 yet,"
139 : " default algType is NHR.");
140 : }
141 0 : HCCL_INFO("[SelectAlgfor910B] ReduceScatterV SelectAlgfor910B algName is [%s]", algName.c_str());
142 0 : return HCCL_SUCCESS;
143 : } else {
144 0 : HCCL_ERROR(
145 : "[ReduceScatterVOperator][SelectAlgfor910B] ReduceScatterV not support uneven devices in multiServer.");
146 0 : return HCCL_E_NOT_SUPPORT;
147 : }
148 : }
149 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH
150 0 : || topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
151 : // Deterministic 确定性分支
152 : bool isDeterministic
153 0 : = topoMatcher_->GetDeterministicConfig() != DETERMINISTIC_DISABLE && isMeshTopo
154 0 : && !multiModuleDiffDeviceNumMode_
155 0 : && (param.VDataDes.dataType == HCCL_DATA_TYPE_FP16 || param.VDataDes.dataType == HCCL_DATA_TYPE_FP32
156 0 : || param.VDataDes.dataType == HCCL_DATA_TYPE_BFP16);
157 0 : if (isDeterministic) {
158 : // 只有浮点数存在不确定性
159 0 : algName = "ReduceScatterVDeterExecutor";
160 0 : HCCL_INFO("[SelectAlgfor910B] ReduceScatterV SelectAlgfor910B algName is [%s]", algName.c_str());
161 0 : return HCCL_SUCCESS;
162 : }
163 :
164 : // pipeline算法回退: task数量多,如果超出FFTS子图限制,则重定向到NHR算法
165 0 : if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE) {
166 0 : u32 contextNum = CalcContextNumForPipeline(HcclCMDType::HCCL_CMD_REDUCE_SCATTER);
167 0 : if (contextNum > HCCL_FFTS_CAPACITY) {
168 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
169 0 : HCCL_WARNING(
170 : "[ReduceScatterVOperator][SelectAlgfor910B] context num[%u] is out of capacity of FFTS+ "
171 : "graph[%u], reset algorithm to NHR.",
172 : contextNum, HCCL_FFTS_CAPACITY);
173 : }
174 : }
175 :
176 : // Pipeline
177 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
178 0 : && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE
179 0 : && topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE
180 0 : && IsMultiMeshInlineReduce(
181 0 : cclBufferManager_.GetInCCLbuffer().ptr(), cclBufferManager_.GetOutCCLbuffer().ptr(),
182 0 : param.VDataDes.dataType, param.reduceType)) {
183 0 : algName = "ReduceScatterVMeshOpbasePipelineExecutor";
184 0 : HCCL_INFO("[SelectAlgfor910B] ReduceScatterV SelectAlgfor910B algName is [%s]", algName.c_str());
185 0 : return HCCL_SUCCESS;
186 : }
187 :
188 0 : const auto* countsPtr = static_cast<const u64*>(param.VDataDes.counts);
189 0 : auto countsPerRank = std::vector<u64>(countsPtr, countsPtr + userRankSize_);
190 0 : u64 maxCount = *std::max_element(countsPerRank.begin(), countsPerRank.end());
191 0 : u32 unitSize = SIZE_TABLE[param.VDataDes.dataType];
192 0 : u64 maxDataSize = maxCount * unitSize; // 单位:字节
193 : // 910B单机AIV模式下ReduceScatterV算子当前仅支持单卡数据量不大于256M的场景,大于256M暂不支持
194 0 : bool isAivMode = (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) && topoMatcher_->GetAivModeConfig()
195 0 : && isSingleMeshAggregation_ && maxDataSize <= AIV_BIG_SIZE
196 0 : && IsSupportAIVReduce(param.VDataDes.dataType, param.reduceType)
197 0 : && topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE;
198 0 : HCCL_INFO(
199 : "[ReduceScatterVOperator][SelectAlgfor910B]isAivMode[%d], maxCount[%llu], maxDataSize[%llu], "
200 : "deterministic[%u], isSingleMeshAggregation[%d].",
201 : isAivMode, maxCount, maxDataSize, topoMatcher_->GetDeterministicConfig(), isSingleMeshAggregation_);
202 :
203 0 : if (isAivMode) {
204 0 : if (maxDataSize > AIV_REDUCE_SCATTER_MID_SIZE) {
205 0 : algName = "ReduceScatterVAIVBigCountExecutor";
206 : } else {
207 0 : algName = "ReduceScatterVMeshAivSmallCountExecutor";
208 : }
209 0 : } else if (
210 0 : GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
211 0 : && IsSupportSDMAReduce(
212 0 : cclBufferManager_.GetInCCLbuffer().ptr(), cclBufferManager_.GetOutCCLbuffer().ptr(),
213 0 : param.VDataDes.dataType, param.reduceType)) {
214 0 : algName = "ReduceScatterVMeshOpbaseExecutor";
215 0 : if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING
216 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB
217 0 : || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR)) {
218 : // 只支持server间ring,NB和NHR,默认使能NHR
219 0 : algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
220 0 : HCCL_WARNING("[ReduceScatterVOperator][SelectAlgfor910B] only support ring, NB and NHR in AlgoLevel1 yet,"
221 : " default algType is NHR.");
222 : }
223 0 : } else if (
224 0 : GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB
225 0 : && IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.VDataDes.dataType, param.reduceType)) {
226 0 : algName = "ReduceScatterVMeshExecutor";
227 : } else {
228 0 : HCCL_ERROR("[ReduceScatterVOperator][SelectAlgfor910B] ReduceScatterV only support inlinereduce.");
229 0 : return HCCL_E_NOT_SUPPORT;
230 : }
231 :
232 0 : HCCL_INFO("[SelectAlgfor910B] ReduceScatterV SelectAlgfor910B is algName [%s]", algName.c_str());
233 0 : return HCCL_SUCCESS;
234 0 : }
235 :
236 0 : HcclResult ReduceScatterVOperator::SelectAlgfor310P3(const OpParam& param, std::string& algName)
237 : {
238 : (void)param;
239 0 : CHK_PRT_RET(
240 : userRankSize_ > MAX_310P_RANK_SIZE,
241 : HCCL_ERROR(
242 : "[ReduceScatterVOperator][SelectAlgfor310P3]rankSize[%u] is not supported.ReduceScatterV does not "
243 : "support the scenario where the rankSize is greater than 4.",
244 : userRankSize_),
245 : HCCL_E_NOT_SUPPORT);
246 0 : algName = "ReduceScatterVFor310PRing";
247 0 : HCCL_INFO("[SelectAlgfor310P3] ReduceScatterV SelectAlgfor310P3 is algName [%s]", algName.c_str());
248 0 : return HCCL_SUCCESS;
249 : }
250 :
251 : REGISTER_OP(HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V, ReduceScatterV, ReduceScatterVOperator);
252 :
253 : } // namespace hccl
|