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