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 "alltoall_operator.h"
12 : #include <vector>
13 : #include "device_capacity.h"
14 : #include "coll_alg_exec_registry.h"
15 : #include "coll_alg_op_registry.h"
16 : #include "coll_all_to_all_executor.h"
17 : #include "hccl_aiv.h"
18 :
19 : namespace hccl {
20 :
21 : constexpr u64 ALLTOALL_PIPELINE_MIN_CCL_SIZE = 80 * 1024 * 1024;
22 : constexpr u64 MAX_RMDA_RANK_SIZE = 8;
23 : constexpr u64 MAX_310P_RANK_SIZE = 4;
24 : constexpr u64 AIV_FLAG_OFFSET = 2 * 1024 * 1024;
25 :
26 8 : AlltoAllOperator::AlltoAllOperator(AlgConfigurator* algConfigurator, CCLBufferManager &cclBufferManager,
27 8 : HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher> &topoMatcher)
28 8 : : CollAlgOperator(algConfigurator, cclBufferManager, dispatcher, topoMatcher, HcclCMDType::HCCL_CMD_ALLTOALL)
29 : {
30 8 : }
31 :
32 16 : AlltoAllOperator::~AlltoAllOperator()
33 : {
34 16 : }
35 :
36 8 : void AlltoAllOperator::SetVirtualDispatcher(const HcclDispatcher vDispatcher)
37 : {
38 8 : vDispatcher_ = vDispatcher;
39 8 : return;
40 : }
41 :
42 8 : void AlltoAllOperator::SetParallelTaskLoader(ParallelTaskLoader* parallelTaskLoader)
43 : {
44 8 : parallelTaskLoader_ = parallelTaskLoader;
45 8 : return;
46 : }
47 :
48 0 : HcclResult AlltoAllOperator::CheckSendRecvParams(
49 : const std::vector<SendRecvInfo> &allMeshAggregationSendRecvInfo)
50 : {
51 0 : u32 rankSize = allMeshAggregationSendRecvInfo.size();
52 0 : for (u32 i = 0; i < rankSize; i++) {
53 0 : u32 sendsSize = allMeshAggregationSendRecvInfo[i].sendLength.size();
54 0 : u32 recvsSize = allMeshAggregationSendRecvInfo[i].recvLength.size();
55 0 : if (rankSize != sendsSize || rankSize != recvsSize) {
56 0 : HCCL_ERROR(
57 : "[AlltoAllV][CheckSendRecvParam] rankSize[%u], sendsSize[%u], recvsSize[%u] are not match Index[%u]",
58 : rankSize, sendsSize, recvsSize, i);
59 0 : return HCCL_E_PARA;
60 : }
61 0 : for (u32 j = 0; j < sendsSize; j++) {
62 0 : if (allMeshAggregationSendRecvInfo[i].sendLength[j] != allMeshAggregationSendRecvInfo[j].recvLength[i]) {
63 0 : HCCL_ERROR("SendLength[%u][%u]: %llu and recvLength[%u][%u]: %llu are not match", i, j,
64 : allMeshAggregationSendRecvInfo[i].sendLength[j], j, i,
65 : allMeshAggregationSendRecvInfo[j].recvLength[i]);
66 0 : return HCCL_E_PARA;
67 : }
68 : }
69 : }
70 0 : return HCCL_SUCCESS;
71 : }
72 :
73 0 : HcclResult AlltoAllOperator::GetAlltoAllvcSendRecvInfo(const void *sendCountMatrix, HcclDataType sendType,
74 : HcclDataType recvType)
75 : {
76 0 : allMeshAggregationSendRecvInfo_.clear();
77 0 : for (u32 i = 0; i < userRankSize_; i++) {
78 0 : SendRecvInfo sendRecvInfo;
79 0 : sendRecvInfo.sendCounts.resize(userRankSize_);
80 0 : sendRecvInfo.sendDispls.resize(userRankSize_);
81 0 : sendRecvInfo.sendLength.resize(userRankSize_);
82 0 : sendRecvInfo.sendOffset.resize(userRankSize_);
83 0 : u64 curSendDispls = 0;
84 0 : u64 curSendOffset = 0;
85 :
86 0 : sendRecvInfo.recvCounts.resize(userRankSize_);
87 0 : sendRecvInfo.recvDispls.resize(userRankSize_);
88 0 : sendRecvInfo.recvLength.resize(userRankSize_);
89 0 : sendRecvInfo.recvOffset.resize(userRankSize_);
90 0 : u64 curRecvDispls = 0;
91 0 : u64 curRecvOffset = 0;
92 : // sendCountMatrix[i * userRankSize_ + j] 代表rank i发送到rank j的count参数
93 0 : for (u32 j = 0; j < userRankSize_; j++) {
94 0 : u64 curSendCounts = *(static_cast<const u64 *>(sendCountMatrix) + i * userRankSize_ + j);
95 0 : u64 curSendLength = curSendCounts * SIZE_TABLE[sendType];
96 0 : sendRecvInfo.sendCounts[j] = curSendCounts;
97 0 : sendRecvInfo.sendDispls[j] = curSendDispls;
98 0 : sendRecvInfo.sendLength[j] = curSendLength;
99 0 : sendRecvInfo.sendOffset[j] = curSendOffset;
100 0 : curSendDispls += curSendCounts;
101 0 : curSendOffset += curSendLength;
102 :
103 0 : u64 curRecvCounts = *(static_cast<const u64 *>(sendCountMatrix) + i + userRankSize_ * j);
104 0 : u64 curRecvLength = curRecvCounts * SIZE_TABLE[recvType];
105 0 : sendRecvInfo.recvCounts[j] = curRecvCounts;
106 0 : sendRecvInfo.recvDispls[j] = curRecvDispls;
107 0 : sendRecvInfo.recvLength[j] = curRecvLength;
108 0 : sendRecvInfo.recvOffset[j] = curRecvOffset;
109 0 : curRecvDispls += curRecvCounts;
110 0 : curRecvOffset += curRecvLength;
111 :
112 0 : HCCL_DEBUG("GetAlltoAllvcSendRecvInfo rank[%u], sendCounts[%llu], sendDispls[%llu] "\
113 : "recvCounts[%llu], recvDispls[%llu]", i, sendRecvInfo.sendCounts[j], sendRecvInfo.sendDispls[j],
114 : sendRecvInfo.recvCounts[j], sendRecvInfo.recvDispls[j]);
115 : }
116 0 : allMeshAggregationSendRecvInfo_.push_back(sendRecvInfo);
117 0 : }
118 0 : CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
119 0 : return HCCL_SUCCESS;
120 : }
121 :
122 0 : void AlltoAllOperator::UpdateAlltoAllCopyMode(std::vector<SendRecvInfo> &allMeshAggregationSendRecvInfo,
123 : std::string& copyMode)
124 : {
125 0 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
126 0 : u64 maxSendSize = 0;
127 0 : u64 maxRecvSize = 0;
128 0 : for (auto &sendRecvInfo : allMeshAggregationSendRecvInfo) {
129 0 : for (u32 i = 0; i < userRankSize_; i++) {
130 0 : u64 curSendSize = sendRecvInfo.sendLength[i] + sendRecvInfo.sendOffset[i];
131 0 : maxSendSize = std::max(maxSendSize, curSendSize);
132 0 : u64 curRecvSize = sendRecvInfo.recvLength[i] + sendRecvInfo.recvOffset[i];
133 0 : maxRecvSize = std::max(maxRecvSize, curRecvSize);
134 : }
135 : }
136 0 : bool isAlltoAllZCopyMode = (maxSendSize <= cclBufferManager_.GetInCCLbufferSize()) &&
137 0 : (maxRecvSize <= cclBufferManager_.GetInCCLbufferSize());
138 0 : if (isAlltoAllZCopyMode) {
139 0 : copyMode = "ZCopy";
140 : }
141 0 : HCCL_INFO("[AlltoAllOperator][UpdateAlltoAllCopyMode] maxSendSize[%llu], maxRecvSize[%llu], "\
142 : "cclBufferSize[%llu], CopyMode[%s]", maxSendSize, maxRecvSize,
143 : cclBufferManager_.GetInCCLbufferSize(), copyMode.c_str());
144 : } else {
145 : // 图模式走ZCopy实现
146 0 : copyMode = "ZCopy";
147 : }
148 0 : }
149 :
150 0 : HcclResult AlltoAllOperator::GetAlltoAllvSendRecvInfo(const OpParam& param, const HostMem &alltoallAddrInfoGathered)
151 : {
152 0 : allMeshAggregationSendRecvInfo_.clear();
153 0 : u64 stepSize = sizeof(u64) * userRankSize_;
154 0 : const u32 addrItemNum = 4;
155 0 : const u32 recvLengthStep = 2;
156 0 : const u32 recvOffsetStep = 3;
157 0 : for (u32 i = 0; i < userRankSize_; i++) {
158 0 : SendRecvInfo sendRecvInfo;
159 0 : sendRecvInfo.sendLength.resize(userRankSize_);
160 0 : sendRecvInfo.sendOffset.resize(userRankSize_);
161 0 : sendRecvInfo.recvLength.resize(userRankSize_);
162 0 : sendRecvInfo.recvOffset.resize(userRankSize_);
163 0 : CHK_SAFETY_FUNC_RET(memcpy_s(sendRecvInfo.sendLength.data(),
164 : stepSize,
165 : static_cast<u8 *>(alltoallAddrInfoGathered.ptr()) + i * stepSize * addrItemNum + 0 * stepSize,
166 : stepSize));
167 0 : CHK_SAFETY_FUNC_RET(memcpy_s(sendRecvInfo.sendOffset.data(),
168 : stepSize,
169 : static_cast<u8 *>(alltoallAddrInfoGathered.ptr()) + i * stepSize * addrItemNum + stepSize,
170 : stepSize));
171 0 : CHK_SAFETY_FUNC_RET(memcpy_s(sendRecvInfo.recvLength.data(),
172 : stepSize,
173 : static_cast<u8 *>(alltoallAddrInfoGathered.ptr()) + i * stepSize * addrItemNum + recvLengthStep * stepSize,
174 : stepSize));
175 0 : CHK_SAFETY_FUNC_RET(memcpy_s(sendRecvInfo.recvOffset.data(),
176 : stepSize,
177 : static_cast<u8 *>(alltoallAddrInfoGathered.ptr()) + i * stepSize * addrItemNum + recvOffsetStep * stepSize,
178 : stepSize));
179 0 : allMeshAggregationSendRecvInfo_.push_back(std::move(sendRecvInfo));
180 0 : }
181 :
182 0 : for (auto &sendRecvInfo : allMeshAggregationSendRecvInfo_) {
183 0 : for (u32 i = 0; i < userRankSize_; i++) {
184 0 : sendRecvInfo.sendCounts.push_back(sendRecvInfo.sendLength[i] / SIZE_TABLE[param.All2AllDataDes.sendType]);
185 0 : sendRecvInfo.sendDispls.push_back(sendRecvInfo.sendOffset[i] / SIZE_TABLE[param.All2AllDataDes.sendType]);
186 0 : sendRecvInfo.recvCounts.push_back(sendRecvInfo.recvLength[i] / SIZE_TABLE[param.All2AllDataDes.recvType]);
187 0 : sendRecvInfo.recvDispls.push_back(sendRecvInfo.recvOffset[i] / SIZE_TABLE[param.All2AllDataDes.recvType]);
188 0 : HCCL_INFO("[GetAlltoAllvSendRecvInfo] rank[%u], sendCounts[%llu], sendDispls[%llu], "\
189 : "recvCounts[%llu], recvDispls[%llu]", i, sendRecvInfo.sendCounts[i], sendRecvInfo.sendDispls[i],
190 : sendRecvInfo.recvCounts[i], sendRecvInfo.recvDispls[i]);
191 0 : HCCL_INFO("[GetAlltoAllvSendRecvInfo] rank[%u], sendLength[%llu], sendOffset[%llu], "\
192 : "recvLength[%llu], recvOffset[%llu]", i, sendRecvInfo.sendLength[i], sendRecvInfo.sendOffset[i],
193 : sendRecvInfo.recvLength[i], sendRecvInfo.recvOffset[i]);
194 : }
195 : }
196 :
197 0 : CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
198 :
199 0 : return HCCL_SUCCESS;
200 : }
201 :
202 5 : HcclResult AlltoAllOperator::SelectAlgforAiv(const OpParam& param, std::string& algName)
203 : {
204 5 : bool isOpbase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
205 :
206 5 : if (deviceType_ == DevType::DEV_TYPE_910B &&
207 5 : param.opType == HcclCMDType::HCCL_CMD_ALLTOALL &&
208 0 : !isSingleMeshAggregation_)
209 : {
210 : // aiv模式下910A2多server场景 alltoall算子
211 0 : bool isSingleAX = serverNum_ == 1 && moduleNum_ == 2; // a+x单机跨module场景
212 0 : bool isSupportNpuDirect = isOpbase && param.supportRoceDirect;
213 0 : if (isSupportNpuDirect && ((isSingleAX && GetExternalInputIntraRoceSwitch() == 1) || !isSingleAX)) {
214 : // 单算子支持Roce直驱场景,使用DirectFullmesh
215 0 : algName = "AlltoAllDirectFullmeshAIVExecutor";
216 : } else {
217 0 : algName = "AlltoAllStagedAIVRdmaExecutor";
218 : }
219 5 : } else if (deviceType_ == DevType::DEV_TYPE_910_93 && serverNum_ > 1) {
220 0 : algName = "AlltoAllMeshAivFor91093Executor";
221 5 : } else if (deviceType_ == DevType::DEV_TYPE_910_93 &&
222 0 : !isOpbase &&
223 0 : param.opType == HcclCMDType::HCCL_CMD_ALLTOALL &&
224 0 : param.All2AllDataDes.sendCount * SIZE_TABLE[param.All2AllDataDes.sendType] <= AIV_A3_ALL_TO_ALL_GRAPH_GUIYI_SIZE)
225 : {
226 0 : algName = "AlltoAllMeshAivSmallCountExecutor";
227 : } else {
228 5 : algName = "AlltoAllMeshAivExecutor";
229 : }
230 :
231 5 : HCCL_INFO("[SelectAlgforAlltoAll] AllToAll algName is [%s]", algName.c_str());
232 5 : return HCCL_SUCCESS;
233 : }
234 :
235 5 : HcclResult AlltoAllOperator::SelectAlgforAlltoAll(const OpParam& param, std::string& algName, std::string& copyMode,
236 : const ResourceLimit& resourceLimit)
237 : {
238 5 : if (IsSatisfyAlltoAllAivCondition(param)) {
239 5 : CHK_RET(SelectAlgforAiv(param, algName));
240 5 : return HCCL_SUCCESS; // alltoall aiv不需要后面操作,直接返回
241 : }
242 :
243 0 : if (resourceLimit.ifCompileForAiv) {
244 0 : HCCL_DEBUG("[SelectAlgForAlltoAll] compile for aiv, early return.");
245 0 : return HCCL_SUCCESS;
246 : }
247 :
248 0 : std::vector<HcclAlgoType> algoTypeArr = topoMatcher_->GetAlgoConfig(HcclCMDType::HCCL_CMD_ALLTOALL);
249 : bool useOneLevelAlgorithm =
250 0 : algoTypeArr[HCCL_ALGO_LEVEL_0] == HcclAlgoType::HCCL_ALGO_TYPE_NA &&
251 0 : algoTypeArr[HCCL_ALGO_LEVEL_1] == HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE;
252 : // 用户配置打平 alltoall
253 :
254 0 : CHK_PRT_RET(deviceType_ == DevType::DEV_TYPE_310P3 && userRankSize_ > MAX_310P_RANK_SIZE,
255 : HCCL_ERROR("[AlltoAllOperator][SelectAlgforAlltoAll]rankSize[%u] is not supported. AlltoAll/AlltoAllV does not "\
256 : "support the scenario where the rankSize is greater than 4.", userRankSize_), HCCL_E_NOT_SUPPORT);
257 :
258 : // NA+pairwise算法不支持A+X跨mesh两卡
259 0 : bool isSingleDeviceModuleP2p = (userRankSize_ <= HCCL_ALLTOALLV_P2P_SIZE);
260 0 : if (userRankSize_ == 1 && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && !param.aicpuUnfoldMode) {
261 0 : algName = "RunAlltoAllSingleExecutor";
262 0 : return HCCL_SUCCESS ;
263 0 : } else if (isCommon310P3DUO_) {
264 0 : algName = "RunAlltoAllVFor310PExecutor";
265 0 : } else if(IsSatisfyA2AContinuousPipelineFor91093Condition(param)) {
266 0 : algName = "RunAlltoAllVPipelineFor91093";
267 0 : HCCL_INFO("[SelectAlgforAlltoAll] AllToAll algName is [%s]", algName.c_str());
268 0 : return HCCL_SUCCESS;
269 0 : } else if (IsSupportDirectFullmeshForAlltoallv(param, deviceType_, useSuperPodMode_, serverNum_,
270 0 : isSingleMeshAggregation_, userRankSize_, cclBufferManager_.GetInCCLbufferSize()) ||
271 0 : (deviceType_ == DevType::DEV_TYPE_910_93 && param.aicpuUnfoldMode) || deviceType_ == DevType::DEV_TYPE_310P3) {
272 0 : bool isHCCS = (serverNum_ == 1 || (serverNum_ != 1 && !GetExternalInputInterHccsDisable()));
273 0 : if (param.supportSymmetricMemory && superPodNum_ == 1 && isHCCS) {
274 0 : algName = "RunAlltoAllFullMeshSymmetricMemory";
275 : } else {
276 0 : algName = "RunAlltoAllDirectFullmesh";
277 : }
278 0 : HCCL_INFO("[SelectAlgforAlltoAll] AllToAll algName is [%s]", algName.c_str());
279 0 : return HCCL_SUCCESS;
280 0 : } else if (IsSatisfyAlltoallContinuousPipelineCondition(param)) {
281 0 : algName = "RunAlltoAllVContinuousPipeline"; // continuous pipeline 算法
282 0 : HCCL_INFO("[SelectAlgforAlltoAll] AllToAll algName is [%s]", algName.c_str());
283 0 : return HCCL_SUCCESS ;
284 0 : } else if (IsSatisfyAlltoallPipelineCondition()) {
285 0 : algName = "RunAlltoAllVTwoLevelPipeline";
286 0 : } else if (SatisfyIntraSuperPod(deviceType_, userRankSize_, useSuperPodMode_, superPodNum_) ||
287 0 : useOneLevelAlgorithm || isAllRankSamePlane_ || isSingleDeviceModuleP2p || multiModuleDiffDeviceNumMode_ ||
288 0 : multiSuperPodDiffServerNumMode_) {
289 0 : algName = "RunAlltoAllVFullMesh"; //910B卡数不一致走这
290 : } else {
291 0 : algName = "RunAlltoAllVStaged";
292 : }
293 :
294 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
295 : // alltoallv
296 0 : CHK_RET(GetAlltoAllvSendRecvInfo(param, hostCollectBuffer_));
297 0 : } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC || param.opType == HcclCMDType::HCCL_CMD_ALLTOALL){
298 : // alltoallvc&&alltoall
299 0 : CHK_RET(GetAlltoAllvcSendRecvInfo(param.All2AllDataDes.sendCountMatrix, param.All2AllDataDes.sendType,
300 : param.All2AllDataDes.recvType));
301 0 : } else {
302 0 : HCCL_ERROR("[AlltoAllOperator][SelectAlgforAlltoAll] get wrong opType");
303 0 : return HCCL_E_PARA;
304 : }
305 0 : UpdateAlltoAllCopyMode(allMeshAggregationSendRecvInfo_, copyMode);
306 :
307 0 : HCCL_INFO("[SelectAlgforAlltoAll] AllToAll algName is [%s].", algName.c_str());
308 0 : return HCCL_SUCCESS;
309 0 : }
310 :
311 0 : HcclResult AlltoAllOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName,
312 : std::string& newTag)
313 : {
314 0 : ResourceLimit resourceLimit;
315 0 : return SelectAlg(tag, param, algName, newTag, resourceLimit);
316 : }
317 :
318 5 : HcclResult AlltoAllOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName,
319 : std::string& newTag, const ResourceLimit& resourceLimit)
320 : {
321 : HcclResult ret;
322 5 : std::string copyMode = "BCopy";
323 :
324 5 : if (isDiffDeviceType_) {
325 0 : HCCL_ERROR("[AlltoAllOperator][SelectAlg] AlltoAll not support diffDeviceType");
326 0 : return HCCL_E_NOT_SUPPORT;
327 : }
328 5 : ret = SelectAlgforAlltoAll(param, algName, copyMode, resourceLimit);
329 5 : CHK_PRT_RET(ret != HCCL_SUCCESS,
330 : HCCL_ERROR("[SelectAlgforAlltoAll][SelectAlg]tag[%s], Alltoall failed, return[%d].", tag.c_str(), ret), ret);
331 :
332 5 : if (resourceLimit.ifCompileForAiv) {
333 0 : HCCL_DEBUG("[SelectAlg] AlltoAllOperator compile for aiv, early return.");
334 0 : return HCCL_SUCCESS;
335 : }
336 :
337 5 : bool useA2AAiv = IsSatisfyAlltoAllAivCondition(param);
338 15 : bool useDirectFullmesh = IsSupportDirectFullmeshForAlltoallv(param, deviceType_, useSuperPodMode_, serverNum_,
339 5 : isSingleMeshAggregation_, userRankSize_, cclBufferManager_.GetInCCLbufferSize());
340 :
341 5 : bool aicpuUnfoldModeFor910B = deviceType_ == DevType::DEV_TYPE_910B && param.aicpuUnfoldMode;
342 5 : if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
343 5 : if (useDirectFullmesh || param.aicpuUnfoldMode) {
344 5 : newTag = tag + algName;
345 : // A2 alltoall AICPU展开需要区分Zcopy与bCopy
346 5 : if (aicpuUnfoldModeFor910B) {
347 0 : newTag += copyMode;
348 : }
349 : } else {
350 0 : newTag = tag + algName + copyMode;
351 : }
352 5 : newTag += (param.aicpuUnfoldMode ? "_device" : "_host");
353 : } else {
354 0 : newTag = tag;
355 : }
356 5 : if ((!useA2AAiv && !useDirectFullmesh && !param.aicpuUnfoldMode) || aicpuUnfoldModeFor910B) {
357 0 : CHK_RET(SetExcutorExtraInfo(algName, param));
358 : }
359 5 : return ret;
360 5 : }
361 :
362 0 : HcclResult AlltoAllOperator::GetAlltoAllvAllAddrInfo(u64 *sendLength, u64 *sendOffset,
363 : u64 *recvLength, u64 *recvOffset, std::unique_ptr<PreProcessMetaInfo> &preMetaInfo)
364 : {
365 0 : const u32 addrItemNum = 4;
366 0 : u64 stepSize = sizeof(u64) * userRankSize_;
367 :
368 0 : std::vector<u64> alltoallAddrInfo(userRankSize_ * addrItemNum, 0);
369 0 : const u32 recvLengthStep = 2;
370 0 : const u32 recvOffsetStep = 3;
371 :
372 0 : CHK_SAFETY_FUNC_RET(memcpy_s(&alltoallAddrInfo[0], stepSize, sendLength, stepSize));
373 0 : CHK_SAFETY_FUNC_RET(memcpy_s(&alltoallAddrInfo[userRankSize_], stepSize, sendOffset, stepSize));
374 0 : CHK_SAFETY_FUNC_RET(memcpy_s(&alltoallAddrInfo[recvLengthStep * userRankSize_], stepSize, recvLength, stepSize));
375 0 : CHK_SAFETY_FUNC_RET(memcpy_s(&alltoallAddrInfo[recvOffsetStep * userRankSize_], stepSize, recvOffset, stepSize));
376 0 : preMetaInfo->inputData = alltoallAddrInfo;
377 0 : preMetaInfo->inputSize = stepSize * addrItemNum;
378 0 : preMetaInfo->outputSize = userRankSize_ * stepSize * addrItemNum;
379 :
380 0 : return HCCL_SUCCESS;
381 0 : }
382 :
383 0 : HcclResult AlltoAllOperator::PrepareAlltoAllAddrInfo(const void *sendCounts, const void *sdispls,
384 : HcclDataType sendType, const void *recvCounts, const void *rdispls, HcclDataType recvType,
385 : std::unique_ptr<PreProcessMetaInfo> &preMetaInfo)
386 : {
387 0 : std::vector<u64> vctSendLength(userRankSize_, 0);
388 0 : std::vector<u64> vctSendOffset(userRankSize_, 0);
389 0 : std::vector<u64> vctRecvLength(userRankSize_, 0);
390 0 : std::vector<u64> vctRecvOffset(userRankSize_, 0);
391 :
392 0 : for (u32 i = 0; i < userRankSize_; i++) {
393 0 : vctSendLength[i] = *(static_cast<const u64 *>(sendCounts) + i) * SIZE_TABLE[sendType];
394 0 : vctSendOffset[i] = *(static_cast<const u64 *>(sdispls) + i) * SIZE_TABLE[sendType];
395 0 : vctRecvLength[i] = *(static_cast<const u64 *>(recvCounts) + i) * SIZE_TABLE[recvType];
396 0 : vctRecvOffset[i] = *(static_cast<const u64 *>(rdispls) + i) * SIZE_TABLE[recvType];
397 :
398 0 : HCCL_DEBUG("[PrepareAlltoAllAddrInfo] rank[%u], SendLength[%llu], SendOffset[%llu], "\
399 : "RecvLength[%llu], RecvOffset[%llu]", i, vctSendLength[i], vctSendOffset[i], vctRecvLength[i],
400 : vctRecvOffset[i]);
401 : }
402 0 : CHK_RET(GetAlltoAllvAllAddrInfo(vctSendLength.data(), vctSendOffset.data(),
403 : vctRecvLength.data(), vctRecvOffset.data(), preMetaInfo));
404 0 : return HCCL_SUCCESS;
405 0 : }
406 :
407 0 : HcclResult AlltoAllOperator::PreparePreOpParam(OpParam& preProcessOpParam,
408 : const std::unique_ptr<PreProcessMetaInfo> &preMetaInfo, Stream &preProcessStream)
409 : {
410 0 : u64 stepSize = sizeof(u64) * userRankSize_;
411 0 : u32 perDataSize = SIZE_TABLE[HCCL_DATA_TYPE_UINT64];
412 :
413 0 : preProcessOpParam.tag = HCCL_ALLTOALL_PARA_ALLGATHER;
414 0 : preProcessOpParam.inputPtr = cclBufferManager_.GetInAlltoAllvParaBuffer().ptr();
415 0 : preProcessOpParam.inputSize = (preMetaInfo->outputSize / stepSize) * perDataSize;
416 0 : preProcessOpParam.outputPtr = cclBufferManager_.GetOutAlltoAllvParaBuffer().ptr();
417 0 : preProcessOpParam.outputSize = (preMetaInfo->outputSize / stepSize) * perDataSize * userRankSize_;
418 0 : preProcessOpParam.DataDes.count = (preMetaInfo->outputSize / stepSize);
419 0 : preProcessOpParam.DataDes.dataType = HCCL_DATA_TYPE_UINT64;
420 0 : preProcessOpParam.stream = preProcessStream;
421 0 : preProcessOpParam.aicpuUnfoldMode = deviceType_ == DevType::DEV_TYPE_910_93 && topoMatcher_->GetAicpuUnfoldConfig();
422 0 : return HCCL_SUCCESS;
423 : }
424 :
425 5 : bool AlltoAllOperator::JudgeIfNeedPreProcessAndGetParam(const OpParam& param,
426 : std::unique_ptr<PreProcessMetaInfo> &preMetaInfo)
427 : {
428 5 : bool useA2AAiv = IsSatisfyAlltoAllAivCondition(param);
429 15 : bool useDirectFullmesh = IsSupportDirectFullmeshForAlltoallv(param, deviceType_, useSuperPodMode_, serverNum_,
430 5 : isSingleMeshAggregation_, userRankSize_, cclBufferManager_.GetInCCLbufferSize());
431 5 : bool useContinuousPipeline = IsSatisfyAlltoallContinuousPipelineCondition(param);
432 5 : if ((param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) && !useA2AAiv) {
433 0 : if (useDirectFullmesh || useContinuousPipeline || param.aicpuUnfoldMode) {
434 0 : return false;
435 : }
436 0 : CHK_RET(PrepareAlltoAllAddrInfo(param.All2AllDataDes.sendCounts, param.All2AllDataDes.sdispls,
437 : param.All2AllDataDes.sendType, param.All2AllDataDes.recvCounts, param.All2AllDataDes.rdispls,
438 : param.All2AllDataDes.recvType, preMetaInfo));
439 0 : preMetaInfo->opType = HcclCMDType::HCCL_CMD_ALLGATHER;
440 0 : return true;
441 : }
442 5 : return false;
443 : }
444 :
445 0 : void AlltoAllOperator::SetPreProcessResult(HostMem hostCollectBuffer)
446 : {
447 0 : hostCollectBuffer_ = std::move(hostCollectBuffer);
448 0 : }
449 :
450 0 : HcclResult AlltoAllOperator::SetExcutorExtraInfo(const std::string& algName, const OpParam& param)
451 : {
452 0 : HCCL_DEBUG("[AlltoAllOperator][SetExcutorExtraInfo]algName[%s]", algName.c_str());
453 0 : if (executor_.get() == nullptr) {
454 0 : executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
455 0 : CHK_PRT_RET(executor_.get() == nullptr,
456 : HCCL_ERROR("[AlltoAllOperator][CalcResRequest]Fail to find executor for algName[%s]", algName.c_str()),
457 : HCCL_E_PARA);
458 0 : CHK_RET(SetExecutorAttr(param));
459 : }
460 :
461 : // AICPU aicpuUnfold展开模式下临时强制OP_BASE,使UpdateAlltoAllZCopyMode正确判断
462 0 : const bool needForceOpBase = param.aicpuUnfoldMode && !param.isZeroCopy;
463 0 : const HcclWorkflowMode savedWorkflowMode = executor_->GetExecutorWorkflowMode();
464 0 : if (needForceOpBase) {
465 0 : executor_->SetWorkflowMode(HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
466 : }
467 :
468 0 : CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor *>(executor_.get());
469 0 : HcclResult ret = alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclBufferManager_.GetInCCLbufferSize());
470 :
471 0 : if (needForceOpBase) {
472 0 : executor_->SetWorkflowMode(savedWorkflowMode);
473 : }
474 0 : return ret;
475 : }
476 :
477 5 : HcclResult AlltoAllOperator::SetExecutorAttr(const OpParam& param)
478 : {
479 5 : CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor *>(executor_.get());
480 5 : CHK_RET(alltoAllExecutor->SetAlgType(algType_));
481 5 : CHK_RET(alltoAllExecutor->SetVirtualDispatcher(vDispatcher_));
482 5 : CHK_RET(alltoAllExecutor->SetCCLInBuffer(cclBufferManager_.GetInCCLbufferSize()));
483 5 : CHK_RET(alltoAllExecutor->SetParallelTaskLoader(parallelTaskLoader_));
484 : #ifdef OPEN_HCCL_TEST
485 : if (!allMeshAggregationSendRecvInfo_.empty()) {
486 : return HCCL_SUCCESS;
487 : }
488 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
489 : CHK_RET(GetAlltoAllvSendRecvInfo(param, hostCollectBuffer_));
490 : } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC || param.opType == HcclCMDType::HCCL_CMD_ALLTOALL){
491 : CHK_RET(GetAlltoAllvcSendRecvInfo(param.All2AllDataDes.sendCountMatrix, param.All2AllDataDes.sendType,
492 : param.All2AllDataDes.recvType));
493 : }
494 :
495 : CHK_RET(alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclBufferManager_.GetInCCLbufferSize()));
496 : #endif
497 5 : return HCCL_SUCCESS;
498 : }
499 :
500 1 : HcclResult AlltoAllOperator::CheckNeedRecreateComm(const std::string& algName, const OpParam& param,
501 : u64 lastScratchMemSize, bool& needRecreateAlltoallComm)
502 : {
503 1 : if (executor_.get() == nullptr) {
504 0 : executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
505 0 : CHK_PRT_RET(executor_.get() == nullptr,
506 : HCCL_ERROR("[AlltoAllOperator][CheckNeedRecreateComm]Fail to find executor for algName[%s]",
507 : algName.c_str()), HCCL_E_PARA);
508 0 : CHK_RET(SetExecutorAttr(param));
509 : }
510 1 : CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor *>(executor_.get());
511 1 : CHK_RET(alltoAllExecutor->CheckNeedRecreateComm(lastScratchMemSize, needRecreateAlltoallComm));
512 1 : return HCCL_SUCCESS;
513 : }
514 :
515 0 : bool AlltoAllOperator::IsSatisfyAlltoallPipelineCondition()
516 : {
517 0 : bool cclBigEnough = cclBufferManager_.GetInCCLbufferSize() >= ALLTOALL_PIPELINE_MIN_CCL_SIZE;
518 0 : bool multiRankPerServer = meshAggregationRankSize_ > 1;
519 0 : bool isMultiServer = ((userRankSize_ > meshAggregationRankSize_) &&
520 0 : (userRankSize_ % meshAggregationRankSize_) == 0);
521 0 : bool isDefaultAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING)
522 0 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD);
523 0 : bool isPipelineAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE);
524 0 : bool isSatisfyAlgType = (isPipelineAlgo || isDefaultAlgo) &&
525 0 : CalcContextNumForPipeline(HcclCMDType::HCCL_CMD_ALLTOALL) <= HCCL_FFTS_CAPACITY;
526 0 : HCCL_DEBUG("[AlltoAllOperator][IsSatisfyAlltoallPipelineCondition]multiRankPerServer %u, "
527 : "isMultiServer %u, satisfyAlgType, %u, multiModuleDiffDeviceNumMode_ %u", multiRankPerServer,
528 : isMultiServer, isSatisfyAlgType, multiModuleDiffDeviceNumMode_);
529 0 : bool res = (deviceType_ == DevType::DEV_TYPE_910B && isSatisfyAlgType && multiRankPerServer &&
530 0 : GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && isMultiServer &&
531 0 : !multiModuleDiffDeviceNumMode_ && cclBigEnough);
532 0 : if (isSatisfyAlgType && !res) {
533 0 : HCCL_WARNING("AllToAll algo type is set to pipeline, but cclBigEnough is %u, multiRankPerServer is %u, "
534 : "isMultiServer is %u", cclBigEnough, multiRankPerServer, isMultiServer);
535 : }
536 0 : return res;
537 : }
538 :
539 0 : bool AlltoAllOperator::IsSatisfy91093OffloadCondition()
540 : {
541 0 : bool isOffload = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB;
542 0 : bool isDeviceType = deviceType_ == DevType::DEV_TYPE_910_93;
543 0 : bool isAicpuUnfoldMode = topoMatcher_->GetAicpuUnfoldConfig();
544 0 : return isAicpuUnfoldMode && isDeviceType && isOffload;
545 : }
546 :
547 0 : bool AlltoAllOperator::IsSatisfyAlltoAllAivCondition(const OpParam& param)
548 : {
549 0 : bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
550 0 : bool isOpbase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
551 0 : bool isBufferEnough = !isOpbase || cclBufferManager_.GetInCCLbufferSize() >= AIV_ALL_TO_ALL_BIG_SIZE * MAX_RANK_SIZE;
552 :
553 0 : bool isSupportAiv = topoMatcher_->GetAivModeConfig()
554 0 : && IsSupportAIVCopy(param.All2AllDataDes.sendType)
555 0 : && userRankSize_ > 1
556 0 : && isBufferEnough
557 0 : && !retryEnable_;
558 : // 如果配置了aiv only,但是实际没有选择aiv算法,需要通过DFX打印出具体原因
559 0 : if (isOnlyAiv && !isSupportAiv) {
560 0 : HCCL_ERROR("The current conditions do not meet the aiv only execution criteria because:");
561 0 : CHK_PRT_RET(!IsSupportAIVCopy(param.All2AllDataDes.sendType), HCCL_ERROR("current data type[%s] not supported, support range: "\
562 : "[int8, int16, int32, uint8, uint16, uint32, float16, float32, bfloat16]",
563 : GetDataTypeEnumStr(param.All2AllDataDes.sendType).c_str()), false);
564 0 : CHK_PRT_RET(userRankSize_ == 1, HCCL_ERROR("current userRankSize[%u] equal to 1.", userRankSize_), false);
565 :
566 0 : CHK_PRT_RET(!isBufferEnough, HCCL_ERROR("current buffer size[%llu] is not enough. isOpbase[%d]",
567 : cclBufferManager_.GetInCCLbufferSize(), isOpbase), false);
568 :
569 0 : CHK_PRT_RET(retryEnable_, HCCL_ERROR("retryEnable_[%d] is true.", retryEnable_), false);
570 0 : return false;
571 : }
572 :
573 0 : if (deviceType_ == DevType::DEV_TYPE_910B) {
574 0 : bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH ||
575 0 : topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH ||
576 0 : userRankSize_ == moduleNum_;
577 0 : bool isModuleSatisfy = isSingleMeshAggregation_;
578 :
579 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
580 : // alltoall算子支持单机和多机场景
581 0 : if (!isSingleMeshAggregation_) {
582 : // 多机场景下当前不支持module间卡数不一致场景,集群中总的服务器数需要满足条件,cclbuffer大小需要满足
583 0 : isModuleSatisfy = isOpbase
584 0 : && !multiModuleDiffDeviceNumMode_
585 0 : && (moduleNum_ <= MAX_RMDA_RANK_SIZE)
586 0 : && IsBufferSatisfyAlltoAllAivCondition(param);
587 : }
588 : }
589 0 : if (isOnlyAiv && (!isModuleSatisfy || !isMeshTopo)) {
590 0 : HCCL_ERROR("opType[%d] topoType_[%d] isSingleMeshAggregation_[%d] isOpbase[%d] multiModuleDiffDeviceNumMode_[%d] "\
591 : "moduleNum_[%u] IsBufferSatisfyAlltoAllAivCondition[%u]", param.opType, topoType_, isSingleMeshAggregation_,
592 : isOpbase, multiModuleDiffDeviceNumMode_, moduleNum_, IsBufferSatisfyAlltoAllAivCondition(param));
593 0 : return false;
594 : }
595 0 : return isSupportAiv && isModuleSatisfy && isMeshTopo;
596 : }
597 :
598 0 : if (deviceType_ == DevType::DEV_TYPE_910_93) {
599 0 : bool isSupportInterHccs = (superPodNum_ == 1 && serverNum_ > 1 && !GetExternalInputInterHccsDisable());
600 :
601 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
602 0 : u64 dataSize = param.All2AllDataDes.sendCount * SIZE_TABLE[param.All2AllDataDes.sendType];
603 0 : bool isAllToAllBufferEnough = serverNum_ == 1 && ((dataSize <= AIV_ALL_TO_ALL_A3_ENTRY_SIZE || isOnlyAiv) || !isOpbase);
604 :
605 0 : if (isOnlyAiv && (!isAllToAllBufferEnough && !isSupportInterHccs)) {
606 0 : HCCL_ERROR("serverNum_[%u] isOpbase[%d] dataSize[%llu] superPodNum_[%u] hccs disable[%u]",
607 : serverNum_, isOpbase, dataSize, superPodNum_, GetExternalInputInterHccsDisable());
608 0 : return false;
609 : }
610 0 : return isSupportAiv && ( isAllToAllBufferEnough || isSupportInterHccs);
611 : }
612 0 : if (isOnlyAiv && serverNum_ != 1 && !isSupportInterHccs) {
613 0 : HCCL_ERROR("serverNum_[%u] isOpbase[%d] superPodNum_[%u] hccs disable[%u]",
614 : serverNum_, isOpbase, superPodNum_, GetExternalInputInterHccsDisable());
615 0 : return false;
616 : }
617 0 : return isSupportAiv && (serverNum_ == 1 || isSupportInterHccs);
618 : }
619 :
620 0 : return false;
621 : }
622 :
623 0 : bool AlltoAllOperator::IsBufferSatisfyAlltoAllAivCondition(const OpParam& param)
624 : {
625 0 : u64 sendCount = param.All2AllDataDes.sendCount;
626 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC && param.All2AllDataDes.sendCountMatrix != nullptr) {
627 0 : sendCount = *(static_cast<const u64 *>(param.All2AllDataDes.sendCountMatrix));
628 : }
629 :
630 0 : u64 dataSize = SIZE_TABLE[param.All2AllDataDes.sendType];
631 0 : u64 scratchMemSize = sendCount * dataSize * userRankSize_;
632 0 : s64 dataSizeLimit = param.supportRoceDirect ? HCCL_SMALL_COUNT_4_MB : HCCL_SMALL_COUNT_190_KB;
633 0 : if (param.supportRoceDirect) {
634 : // 使用roce直驱时,total数据量应小于4M
635 0 : if(!(scratchMemSize <= static_cast<u64>(dataSizeLimit))) {
636 0 : HCCL_WARNING("[AlltoAllOperator]total dataSize[%llu] > [%lld], doesn't meet the aiv condition, select default algorithm",
637 : scratchMemSize, dataSizeLimit);
638 0 : return false;
639 : }
640 : // Roce直驱跨机场景,ccl需要预留flag位(与AIV保持一致,预留2M)
641 0 : scratchMemSize += AIV_FLAG_OFFSET;
642 : } else {
643 : // 每个rank的数据需要满足小于190K
644 0 : if (!(sendCount * dataSize <= static_cast<u64>(dataSizeLimit))) {
645 0 : HCCL_WARNING("[AlltoAllOperator]dataSize[%llu] > [%lld], doesn't meet the aiv condition, select default algorithm",
646 : sendCount * dataSize, dataSizeLimit);
647 0 : return false;
648 : }
649 : }
650 :
651 : // cclbuffer是否足够存储每个rank的中转数据
652 0 : if (!(scratchMemSize <= cclBufferManager_.GetInCCLbufferSize())) {
653 0 : HCCL_WARNING("[AlltoAllOperator]cclbuffer[%llu] < scratchMemSize[%llu]+32K, don't meet the aiv condition, "
654 : "please set HCCL_BUFFSIZE to increase cclbuffer", cclBufferManager_.GetInCCLbufferSize(), scratchMemSize);
655 0 : return false;
656 : }
657 0 : return true;
658 : }
659 :
660 5 : bool AlltoAllOperator::IsSatisfyA2AContinuousPipelineFor91093Condition(const OpParam& param)
661 : {
662 5 : constexpr u32 SERVERNUM = 2;
663 5 : constexpr u32 RANKSPERSERVER = 1;
664 5 : bool cclBigEnough = cclBufferManager_.GetInCCLbufferSize() >= ALLTOALL_PIPELINE_MIN_CCL_SIZE;
665 5 : bool multiServer = (serverNum_ == SERVERNUM) && (superPodNum_ == SERVERNUM);
666 5 : bool multiRankPerServer = meshAggregationRankSize_ > RANKSPERSERVER;
667 5 : bool isOpbse = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
668 10 : bool isAlltoAll = param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV
669 1 : || param.opType == HcclCMDType::HCCL_CMD_ALLTOALL
670 6 : || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC;
671 10 : bool isDefaultAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING)
672 5 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD)
673 10 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR);
674 5 : bool isPipelineAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE);
675 5 : bool satisfyAlgType = isPipelineAlgo || isDefaultAlgo;
676 0 : bool res = (deviceType_ == DevType::DEV_TYPE_910_93) && multiServer && multiRankPerServer
677 5 : && !multiSuperPodDiffDeviceNumMode_ && isOpbse && isAlltoAll && cclBigEnough && satisfyAlgType;
678 :
679 5 : HCCL_DEBUG("[AlltoAllOperator][IsSatisfyA2AContinuousPipelineFor91093Condition] isSatisfy[%d], serverNum[%d], superPodNum %u,"
680 : "meshAggregationRankSize_ %u, isOpbse %u, isAlltoAll(vc|v) %u, multiSuperPodDiffDeviceNumMode_ %u, aicpuUnfoldMode[%u].",
681 : res, serverNum_, superPodNum_, meshAggregationRankSize_, isOpbse, isAlltoAll, multiSuperPodDiffDeviceNumMode_, param.aicpuUnfoldMode);
682 5 : return res;
683 : }
684 :
685 10 : bool AlltoAllOperator::IsSatisfyAlltoallContinuousPipelineCondition(const OpParam& param)
686 : {
687 10 : std::vector<HcclAlgoType> algoTypeArr = topoMatcher_->GetAlgoConfig(HcclCMDType::HCCL_CMD_ALLTOALLV);
688 : bool useOneLevelAlgorithm =
689 10 : algoTypeArr[HCCL_ALGO_LEVEL_0] == HcclAlgoType::HCCL_ALGO_TYPE_NA &&
690 0 : algoTypeArr[HCCL_ALGO_LEVEL_1] == HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE;
691 :
692 10 : bool cclBigEnough = cclBufferManager_.GetInCCLbufferSize() >= ALLTOALL_PIPELINE_MIN_CCL_SIZE;
693 10 : bool multiRankPerServer = meshAggregationRankSize_ > 1;
694 20 : bool isMultiServer = (meshAggregationRankSize_ != 0) && ((userRankSize_ > meshAggregationRankSize_) &&
695 10 : (userRankSize_ % meshAggregationRankSize_) == 0);
696 20 : bool isDefaultAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING)
697 10 : || (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD);
698 10 : bool isPipelineAlgo = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_PIPELINE);
699 10 : bool satisfyAlgType = isPipelineAlgo || isDefaultAlgo;
700 10 : bool isAlltoAllv = param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV;
701 10 : bool res = (deviceType_ == DevType::DEV_TYPE_910B && isAlltoAllv && satisfyAlgType && multiRankPerServer &&
702 0 : GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && isMultiServer &&
703 20 : !multiModuleDiffDeviceNumMode_ && cclBigEnough && !useOneLevelAlgorithm && !param.isCapture);
704 10 : HCCL_DEBUG("[AlltoAllOperator][IsSatisfyAlltoallContinuousPipelineCondition] isSatisfy[%d], isAlltoAllv %u,"
705 : "multiRankPerServer %u, isMultiServer %u, satisfyAlgType %u, multiModuleDiffDeviceNumMode_ %u,"
706 : "useOneLevelAlgorithm %u, isCapture %u.",
707 : res, isAlltoAllv, multiRankPerServer, isMultiServer, satisfyAlgType, multiModuleDiffDeviceNumMode_,
708 : useOneLevelAlgorithm, param.isCapture);
709 10 : return res;
710 10 : }
711 :
712 0 : HcclResult AlltoAllOperator::GetAlltoAllStagedWorkSpaceMemSize(const OpParam& param, u64 &memSize)
713 : {
714 0 : if (multiModuleDiffDeviceNumMode_ || multiSuperPodDiffServerNumMode_) {
715 0 : memSize = 0;
716 0 : HCCL_INFO("[Get][AlltoAllStagedWorkSpaceMemSize]Asym scene, No workSpaceMem required. "\
717 : "multiModuleDiffDeviceNumMode[%d], multiSuperPodDiffServerNumMode[%d], memSize:[%llu]",
718 : multiModuleDiffDeviceNumMode_, multiSuperPodDiffServerNumMode_, memSize);
719 0 : return HCCL_SUCCESS;
720 : }
721 0 : CHK_PTR_NULL(hostCollectBuffer_.ptr());
722 0 : CHK_RET(GetAlltoAllvSendRecvInfo(param, hostCollectBuffer_));
723 :
724 : AlltoAllUserRankInfo userRankInfo;
725 0 : userRankInfo.userRank = userRank_;
726 0 : userRankInfo.userRankSize = userRankSize_;
727 0 : AlltoAllVStagedCalculator::CalcWorkSpaceMemSize(userRankInfo, allMeshAggregationSendRecvInfo_,
728 : memSize, meshAggregationRankSize_);
729 :
730 0 : HCCL_INFO("Calculate workSpace MemSize done, memSize[%llu]", memSize);
731 :
732 : // 计算结果
733 0 : return HCCL_SUCCESS;
734 : }
735 :
736 0 : HcclResult AlltoAllOperator::GetAlltoAllStagedWorkSpaceMemSize(
737 : std::vector<SendRecvInfo> &allMeshAggregationSendRecvInfo, u64 &memSize)
738 : {
739 0 : if (multiModuleDiffDeviceNumMode_ || multiSuperPodDiffServerNumMode_) {
740 0 : memSize = 0;
741 0 : HCCL_INFO("[Get][AlltoAllStagedWorkSpaceMemSize]Asym scene, No workSpaceMem required. "\
742 : "multiModuleDiffDeviceNumMode[%d], multiSuperPodDiffServerNumMode[%d], memSize:[%llu]",
743 : multiModuleDiffDeviceNumMode_, multiSuperPodDiffServerNumMode_, memSize);
744 0 : return HCCL_SUCCESS;
745 : }
746 : AlltoAllUserRankInfo userRankInfo;
747 0 : userRankInfo.userRank = userRank_;
748 0 : userRankInfo.userRankSize = userRankSize_;
749 0 : AlltoAllVStagedCalculator::CalcWorkSpaceMemSize(userRankInfo, allMeshAggregationSendRecvInfo,
750 : memSize, meshAggregationRankSize_);
751 :
752 0 : HCCL_INFO("Calculate workSpace MemSize done, memSize[%llu]", memSize);
753 :
754 : // 计算结果
755 0 : return HCCL_SUCCESS;
756 : }
757 :
758 : REGISTER_OP(HcclCMDType::HCCL_CMD_ALLTOALLV, AlltoAllV, AlltoAllOperator);
759 : REGISTER_OP(HcclCMDType::HCCL_CMD_ALLTOALL, AlltoAll, AlltoAllOperator);
760 : REGISTER_OP(HcclCMDType::HCCL_CMD_ALLTOALLVC, AlltoAllVC, AlltoAllOperator);
761 :
762 : }
|