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 <iomanip>
12 : #include "aicpu_communicator.h"
13 : #include "dispatcher.h"
14 : #include "aicpu_hccl_process.h"
15 : #include "coll_alg_exec_registry.h"
16 : #include "coll_all_to_all_executor.h"
17 : #include "common/aicpu_hccl_common.h"
18 : #include "executor_tracer.h"
19 : #include "profiling_manager_device.h"
20 : #include "utils/aicpu_hdc_utils.h"
21 : #include "comm_engine_utils.h"
22 : #include "utils/hccl_aicpu_utils.h"
23 : #include "framework/aicpu_hdc.h"
24 : #include "common/aicpu_sqe_context.h"
25 : #include "coll_batch_send_recv_retry_executor.h"
26 : #include "log_control.h"
27 : #include "aicpu_hccl_sqcq.h"
28 : #include "aicpu_hccl_sqcqv1.h"
29 : #include "sal_pub.h"
30 : #include "externalinput_pub.h"
31 : #include "env_config.h"
32 : #include "config_log.h"
33 : #include "aicpu_one_side_service.h"
34 : #include "notify_manager.h"
35 : #include "dispatcher_aicpu.h"
36 : #include "dlprof_function.h"
37 : #include "profiling_command_handle.h"
38 : #include "dispatcher_ctx.h"
39 : #include "aicpu_res_package_helper.h"
40 : #include "aicpu_symmetric_memory.h"
41 :
42 : namespace hccl {
43 : constexpr u32 IPC_SIGNAL_MODULUS = 2;
44 : constexpr u32 RDMA_SIGNAL_MODULUS = 3;
45 : constexpr u32 KEY_VALUE_TO_VECTOR_MODULUS = 2;
46 :
47 : constexpr u32 BSR_RETRY_SEND_STREAM_INDEX = 0;
48 : constexpr u32 BSR_RETRY_RECV_STREAM_INDEX = 1;
49 : constexpr u32 BSR_RETRY_STREAM_NUM = 2;
50 : constexpr u32 MAX_REPORT_STATUS = 100U; // reportStatus的最大缓存数量
51 : constexpr u32 INPUT = 0;
52 : constexpr u32 OUTPUT = 1;
53 : constexpr u32 AICPU_RETRY_LINKROCE_DEFAULT = 0;
54 : constexpr u32 AICPU_RETRY_LINKROCE_BACKUP = 1;
55 :
56 : constexpr u32 BSR_RETRY_SENDRECV_PAIR_NUM_MAX = 2;
57 : constexpr u32 BSR_RETRY_SENDRECV_PAIR_INDEX_0 = 0;
58 : constexpr u32 BSR_RETRY_SENDRECV_PAIR_INDEX_1 = 1;
59 :
60 : constexpr u32 NOTIFY_SIZE_FOUR = 4;
61 : constexpr u32 NOTIFY_SIZE_EIGHT = 8;
62 :
63 : bool HcclCommAicpu::errMessageReport_ = true;
64 :
65 : #define HCCL_RETRY_CHK_RET_AND_TRANS_FSM(result__, exeLog__, error__, state__) \
66 : do { \
67 : if (UNLIKELY((result__) != HCCL_SUCCESS)) { \
68 : exeLog__; \
69 : errorCode = (error__); \
70 : fsmState = (state__); \
71 : return (result__); \
72 : } \
73 : } while (0)
74 :
75 363 : HcclCommAicpu::HcclCommAicpu() { HCCL_RUN_INFO("Construct HcclCommAicpu complete."); }
76 :
77 288 : HcclCommAicpu::~HcclCommAicpu()
78 : {
79 32 : if (UtraceInfo_ != nullptr) {
80 11 : UtraceInfo_->DeInit();
81 11 : UtraceInfo_ = nullptr;
82 : }
83 32 : if (dispatcher_ != nullptr) {
84 11 : HcclDispatcherDestroy(dispatcher_);
85 11 : dispatcher_ = nullptr;
86 : }
87 32 : if (dispatcherCtx_ != nullptr) {
88 0 : DestroyDispatcherCtx(dispatcherCtx_, identifier_.c_str());
89 0 : HCCL_DEBUG("[%s] destroy dispatcherCtx[%p] group[%s] success!", __func__, dispatcherCtx_, identifier_.c_str());
90 0 : dispatcherCtx_ = nullptr;
91 : }
92 :
93 32 : commPlaneVector_.clear();
94 32 : isBridgeVector_.clear();
95 32 : indOpCommInitialized_ = false;
96 32 : initialized_ = false;
97 :
98 32 : HCCL_RUN_INFO("Destruct HcclCommAicpu group[%s] success!", identifier_.c_str());
99 352 : }
100 :
101 13 : HcclResult HcclCommAicpu::Init(const HcclOpResParam* commParam, bool isCustom)
102 : {
103 13 : if (initialized_) {
104 2 : HCCL_RUN_INFO("[%s][Init]Group[%s] already initialized, skip reinit", __func__, identifier_.c_str());
105 2 : return HCCL_SUCCESS;
106 : }
107 :
108 11 : CHK_PTR_NULL(commParam);
109 11 : identifier_ = commParam->hcomId;
110 11 : isCustom_ = isCustom;
111 11 : HCCL_RUN_INFO(
112 : "[HcclCommAicpu][Init]Entry-Init group[%s], rankSize[%u], isCustom[%d].", identifier_.c_str(),
113 : commParam->rankSize, isCustom_);
114 11 : CHK_RET(aicpuShareData_.Init(commParam->aicpuCustomParamAddr, commParam->aicpuCustomParamSize));
115 11 : CHK_RET(SetHrtWorkMode(commParam));
116 11 : CHK_RET(SetHrtDeviceSatMode(commParam));
117 11 : CHK_RET(InitConfigInfo(commParam));
118 11 : CHK_RET(InitCclbuffer(commParam));
119 11 : CHK_RET(InitTopoInfo(commParam));
120 11 : CHK_RET(InitOpNotifyObj(commParam));
121 11 : CHK_RET(HcclDispatcherAicpuInit(&dispatcher_, devId_, commParam->hcclSdmaQos, DispatcherType::DISPATCHER_AICPU));
122 11 : CHK_RET(RegisterProfilingCallback());
123 11 : CHK_RET(InitLocalNotifyObj(commParam));
124 11 : CHK_RET(InitMainStreamObj(commParam));
125 11 : CHK_RET(InitSlaveStreamObjs(commParam));
126 11 : CHK_RET(InitOrderStreamObj(commParam));
127 11 : CHK_RET(InitLocalTagRes(commParam->localRes.nextTagRes));
128 11 : CHK_RET(InitTimeOutConfig(commParam));
129 11 : CHK_RET(InitHostDeviceLock(commParam));
130 11 : CHK_RET(InitTopoMatcher());
131 11 : CHK_RET(InitOpRetry(commParam));
132 11 : CHK_RET(RegisterDispatcherCallback());
133 11 : CHK_RET(InitTinyMem(commParam));
134 11 : CHK_RET(InitProfResource());
135 11 : CHK_RET(InitZeroCopyExchanger(commParam));
136 11 : CHK_RET(InitOpCounter(commParam->opCounterInfo));
137 11 : CHK_RET(InitUtraceInfo(commParam));
138 11 : CHK_RET(aicpuCacheManager_.InitOpUnfoldCache());
139 11 : CHK_RET(RegisterProfCallBack());
140 11 : InitCommInfoStatus(true);
141 11 : SetCommInfoStreamStatus(true);
142 :
143 11 : initialized_ = true;
144 :
145 11 : HCCL_RUN_INFO("[HcclCommAicpu][Init] group[%s] success!", identifier_.c_str());
146 11 : return HCCL_SUCCESS;
147 : }
148 :
149 11 : HcclResult HcclCommAicpu::InitUtraceInfo(const HcclOpResParam* commParam)
150 : {
151 11 : u32 hostpid = 0;
152 11 : u32 cpType = DEVDRV_PROCESS_CPTYPE_MAX;
153 11 : CHK_RET(HrtHalDrvQueryProcessHostPid(getpid(), nullptr, nullptr, &hostpid, &cpType));
154 :
155 : HcclTraceInfo::UtraceAttr utraceAttr;
156 11 : utraceAttr.utraceStatusFlag = commParam->utraceStatusFlag;
157 11 : utraceAttr.deviceid = GetDevId();
158 11 : utraceAttr.pid = hostpid;
159 11 : UtraceInfo_.reset(new (std::nothrow) HcclTraceInfo(utraceAttr));
160 11 : CHK_PTR_NULL(UtraceInfo_);
161 :
162 : /* 申请trace资源信息 */
163 11 : std::string logInfo = "HCCL_";
164 11 : logInfo.append(std::to_string(SalGetTid()));
165 11 : logInfo.append("_");
166 11 : logInfo.append(std::to_string(GetDevId()));
167 11 : CHK_RET(UtraceInfo_->Init(logInfo));
168 11 : return HCCL_SUCCESS;
169 11 : }
170 :
171 11 : HcclResult HcclCommAicpu::InitProfResource()
172 : {
173 11 : groupHashId_ = dfx::ProfilingManager::GetProfHashId(identifier_.c_str(), identifier_.length());
174 11 : HCCL_RUN_INFO("[Init][ProfResource]group[%s], groupHashId_[%llu].", identifier_.c_str(), groupHashId_);
175 :
176 11 : dfx::ProfCommInfo profInfo{groupHashId_, topoInfo_.userRankSize, topoInfo_.userRank};
177 11 : CHK_RET(dfx::ProfilingManager::AddProfInfoByStreamId(mainStream_.id(), identifier_, profInfo));
178 451 : for (auto& slaveStream : slaveStreams_) {
179 440 : CHK_RET(dfx::ProfilingManager::AddProfInfoByStreamId(slaveStream.id(), identifier_, profInfo));
180 : }
181 11 : dfx::ProfilingExtendInfoHelper::InitProfItemId();
182 11 : return HCCL_SUCCESS;
183 : }
184 :
185 462 : HcclResult HcclCommAicpu::StreamRestore(u32 streamId)
186 : {
187 462 : HcclResult ret = hrtHalResourceIdRestore(devId_, 0, DRV_STREAM_ID, streamId, 0);
188 : // custom进程需要恢复stream资源, custom进程调用失败直接报错,aicpu进程调用失败做兼容性处理
189 462 : if (ret == HCCL_E_NOT_SUPPORT) {
190 0 : CHK_PRT_RET(
191 : isCustom_,
192 : HCCL_ERROR(
193 : "%s hrtHalResourceIdRestore fail, drv not support, custom[%d], ret[%d]", __func__, isCustom_, ret),
194 : HCCL_E_DRV);
195 462 : } else if (ret != HCCL_SUCCESS) {
196 0 : HCCL_ERROR("%s hrtHalResourceIdRestore fail, ret[%d]", __func__, ret);
197 0 : return HCCL_E_DRV;
198 : }
199 462 : return HCCL_SUCCESS;
200 : }
201 :
202 11 : HcclResult HcclCommAicpu::SetHrtWorkMode(const HcclOpResParam* commParam)
203 : {
204 11 : CHK_RET(hrtSetWorkModeAicpu(true));
205 11 : CHK_RET(hrtSetlocalDevice(commParam->topoInfo.deviceLogicId));
206 11 : CHK_RET(hrtSetlocalDeviceType(static_cast<DevType>(commParam->topoInfo.deviceType)));
207 11 : return HCCL_SUCCESS;
208 : }
209 :
210 11 : HcclResult HcclCommAicpu::SetHrtDeviceSatMode(const HcclOpResParam* commParam)
211 : {
212 11 : CHK_RET(hrtSetLocalDeviceSatMode(commParam->config.floatOverflowMode));
213 11 : HCCL_RUN_INFO(
214 : "[HcclCommAicpu][Init]SetHrtDeviceSatMode[%d]", static_cast<u32>(commParam->config.floatOverflowMode));
215 11 : return HCCL_SUCCESS;
216 : }
217 :
218 11 : HcclResult HcclCommAicpu::InitTopoMatcher()
219 : {
220 11 : externalEnable_.enableFfts = 1; // FFTS+在算法模块不会使用多线程,固定使能
221 11 : externalEnable_.deterministic = deterministic_;
222 11 : externalEnable_.intraRoceSwitch = 0;
223 11 : externalEnable_.dumpDebug = dumpDebug_;
224 11 : externalEnable_.interHccsDisable = interHccsDisable_;
225 :
226 11 : topoMatcher_.reset((new (std::nothrow) TopoMatcher(
227 22 : commPlaneVector_, isBridgeVector_, topoInfo_, algoInfo_, externalEnable_, serverAndsuperPodToRank_)));
228 11 : CHK_SMART_PTR_NULL(topoMatcher_);
229 11 : HCCL_RUN_INFO(
230 : "[HcclCommAicpu][InitTopoMatcher]topo matcher init success. group[%s] deterministic:%u, "
231 : "dumpDebug:%u, interHccsDisable:%u",
232 : identifier_.c_str(), deterministic_, dumpDebug_, interHccsDisable_);
233 11 : return HCCL_SUCCESS;
234 : }
235 :
236 11 : HcclResult HcclCommAicpu::InitOpRetry(const HcclOpResParam* commParam)
237 : {
238 11 : CHK_PTR_NULL(commParam);
239 11 : retryEnable_ = (commParam->config.retryEnable == 1) ? true : false;
240 11 : retryHoldTime_ = commParam->config.retryHoldTime;
241 11 : retryIntervalTime_ = commParam->config.retryIntervalTime;
242 11 : HCCL_RUN_INFO(
243 : "[InitOpRetry]retryEnable[%d], retryHoldTime[%u ms], retryIntervalTime[%u ms]", retryEnable_, retryHoldTime_,
244 : retryIntervalTime_);
245 :
246 11 : if (commParam->kfcControlTransferH2DParams.buffLen != 0 && kfcControlTransferH2D_ == nullptr) {
247 0 : EXCEPTION_CATCH((kfcControlTransferH2D_ = std::make_shared<hccl::HDCommunicate>()), return HCCL_E_PTR);
248 0 : CHK_SMART_PTR_NULL(kfcControlTransferH2D_);
249 0 : CHK_RET(kfcControlTransferH2D_->InitDevice(commParam->kfcControlTransferH2DParams));
250 : }
251 11 : if (commParam->kfcStatusTransferD2HParams.buffLen != 0 && kfcStatusTransferD2H_ == nullptr) {
252 0 : EXCEPTION_CATCH((kfcStatusTransferD2H_ = std::make_shared<hccl::HDCommunicate>()), return HCCL_E_PTR);
253 0 : CHK_SMART_PTR_NULL(kfcStatusTransferD2H_);
254 0 : CHK_RET(kfcStatusTransferD2H_->InitDevice(commParam->kfcStatusTransferD2HParams));
255 : }
256 11 : return HCCL_SUCCESS;
257 : }
258 :
259 11 : HcclResult HcclCommAicpu::InitZeroCopyExchanger(const HcclOpResParam* commParam)
260 : {
261 11 : CHK_PTR_NULL(commParam);
262 0 : auto nSecStopFunc = [this]() -> bool {
263 : // 检查到OP状态不Ok则认为需要终止
264 0 : auto ret = this->CheckOpExecStatus();
265 0 : if (ret == HCCL_SUCCESS) {
266 0 : return false;
267 0 : } else if (ret == HCCL_E_SUSPENDING) {
268 : // NS快恢场景,需要提前终止
269 0 : HcclOpExecFSM fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT;
270 0 : KfcError errorCode = KfcError::kNone;
271 0 : SetCommRecoveryFlag(true);
272 0 : UpdateOpExecStatus(fsmState, KfcStatus::kStoplaunch, errorCode, 0);
273 0 : HCCL_RUN_INFO("[HcclCommAicpu][nSecStopFunc] need stop launch");
274 0 : return true;
275 : } else {
276 0 : return true;
277 : }
278 11 : };
279 :
280 11 : u32 timeoutSec = commParam->config.notifyWaitTime;
281 11 : HCCL_INFO("[HcclCommAicpu][InitZeroCopyExchanger] set timeout is [%u s]", timeoutSec);
282 :
283 11 : EXCEPTION_CATCH(
284 : (ZeroCopyExchanger_ = std::make_shared<hccl::AicpuZeroCopyExchanger>(
285 : commParam->localUsrRankId, commParam->rankSize, commParam, nSecStopFunc, timeoutSec,
286 : topoInfo_.deviceNumPerAggregation, taskMonitorInterval_)),
287 : return HCCL_E_PTR);
288 :
289 : // 通信域第一次初始化时,如果IPC内存有不为空的则认为是使能该特性
290 11 : isZeroCopy_ = false;
291 363 : for (u32 i = 0; i < AICPU_ZERO_COPY_MAX_DEVICE_NUM_A3; ++i) {
292 352 : if (commParam->zeroCopyIpcPtrs[i] != 0) {
293 0 : isZeroCopy_ = true;
294 0 : break;
295 : }
296 : }
297 :
298 11 : return HCCL_SUCCESS;
299 : }
300 :
301 11 : HcclResult HcclCommAicpu::InitOpCounter(const OpCounterInfo& opCounterInfo)
302 : {
303 11 : if (opCounterInfo.isEnableCounter && !retryEnable_
304 0 : && (opCounterInfo.headCountMem == 0 || opCounterInfo.tailCountMem == 0 || opCounterInfo.memSize == 0)) {
305 0 : HCCL_ERROR("[HcclCommAicpu][InitOpCounter] headCountMem or tailCountMem or memSize is null");
306 0 : return HCCL_E_PARA;
307 : }
308 11 : opCounterInfo_ = opCounterInfo;
309 11 : return HCCL_SUCCESS;
310 : }
311 :
312 1 : void HcclCommAicpu::SetZeroCopyEnable(bool enable) { isZeroCopy_ = enable; }
313 :
314 1 : void HcclCommAicpu::SetSymmetricMemoryEnable(bool enable)
315 : {
316 1 : HCCL_INFO("[HcclCommAicpu::SetSymmetricMemoryEnable] enable[%d]", enable);
317 1 : isSymmetricMemory_ = enable;
318 1 : aicpuCacheManager_.SetSymmetricMemoryEnable(enable);
319 1 : }
320 :
321 0 : HcclResult HcclCommAicpu::PrepareZeroCopyExchanger(
322 : const std::string& newTag, OpParam& opParam, AlgResourceResponse* algResResponse)
323 : {
324 0 : return ZeroCopyExchanger_->ExchangeAddress(newTag, opParam.inputPtr, opParam.outputPtr, algResResponse);
325 : }
326 :
327 11 : HcclResult HcclCommAicpu::RegisterProfilingCallback()
328 : {
329 11 : (void)RegisterLoadTaskCallBack(dispatcher_, nullptr, dfx::TaskProfilingCallBack);
330 :
331 11 : return HCCL_SUCCESS;
332 : }
333 :
334 11 : HcclResult HcclCommAicpu::RegisterDispatcherCallback()
335 : {
336 0 : auto checkOpExecStatusCallback = [this]() {
337 0 : return this->CheckOpExecStatusCallback();
338 11 : };
339 :
340 11 : return HcclSetOpExecStatusCallback(dispatcher_, checkOpExecStatusCallback);
341 : }
342 :
343 11 : HcclResult HcclCommAicpu::RegisterProfCallBack()
344 : {
345 11 : if (MsprofRegisterCallback != nullptr) {
346 11 : HCCL_INFO("RegisterProfCallBack not null");
347 11 : int32_t ret = MsprofRegisterCallback(AICPU, &DeviceCommandHandle);
348 11 : CHK_PRT_RET((ret != 0), HCCL_ERROR("[%s] failed. ret = [%d]", __func__, ret), HCCL_E_PARA);
349 : } else {
350 0 : HCCL_INFO("RegisterProfCallBack is null");
351 : }
352 11 : return HCCL_SUCCESS;
353 : }
354 :
355 0 : HcclResult HcclCommAicpu::GetSuspendingFlag(HcclComSuspendingFlag& flag)
356 : {
357 0 : CHK_RET(AicpuHdcUtils::GetSuspendingStatus(kfcControlTransferH2D_, flag));
358 0 : return HCCL_SUCCESS;
359 : }
360 :
361 57 : HcclResult HcclCommAicpu::BackGroundGetCmd(KfcCommand& cmd)
362 : {
363 57 : CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd));
364 54 : return HCCL_SUCCESS;
365 : }
366 :
367 2 : HcclResult HcclCommAicpu::BackGroundSetStatus(KfcStatus status)
368 : {
369 2 : CHK_RET(aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, status, KfcError::kNone, 0));
370 2 : return HCCL_SUCCESS;
371 : }
372 :
373 0 : HcclResult HcclCommAicpu::SaveTraceInfo(std::string& logInfo)
374 : {
375 0 : CHK_PTR_NULL(UtraceInfo_);
376 0 : CHK_RET(UtraceInfo_->SaveTraceInfo(logInfo, AtraceOption::Opbasekey));
377 0 : return HCCL_SUCCESS;
378 : }
379 :
380 0 : HcclResult HcclCommAicpu::FlushUtraceInfo()
381 : {
382 0 : if (GetCommInfoStatus()) {
383 0 : CHK_RET(UtraceInfo_->Flush());
384 : }
385 0 : return HCCL_SUCCESS;
386 : }
387 :
388 0 : std::string HcclCommAicpu::GetExcuteOp()
389 : {
390 0 : std::stringstream ss;
391 0 : ss << "tag: " << excuteOpId_.tag << ", ";
392 0 : ss << "newTag: " << excuteOpId_.newTag << ", ";
393 0 : ss << "index: " << excuteOpId_.index;
394 0 : return ss.str();
395 0 : }
396 :
397 11 : void HcclCommAicpu::InitCommInfoStatus(bool commInfo) { commOpenStatus = commInfo; }
398 :
399 11 : HcclResult HcclCommAicpu::InitTinyMem(const HcclOpResParam* commParam)
400 : {
401 11 : CHK_PTR_NULL(commParam);
402 11 : auto tinyMemPtr = reinterpret_cast<void*>(commParam->tinyMem);
403 11 : tinySendRecvMem_ = DeviceMem::create(tinyMemPtr, commParam->tinyMemSize);
404 :
405 11 : return HCCL_SUCCESS;
406 : }
407 :
408 11 : HcclResult HcclCommAicpu::InitTimeOutConfig(const HcclOpResParam* commParam)
409 : {
410 11 : CHK_PTR_NULL(commParam);
411 11 : CHK_RET(HcclSetSqeTimeOut(dispatcher_, commParam->config.notifyWaitTime));
412 11 : linkTimeOut_ = commParam->config.linkTimeOut;
413 11 : return HCCL_SUCCESS;
414 : }
415 :
416 11 : HcclResult HcclCommAicpu::InitHostDeviceLock(const HcclOpResParam* commParam)
417 : {
418 11 : CHK_PTR_NULL(commParam);
419 11 : hostDeviceLock_.reset(new (std::nothrow) PetersonLock(
420 11 : reinterpret_cast<void*>(commParam->lockAddr), PetersonLock::DEFAULT_LOCK_TIMEOUT_SEC));
421 11 : CHK_SMART_PTR_NULL(hostDeviceLock_);
422 11 : CHK_RET(hostDeviceLock_->Init());
423 :
424 11 : return HCCL_SUCCESS;
425 : }
426 :
427 0 : HcclResult HcclCommAicpu::UpdateNotifyWaitTimeOut(SyncMode syncMode, u64 notifyWaitTime)
428 : {
429 0 : sqeWaitTimeOut_ = (notifyWaitTime == 0) ? notifyWaitTime : (notifyWaitTime + AICPU_SQE_TIMEOUT_INC);
430 0 : if (syncMode == SyncMode::UNLIMITED_TIMEWAITSYNCMODE) {
431 0 : CHK_RET(HcclSetSqeTimeOut(dispatcher_, GetNotifyMaxWaitTime()));
432 : }
433 0 : return HcclSetSqFullWaitTimeOut(dispatcher_, notifyWaitTime);
434 : }
435 :
436 0 : void HcclCommAicpu::PrepareOpRetryHandler(
437 : u8 inplaceSupportRetry, u8 retryEnable, u8 inPlaceSupportRetryStatus, u8 isInplacePreSync, u8 isPostSync)
438 : {
439 0 : algOpContext_.opRetryHandler.inplaceSupportRetry = static_cast<bool>(inplaceSupportRetry);
440 0 : algOpContext_.opRetryHandler.retryEnable = static_cast<bool>(retryEnable);
441 : algOpContext_.opRetryHandler.inPlaceSupportRetryStatus
442 0 : = static_cast<InplaceSupportRetryStatus>(inPlaceSupportRetryStatus);
443 0 : algOpContext_.opRetryHandler.isInplacePreSync = static_cast<bool>(isInplacePreSync);
444 0 : algOpContext_.opRetryHandler.isPostSync = static_cast<bool>(isPostSync);
445 0 : HCCL_INFO(
446 : "[HcclCommAicpu][PrepareOpRetryHandler] inplaceSupportRetry %d, retryEnable %d, "
447 : "inPlaceSupportRetryStatus %d, isInplacePreSync %d, isPostSync %d.",
448 : algOpContext_.opRetryHandler.inplaceSupportRetry, algOpContext_.opRetryHandler.retryEnable,
449 : algOpContext_.opRetryHandler.inPlaceSupportRetryStatus, algOpContext_.opRetryHandler.isInplacePreSync,
450 : algOpContext_.opRetryHandler.isPostSync);
451 0 : }
452 :
453 0 : HcclResult HcclCommAicpu::UpdateOpRingBufferIdx()
454 : {
455 0 : return HcclSetOpRingBufferIdx(dispatcher_, aicpuShareData_.GetOpRingBufferIdx());
456 : }
457 :
458 0 : HcclResult HcclCommAicpu::InvokeKfcHandler(AicpuKfcHandlerType type, const std::vector<u64> args)
459 : {
460 0 : CHK_PRT_RET(
461 : static_cast<size_t>(type) >= static_cast<size_t>(AicpuKfcHandlerType::kMax),
462 : HCCL_ERROR("Device mode %u, handler type %u.", static_cast<u32>(isDeviceMode_), static_cast<size_t>(type)),
463 : HCCL_E_INTERNAL);
464 0 : const auto handler = kfcHandlers_[static_cast<size_t>(type)];
465 0 : if (handler == nullptr) {
466 0 : return HCCL_SUCCESS;
467 : }
468 0 : return handler(args);
469 0 : }
470 :
471 0 : HcclResult HcclCommAicpu::NotifyPost(void)
472 : {
473 0 : if (isDeviceMode_) {
474 0 : return InvokeKfcHandler(
475 : AicpuKfcHandlerType::kNotifyRecord,
476 0 : {rpc_, reinterpret_cast<u64>(dispatcher_), reinterpret_cast<u64>(&mainStream_)});
477 : } else {
478 0 : CHK_RET(LocalNotify::Post(mainStream_, dispatcher_, opNotifies_[1]));
479 0 : HcclSqeContext* sqeContext = mainStream_.GetSqeContextPtr();
480 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
481 0 : return dfx::ProfilingManager::ReportMainStreamTask(mainStream_, sqeContextBuffer->tailSqeTaskId - 1, TAIL_TASK);
482 : }
483 : }
484 :
485 0 : HcclResult HcclCommAicpu::NotifyWait(void)
486 : {
487 0 : if (isDeviceMode_) {
488 0 : return InvokeKfcHandler(
489 : AicpuKfcHandlerType::kNotifyWait,
490 0 : {rpc_, reinterpret_cast<u64>(dispatcher_), reinterpret_cast<u64>(&mainStream_)});
491 : } else {
492 0 : HcclSqeContext* sqeContext = mainStream_.GetSqeContextPtr();
493 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
494 0 : CHK_RET(dfx::ProfilingManager::ReportMainStreamTask(mainStream_, sqeContextBuffer->tailSqeTaskId, HEAD_TASK));
495 0 : return LocalNotify::Wait(mainStream_, dispatcher_, opNotifies_[0]);
496 : }
497 : }
498 :
499 : // 按照算子模式来Post对应的Notify
500 0 : HcclResult HcclCommAicpu::RecordHostOrder(const HcclOpResParam* commParam, const std::string& tag, u8 orderLaunchMode)
501 : {
502 0 : const u8 orderLaunchInvalidInHcom = 255;
503 0 : if (orderLaunchMode == orderLaunchInvalidInHcom) {
504 0 : HCCL_INFO("[%s] attachedStreams_[%d] is invalid in graph mode", __func__, orderStream_.id());
505 0 : return HCCL_SUCCESS;
506 : }
507 0 : if (orderNotifies_[orderLaunchMode] == nullptr) {
508 0 : std::shared_ptr<LocalNotify> notify;
509 0 : HcclSignalInfo* aicpuOrderNotify = reinterpret_cast<HcclSignalInfo*>(
510 0 : static_cast<u64>(commParam->aicpuOrderNotifyAddr) + (sizeof(HcclSignalInfo) * orderLaunchMode));
511 0 : HCCL_INFO(
512 : "[%s] attachedStreams_[%d] aicpuOrderNotify resId[%llu], addr[0x%llx], flag[%u], devId[%u], tsId[%u], "
513 : "rankId[%u]",
514 : __func__, orderStream_.id(), aicpuOrderNotify->resId, aicpuOrderNotify->addr, aicpuOrderNotify->flag,
515 : aicpuOrderNotify->devId, aicpuOrderNotify->tsId, aicpuOrderNotify->rankId);
516 0 : HcclResult ret = InitAndVerifySingleSignal(*aicpuOrderNotify, notify);
517 0 : CHK_PRT_RET(
518 : ret != HCCL_SUCCESS,
519 : HCCL_ERROR(
520 : "[%s] check localRes noftify failed, resId[%u], group[%s]", __func__, aicpuOrderNotify->resId,
521 : identifier_.c_str()),
522 : ret);
523 0 : orderNotifies_[orderLaunchMode] = notify;
524 0 : HCCL_INFO("%s success, group[%s], resId[%llu]", __func__, identifier_.c_str(), aicpuOrderNotify->resId);
525 0 : }
526 :
527 0 : HCCL_INFO(
528 : "%s group[%s] tag[%s] isDeviceMode[%d] orderLaunchMode[%u] mode[%d] streamId[%d] notifyId[%u]", __func__,
529 : identifier_.c_str(), tag.c_str(), isDeviceMode_, orderLaunchMode, GetWorkflowMode(), orderStream_.id(),
530 : orderNotifies_[orderLaunchMode]->notifyId_);
531 0 : CHK_RET(LocalNotify::Post(orderStream_, dispatcher_, orderNotifies_[orderLaunchMode]));
532 0 : CHK_RET(LaunchTask(dispatcher_, const_cast<Stream&>(orderStream_)));
533 0 : return HCCL_SUCCESS;
534 : }
535 :
536 462 : HcclResult HcclCommAicpu::GetStreamData(
537 : const HcclStreamInfo& streamInfo, HcclComStreamInfo& comStreamInfo, u32& sqHead, u32& sqTail)
538 : {
539 462 : comStreamInfo.sqId = streamInfo.sqIds;
540 462 : comStreamInfo.actualStreamId = streamInfo.streamIds;
541 462 : comStreamInfo.logicCqId = streamInfo.logicCqids;
542 462 : u64 sq_addr = 0;
543 462 : CHK_RET(QuerySqBaseAddr(devId_, streamInfo.sqIds, sq_addr));
544 462 : comStreamInfo.sqBaseAddr = reinterpret_cast<void*>(sq_addr);
545 462 : if (comStreamInfo.sqBaseAddr == nullptr) {
546 0 : HCCL_ERROR("[HcclCommAicpu][GetStreamData]sqe base addr ptr is null.");
547 0 : return HCCL_E_PARA;
548 : }
549 462 : CHK_RET(QuerySqStatusByType(devId_, streamInfo.sqIds, DRV_SQCQ_PROP_SQ_DEPTH, comStreamInfo.sqDepth));
550 462 : CHK_RET(QuerySqStatusByType(devId_, streamInfo.sqIds, DRV_SQCQ_PROP_SQ_TAIL, sqTail));
551 462 : CHK_RET(QuerySqStatusByType(devId_, streamInfo.sqIds, DRV_SQCQ_PROP_SQ_HEAD, sqHead));
552 462 : HCCL_DEBUG(
553 : "[HcclCommAicpu][GetStreamData] get stream data success, group[%s], streamId[%d], sqId[%d], "
554 : "logicCqId[%u], sqDepth[%u], sqHead[%u], sqTail[%u]",
555 : identifier_.c_str(), comStreamInfo.actualStreamId, comStreamInfo.sqId, comStreamInfo.logicCqId,
556 : comStreamInfo.sqDepth, sqHead, sqTail);
557 462 : return HCCL_SUCCESS;
558 : }
559 :
560 11 : HcclResult HcclCommAicpu::InitMainStreamObj(const HcclOpResParam* commParam)
561 : {
562 11 : CHK_RET(InitStreamObj(commParam->localRes.mainStreamParam, mainStream_));
563 11 : HCCL_INFO("%s success, group[%s], streamId[%d]", __func__, identifier_.c_str(), mainStream_.id());
564 11 : return HCCL_SUCCESS;
565 : }
566 :
567 11 : HcclResult HcclCommAicpu::InitSlaveStreamObjs(const HcclOpResParam* commParam)
568 : {
569 11 : if (commParam->localRes.streamNum > LOCAL_STREAM_MAX_NUM) {
570 0 : HCCL_ERROR(
571 : "[HcclCommAicpu][InitSlaveStreamObjs] local streams great max numbers,current numbers[%u], max "
572 : "numbers[%u], group[%s]",
573 : commParam->localRes.streamNum, LOCAL_STREAM_MAX_NUM, identifier_.c_str());
574 0 : return HCCL_E_PARA;
575 : }
576 451 : for (u32 i = 0; i < commParam->localRes.streamNum; i++) {
577 440 : if (streamToObj_.find(commParam->localRes.streamParam[i].streamInfo.sqIds) == streamToObj_.end()) {
578 440 : Stream stream;
579 440 : CHK_RET(InitStreamObj(commParam->localRes.streamParam[i], stream));
580 440 : slaveStreams_.emplace_back(stream);
581 440 : streamToObj_.insert(commParam->localRes.streamParam[i].streamInfo.sqIds);
582 440 : }
583 : }
584 11 : HCCL_DEBUG(
585 : "[HcclCommAicpu][InitSlaveStreamObjs] success, group[%s], slave stream numbers[%u]", identifier_.c_str(),
586 : commParam->localRes.streamNum);
587 11 : return HCCL_SUCCESS;
588 : }
589 :
590 11 : HcclResult HcclCommAicpu::InitOrderStreamObj(const HcclOpResParam* commParam)
591 : {
592 11 : CHK_RET(InitStreamObj(commParam->aicpuOrderStreamParam, orderStream_));
593 11 : HCCL_INFO("%s success, group[%s], streamId[%d]", __func__, identifier_.c_str(), orderStream_.id());
594 11 : return HCCL_SUCCESS;
595 : }
596 :
597 462 : HcclResult HcclCommAicpu::InitStreamObj(const HcclStreamParam& streamParam, Stream& stream)
598 : {
599 : u32 sqTail;
600 : u32 sqHead;
601 462 : HcclResult ret = HCCL_SUCCESS;
602 462 : ret = StreamRestore(streamParam.streamInfo.streamIds);
603 462 : CHK_PRT_RET(
604 : ret != HCCL_SUCCESS,
605 : HCCL_ERROR(
606 : "%s StreamId[%d] Restore error group[%s]", __func__, streamParam.streamInfo.streamIds, identifier_.c_str()),
607 : ret);
608 :
609 462 : HcclComStreamInfo comStreamInfo = {};
610 462 : ret = GetStreamData(streamParam.streamInfo, comStreamInfo, sqHead, sqTail);
611 462 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("%s error group[%s]", __func__, identifier_.c_str()), ret);
612 462 : stream = Stream(comStreamInfo);
613 :
614 : // 初始化stream的sqeContext
615 462 : SqCqeContext* sqCqeContext = reinterpret_cast<SqCqeContext*>(streamParam.sqCqContextAddr);
616 462 : u64 sqCqContextSize = streamParam.sqCqContextSize;
617 462 : if (sqCqeContext == nullptr || sqCqContextSize != sizeof(SqCqeContext)) {
618 0 : HCCL_ERROR(
619 : "%s failed, sqCqeContext[%p] is null or size[%llu] does not match expected size[%llu], group[%s]", __func__,
620 : sqCqeContext, sqCqContextSize, sizeof(SqCqeContext), identifier_.c_str());
621 0 : return HCCL_E_PARA;
622 : }
623 462 : ret = stream.InitSqAndCqeContext(sqHead, sqTail, sqCqeContext);
624 462 : CHK_PRT_RET(
625 : ret != HCCL_SUCCESS, HCCL_ERROR("%s: InitSqAndCqeContext failed, group[%s]", __func__, identifier_.c_str()),
626 : ret);
627 462 : HCCL_INFO("%s success, group[%s], streamId[%d]", __func__, identifier_.c_str(), stream.id());
628 462 : return HCCL_SUCCESS;
629 : }
630 :
631 11 : HcclResult HcclCommAicpu::InitOpNotifyObj(const HcclOpResParam* commParam)
632 : {
633 11 : HcclResult ret = HCCL_SUCCESS;
634 33 : for (u32 i = 0; i < AICPU_OP_NOTIFY_MAX_NUM; i++) {
635 22 : ret = InitAndVerifySignal(commParam->localRes.aicpuOpNotify[i], opNotifies_);
636 22 : CHK_PRT_RET(
637 : ret != HCCL_SUCCESS,
638 : HCCL_ERROR(
639 : "[HcclCommAicpu][InitOpNotifyObj] check localRes op noftify failed, resId[%u], group[%s]",
640 : commParam->localRes.localSignals[i].resId, identifier_.c_str()),
641 : ret);
642 : }
643 11 : CHK_RET(hrtDrvGetLocalDevIDByHostDevID(commParam->localRes.aicpuOpNotify[0].devId, &devId_));
644 11 : HCCL_INFO("[HcclCommAicpu][InitOpNotifyObj] success, group[%s]", identifier_.c_str());
645 11 : return HCCL_SUCCESS;
646 : }
647 :
648 11 : HcclResult HcclCommAicpu::InitLocalNotifyObj(const HcclOpResParam* commParam)
649 : {
650 11 : HcclResult ret = HCCL_SUCCESS;
651 :
652 11 : if (commParam->localRes.signalNum > LOCAL_NOTIFY_MAX_NUM) {
653 0 : HCCL_ERROR(
654 : "[HcclCommAicpu][InitLocalNotifyObj] local notifys great max numbers, numbers[%u], max numbers[%u], "
655 : "group[%s]",
656 : commParam->localRes.signalNum, LOCAL_NOTIFY_MAX_NUM, identifier_.c_str());
657 0 : return HCCL_E_PARA;
658 : }
659 715 : for (u32 i = 0; i < commParam->localRes.signalNum; i++) {
660 704 : if (notifysToObj_.find(commParam->localRes.localSignals[i].resId) == notifysToObj_.end()) {
661 704 : ret = InitAndVerifySignal(commParam->localRes.localSignals[i], localNotifies_);
662 704 : CHK_PRT_RET(
663 : ret != HCCL_SUCCESS,
664 : HCCL_ERROR(
665 : "[HcclCommAicpu][InitLocalNotifyObj] check localRes prenoftify failed, resId[%u]",
666 : commParam->localRes.localSignals[i].resId),
667 : ret);
668 704 : notifysToObj_.insert(commParam->localRes.localSignals[i].resId);
669 : }
670 : }
671 11 : HCCL_DEBUG(
672 : "[HcclCommAicpu][InitLocalNotifyObj] success, group[%s], signal numbers[%u]", identifier_.c_str(),
673 : commParam->localRes.signalNum);
674 11 : return HCCL_SUCCESS;
675 : }
676 :
677 22 : HcclResult HcclCommAicpu::ParseTlvToVector(
678 : u64 srcTlv, u64 srcTlvTotalLength, std::vector<std::vector<std::vector<u32>>>& vectorInfo)
679 : {
680 22 : u64 parseLength = 0;
681 22 : u8* srcTlvptr = reinterpret_cast<u8*>(srcTlv);
682 22 : if (srcTlvptr == nullptr) {
683 0 : HCCL_ERROR("[HcclCommAicpu][ParseTlvToVector]tlv ptr is null.");
684 0 : return HCCL_E_PARA;
685 : }
686 22 : u64 unPareseLength = srcTlvTotalLength;
687 143 : while (unPareseLength > 0) {
688 121 : CommonTlv* commonTlv = reinterpret_cast<CommonTlv*>(srcTlvptr + parseLength);
689 121 : if (unPareseLength <= (sizeof(LENGTH_TYPE) + sizeof(TAG_TYPE))) {
690 0 : HCCL_ERROR(
691 : "[HcclCommAicpu][ParseTlvToVector] Tlv length is error, tag[%s], totalLength[%lu], "
692 : "unParseLength[%lu], already parsed Length[%lu]",
693 : identifier_.c_str(), srcTlvTotalLength, unPareseLength, parseLength);
694 0 : return HCCL_E_PARA;
695 : }
696 121 : if (commonTlv->length > unPareseLength || commonTlv->length % sizeof(RANK_TYPE) != 0) {
697 0 : HCCL_ERROR(
698 : "[HcclCommAicpu][ParseTlvToVector] parse Tlv error, group[%s], total Length[%lu], tlvLength[%lu], "
699 : "unParsed Length[%lu], already parsed Length[%lu]",
700 : identifier_.c_str(), srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
701 0 : return HCCL_E_PARA;
702 : }
703 121 : u16 level0 = (commonTlv->type & TOP_COMM_LEVEL0_LOCATION) >> TOP_COMM_LEVEL0_SHIFT;
704 121 : u16 level1 = (commonTlv->type & TOP_COMM_LEVEL1_LOCATION);
705 121 : u64 itemNum = (commonTlv->length - sizeof(TAG_TYPE) - sizeof(LENGTH_TYPE)) / sizeof(RANK_TYPE);
706 242 : std::vector<RANK_TYPE> values{&commonTlv->value, (&commonTlv->value) + itemNum};
707 121 : if (level0 >= vectorInfo.size()) {
708 99 : vectorInfo.resize(level0 + 1);
709 : }
710 121 : if (level1 >= vectorInfo[level0].size()) {
711 121 : vectorInfo[level0].resize(level1 + 1);
712 : }
713 121 : vectorInfo[level0][level1] = std::move(values);
714 121 : parseLength += commonTlv->length;
715 121 : unPareseLength -= commonTlv->length;
716 121 : HCCL_DEBUG(
717 : "[HcclCommAicpu][ParseTlvToVector] parse Tlv group[%s], level0[%u], level1[%u], total Length[%lu], "
718 : "tlvLength[%lu], unParsed Length[%lu], already parsed Length[%lu]",
719 : identifier_.c_str(), level0, level1, srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
720 121 : }
721 143 : for (u32 idx = 0; idx < vectorInfo.size(); idx++) {
722 242 : for (u32 ringidx = 0; ringidx < vectorInfo[idx].size(); ringidx++) {
723 121 : HCCL_DEBUG(
724 : "[HcclCommAicpu][ParseTlvToVector] idx[%u] ringidx[%u] size[%u]", idx, ringidx,
725 : vectorInfo[idx][ringidx].size());
726 : }
727 : }
728 22 : HCCL_INFO("[HcclCommAicpu][ParseTlvToVector] success, group[%s]", identifier_.c_str());
729 22 : return HCCL_SUCCESS;
730 : }
731 :
732 11 : HcclResult HcclCommAicpu::ParseTlvToSubGroupVector(
733 : u64 srcTlv, u64 srcTlvTotalLength, std::vector<std::vector<std::vector<std::vector<u32>>>>& vectorInfo)
734 : {
735 11 : u64 parseLength = 0;
736 11 : u8* srcTlvptr = reinterpret_cast<u8*>(srcTlv);
737 11 : if (srcTlvptr == nullptr) {
738 0 : HCCL_ERROR("[HcclCommAicpu][ParseTlvToSubGroupVector]tlv ptr is null.");
739 0 : return HCCL_E_PARA;
740 : }
741 11 : u64 unPareseLength = srcTlvTotalLength;
742 33 : while (unPareseLength > 0) {
743 22 : CommonTlv* commonTlv = reinterpret_cast<CommonTlv*>(srcTlvptr + parseLength);
744 22 : if (unPareseLength <= (sizeof(LENGTH_TYPE) + sizeof(TAG_TYPE))) {
745 0 : HCCL_ERROR(
746 : "[HcclCommAicpu][ParseTlvToSubGroupVector] Tlv length is error, tag[%s], totalLength[%lu], "
747 : "unParseLength[%lu], already parsed Length[%lu]",
748 : identifier_.c_str(), srcTlvTotalLength, unPareseLength, parseLength);
749 0 : return HCCL_E_PARA;
750 : }
751 22 : if (commonTlv->length > unPareseLength || commonTlv->length % sizeof(RANK_TYPE) != 0) {
752 0 : HCCL_ERROR(
753 : "[HcclCommAicpu][ParseTlvToSubGroupVector] parse Tlv error, group[%s], total Length[%lu], "
754 : "tlvLength[%lu], "
755 : "unParsed Length[%lu], already parsed Length[%lu]",
756 : identifier_.c_str(), srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
757 0 : return HCCL_E_PARA;
758 : }
759 22 : u16 level0 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL0_LOCATION)
760 22 : >> (TOP_HIERARCHICAL_COMM_LEVEL0_SHIFT + TOP_HIERARCHICAL_COMM_LEVEL1_SHIFT);
761 22 : u16 level1 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL1_LOCATION) >> TOP_HIERARCHICAL_COMM_LEVEL1_SHIFT;
762 22 : u16 level2 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL2_LOCATION);
763 22 : u64 itemNum = (commonTlv->length - sizeof(TAG_TYPE) - sizeof(LENGTH_TYPE)) / sizeof(RANK_TYPE);
764 44 : std::vector<RANK_TYPE> values{&commonTlv->value, (&commonTlv->value) + itemNum};
765 22 : if (level0 >= vectorInfo.size()) {
766 11 : vectorInfo.resize(level0 + 1);
767 : }
768 22 : if (level1 >= vectorInfo[level0].size()) {
769 11 : vectorInfo[level0].resize(level1 + 1);
770 : }
771 22 : if (level2 >= vectorInfo[level0][level1].size()) {
772 22 : vectorInfo[level0][level1].resize(level2 + 1);
773 : }
774 22 : vectorInfo[level0][level1][level2] = std::move(values);
775 22 : parseLength += commonTlv->length;
776 22 : unPareseLength -= commonTlv->length;
777 22 : HCCL_DEBUG(
778 : "[HcclCommAicpu][ParseTlvToSubGroupVector] parse Tlv group[%s], level0[%u], level1[%u], total Length[%lu], "
779 : "tlvLength[%lu], unParsed Length[%lu], already parsed Length[%lu]",
780 : identifier_.c_str(), level0, level1, srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
781 22 : }
782 22 : for (u32 level0Idx = 0; level0Idx < vectorInfo.size(); level0Idx++) {
783 22 : for (u32 level1Idx = 0; level1Idx < vectorInfo[level0Idx].size(); level1Idx++) {
784 33 : for (u32 level2Idx = 0; level2Idx < vectorInfo[level0Idx][level1Idx].size(); level2Idx++) {
785 22 : HCCL_DEBUG(
786 : "[HcclCommAicpu][ParseTlvToSubGroupVector] level0Idx[%u] level1Idx[%u] level2Idx[%u] size[%u]",
787 : level0Idx, level1Idx, level2Idx, vectorInfo[level0Idx][level1Idx][level2Idx].size());
788 : }
789 : }
790 : }
791 11 : HCCL_INFO("[HcclCommAicpu][ParseTlvToSubGroupVector] success, group[%s]", identifier_.c_str());
792 11 : return HCCL_SUCCESS;
793 : }
794 :
795 11 : HcclResult HcclCommAicpu::InitTopoInfo(const HcclOpResParam* commParam)
796 : {
797 11 : topoInfo_.userRank = commParam->topoInfo.userRank;
798 11 : topoInfo_.userRankSize = commParam->topoInfo.userRankSize;
799 11 : topoInfo_.deviceLogicId = commParam->topoInfo.deviceLogicId;
800 11 : topoInfo_.isSingleMeshAggregation = commParam->topoInfo.isSingleMeshAggregation;
801 11 : topoInfo_.deviceNumPerAggregation = commParam->topoInfo.deviceNumPerAggregation;
802 11 : topoInfo_.superPodNum = commParam->topoInfo.superPodNum;
803 11 : topoInfo_.devicePhyId = commParam->topoInfo.devicePhyId;
804 11 : topoInfo_.deviceType = static_cast<DevType>(commParam->topoInfo.deviceType);
805 11 : topoInfo_.topoType = static_cast<TopoType>(commParam->topoInfo.topoType);
806 11 : topoInfo_.is310P3Common = (topoInfo_.deviceType == DevType::DEV_TYPE_310P3);
807 11 : topoInfo_.serverNum = commParam->topoInfo.serverNum;
808 11 : topoInfo_.meshAggregationRankSize = commParam->topoInfo.meshAggregationRankSize;
809 11 : topoInfo_.multiModuleDiffDeviceNumMode = commParam->topoInfo.multiModuleDiffDeviceNumMode;
810 11 : topoInfo_.multiSuperPodDiffServerNumMode = commParam->topoInfo.multiSuperPodDiffServerNumMode;
811 11 : topoInfo_.realUserRank = commParam->topoInfo.realUserRank;
812 11 : topoInfo_.isDiffDeviceModule = commParam->topoInfo.isDiffDeviceModule;
813 11 : topoInfo_.isDiffDeviceType = commParam->topoInfo.isDiffDeviceType;
814 11 : topoInfo_.gcdDeviceNumPerAggregation = commParam->topoInfo.gcdDeviceNumPerAggregation;
815 11 : topoInfo_.moduleNum = commParam->topoInfo.moduleNum;
816 11 : topoInfo_.useSuperPodMode = true;
817 11 : topoInfo_.isARSDoubleRing = commParam->isARSDoubleRing;
818 11 : topoInfo_.multiSuperPodDiffDeviceNumMode = commParam->multiSuperPodDiffDeviceNumMode;
819 11 : if (commParam->topoInfo.isUsedRdmaRankPairNum % KEY_VALUE_TO_VECTOR_MODULUS != 0) {
820 0 : HCCL_ERROR(
821 : "[HcclCommAicpu][InitTopoInfo]rdma rank pair number[%lu] is error.",
822 : commParam->topoInfo.isUsedRdmaRankPairNum);
823 0 : return HCCL_E_PARA;
824 : }
825 11 : u32* isUsedRdmaRankPairPtr = reinterpret_cast<u32*>(commParam->topoInfo.isUsedRdmaRankPair);
826 11 : if (isUsedRdmaRankPairPtr == nullptr) {
827 0 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]rdma rank pair ptr is null.");
828 0 : return HCCL_E_PARA;
829 : }
830 55 : for (u64 i = 0; i < commParam->topoInfo.isUsedRdmaRankPairNum; i += KEY_VALUE_TO_VECTOR_MODULUS) {
831 44 : topoInfo_.isUsedRdmaMap.insert({isUsedRdmaRankPairPtr[i], static_cast<bool>(isUsedRdmaRankPairPtr[i + 1])});
832 : }
833 :
834 11 : if (commParam->topoInfo.pairLinkCounterNum % KEY_VALUE_TO_VECTOR_MODULUS != 0) {
835 0 : HCCL_ERROR(
836 : "[HcclCommAicpu][InitTopoInfo]pair link count number[%lu] is error.",
837 : commParam->topoInfo.pairLinkCounterNum);
838 0 : return HCCL_E_PARA;
839 : }
840 11 : u32* pairLinkCounterPtr = reinterpret_cast<u32*>(commParam->topoInfo.pairLinkCounter);
841 11 : if (pairLinkCounterPtr == nullptr) {
842 0 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]rdma rank pair ptr is null.");
843 0 : return HCCL_E_PARA;
844 : }
845 :
846 55 : for (u64 i = 0; i < commParam->topoInfo.pairLinkCounterNum; i += KEY_VALUE_TO_VECTOR_MODULUS) {
847 44 : topoInfo_.pairLinkCounter.insert({pairLinkCounterPtr[i], pairLinkCounterPtr[i + 1]});
848 : }
849 :
850 11 : u32* nicListPtr = reinterpret_cast<u32*>(commParam->topoInfo.nicList);
851 11 : if (nicListPtr == nullptr) {
852 0 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]nic list ptr is null.");
853 0 : return HCCL_E_PARA;
854 : }
855 22 : std::vector<u32> niclist{nicListPtr, nicListPtr + commParam->topoInfo.nicNum};
856 11 : topoInfo_.nicList = std::move(niclist);
857 :
858 11 : bool* bridgeRankPtr = reinterpret_cast<bool*>(commParam->topoInfo.bridgeRank);
859 11 : if (bridgeRankPtr != nullptr) {
860 11 : isBridgeVector_.resize(commParam->topoInfo.bridgeRankNum);
861 33 : for (u32 i = 0; i < commParam->topoInfo.bridgeRankNum; ++i) {
862 22 : isBridgeVector_[i] = bridgeRankPtr[i];
863 22 : HCCL_DEBUG("[HcclCommAicpu][InitTopoInfo] bridge rank info idx[%u] value[%u]", i, isBridgeVector_[i]);
864 : }
865 : } else {
866 0 : HCCL_RUN_INFO("[HcclCommAicpu][InitTopoInfo] bridge rank number is 0, group[%s]", identifier_.c_str());
867 : }
868 :
869 11 : HcclResult ret = HCCL_SUCCESS;
870 11 : ret = ParseTlvToVector(commParam->topoInfo.complanRank, commParam->topoInfo.complanRankLength, commPlaneVector_);
871 11 : CHK_PRT_RET(
872 : ret != HCCL_SUCCESS,
873 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init CommPlane error group[%s]", identifier_.c_str()), ret);
874 :
875 22 : ret = ParseTlvToVector(
876 11 : commParam->topoInfo.serverAndsuperPodRank, commParam->topoInfo.serverAndsuperPodRankLength,
877 11 : serverAndsuperPodToRank_);
878 11 : CHK_PRT_RET(
879 : ret != HCCL_SUCCESS,
880 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init server and superPod rank error group[%s]", identifier_.c_str()),
881 : ret);
882 :
883 22 : ret = ParseTlvToSubGroupVector(
884 11 : commParam->hierarchicalAlgInfo.commplaneSubGroupRank,
885 11 : commParam->hierarchicalAlgInfo.commplaneSubGroupRankLength, topoInfo_.CommPlaneSubGroupVector);
886 11 : CHK_PRT_RET(
887 : ret != HCCL_SUCCESS,
888 : HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init CommPlaneSubGroup error group[%s]", identifier_.c_str()), ret);
889 :
890 11 : HCCL_INFO(
891 : "[HcclCommAicpu][InitTopoInfo] success, group[%s], device Type[%u]", identifier_.c_str(),
892 : commParam->topoInfo.deviceType);
893 11 : return HCCL_SUCCESS;
894 11 : }
895 :
896 11 : HcclResult HcclCommAicpu::InitCclbuffer(const HcclOpResParam* commParam)
897 : {
898 11 : if (commParam->localWindowsIn == 0 || commParam->localWindowsOut == 0 || cclInputBuffer_.ptr() != nullptr
899 22 : || cclOutputBuffer_.ptr() != nullptr) {
900 0 : HCCL_INFO(
901 : "[HcclCommAicpu][InitCclBuffer] don't need init cclbuffer "
902 : "ccl winIn[0x%lx] winout[0x%lx] cclin ptr[%p] cclout ptr[%p]",
903 : commParam->localWindowsIn, commParam->localWindowsOut, cclInputBuffer_.ptr(), cclOutputBuffer_.ptr());
904 0 : return HCCL_SUCCESS;
905 : }
906 :
907 11 : auto cclInPtr = reinterpret_cast<void*>(commParam->localWindowsIn);
908 11 : auto cclOutPtr = reinterpret_cast<void*>(commParam->localWindowsOut);
909 11 : cclInputBuffer_ = DeviceMem::create(cclInPtr, commParam->winSize);
910 11 : cclOutputBuffer_ = DeviceMem::create(cclOutPtr, commParam->winSize);
911 11 : cclbufferSize_ = commParam->winSize;
912 11 : HCCL_INFO(
913 : "[HcclCommAicpu][InitCclbuffer] success, group[%s], cclin[%llu], cclout[%llu], size[%lu]", identifier_.c_str(),
914 : commParam->localWindowsIn, commParam->localWindowsOut, commParam->winSize);
915 11 : return HCCL_SUCCESS;
916 : }
917 :
918 11 : HcclResult HcclCommAicpu::InitConfigInfo(const HcclOpResParam* commParam)
919 : {
920 11 : deterministic_ = commParam->config.deterministic;
921 11 : interHccsDisable_ = commParam->config.interHccsDisable;
922 11 : multiQpThreshold_ = commParam->config.multiQpThreshold;
923 11 : inlineReducEnable_ = true;
924 11 : fftsEnable_ = false;
925 11 : taskMonitorInterval_ = commParam->config.taskMonitorInterval;
926 11 : algoInfo_.inlineReduceSwitchOn = true;
927 11 : algoInfo_.identifier = commParam->hcomId;
928 11 : algoInfo_.isSupportAtomicWrite = static_cast<bool>(commParam->config.isSupportAtomicWrite);
929 11 : notifySize_ = commParam->notifysize;
930 11 : slaveStreams_.reserve(LOCAL_STREAM_MAX_NUM);
931 11 : localNotifies_.reserve(LOCAL_NOTIFY_MAX_NUM);
932 11 : SetExternalInputDebugConfig(commParam->debugConfig);
933 11 : InitDebugConfigByValue(commParam->debugConfig);
934 11 : HCCL_INFO(
935 : "[HcclCommAicpu][Init]success, group[%s] reserve noipc notifys[%lu], slave streams[%lu].", identifier_.c_str(),
936 : LOCAL_NOTIFY_MAX_NUM, LOCAL_STREAM_MAX_NUM);
937 11 : return HCCL_SUCCESS;
938 : }
939 :
940 13 : void HcclCommAicpu::SetDumpDebug(bool dumpDebug) { dumpDebug_ = dumpDebug; }
941 :
942 : template <typename T>
943 : HcclResult
944 726 : HcclCommAicpu::InitAndVerifySignal(const HcclSignalInfo& signalInfo, std::vector<std::shared_ptr<T>>& notifyVec)
945 : {
946 726 : if (signalInfo.resId == INVALID_U64) {
947 : // 无效值不做校验
948 0 : HCCL_INFO("[HcclCommAicpu][InitAndVerifySignal] resId is invalid, need not check");
949 0 : return HCCL_SUCCESS;
950 : }
951 :
952 726 : std::shared_ptr<T> notify;
953 726 : EXCEPTION_CATCH((notify = std::make_shared<T>()), return HCCL_E_PTR);
954 726 : CHK_SMART_PTR_NULL(notify);
955 726 : CHK_RET(notify->Init(signalInfo, NotifyLoadType::DEVICE_NOTIFY));
956 726 : notifyVec.push_back(notify);
957 726 : HCCL_INFO(
958 : "[HcclCommAicpu][InitAndVerifySignal] success group[%s], resId[%u], tsId:%d, devId[%u]", identifier_.c_str(),
959 : signalInfo.resId, signalInfo.tsId, signalInfo.devId);
960 :
961 726 : return HCCL_SUCCESS;
962 726 : }
963 :
964 33 : void HcclCommAicpu::HandleExistTagReAlloc(
965 : HccltagLocalResV2* tagRes, const std::string& tag, bool reAllocFlag, ListCommon*& curList, bool& needSkip)
966 : {
967 33 : needSkip = false;
968 : // 如果 tag 已经存在且需要重新申请内存, 删除旧的资源与记录
969 33 : if (localTagResToObj_.find(tag) != localTagResToObj_.end() && reAllocFlag) {
970 0 : u64 currSize = tagRes->ScratchmemSize;
971 0 : u64 existSize = tagScratchMem_[tag]->size();
972 : // 新内存更大,删除旧记录,保留新的
973 0 : if (currSize > existSize) {
974 0 : localTagResToObj_.erase(tag);
975 0 : tagScratchMem_.erase(tag);
976 0 : HCCL_DEBUG(
977 : "[HcclCommAicpu][%s] tag exists, replace old small mem, tag[%s], old[%lu] new[%lu]", __func__,
978 : tag.c_str(), existSize, currSize);
979 : } else {
980 : // 旧内存更大,需要跳过
981 0 : HCCL_DEBUG(
982 : "[HcclCommAicpu][%s] tag exists, keep larger old mem, skip new, tag[%s], old[%lu] new[%lu]", __func__,
983 : tag.c_str(), existSize, currSize);
984 0 : curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
985 0 : needSkip = true;
986 : }
987 : }
988 33 : }
989 :
990 11 : HcclResult HcclCommAicpu::InitLocalTagRes(const ListCommon& head, bool reAllocFlag)
991 : {
992 11 : ListCommon* curList = reinterpret_cast<ListCommon*>(head.nextDevice);
993 11 : if (curList == nullptr) {
994 0 : HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes]list ptr is null.");
995 0 : return HCCL_E_PARA;
996 : }
997 44 : while (curList != &head) {
998 33 : HccltagLocalResV2* tagRes = list_entry(curList, HccltagLocalResV2, nextTagRes);
999 33 : std::string tag = tagRes->tag;
1000 33 : bool needSkip = false;
1001 33 : HandleExistTagReAlloc(tagRes, tag, reAllocFlag, curList, needSkip);
1002 33 : if (needSkip) {
1003 0 : continue;
1004 : }
1005 33 : if (localTagResToObj_.find(tag) == localTagResToObj_.end()
1006 33 : || localTagResToObj_[tag].find(tagRes->Scratchmem) == localTagResToObj_[tag].end()) {
1007 33 : auto scratchMemPtr = reinterpret_cast<void*>(tagRes->Scratchmem);
1008 33 : if (scratchMemPtr == nullptr) {
1009 0 : HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes]scratch mem ptr is null.");
1010 0 : return HCCL_E_PARA;
1011 : }
1012 33 : DeviceMem loalScratchmem = DeviceMem::create(scratchMemPtr, tagRes->ScratchmemSize);
1013 33 : std::shared_ptr<DeviceMem> loalScratchmemPtr;
1014 33 : EXCEPTION_CATCH(
1015 : (loalScratchmemPtr = std::make_shared<DeviceMem>(std::move(loalScratchmem))), return HCCL_E_PTR);
1016 33 : CHK_SMART_PTR_NULL(loalScratchmemPtr);
1017 33 : if (tagScratchMem_.find(tag) == tagScratchMem_.end()) {
1018 33 : tagScratchMem_.insert({tag, loalScratchmemPtr});
1019 : }
1020 33 : std::unordered_set<u64> tmpTagRes;
1021 33 : tmpTagRes.insert(tagRes->Scratchmem);
1022 33 : localTagResToObj_[tag] = tmpTagRes;
1023 33 : HCCL_DEBUG(
1024 : "[HcclCommAicpu][InitLocalTagRes] parse remote resource, tag[%s], Scratchmem[%p], "
1025 : "ScratchmemSize[%lu]",
1026 : tag.c_str(), tagRes->Scratchmem, tagRes->ScratchmemSize);
1027 33 : }
1028 33 : curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
1029 33 : if (curList == nullptr) {
1030 0 : HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes] next list ptr is null.");
1031 0 : return HCCL_E_PARA;
1032 : }
1033 33 : };
1034 11 : HCCL_INFO("[HcclCommAicpu][InitLocalTagRes] success, group[%s]", identifier_.c_str());
1035 11 : return HCCL_SUCCESS;
1036 : }
1037 :
1038 0 : HcclResult HcclCommAicpu::CheckNotifyOrQPMaxNum(u64& existNum, const u64& MaxNum, const bool& isNotifyRes)
1039 : {
1040 0 : std::string resType = isNotifyRes ? "Notify" : "QP";
1041 0 : if (existNum + 1 > MaxNum) {
1042 0 : HCCL_ERROR(
1043 : "[%s]%s resources are insufficient, existNum[%llu], MaxNum is [%llu]", __func__, resType.c_str(), existNum,
1044 : MaxNum);
1045 0 : return HCCL_E_INTERNAL;
1046 : }
1047 0 : HCCL_DEBUG(
1048 : "[%s]%s resources are sufficient, existNum[%llu], MaxNum is [%llu]", __func__, resType.c_str(), existNum,
1049 : MaxNum);
1050 0 : return HCCL_SUCCESS;
1051 0 : }
1052 :
1053 0 : HcclResult HcclCommAicpu::SetTransportMachinePara(
1054 : MachinePara& machinePara, u32& rankId, const std::string& newTag, TransportLinkType linkType)
1055 : {
1056 0 : machinePara.linkAttribute = 0x03; /* 0x03同时支持目的端和源端发起 */
1057 0 : if (rankData_.find(rankId) == rankData_.end()) {
1058 0 : HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
1059 0 : return HCCL_E_NOT_FOUND;
1060 : }
1061 :
1062 0 : machinePara.localUserrank = localUserRank_;
1063 0 : machinePara.remoteWorldRank = rankData_[rankId].remoteWorldRank;
1064 0 : machinePara.remoteUserrank = rankData_[rankId].remoteUsrRankId;
1065 0 : machinePara.deviceLogicId = topoInfo_.deviceLogicId;
1066 0 : machinePara.localDeviceId = topoInfo_.devicePhyId;
1067 0 : machinePara.deviceType = topoInfo_.deviceType;
1068 0 : machinePara.tag = newTag;
1069 0 : machinePara.isAicpuModeEn = true;
1070 0 : if (linkType == TransportLinkType::RESERVED) {
1071 : // 非910_93 2die sio与hccs并发场景,specifyLink设置为RESERVED_LINK_TYPE,平台层将按实际链路类型建链
1072 0 : machinePara.specifyLink = LinkTypeInServer::RESERVED_LINK_TYPE;
1073 : } else {
1074 : // 910_93 2die sio与hccs并发场景,
1075 : // 并发链路中的的hccs链路specifyLink设置为HCCS_SW_TYPE,平台层将使用hccs链路来建链;
1076 : // 并发链路中的的sio链路specifyLink设置为SIO_TYPE,平台层将使用sio链路来建链
1077 : machinePara.specifyLink
1078 0 : = (linkType == TransportLinkType::SIO) ? LinkTypeInServer::SIO_TYPE : LinkTypeInServer::HCCS_SW_TYPE;
1079 : }
1080 :
1081 0 : HCCL_INFO(
1082 : "%s success, group[%s], rankId[%u], linkAttribute[%x], localUserRank[%u], remoteWorldRank[%u], "
1083 : "remoteUserrank[%u], deviceLogicId[%d], localDeviceId[%d], deviceType[%d], newTag[%s], specifyLink[%d], "
1084 : "isAicpuModeEn[%d]",
1085 : __func__, identifier_.c_str(), rankId, machinePara.linkAttribute, machinePara.localUserrank,
1086 : machinePara.remoteWorldRank, machinePara.remoteUserrank, machinePara.deviceLogicId, machinePara.localDeviceId,
1087 : machinePara.deviceType, machinePara.tag.c_str(), machinePara.specifyLink, machinePara.isAicpuModeEn);
1088 0 : return HCCL_SUCCESS;
1089 : }
1090 :
1091 : template <typename T>
1092 0 : HcclResult HcclCommAicpu::InitAndVerifySingleSignal(const HcclSignalInfo& signalInfo, std::shared_ptr<T>& notify)
1093 : {
1094 0 : if (signalInfo.resId == INVALID_U64) {
1095 : // 无效值不做校验
1096 0 : HCCL_DEBUG("[%s]resId[%llu] is invalid, need not check", __func__, signalInfo.resId);
1097 0 : return HCCL_SUCCESS;
1098 : }
1099 : HcclSignalInfo tmpSignalInfo;
1100 :
1101 0 : EXCEPTION_CATCH((notify = std::make_shared<T>()), return HCCL_E_PTR);
1102 0 : CHK_SMART_PTR_NULL(notify);
1103 0 : CHK_RET(notify->Init(signalInfo, NotifyLoadType::DEVICE_NOTIFY));
1104 0 : CHK_RET(notify->GetNotifyData(tmpSignalInfo));
1105 0 : HCCL_DEBUG(
1106 : "[%s] success group[%s], resId[%llu], tsId:%d, devId[%u]", __func__, identifier_.c_str(), tmpSignalInfo.resId,
1107 : tmpSignalInfo.tsId, tmpSignalInfo.devId);
1108 :
1109 0 : return HCCL_SUCCESS;
1110 : }
1111 :
1112 0 : HcclResult HcclCommAicpu::SetTagRemoteRes(u32& rankId, const std::string& tag, HccltagRemoteResV2* tagRes)
1113 : {
1114 0 : if (rankTagRemoteRes_.find(rankId) == rankTagRemoteRes_.end()
1115 0 : || rankTagRemoteRes_[rankId].find(tag) == rankTagRemoteRes_[rankId].end()) {
1116 0 : HccltagRemoteResV3 tempTagRemoteRes;
1117 0 : tempTagRemoteRes.tagRemoteResPtr = tagRes;
1118 0 : rankTagRemoteRes_[rankId][tag] = tempTagRemoteRes;
1119 : }
1120 0 : HCCL_DEBUG("[%s]get TagRemoteRes success, rankId[%u], tag[%s]", __func__, rankId, tag.c_str());
1121 0 : return HCCL_SUCCESS;
1122 : }
1123 :
1124 0 : HcclResult HcclCommAicpu::SetTransportPtpNotify(
1125 : TransportDeviceP2pData& transDevP2pData, u64& p2pNotifyNum, HcclLinkP2pV2& linkP2p, u32 notifyNum)
1126 : {
1127 0 : u64 actualNotifyNum = 0;
1128 : // 获取Ipc notify信息
1129 0 : CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
1130 0 : std::shared_ptr<LocalNotify> ipcPreWaitNotify = std::make_shared<LocalNotify>();
1131 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcPreWaitNotify));
1132 0 : transDevP2pData.ipcPreWaitNotify = ipcPreWaitNotify;
1133 :
1134 0 : std::shared_ptr<RemoteNotify> ipcPreRecordNotify = std::make_shared<RemoteNotify>();
1135 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcPreRecordNotify));
1136 0 : transDevP2pData.ipcPreRecordNotify = ipcPreRecordNotify;
1137 0 : actualNotifyNum++;
1138 :
1139 0 : CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
1140 0 : std::shared_ptr<LocalNotify> ipcPostWaitNotify = std::make_shared<LocalNotify>();
1141 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcPostWaitNotify));
1142 0 : transDevP2pData.ipcPostWaitNotify = ipcPostWaitNotify;
1143 :
1144 0 : std::shared_ptr<RemoteNotify> ipcPostRecordNotify = std::make_shared<RemoteNotify>();
1145 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcPostRecordNotify));
1146 0 : transDevP2pData.ipcPostRecordNotify = ipcPostRecordNotify;
1147 0 : actualNotifyNum++;
1148 :
1149 0 : transDevP2pData.userLocalNotify.resize(notifyNum, nullptr);
1150 0 : transDevP2pData.userRemoteNotify.resize(notifyNum, nullptr);
1151 :
1152 0 : for (u32 idx = 0; idx < notifyNum; idx++) {
1153 0 : CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
1154 0 : std::shared_ptr<LocalNotify> ipcWaitNotify = std::make_shared<LocalNotify>();
1155 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcWaitNotify));
1156 0 : transDevP2pData.userLocalNotify[idx] = ipcWaitNotify;
1157 :
1158 0 : std::shared_ptr<RemoteNotify> ipcRecordNotify = std::make_shared<RemoteNotify>();
1159 0 : CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcRecordNotify));
1160 0 : transDevP2pData.userRemoteNotify[idx] = ipcRecordNotify;
1161 :
1162 0 : actualNotifyNum++;
1163 0 : }
1164 :
1165 0 : HCCL_DEBUG("[%s]get p2pNotify success, actualNotifyNum[%u]", __func__, actualNotifyNum);
1166 0 : p2pNotifyNum = actualNotifyNum;
1167 :
1168 0 : return HCCL_SUCCESS;
1169 0 : }
1170 :
1171 0 : HcclResult HcclCommAicpu::SetTransportRoceQP(
1172 : TransportDeviceIbverbsData& transDevIbverbsData, u64& roceQpNum, HcclLinkRoceV2* linkRoce)
1173 : {
1174 0 : roceQpNum = linkRoce->qpsPerConnection;
1175 0 : u32 roceQpNumSum = linkRoce->qpsPerConnection + static_cast<u32>(linkRoce->qpsPerConnection != 1);
1176 0 : transDevIbverbsData.qpInfo.resize(roceQpNumSum);
1177 0 : std::copy_n(linkRoce->QpInfo, roceQpNumSum, transDevIbverbsData.qpInfo.begin());
1178 0 : transDevIbverbsData.multiQpThreshold = multiQpThreshold_;
1179 0 : transDevIbverbsData.qpsPerConnection = linkRoce->qpsPerConnection;
1180 0 : HCCL_INFO(
1181 : "[%s]transDevIbverbsData.qpInfo.qpPtr[%llu], transDevIbverbsData.qpInfo.sqIndex[%u], "
1182 : "transDevIbverbsData.qpInfo.dbIndex[%u], roceQpNum[%llu], roceQpNumSum[%u], multiQpThreshold_[%u]",
1183 : __func__, transDevIbverbsData.qpInfo[0].qpPtr, transDevIbverbsData.qpInfo[0].sqIndex,
1184 : transDevIbverbsData.qpInfo[0].dbIndex, roceQpNum, roceQpNumSum, multiQpThreshold_);
1185 0 : return HCCL_SUCCESS;
1186 : }
1187 :
1188 0 : HcclResult HcclCommAicpu::SetTransportRoceNotify(
1189 : TransportDeviceIbverbsData& transDevIbverbsData, u64& roceNotifyNum, HcclLinkRoceV2* linkRoce,
1190 : [[maybe_unused]] u32 notifyNum)
1191 : {
1192 0 : u64 actualNotifyNum = 0;
1193 0 : if (linkRoce->localNotifyList == 0 || linkRoce->remoteNotifyList == 0) {
1194 0 : HCCL_DEBUG("[%s] Empty local and remote notify lists, skipping notify resource creation.", __func__);
1195 0 : return HCCL_SUCCESS;
1196 : }
1197 0 : HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(linkRoce->localNotifyList);
1198 0 : AddrKey* remoteNotifyList = reinterpret_cast<AddrKey*>(linkRoce->remoteNotifyList);
1199 0 : if (localNotifyList == nullptr || remoteNotifyList == nullptr) {
1200 0 : HCCL_ERROR("[%s]nullptr found in localNotifyList or remoteNotifyList from device mem, check.", __func__);
1201 0 : return HCCL_E_INTERNAL;
1202 : }
1203 : // 获取RDMA Notify信息
1204 0 : std::shared_ptr<LocalNotify> ackNotify = std::make_shared<LocalNotify>();
1205 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], ackNotify));
1206 0 : transDevIbverbsData.ackNotify = ackNotify;
1207 0 : transDevIbverbsData.remoteAckNotifyDetails = remoteNotifyList[actualNotifyNum];
1208 0 : actualNotifyNum++;
1209 :
1210 0 : std::shared_ptr<LocalNotify> dataNotify = std::make_shared<LocalNotify>();
1211 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataNotify));
1212 0 : transDevIbverbsData.dataNotify = dataNotify;
1213 0 : transDevIbverbsData.remoteDataNotifyDetails = remoteNotifyList[actualNotifyNum];
1214 0 : actualNotifyNum++;
1215 :
1216 0 : std::shared_ptr<LocalNotify> dataAckNotify = std::make_shared<LocalNotify>();
1217 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataAckNotify));
1218 0 : transDevIbverbsData.dataAckNotify = dataAckNotify;
1219 0 : transDevIbverbsData.remoteDataAckNotifyDetails = remoteNotifyList[actualNotifyNum];
1220 0 : transDevIbverbsData.notifySize = notifySize_;
1221 0 : actualNotifyNum++;
1222 :
1223 0 : transDevIbverbsData.userLocalNotify.resize(linkRoce->qpsPerConnection);
1224 0 : transDevIbverbsData.userRemoteNotifyDetails.resize(linkRoce->qpsPerConnection);
1225 : // 当前多QP下每个QP会多申请一个DataNotify
1226 0 : u64 singleQpNotifySize = linkRoce->singleQPNotifyNum + static_cast<u32>(linkRoce->qpsPerConnection > 1);
1227 0 : for (u32 qpIndex = 0; qpIndex < linkRoce->qpsPerConnection; qpIndex++) {
1228 0 : transDevIbverbsData.userLocalNotify[qpIndex].resize(singleQpNotifySize, nullptr);
1229 0 : transDevIbverbsData.userRemoteNotifyDetails[qpIndex].resize(singleQpNotifySize);
1230 0 : for (u32 i = 0, idx = actualNotifyNum + singleQpNotifySize * qpIndex; i < singleQpNotifySize; ++idx, ++i) {
1231 0 : std::shared_ptr<LocalNotify> locNotify = std::make_shared<LocalNotify>();
1232 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[idx], locNotify));
1233 0 : transDevIbverbsData.userLocalNotify[qpIndex][i] = locNotify;
1234 0 : transDevIbverbsData.userRemoteNotifyDetails[qpIndex][i] = remoteNotifyList[idx];
1235 0 : }
1236 : }
1237 0 : roceNotifyNum = linkRoce->singleQPNotifyNum;
1238 0 : HCCL_DEBUG("[%s]get roceNotify success, roceNotifyNum[%u]", __func__, roceNotifyNum);
1239 0 : return HCCL_SUCCESS;
1240 0 : }
1241 :
1242 0 : HcclResult HcclCommAicpu::InitLinkP2p(
1243 : HccltagRemoteResV2* tagRes, u32& rankId, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
1244 : {
1245 0 : std::unordered_map<u32, std::unordered_map<std::string, std::shared_ptr<Transport>>>& linkRes
1246 : = (linkType == TransportLinkType::SIO) ? linkResSio_ : linkRes_;
1247 0 : HcclLinkP2pV2& linkP2p = (linkType == TransportLinkType::SIO) ? tagRes->linkP2pSio : tagRes->linkP2p;
1248 :
1249 0 : if (linkRes.find(rankId) == linkRes.end() || linkRes[rankId].find(newTag) == linkRes[rankId].end()) {
1250 : // 优先校验notify去判定link是否有效
1251 0 : if (linkP2p.localIpcSignal[0].resId == INVALID_U64) {
1252 0 : HCCL_INFO(
1253 : "[%s]the link is invalid, no need to create transport, rankId[%u], newTag[%s]", __func__, rankId,
1254 : newTag.c_str());
1255 0 : return HCCL_SUCCESS;
1256 : }
1257 : // 创建Transport对象
1258 0 : MachinePara machinePara;
1259 0 : CHK_RET(SetTransportMachinePara(machinePara, rankId, newTag, linkType));
1260 0 : machinePara.notifyNum = notifyNum;
1261 : // 获取localMem & remoteMem
1262 0 : TransportDeviceP2pData transDevP2pData;
1263 0 : transDevP2pData.inputBufferPtr = reinterpret_cast<void*>((linkP2p.remoteMem)[INPUT].addr);
1264 0 : transDevP2pData.outputBufferPtr = reinterpret_cast<void*>((linkP2p.remoteMem)[OUTPUT].addr);
1265 0 : if (transDevP2pData.inputBufferPtr == nullptr || transDevP2pData.outputBufferPtr == nullptr) {
1266 0 : HCCL_ERROR(
1267 : "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevP2pData.inputBufferPtr,
1268 : transDevP2pData.outputBufferPtr);
1269 0 : return HCCL_E_PARA;
1270 : }
1271 : // 获取Notify资源
1272 0 : CHK_RET(SetTagRemoteRes(rankId, newTag, tagRes));
1273 0 : HccltagRemoteResV3* tagRemoteRes = &(rankTagRemoteRes_[rankId][newTag]);
1274 0 : CHK_RET(SetTransportPtpNotify(transDevP2pData, tagRemoteRes->p2pNotifyNum, linkP2p, notifyNum));
1275 : // 获取transportAttr信息
1276 0 : transDevP2pData.transportAttr = linkP2p.transportAttr;
1277 : // 创建Transport对象
1278 0 : std::shared_ptr<Transport> link;
1279 0 : TransportPara para{};
1280 0 : const std::unique_ptr<NotifyPool> notifyPool;
1281 0 : link.reset(new (std::nothrow) Transport(
1282 0 : TransportType::TRANS_TYPE_DEVICE_P2P, para, dispatcher_, notifyPool, machinePara, transDevP2pData));
1283 0 : CHK_SMART_PTR_NULL(link);
1284 0 : CHK_RET(link->Init());
1285 0 : linkRes[rankId][newTag] = link;
1286 0 : HCCL_INFO("[%s]linkRes_, rankId[%u], newTag[%s]", __func__, rankId, newTag.c_str());
1287 0 : }
1288 0 : return HCCL_SUCCESS;
1289 : }
1290 0 : HcclResult HcclCommAicpu::InitLinkRoce(
1291 : HccltagRemoteResV2* tagRes, HcclLinkRoceV2* linkRoce, u32& rankId, const std::string& newTag, u32 notifyNum,
1292 : const bool isBackup, const bool isSecond)
1293 : {
1294 : // 优先校验notify去判定link是否有效
1295 0 : if (linkRoce->localNotifyList == 0) {
1296 0 : HCCL_INFO(
1297 : "[%s]the link is invalid, no need to create transport, rankId[%u], newTag[%s], isBackup[%d]", __func__,
1298 : rankId, newTag.c_str(), isBackup);
1299 0 : return HCCL_SUCCESS;
1300 : }
1301 0 : HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(linkRoce->localNotifyList);
1302 0 : if (localNotifyList[0].resId == INVALID_U64) {
1303 0 : HCCL_INFO(
1304 : "[%s]the link notify resource is invalid, no need to create transport, rankId[%u], newTag[%s], "
1305 : "resId[%llu], "
1306 : "isBackup[%d]",
1307 : __func__, rankId, newTag.c_str(), localNotifyList[0].resId, isBackup);
1308 0 : return HCCL_SUCCESS;
1309 : }
1310 :
1311 : // 创建Transport对象
1312 0 : MachinePara machinePara;
1313 0 : CHK_RET(SetTransportMachinePara(machinePara, rankId, newTag));
1314 0 : machinePara.notifyNum = notifyNum;
1315 : // 获取localMem & remoteMem
1316 0 : TransportDeviceIbverbsData transDevIbverbsData;
1317 0 : transDevIbverbsData.inputBufferPtr = reinterpret_cast<void*>((linkRoce->remoteMem)[INPUT].addr);
1318 0 : transDevIbverbsData.outputBufferPtr = reinterpret_cast<void*>((linkRoce->remoteMem)[OUTPUT].addr);
1319 0 : if (transDevIbverbsData.inputBufferPtr == nullptr || transDevIbverbsData.outputBufferPtr == nullptr) {
1320 0 : HCCL_ERROR(
1321 : "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevIbverbsData.inputBufferPtr,
1322 : transDevIbverbsData.outputBufferPtr);
1323 0 : return HCCL_E_PARA;
1324 : }
1325 0 : transDevIbverbsData.localInputMem = (linkRoce->localMem)[INPUT];
1326 0 : transDevIbverbsData.localOutputMem = (linkRoce->localMem)[OUTPUT];
1327 0 : transDevIbverbsData.localNotifyValueAddr = linkRoce->notifyValue;
1328 0 : transDevIbverbsData.notifyValueKey = linkRoce->notifyValueKey;
1329 0 : transDevIbverbsData.remoteInputKey = (linkRoce->remoteMem)[INPUT].key;
1330 0 : transDevIbverbsData.remoteOutputKey = (linkRoce->remoteMem)[OUTPUT].key;
1331 : // 获取QPinfo
1332 0 : CHK_RET(SetTagRemoteRes(rankId, newTag, tagRes));
1333 0 : HccltagRemoteResV3* tagRemoteRes = &(rankTagRemoteRes_[rankId][newTag]);
1334 0 : u64& roceQpNum = isBackup ? tagRemoteRes->qpNumBackup : tagRemoteRes->qpNum;
1335 0 : CHK_RET(SetTransportRoceQP(transDevIbverbsData, roceQpNum, linkRoce));
1336 : // 获取notify
1337 0 : u64& roceNotifyNum = isBackup ? tagRemoteRes->roceNotifyNumBackup : tagRemoteRes->roceNotifyNum;
1338 0 : CHK_RET(SetTransportRoceNotify(transDevIbverbsData, roceNotifyNum, linkRoce, notifyNum));
1339 0 : HCCL_INFO("[%s]transDevIbverbsData isBackup[%d]", __func__, isBackup);
1340 : // 获取atomic write
1341 0 : transDevIbverbsData.useAtomicWrite = linkRoce->useAtomicWrite;
1342 : // 创建Transport对象
1343 0 : std::shared_ptr<Transport> link;
1344 0 : TransportPara para{};
1345 0 : para.timeout = linkTimeOut_;
1346 0 : const std::unique_ptr<NotifyPool> notifyPool;
1347 0 : link.reset(new (std::nothrow) Transport(
1348 0 : TransportType::TRANS_TYPE_DEVICE_IBVERBS, para, dispatcher_, notifyPool, machinePara, TransportDeviceP2pData(),
1349 0 : transDevIbverbsData));
1350 0 : CHK_SMART_PTR_NULL(link);
1351 0 : CHK_RET(link->Init());
1352 0 : if (isBackup) {
1353 0 : linkRdmaResBackUp_[rankId][newTag].push_back(link);
1354 0 : HCCL_INFO(
1355 : "[%s]linkRdmaResBackUp_, rankId[%u], newTag[%s], isBackup[%d], isSecond[%d], qpNum[%u], notifyNum[%u]",
1356 : __func__, rankId, newTag.c_str(), isBackup, isSecond, roceQpNum, roceNotifyNum);
1357 : } else {
1358 0 : linkRdmaRes_[rankId][newTag].push_back(link);
1359 0 : HCCL_INFO(
1360 : "[%s]linkRdmaRes_, rankId[%u], newTag[%s], isBackup[%d], isSecond[%d], qpNum[%u], notifyNum[%u]", __func__,
1361 : rankId, newTag.c_str(), isBackup, isSecond, roceQpNum, roceNotifyNum);
1362 : }
1363 0 : return HCCL_SUCCESS;
1364 0 : }
1365 :
1366 0 : HcclResult HcclCommAicpu::InitLinkRoce(
1367 : HccltagRemoteResV2* tagRes, u32& rankId, const std::string& newTag, u32 notifyNum, const bool isBackup)
1368 : {
1369 0 : auto tempLinkRes = isBackup ? linkRdmaResBackUp_ : linkRdmaRes_;
1370 0 : if (tempLinkRes.find(rankId) == tempLinkRes.end()
1371 0 : || tempLinkRes[rankId].find(newTag) == tempLinkRes[rankId].end()) {
1372 0 : bool isBatchSendRecv = newTag.find("BatchSendRecv") != std::string::npos;
1373 0 : if (isBatchSendRecv) {
1374 : // 如果是batchsendrecv,相同rank,需要刷新两次transport,如果是主的话就刷新0,2 备就刷新1,3
1375 0 : if (isBackup) {
1376 0 : CHK_RET(InitLinkRoce(
1377 : tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP]), rankId, newTag, notifyNum, isBackup));
1378 0 : CHK_RET(InitLinkRoce(
1379 : tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP + 2]), rankId, newTag, notifyNum, isBackup,
1380 : true));
1381 : } else {
1382 0 : CHK_RET(InitLinkRoce(
1383 : tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT]), rankId, newTag, notifyNum, isBackup));
1384 0 : CHK_RET(InitLinkRoce(
1385 : tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT + 2]), rankId, newTag, notifyNum, isBackup,
1386 : true));
1387 : }
1388 : } else {
1389 : // 非batchsendrecv只刷新主0,备1
1390 0 : HcclLinkRoceV2* linkRoce = isBackup ? &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP]) :
1391 : &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT]);
1392 0 : CHK_RET(InitLinkRoce(tagRes, linkRoce, rankId, newTag, notifyNum, isBackup));
1393 : }
1394 : }
1395 0 : return HCCL_SUCCESS;
1396 0 : }
1397 :
1398 0 : HcclResult HcclCommAicpu::InitRemoteTagRes(
1399 : u32& rankId, const ListCommon& head, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
1400 : {
1401 0 : HCCL_RUN_INFO(
1402 : "[%s] Entry parse remote resource rankId[%u], group[%s], newTag[%s], head[%p], "
1403 : "linkType[%d]",
1404 : __func__, rankId, identifier_.c_str(), newTag.c_str(), &head, linkType);
1405 0 : ListCommon* curList = reinterpret_cast<ListCommon*>(head.nextDevice);
1406 0 : if (curList == nullptr) {
1407 0 : HCCL_ERROR("[%s]cur list ptr is null.", __func__);
1408 0 : return HCCL_E_PARA;
1409 : }
1410 :
1411 0 : HccltagRemoteResV2* tagRes = nullptr;
1412 0 : while (curList != &head) {
1413 0 : HccltagRemoteResV2* tagResTemp = list_entry(curList, HccltagRemoteResV2, nextTagRes);
1414 0 : if (strcmp(tagResTemp->tag, newTag.c_str()) == 0) {
1415 0 : tagRes = tagResTemp;
1416 0 : break;
1417 : }
1418 :
1419 0 : curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
1420 0 : if (curList == nullptr) {
1421 0 : HCCL_ERROR("[%s]next list ptr is null.", __func__);
1422 0 : return HCCL_E_PARA;
1423 : }
1424 : }
1425 :
1426 0 : if (tagRes == nullptr) {
1427 0 : HCCL_ERROR(
1428 : "[%s]newTag[%s] not found, rankId[%u], head[%p], curList[%p], nextList[%llu], notifyNum[%u], "
1429 : "linkType[%d]",
1430 : __func__, newTag.c_str(), rankId, &head, curList, curList->nextDevice, notifyNum, linkType);
1431 0 : return HCCL_E_PARA;
1432 : }
1433 :
1434 0 : HCCL_INFO(
1435 : "[%s]newTag[%s], rankId[%u], head[%p], curList[%p], nextList[%llu], notifyNum[%u], linkType[%d]", __func__,
1436 : newTag.c_str(), rankId, &head, curList, curList->nextDevice, notifyNum, linkType);
1437 0 : if (linkType != TransportLinkType::RDMA) {
1438 : // 创建P2P链路
1439 0 : CHK_RET(InitLinkP2p(tagRes, rankId, newTag, notifyNum, linkType));
1440 : } else {
1441 : // 创建roce链路
1442 0 : CHK_RET(InitLinkRoce(tagRes, rankId, newTag, notifyNum));
1443 : // 创建roce链路(备用链路)
1444 0 : CHK_RET(InitLinkRoce(tagRes, rankId, newTag, notifyNum, true));
1445 : }
1446 0 : HCCL_INFO(
1447 : "[%s] End parse remote resource rankId[%u] tag[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
1448 : newTag.c_str());
1449 0 : return HCCL_SUCCESS;
1450 : }
1451 :
1452 0 : HcclResult HcclCommAicpu::RefreshTransportsResForRank(
1453 : const HcclOpResParam* commParam, u32 rankId, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
1454 : {
1455 0 : if (rankId >= AICPU_MAX_RANK_NUM) {
1456 0 : HCCL_ERROR(
1457 : "[%s] rankId[%u] overflow for group[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
1458 : newTag.c_str());
1459 0 : return HCCL_E_PARA;
1460 : }
1461 0 : if (commParam->remoteRes[rankId].nextDevicePtr == 0) {
1462 0 : return HCCL_SUCCESS;
1463 : }
1464 0 : HcclRankRelationResV2* rankRelationResPtr
1465 0 : = reinterpret_cast<HcclRankRelationResV2*>(commParam->remoteRes[rankId].nextDevicePtr);
1466 0 : if (rankRelationResPtr == nullptr) {
1467 0 : HCCL_ERROR(
1468 : "[%s]rank relation resource ptr is null, commParam->remoteRes[rankId].nextDevicePtr[%p],"
1469 : " rankId[%u]",
1470 : __func__, reinterpret_cast<HcclRankRelationResV2*>(commParam->remoteRes[rankId].nextDevicePtr), rankId);
1471 0 : return HCCL_E_PARA;
1472 : }
1473 :
1474 : // 1. init公共参数(对应remoteWorldRank,remoteUsrRankId暂不处理:windowsIn,windowsOut)
1475 0 : rankData_[rankId].remoteWorldRank = rankRelationResPtr->remoteWorldRank;
1476 0 : rankData_[rankId].remoteUsrRankId = rankRelationResPtr->remoteUsrRankId;
1477 : // 2. 遍历链表,获取HccltagRemoteResV2创建Tranport对象
1478 0 : if (reinterpret_cast<ListCommon*>(rankRelationResPtr->nextTagRes.nextDevice) != &(rankRelationResPtr->nextTagRes)) {
1479 0 : HCCL_DEBUG(
1480 : "[%s] Start to parse rankId[%u] tag resources, head[%p], nextDevice[%p], pre Device[%p], group[%s]",
1481 : __func__, rankId, &rankRelationResPtr->nextTagRes, rankRelationResPtr->nextTagRes.nextDevice,
1482 : rankRelationResPtr->nextTagRes.preDevice, identifier_.c_str());
1483 0 : CHK_RET(InitRemoteTagRes(rankId, rankRelationResPtr->nextTagRes, newTag, notifyNum, linkType));
1484 : } else {
1485 0 : HCCL_ERROR(
1486 : "[%s]could not find member in rankRelationRes list, rankId[%u], head[%p], nextDevice[%p]", __func__, rankId,
1487 : &rankRelationResPtr->nextTagRes, rankRelationResPtr->nextTagRes.nextDevice);
1488 0 : return HCCL_E_PARA;
1489 : }
1490 0 : HCCL_INFO(
1491 : "[%s] process success rankId[%u], group[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
1492 : newTag.c_str());
1493 0 : return HCCL_SUCCESS;
1494 : }
1495 :
1496 0 : HcclResult HcclCommAicpu::GetRdmaLinksByRankAndTag(
1497 : const HcclOpResParam* commParam, CommTransportsType type, u32 rankId, const std::string& newTag, LINK& link,
1498 : bool isBackup, u32 notifyNum, bool isSecond)
1499 : {
1500 0 : HCCL_INFO(
1501 : "[%s] Start to rdma get Link group[%s], rankId[%u], newTag[%s], isBackup[%d], deviceLogicId[%d],"
1502 : "notifyNum[%u], isSecond[%d]",
1503 : __func__, identifier_.c_str(), rankId, newTag.c_str(), isBackup, commParam->topoInfo.deviceLogicId, notifyNum,
1504 : isSecond);
1505 :
1506 0 : auto* linkRes = isBackup ? &linkRdmaResBackUp_ : &linkRdmaRes_;
1507 0 : auto iterRankLinks = linkRes->find(rankId);
1508 0 : if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
1509 0 : HCCL_INFO(
1510 : "[%s] could not find link resource, rankId[%u], group[%s], newTag[%s]", __func__, rankId,
1511 : identifier_.c_str(), newTag.c_str());
1512 0 : CHK_RET(RefreshTransportsResForRank(commParam, rankId, newTag, notifyNum, TransportLinkType::RDMA));
1513 0 : iterRankLinks = linkRes->find(rankId);
1514 0 : if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
1515 0 : HCCL_ERROR(
1516 : "[%s] refresh transport failed, newTag[%s], remoteUserRankId[%u]", __func__, newTag.c_str(), rankId);
1517 0 : return HCCL_E_INTERNAL;
1518 : }
1519 : }
1520 0 : if (isSecond && iterRankLinks->second[newTag].size() <= 1) {
1521 0 : HCCL_ERROR("[%s] get rdma Link failed, newTag[%s], remoteUserRankId[%u]", __func__, newTag.c_str(), rankId);
1522 0 : return HCCL_E_INTERNAL;
1523 : }
1524 :
1525 0 : link = isSecond ? iterRankLinks->second[newTag][1] : iterRankLinks->second[newTag][0];
1526 :
1527 0 : if (receivedAcks_.find(rankId) == receivedAcks_.end()) {
1528 0 : HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
1529 0 : return HCCL_E_NOT_FOUND;
1530 : }
1531 0 : link->SetSupportDataReceivedAck(receivedAcks_[rankId]);
1532 0 : HCCL_DEBUG(
1533 : "[HcclCommAicpu][GetLinksByRankAndTag]rankid[%d] supportDataReceivedAck is %d", rankId, receivedAcks_[rankId]);
1534 0 : HCCL_INFO(
1535 : "[%s] group[%s], newTag[%s], rankId[%u] type[%u] success!", __func__, identifier_.c_str(), newTag.c_str(),
1536 : rankId, type);
1537 0 : return HCCL_SUCCESS;
1538 : }
1539 :
1540 0 : HcclResult HcclCommAicpu::GetSdmaLinksByRankAndTag(
1541 : const HcclOpResParam* commParam, CommTransportsType type, u32 rankId, const std::string& newTag, LINK& link,
1542 : bool isBackup, u32 notifyNum, TransportLinkType linkType)
1543 : {
1544 0 : HCCL_INFO(
1545 : "[%s] Start to get sdma Link group[%s], rankId[%u], newTag[%s], isBackup[%d], deviceLogicId[%d], "
1546 : "notifyNum[%u], linkType[%d]",
1547 : __func__, identifier_.c_str(), rankId, newTag.c_str(), isBackup, commParam->topoInfo.deviceLogicId, notifyNum,
1548 : linkType);
1549 :
1550 0 : auto* linkRes = &linkRes_;
1551 0 : if (linkType == TransportLinkType::SIO) { // HCCS SIO并发场景,HCCS链路与SIO链路分开管理
1552 0 : linkRes = &linkResSio_;
1553 : }
1554 0 : auto iterRankLinks = linkRes->find(rankId);
1555 0 : if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
1556 0 : HCCL_INFO(
1557 : "[%s] could not find link resource, rankId[%u], group[%s], newTag[%s]", __func__, rankId,
1558 : identifier_.c_str(), newTag.c_str());
1559 0 : CHK_RET(RefreshTransportsResForRank(commParam, rankId, newTag, notifyNum, linkType));
1560 0 : iterRankLinks = linkRes->find(rankId);
1561 0 : if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
1562 0 : HCCL_ERROR(
1563 : "[%s] refresh transport failed, newTag[%s], remoteUserRankId[%u], %p", __func__, newTag.c_str(), rankId,
1564 : linkRes);
1565 0 : return HCCL_E_INTERNAL;
1566 : }
1567 : }
1568 :
1569 0 : link = iterRankLinks->second[newTag];
1570 0 : if (receivedAcks_.find(rankId) == receivedAcks_.end()) {
1571 0 : HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
1572 0 : return HCCL_E_NOT_FOUND;
1573 : }
1574 0 : link->SetSupportDataReceivedAck(receivedAcks_[rankId]);
1575 0 : HCCL_DEBUG(
1576 : "[HcclCommAicpu][GetLinksByRankAndTag]rankid[%d] supportDataReceivedAck is %d", rankId, receivedAcks_[rankId]);
1577 0 : HCCL_INFO(
1578 : "[%s] group[%s], newTag[%s], rankId[%u] type[%u] success!", __func__, identifier_.c_str(), newTag.c_str(),
1579 : rankId, type);
1580 0 : return HCCL_SUCCESS;
1581 : }
1582 :
1583 0 : HcclResult HcclCommAicpu::CleanRoceResource(
1584 : const std::string& newTag, AlgResourceResponse& algResResponse,
1585 : [[maybe_unused]] const std::map<u32, bool>& remoteRankPortMap, [[maybe_unused]] const OpParam& param)
1586 : {
1587 0 : HCCL_INFO("[%s] Entry alloc transport group[%s], tag[%s]", __func__, identifier_.c_str(), newTag.c_str());
1588 :
1589 0 : for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
1590 0 : for (auto& singleSubCommTransport : levelNSubCommTransport) {
1591 0 : for (auto& transportRequest : singleSubCommTransport.transportRequests) {
1592 0 : if (transportRequest.isValid && transportRequest.isUsedRdma) {
1593 0 : u32 remoteUserRank = transportRequest.remoteUserRank;
1594 0 : linkRdmaRes_[remoteUserRank].erase(newTag);
1595 0 : linkRdmaResBackUp_[remoteUserRank].erase(newTag);
1596 : }
1597 : }
1598 : }
1599 : }
1600 :
1601 0 : return HCCL_SUCCESS;
1602 : }
1603 :
1604 1 : HcclResult HcclCommAicpu::CleanAllRoceResource()
1605 : {
1606 1 : HCCL_INFO("Clean all link rdna resources");
1607 : // 清空主链路资源
1608 1 : linkRdmaRes_.clear();
1609 : // 清空备链路资源
1610 1 : linkRdmaResBackUp_.clear();
1611 1 : return HCCL_SUCCESS;
1612 : }
1613 :
1614 2 : HcclResult HcclCommAicpu::ClearOpResource(const std::string& tag)
1615 : {
1616 : // 与 GetAlgResponseRes/AllocAlgResource/ReAllocTransportResource 互斥,避免读写竞争 resMap_/linkRes_
1617 2 : std::lock_guard<std::mutex> lock(preemptMutexForResMap_);
1618 :
1619 6 : auto eraseTagFromAll = [this](const std::string& t) -> bool {
1620 6 : bool hit = false;
1621 : // 主资源map:vector<LINK>析构会让shared_ptr<Transport>引用-1,归零时触发driver资源释放
1622 6 : if (resMap_.erase(t) > 0) {
1623 1 : hit = true;
1624 : }
1625 : // SDMA HCCS链路缓存:报错日志中driver halResAddrMap ioctl失败的根本累积点
1626 9 : for (auto& rankIt : linkRes_) {
1627 3 : if (rankIt.second.erase(t) > 0) {
1628 1 : hit = true;
1629 : }
1630 : }
1631 : // SDMA SIO并发链路缓存
1632 9 : for (auto& rankIt : linkResSio_) {
1633 3 : if (rankIt.second.erase(t) > 0) {
1634 1 : hit = true;
1635 : }
1636 : }
1637 : // RDMA主备链路缓存(CleanAllRoceResource按通信域全清,本接口按tag细粒度清)
1638 9 : for (auto& rankIt : linkRdmaRes_) {
1639 3 : if (rankIt.second.erase(t) > 0) {
1640 1 : hit = true;
1641 : }
1642 : }
1643 9 : for (auto& rankIt : linkRdmaResBackUp_) {
1644 3 : if (rankIt.second.erase(t) > 0) {
1645 1 : hit = true;
1646 : }
1647 : }
1648 : // 本地scratchMem和localTagResToObj按tag索引
1649 6 : if (tagScratchMem_.erase(t) > 0) {
1650 1 : hit = true;
1651 : }
1652 6 : if (localTagResToObj_.erase(t) > 0) {
1653 1 : hit = true;
1654 : }
1655 9 : for (auto& rankIt : rankTagRemoteRes_) {
1656 3 : if (rankIt.second.erase(t) > 0) {
1657 1 : hit = true;
1658 : }
1659 : }
1660 6 : return hit;
1661 2 : };
1662 :
1663 : // 与 host 端 ClearOpResource 对齐:尝试 base/_host/_device 三种后缀
1664 2 : bool found = false;
1665 2 : found = eraseTagFromAll(tag) || found;
1666 2 : found = eraseTagFromAll(tag + "_host") || found;
1667 2 : found = eraseTagFromAll(tag + "_device") || found;
1668 2 : if (!found) {
1669 1 : HCCL_WARNING(
1670 : "[HcclCommAicpu][ClearOpResource] no entries matched tag[%s] "
1671 : "(also tried _host/_device variants), group[%s]",
1672 : tag.c_str(), identifier_.c_str());
1673 : } else {
1674 1 : HCCL_INFO(
1675 : "[HcclCommAicpu][ClearOpResource] cleared resources for tag[%s], group[%s]", tag.c_str(),
1676 : identifier_.c_str());
1677 : }
1678 2 : return HCCL_SUCCESS;
1679 2 : }
1680 :
1681 : // 借轨重新刷新资源
1682 0 : HcclResult HcclCommAicpu::ReAllocTransportResource(
1683 : const std::string& newTag, AlgResourceResponse& algResResponse, std::map<u32, bool>& remoteRankPortMap,
1684 : const HcclOpResParam* commParam, const OpParam& param)
1685 : {
1686 0 : HCCL_INFO("[%s] Entry alloc transport group[%s], tag[%s]", __func__, identifier_.c_str(), newTag.c_str());
1687 0 : std::set<u32> bsrTansportRank;
1688 0 : for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
1689 0 : for (auto& singleSubCommTransport : levelNSubCommTransport) {
1690 0 : singleSubCommTransport.links.clear();
1691 0 : singleSubCommTransport.links.reserve(singleSubCommTransport.transportRequests.size());
1692 0 : for (auto& transportRequest : singleSubCommTransport.transportRequests) {
1693 0 : singleSubCommTransport.links.push_back(nullptr);
1694 0 : if (transportRequest.isValid) {
1695 0 : HCCL_INFO(
1696 : "[%s] alloc transport, newTag[%s], rankId[%u], "
1697 : "input memory type[%u], output memory type[%u], ",
1698 : __func__, newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
1699 : transportRequest.outputMemType);
1700 0 : receivedAcks_[transportRequest.remoteUserRank] = singleSubCommTransport.supportDataReceivedAck;
1701 0 : bool isBackup = remoteRankPortMap.find(transportRequest.remoteUserRank) != remoteRankPortMap.end()
1702 0 : && !remoteRankPortMap[transportRequest.remoteUserRank];
1703 0 : bool isSecondBuild = false;
1704 0 : bool isBatchSendRecv = newTag.find("BatchSendRecv") != std::string::npos;
1705 0 : if (transportRequest.isUsedRdma && isBatchSendRecv
1706 0 : && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
1707 : // 仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
1708 0 : isSecondBuild = true;
1709 : }
1710 : // A3 bsr远端是DirectNpu 链路的话则跳过
1711 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
1712 0 : && (param.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
1713 0 : continue;
1714 : }
1715 0 : bsrTansportRank.insert(transportRequest.remoteUserRank);
1716 0 : CHK_RET(CreateLink(
1717 : newTag, transportRequest, commParam, singleSubCommTransport.links.back(),
1718 : transportRequest.notifyNum, isBackup, isSecondBuild));
1719 : }
1720 : }
1721 : }
1722 : }
1723 :
1724 0 : return HCCL_SUCCESS;
1725 0 : }
1726 :
1727 0 : HcclResult HcclCommAicpu::AllocTransportResource(
1728 : const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
1729 : AlgResourceResponse& algResResponse)
1730 : {
1731 0 : HCCL_INFO("[%s] Entry alloc transport group[%s]", __func__, identifier_.c_str());
1732 0 : algResResponse.opTransportResponse = resRequest.opTransport;
1733 :
1734 0 : std::set<u32> bsrTansportRank;
1735 0 : for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
1736 0 : for (auto& singleSubCommTransport : levelNSubCommTransport) {
1737 0 : singleSubCommTransport.links.clear();
1738 0 : singleSubCommTransport.links.reserve(singleSubCommTransport.transportRequests.size());
1739 0 : for (auto& transportRequest : singleSubCommTransport.transportRequests) {
1740 0 : singleSubCommTransport.links.push_back(nullptr);
1741 0 : if (transportRequest.isValid) {
1742 0 : localUserRank_ = transportRequest.localUserRank;
1743 0 : receivedAcks_[transportRequest.remoteUserRank] = singleSubCommTransport.supportDataReceivedAck;
1744 0 : HCCL_DEBUG(
1745 : "[%s] alloc transport, newTag[%s], rankId[%u], input memory type[%u], "
1746 : "output memory type[%u], ",
1747 : __func__, newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
1748 : transportRequest.outputMemType);
1749 :
1750 0 : bool isSecondBuild = false;
1751 0 : if (transportRequest.isUsedRdma && opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV
1752 0 : && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
1753 : // 仅仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
1754 0 : isSecondBuild = true;
1755 : }
1756 : // A3 bsr远端是DirectNpu 链路的话则跳过
1757 0 : if ((opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
1758 0 : && (opParam.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
1759 0 : continue;
1760 : }
1761 0 : bsrTansportRank.insert(transportRequest.remoteUserRank);
1762 0 : CHK_RET(CreateLink(
1763 : newTag, transportRequest, commParam, singleSubCommTransport.links.back(),
1764 : transportRequest.notifyNum, false, isSecondBuild));
1765 : }
1766 : }
1767 : }
1768 : }
1769 :
1770 0 : return HCCL_SUCCESS;
1771 0 : }
1772 :
1773 : // 在resMap_[tag]对应原有通信资源的基础上继续增量建链,目前batchsendrecv会用到本接口
1774 0 : HcclResult HcclCommAicpu::IncreAllocTransportResource(
1775 : const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
1776 : AlgResourceResponse& algResResponse)
1777 : {
1778 0 : HCCL_INFO("[HcclCommAicpu][IncreAllocTransportResource] Entry alloc transport group[%s]", identifier_.c_str());
1779 0 : std::set<u32> bsrTansportRank;
1780 0 : for (u32 levelIndex = 0; levelIndex < resRequest.opTransport.size(); levelIndex++) {
1781 0 : for (u32 ringIndex = 0; ringIndex < resRequest.opTransport[levelIndex].size(); ringIndex++) {
1782 0 : SingleSubCommTransport& reqSingleSubComm = resRequest.opTransport[levelIndex][ringIndex];
1783 0 : SingleSubCommTransport& respSingleSubComm = algResResponse.opTransportResponse[levelIndex][ringIndex];
1784 0 : for (u32 rankIndex = 0; rankIndex < reqSingleSubComm.transportRequests.size(); rankIndex++) {
1785 0 : TransportRequest& transportRequest = reqSingleSubComm.transportRequests[rankIndex];
1786 0 : CHK_PRT_RET(
1787 : rankIndex >= respSingleSubComm.links.size(),
1788 : HCCL_ERROR(
1789 : "[HcclCommAicpu][IncreAllocTransportResource] The remote rank_id[%u] is larger than "
1790 : "the existent respSingleSubComm map size[%u]",
1791 : rankIndex, respSingleSubComm.links.size()),
1792 : HCCL_E_PARA);
1793 0 : if (respSingleSubComm.links[rankIndex] != nullptr
1794 0 : && respSingleSubComm.links[rankIndex]->GetLinkType() != hccl::LinkType::LINK_RESERVED) {
1795 0 : HCCL_INFO(
1796 : "[IncreAlloc] The link to remote userRank[%u] has existed", transportRequest.remoteUserRank);
1797 0 : continue;
1798 : }
1799 0 : if (transportRequest.isValid) {
1800 0 : receivedAcks_[transportRequest.remoteUserRank] = reqSingleSubComm.supportDataReceivedAck;
1801 0 : respSingleSubComm.transportRequests[rankIndex] = transportRequest;
1802 0 : HCCL_DEBUG(
1803 : "[HcclCommAicpu][IncreAllocTransportResource] alloc transport, newTag[%s], rankId[%u], "
1804 : "input memory type[%u], output memory type[%u], ",
1805 : newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
1806 : transportRequest.outputMemType);
1807 0 : bool isSecondBuild = false;
1808 0 : if (transportRequest.isUsedRdma && opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV
1809 0 : && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
1810 : // 仅仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
1811 0 : isSecondBuild = true;
1812 : }
1813 : // A3 bsr远端是DirectNpu 链路的话则跳过
1814 0 : if ((opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
1815 0 : && (opParam.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
1816 0 : continue;
1817 : }
1818 0 : bsrTansportRank.insert(transportRequest.remoteUserRank);
1819 0 : CHK_RET(CreateLink(
1820 : newTag, transportRequest, commParam, respSingleSubComm.links[rankIndex],
1821 : transportRequest.notifyNum, false, isSecondBuild));
1822 : }
1823 : }
1824 : }
1825 : }
1826 0 : return HCCL_SUCCESS;
1827 0 : }
1828 :
1829 0 : HcclResult HcclCommAicpu::CreateLink(
1830 : const std::string& newTag, TransportRequest& transportRequest, const HcclOpResParam* commParam, LINK& link,
1831 : u32 notifyNum, bool isBackup, bool isSecond) // 主备的选择
1832 : {
1833 0 : if (transportRequest.isUsedRdma) {
1834 0 : CHK_RET(GetRdmaLinksByRankAndTag(
1835 : commParam, CommTransportsType::SPECIAL, transportRequest.remoteUserRank, newTag, link, isBackup, notifyNum,
1836 : isSecond));
1837 : } else {
1838 0 : CHK_RET(GetSdmaLinksByRankAndTag(
1839 : commParam, CommTransportsType::SPECIAL, transportRequest.remoteUserRank, newTag, link, isBackup, notifyNum,
1840 : transportRequest.linkType));
1841 : }
1842 :
1843 0 : HCCL_DEBUG("[%s] alloc special transport success!, tag[%s]", __func__, newTag.c_str());
1844 0 : return HCCL_SUCCESS;
1845 : }
1846 :
1847 0 : HcclResult HcclCommAicpu::AllocLocalNotifysResource(
1848 : const std::string& newTag, const HcclOpResParam* commParam, const u32 notifyNum,
1849 : std::vector<std::shared_ptr<LocalNotify>>& notifiesMain, std::vector<std::shared_ptr<LocalNotify>>& notifiesAux)
1850 : {
1851 0 : HCCL_INFO(
1852 : "[HcclCommAicpu][AllocLocalNotifysResource]requesting for [%u] notifys, tag[%s].", notifyNum, newTag.c_str());
1853 0 : if (localNotifies_.capacity() < notifyNum) {
1854 0 : HCCL_ERROR(
1855 : "[HcclCommAicpu][AllocLocalNotifysResource]request number exceed max notify numbers, alloc failed. Max "
1856 : "number is [%u],request num[%u], tag[%s]",
1857 : localNotifies_.capacity(), notifyNum, newTag.c_str());
1858 0 : return HCCL_E_PARA;
1859 : }
1860 :
1861 0 : if (localNotifies_.size() < notifyNum) {
1862 0 : if (InitLocalNotifyObj(commParam) != HCCL_SUCCESS || localNotifies_.size() < notifyNum) {
1863 0 : HCCL_ERROR(
1864 : "[HcclCommAicpu][AllocLocalNotifysResource] the need of notify is more than the available, group[%s], "
1865 : "need[%u], total[%u]",
1866 : newTag.c_str(), notifyNum, localNotifies_.size());
1867 0 : return HCCL_E_INTERNAL;
1868 : }
1869 : }
1870 :
1871 0 : u32 halfNotifyNum = notifyNum >> 1;
1872 0 : notifiesMain.resize(halfNotifyNum);
1873 0 : notifiesAux.resize(halfNotifyNum);
1874 0 : for (u32 i = 0; i < halfNotifyNum; i++) {
1875 0 : notifiesMain[i] = localNotifies_[i << 1];
1876 0 : notifiesAux[i] = localNotifies_[(i << 1) + 1];
1877 : }
1878 0 : HCCL_INFO(
1879 : "[HcclCommAicpu][AllocLocalNotifysResource]find enough notifys, numbers[%u], tag[%s].", notifyNum,
1880 : newTag.c_str());
1881 0 : return HCCL_SUCCESS;
1882 : }
1883 :
1884 0 : HcclResult HcclCommAicpu::AllocStreamsResource(
1885 : const std::string& newTag, const HcclOpResParam* commParam, const u32 streamNum, std::vector<Stream>& streams)
1886 : {
1887 0 : HCCL_INFO(
1888 : "[HcclCommAicpu][AllocStreamsResource]requesting for [%u] slave streams, newTag[%s], group[%s].", streamNum,
1889 : newTag.c_str(), identifier_.c_str());
1890 0 : if (streamNum == 0) {
1891 0 : return HCCL_SUCCESS;
1892 : }
1893 0 : if (slaveStreams_.capacity() < streamNum) {
1894 0 : HCCL_ERROR(
1895 : "[HcclCommAicpu][AllocStreamsResource]request number exceed max substream num, alloc failed. Max "
1896 : "number is [%u],request num[%u], tag[%s]",
1897 : slaveStreams_.capacity(), streamNum, newTag.c_str());
1898 0 : return HCCL_E_PARA;
1899 : }
1900 0 : if (slaveStreams_.size() < streamNum) {
1901 0 : if (InitSlaveStreamObjs(commParam) != HCCL_SUCCESS || slaveStreams_.size() < streamNum) {
1902 0 : HCCL_ERROR(
1903 : "[HcclCommAicpu][AllocStreamsResource] the need of streams is more than the "
1904 : "available, tag[%s], need[%u], total[%u]",
1905 : newTag.c_str(), streamNum, slaveStreams_.size());
1906 0 : return HCCL_E_INTERNAL;
1907 : }
1908 : }
1909 0 : streams = std::vector<Stream>(slaveStreams_.begin(), slaveStreams_.begin() + streamNum);
1910 0 : HCCL_INFO(
1911 : "[HcclCommAicpu][AllocStreamsResource]find enough slave streams [%u], tag[%s].", streamNum, newTag.c_str());
1912 0 : return HCCL_SUCCESS;
1913 : }
1914 :
1915 0 : HcclResult HcclCommAicpu::AllocScratchMemResource(
1916 : const std::string& newTag, const HcclOpResParam* commParam, const u64& scratchMemSize, DeviceMem& scratchMem,
1917 : bool reAllocFlag)
1918 : {
1919 0 : HCCL_INFO(
1920 : "[HcclCommAicpu][AllocScratchMemResource]requesting for [%llu] bytes scratch mem, tag[%s].", scratchMemSize,
1921 : newTag.c_str());
1922 0 : if (scratchMemSize != 0) {
1923 0 : if (tagScratchMem_.find(newTag) == tagScratchMem_.end()) {
1924 0 : HcclResult ret = InitLocalTagRes(commParam->localRes.nextTagRes);
1925 0 : CHK_PRT_RET(
1926 : ret != HCCL_SUCCESS,
1927 : HCCL_ERROR(
1928 : "[HcclCommAicpu][AllocScratchMemResource]InitLocalTagRes error group[%s]", identifier_.c_str()),
1929 : ret);
1930 : }
1931 :
1932 0 : if (tagScratchMem_.find(newTag) == tagScratchMem_.end()) {
1933 0 : HCCL_ERROR(
1934 : "[HcclCommAicpu][AllocScratchMemResource]alloc scratch memory failed."
1935 : "requesting for [%llu] bytes, tag[%s].",
1936 : scratchMemSize, newTag.c_str());
1937 0 : return HCCL_E_NOT_FOUND;
1938 : }
1939 :
1940 0 : if (reAllocFlag) {
1941 0 : HCCL_INFO(
1942 : "[HcclCommAicpu][AllocScratchMemResource]need to reAlloc mem [%llu] bytes scratch mem, tag[%s].",
1943 : scratchMemSize, newTag.c_str());
1944 0 : HcclResult ret = InitLocalTagRes(commParam->localRes.nextTagRes, reAllocFlag);
1945 0 : CHK_PRT_RET(
1946 : ret != HCCL_SUCCESS,
1947 : HCCL_ERROR(
1948 : "[HcclCommAicpu][AllocScratchMemResource]InitLocalTagRes error group[%s]", identifier_.c_str()),
1949 : ret);
1950 : }
1951 :
1952 : // 因为aicpu_communicator中会对scratchMem做对齐,所以tagScratchMem_中的大小会偏小(被对齐截断一部分)
1953 : // 但是两者的差值应该不能超过2个CCE_REDUCE_ALIGN_SIZE,否则应该是不对的
1954 0 : if (scratchMemSize - tagScratchMem_[newTag]->size() > (CCE_REDUCE_ALIGN_SIZE + CCE_REDUCE_ALIGN_SIZE)) {
1955 0 : HCCL_ERROR(
1956 : "[HcclCommAicpu][AllocScratchMemResource]alloc tag[%s] scratch memory failed."
1957 : "requesting [%llu] bytes actual [%llu] bytes",
1958 : newTag.c_str(), scratchMemSize, tagScratchMem_[newTag]->size());
1959 0 : return HCCL_E_PARA;
1960 : }
1961 0 : scratchMem = DeviceMem::create(tagScratchMem_[newTag]->ptr(), tagScratchMem_[newTag]->size());
1962 : }
1963 0 : HCCL_INFO(
1964 : "[HcclCommAicpu][AllocScratchMemResource]find enough [%llu] bytes scratch mem, tag[%s].", scratchMemSize,
1965 : newTag.c_str());
1966 0 : return HCCL_SUCCESS;
1967 : }
1968 :
1969 0 : HcclResult HcclCommAicpu::AllocAlgResource(
1970 : const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
1971 : AlgResourceResponse& algResResponse)
1972 : {
1973 0 : algResResponse.cclInputMem = cclInputBuffer_;
1974 0 : algResResponse.cclOutputMem = cclOutputBuffer_;
1975 0 : algResResponse.paramInputMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
1976 0 : algResResponse.paramOutputMem = DeviceMem::create(opParam.outputPtr, opParam.outputSize);
1977 :
1978 0 : PetersonLockGuard guard(hostDeviceLock_.get());
1979 0 : CHK_PRT_RET(
1980 : guard.IsLockFailed(), HCCL_ERROR("[HcclCommAicpu][AllocAlgResource] hostDeviceLock lock failed"),
1981 : HCCL_E_INTERNAL);
1982 :
1983 0 : CHK_RET(AllocScratchMemResource(newTag, commParam, resRequest.scratchMemSize, algResResponse.scratchMem));
1984 0 : CHK_RET(AllocStreamsResource(newTag, commParam, resRequest.streamNum, algResResponse.slaveStreams));
1985 0 : CHK_RET(AllocLocalNotifysResource(
1986 : newTag, commParam, resRequest.notifyNum, algResResponse.notifiesMain, algResResponse.notifiesAux));
1987 0 : CHK_RET(AllocTransportResource(newTag, opParam, commParam, resRequest, algResResponse));
1988 0 : HCCL_INFO("[HcclCommAicpu][AllocAlgResource] alloc resource success tag[%s].", newTag.c_str());
1989 0 : return HCCL_SUCCESS;
1990 0 : }
1991 :
1992 0 : HcclResult HcclCommAicpu::CalcResRequest(
1993 : const std::string& algName, const OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
1994 : AlgResourceRequest& resourceRequest)
1995 : {
1996 0 : if (executor.get() == nullptr) {
1997 0 : executor = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
1998 0 : CHK_PRT_RET(
1999 : executor.get() == nullptr,
2000 : HCCL_ERROR("[HcclCommAicpu][CalcResRequest]Fail to find executor for algName[%s]", algName.c_str()),
2001 : HCCL_E_PARA);
2002 0 : executor->SetAlgType(algType_);
2003 0 : executor->SetCCLInBuffer(cclbufferSize_);
2004 :
2005 0 : if (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
2006 0 : bool isSupportSDMAReduce = false;
2007 0 : if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
2008 : isSupportSDMAReduce
2009 0 : = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
2010 : } else {
2011 0 : isSupportSDMAReduce = IsSupportSDMAReduce(
2012 0 : cclInputBuffer_.ptr(), cclOutputBuffer_.ptr(), param.DataDes.dataType, param.reduceType);
2013 : }
2014 0 : executor->SetIsSupportSDMAReduce(isSupportSDMAReduce);
2015 : }
2016 : }
2017 0 : CHK_RET(CalSendRecvInfoFor910B(algName, param, executor));
2018 0 : return executor->CalcResRequest(param, resourceRequest);
2019 : }
2020 :
2021 0 : u32 HcclCommAicpu::CalculateOpExecIndex(const OpParam& opParam, u32 userRank)
2022 : {
2023 0 : u32 opIndex = 0;
2024 0 : s32 commIndex = 0;
2025 : // 用于重执行和taskException打印的算子计数,bsr/sendrecv/其他算子分别计数
2026 0 : if (opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) {
2027 0 : commIndex = -1; // batchSendRecv使用 key = -1
2028 0 : } else if (opParam.opType == HcclCMDType::HCCL_CMD_SEND) {
2029 0 : commIndex = opParam.dstRank;
2030 0 : } else if (opParam.opType == HcclCMDType::HCCL_CMD_RECEIVE) {
2031 0 : commIndex = opParam.srcRank;
2032 : } else {
2033 0 : commIndex = userRank;
2034 : }
2035 :
2036 0 : auto it = opExecIndexMap_.find(commIndex);
2037 0 : if (it != opExecIndexMap_.end()) {
2038 0 : opIndex = ++(it->second);
2039 : } else {
2040 0 : opExecIndexMap_.insert({commIndex, 1});
2041 0 : opIndex = 1;
2042 : }
2043 :
2044 0 : HCCL_DEBUG(
2045 : "%s tag:%s opType:%u commIndex:%d opIndex:%u", __func__, opParam.tag.c_str(), opParam.opType, commIndex,
2046 : opIndex);
2047 0 : return opIndex;
2048 : }
2049 :
2050 2 : HcclResult HcclCommAicpu::PrepareSymmetricMemory(const OpParam& param, OpCommTransport& opTransportResponse)
2051 : {
2052 2 : CHK_PRT_RET(
2053 : opTransportResponse.size() == 0,
2054 : HCCL_ERROR("[HcclCommAicpu][PrepareSymmetricMemory] opTransportResponse size is 0"), HCCL_E_PARA);
2055 :
2056 : const std::unordered_set<LinkType> supportedLinkTypes
2057 2 : = {LinkType::LINK_HCCS, LinkType::LINK_SIO, LinkType::LINK_HCCS_SW};
2058 2 : for (u32 levelIdx = 0; levelIdx < opTransportResponse.size(); levelIdx++) {
2059 2 : for (auto& singleSubCommTransport : opTransportResponse[levelIdx]) {
2060 1 : if (singleSubCommTransport.isZeroCopy == false) {
2061 1 : continue;
2062 : }
2063 0 : for (u64 i = 0; i < singleSubCommTransport.links.size(); ++i) {
2064 0 : LINK& link = singleSubCommTransport.links[i];
2065 0 : if (link == nullptr || !singleSubCommTransport.transportRequests[i].isValid
2066 0 : || supportedLinkTypes.count(link->GetLinkType()) == 0) {
2067 0 : continue; // 无效或者不支持的链路
2068 : }
2069 0 : u32 peerRank = link->GetRemoteRank();
2070 0 : void* remoteIn = nullptr;
2071 0 : CHK_RET(HcclSymWinGetPeerPointer(param.inputSymWindow, param.inputOffset, peerRank, &remoteIn));
2072 0 : void* remoteOut = nullptr;
2073 0 : CHK_RET(HcclSymWinGetPeerPointer(param.outputSymWindow, param.outputOffset, peerRank, &remoteOut));
2074 :
2075 0 : CHK_PRT_RET(
2076 : remoteIn == nullptr || remoteOut == nullptr,
2077 : HCCL_ERROR(
2078 : "[HcclCommAicpu][PrepareSymmetricMemory] remoteRank[%d] in[%p] out[%p] is invalid", peerRank,
2079 : remoteIn, remoteOut),
2080 : HCCL_E_INTERNAL);
2081 0 : HCCL_INFO(
2082 : "[HcclCommAicpu][PrepareSymmetricMemory] remoteRank[%d] in[%p] out[%p]", peerRank, remoteIn,
2083 : remoteOut);
2084 0 : CHK_RET(link->UpdateRemoteAddr(remoteIn, remoteOut));
2085 : }
2086 : }
2087 : }
2088 1 : return HCCL_SUCCESS;
2089 1 : }
2090 :
2091 1 : HcclResult HcclCommAicpu::ExecOp(
2092 : const std::string& newTag, const std::string& algName, OpParam& opParam, const HcclOpResParam* commParam)
2093 : {
2094 1 : std::unique_ptr<CollExecutorBase> executor;
2095 : hccl::AlgResourceResponse* algResResponse;
2096 1 : CHK_RET(GetAlgResponseRes(newTag, algName, opParam, commParam, executor, algResResponse));
2097 :
2098 1 : if (isZeroCopy_ || isSymmetricMemory_) {
2099 1 : if (isSymmetricMemory_) {
2100 1 : CHK_RET(PrepareSymmetricMemory(opParam, algResResponse->opTransportResponse));
2101 : } else {
2102 0 : HcclResult ret = PrepareZeroCopyExchanger(newTag, opParam, algResResponse);
2103 0 : CHK_PRT_RET(
2104 : ret != HCCL_SUCCESS,
2105 : HCCL_ERROR(
2106 : "[HcclCommAicpu][ExecOp] newTag[%s], localRankId[%u]", newTag.c_str(), commParam->localUsrRankId),
2107 : ret);
2108 : }
2109 :
2110 : // 零拷贝场景scratchMem的大小会与用户的输入大小不同,会导致后续算法展开模块计算出错
2111 : // 但是该场景下不会直接访问scratchMem,因此直接使用输入作为scratchMem,使得后续计算正确
2112 0 : if (opParam.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
2113 0 : algResResponse->scratchMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
2114 0 : HCCL_INFO(
2115 : "[HcclCommAicpu][ExecOp] ZeroCopy reduce-scatter use userInput as scratchMem, inputPtr[%p] "
2116 : "intputSize[%lu]",
2117 : opParam.inputPtr, opParam.inputSize);
2118 : }
2119 :
2120 0 : algResResponse->paramInputMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
2121 0 : algResResponse->paramOutputMem = DeviceMem::create(opParam.outputPtr, opParam.outputSize);
2122 0 : HCCL_INFO(
2123 : "[HcclCommAicpu][ExecOp] zero copy modify paramInput paramOutput to algResResp inputPtr[%p] inputSize[%lu] "
2124 : "outputPtr[%p] outputSize[%lu]",
2125 : algResResponse->paramInputMem.ptr(), algResResponse->paramInputMem.size(),
2126 : algResResponse->paramOutputMem.ptr(), algResResponse->paramOutputMem.size());
2127 : }
2128 :
2129 0 : hcclOpExecIndex_ = CalculateOpExecIndex(opParam, localUserRank_);
2130 0 : HcclResult ret = Orchestrate(newTag, algName, opParam, executor, *algResResponse, commParam);
2131 0 : if (ret != HCCL_SUCCESS) {
2132 0 : HCCL_ERROR(
2133 : "[HcclCommAicpu][ExecOp] executor op fail, tag[%s], algName[%s], identifier[%s]", newTag.c_str(),
2134 : algName.c_str(), identifier_.c_str());
2135 0 : CHK_PRT_CONT(
2136 : retryEnable_, HCCL_ERROR("[HcclCommAicpu][ExecOp] executor op fail, some error logs may be recorded in the "
2137 : "log/run/device directory, search keyword [ErrToWarn]"));
2138 0 : if (printTaskExceptionForErr_) {
2139 0 : PrintTaskExceptionAllComm();
2140 0 : PrintAicpuCommExecStatus();
2141 0 : printTaskExceptionForErr_ = false;
2142 : }
2143 0 : return ret;
2144 : }
2145 :
2146 0 : HCCL_ENTRY_INFO(
2147 : commParam->opEntry,
2148 : "[HcclCommAicpu][ExecOp] executor op success tag[%s], newTag[%s], algName[%s], identifier[%s].",
2149 : opParam.tag.c_str(), newTag.c_str(), algName.c_str(), identifier_.c_str());
2150 0 : return HCCL_SUCCESS;
2151 1 : }
2152 :
2153 0 : HcclResult HcclCommAicpu::RefreshAlgResponseTransportRes(
2154 : const std::string& newTag, AlgResourceResponse& algResResponse, std::map<u32, bool>& remoteRankPortMap,
2155 : bool isChangeLinkFlag, const HcclOpResParam* commParam, const OpParam& param)
2156 : {
2157 0 : CHK_PTR_NULL(commParam);
2158 0 : auto iter = resMap_.find(newTag);
2159 0 : CHK_PRT_RET(
2160 : iter == resMap_.end(), HCCL_ERROR("[%s]Fail to find algResResponse for tag[%s]", __func__, newTag.c_str()),
2161 : HCCL_E_PARA);
2162 :
2163 0 : PetersonLockGuard guard(hostDeviceLock_.get());
2164 0 : CHK_PRT_RET(guard.IsLockFailed(), HCCL_ERROR("[%s] hostDeviceLock lock failed", __func__), HCCL_E_INTERNAL);
2165 0 : if (!isChangeLinkFlag) {
2166 0 : CleanRoceResource(newTag, algResResponse, remoteRankPortMap, param);
2167 0 : CHK_RET(ReAllocTransportResource(newTag, algResResponse, remoteRankPortMap, commParam, param));
2168 0 : HCCL_RUN_INFO("[%s] ChangeLinkFlag[%d], current tag[%s].", __func__, isChangeLinkFlag, newTag.c_str());
2169 : } else {
2170 : // 提前清理所有tag的链路,避免冲突
2171 0 : for (auto& resMapIt : resMap_) {
2172 0 : HCCL_RUN_INFO("[%s] clean roce resource of tag[%s].", __func__, resMapIt.first.c_str());
2173 0 : CleanRoceResource(resMapIt.first, resMapIt.second, remoteRankPortMap, param);
2174 : }
2175 : // 对resMap中所有tag的transport link根据主备进行刷新
2176 0 : for (auto& resMapIt : resMap_) {
2177 0 : HCCL_RUN_INFO("[%s] refresh algResResponse of tag[%s].", __func__, resMapIt.first.c_str());
2178 0 : CHK_RET(ReAllocTransportResource(resMapIt.first, resMapIt.second, remoteRankPortMap, commParam, param));
2179 0 : if (resMapIt.first == newTag) {
2180 0 : HCCL_RUN_INFO("[%s] current tag[%s].", __func__, newTag.c_str());
2181 0 : algResResponse = resMapIt.second;
2182 : }
2183 : }
2184 : }
2185 :
2186 0 : HCCL_RUN_INFO("[%s] alloc resource success tag[%s].", __func__, newTag.c_str());
2187 0 : return HCCL_SUCCESS;
2188 0 : }
2189 :
2190 0 : HcclResult HcclCommAicpu::CalSendRecvInfoForAlltoall(const OpParam& param)
2191 : {
2192 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
2193 : std::vector<u64> sendCountMatrix(
2194 0 : topoInfo_.userRankSize * topoInfo_.userRankSize, param.All2AllDataDes.sendCount);
2195 0 : CHK_RET(GetAlltoAllvcSendRecvInfo(
2196 : static_cast<void*>(sendCountMatrix.data()), param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
2197 0 : } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
2198 0 : CHK_PTR_NULL(sendRecvInfoPtr_);
2199 0 : CHK_RET(
2200 : GetAlltoAllvSendRecvInfo(sendRecvInfoPtr_, param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
2201 : } else {
2202 0 : CHK_RET(GetAlltoAllvcSendRecvInfo(
2203 : param.All2AllDataDes.sendCountMatrix, param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
2204 : }
2205 0 : return HCCL_SUCCESS;
2206 : }
2207 :
2208 0 : HcclResult HcclCommAicpu::CalSendRecvInfoFor910B(
2209 : const std::string& algName, const OpParam& param, std::unique_ptr<CollExecutorBase>& executor)
2210 : {
2211 : // A2 AICPU才有机会走入RunAlltoAllVStaged
2212 0 : if (algName == "RunAlltoAllVStaged" || algName == "RunAlltoAllVFullMesh") {
2213 0 : CHK_PRT_RET(
2214 : executor.get() == nullptr,
2215 : HCCL_ERROR("[HcclCommAicpu][%s]Fail to find executor for algName[%s]", __func__, algName.c_str()),
2216 : HCCL_E_PARA);
2217 0 : CHK_RET(CalSendRecvInfoForAlltoall(param));
2218 0 : CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor*>(executor.get());
2219 0 : CHK_PTR_NULL(alltoAllExecutor);
2220 0 : CHK_RET(alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclbufferSize_));
2221 0 : HCCL_DEBUG("[HcclCommAicpu][%s] running algName[%s], prepare SendRecvInfo.", __func__, algName.c_str());
2222 0 : return HCCL_SUCCESS;
2223 : }
2224 0 : return HCCL_SUCCESS;
2225 : }
2226 :
2227 0 : HcclResult HcclCommAicpu::GetAlgResponseRes(
2228 : const std::string& newTag, const std::string& algName, const OpParam& opParam, const HcclOpResParam* commParam,
2229 : std::unique_ptr<CollExecutorBase>& executor, AlgResourceResponse*& algResResponse)
2230 : {
2231 0 : HCCL_INFO("[%s] algName[%s]", __func__, algName.c_str());
2232 0 : CHK_PTR_NULL(commParam);
2233 : // 刷新CCLBuffer
2234 0 : CHK_RET(InitCclbuffer(commParam));
2235 0 : auto iter = resMap_.find(newTag);
2236 0 : if (iter == resMap_.end()) {
2237 0 : std::lock_guard<std::mutex> lock(preemptMutexForResMap_);
2238 0 : iter = resMap_.find(newTag);
2239 0 : if (iter == resMap_.end()) {
2240 0 : HCCL_RUN_INFO("[%s] Alloc resource for alg[%s], tag[%s]", __func__, algName.c_str(), newTag.c_str());
2241 0 : AlgResourceRequest resRequest;
2242 0 : CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
2243 0 : CHK_RET(AllocAlgResource(newTag, opParam, commParam, resRequest, resMap_[newTag]));
2244 0 : iter = resMap_.find(newTag);
2245 0 : } else {
2246 0 : HCCL_INFO("[%s] Repeatedly inited for alg [%s] is not allowed.", __func__, algName.c_str());
2247 : }
2248 0 : } else if (algName == "BatchSendRecv" || algName == "BatchSendRecvRetry" || algName == "BatchSendRecvGroup") {
2249 : // 如果是非aclgraph模式,而且不需要增量建链,则跳过CalcResRequest这个计算,节省时间。在非aclgraph模式下,跳过是安全的。
2250 0 : bool canSkipCalcResRequest = !opParam.isCapture && !opParam.needIncreLink;
2251 0 : if (!canSkipCalcResRequest) { // 如果不能跳过计算,则走一遍计算的流程,否则就跳过以下计算
2252 0 : AlgResourceRequest resRequest;
2253 0 : HCCL_INFO("[%s]IncreAlloc resource for alg[%s], tag[%s]", __func__, algName.c_str(), newTag.c_str());
2254 0 : CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
2255 0 : CHK_RET(IncreAllocTransportResource(newTag, opParam, commParam, resRequest, resMap_[newTag]));
2256 0 : }
2257 0 : } else if (algName == "RunAlltoAllVStaged" || algName == "RunAlltoAllVFullMesh") {
2258 0 : AlgResourceRequest resRequest;
2259 0 : CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
2260 0 : HCCL_INFO(
2261 : "[%s] check if need refresh resource for alg[%s], tag[%s], old[%lu], new[%lu]", __func__, algName.c_str(),
2262 : newTag.c_str(), resMap_[newTag].scratchMem.size(), resRequest.scratchMemSize);
2263 0 : bool reAllocFlag = !(resMap_[newTag].scratchMem.size() == resRequest.scratchMemSize);
2264 0 : if (reAllocFlag) {
2265 0 : PetersonLockGuard guard(hostDeviceLock_.get());
2266 0 : CHK_PRT_RET(
2267 : guard.IsLockFailed(), HCCL_ERROR("[HcclCommAicpu][AllocAlgResource] hostDeviceLock lock failed"),
2268 : HCCL_E_INTERNAL);
2269 0 : CHK_RET(AllocScratchMemResource(
2270 : newTag, commParam, resRequest.scratchMemSize, resMap_[newTag].scratchMem, true));
2271 0 : HCCL_INFO(
2272 : "[%s] refresh resource success for alg[%s], tag[%s], scratchMemSize[%lu], ptr[%p]", __func__,
2273 : algName.c_str(), newTag.c_str(), resRequest.scratchMemSize, resMap_[newTag].scratchMem.ptr());
2274 0 : }
2275 0 : }
2276 0 : CHK_PRT_RET(
2277 : iter == resMap_.end(), HCCL_ERROR("[%s]Fail to find algResResponse for tag[%s]", __func__, newTag.c_str()),
2278 : HCCL_E_PARA);
2279 0 : algResResponse = &iter->second;
2280 0 : HCCL_INFO("[HcclCommAicpu][GetAlgResponseRes] success!");
2281 0 : return HCCL_SUCCESS;
2282 : }
2283 :
2284 0 : HcclResult HcclCommAicpu::GetAlltoAllVCTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
2285 : {
2286 0 : for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
2287 0 : sendCount += *(
2288 0 : static_cast<const u64*>(param.All2AllDataDes.sendCountMatrix) + topoInfo_.userRank * topoInfo_.userRankSize
2289 0 : + i);
2290 0 : recvCount += *(
2291 0 : static_cast<const u64*>(param.All2AllDataDes.sendCountMatrix) + topoInfo_.userRank
2292 0 : + topoInfo_.userRankSize * i);
2293 : }
2294 0 : return HCCL_SUCCESS;
2295 : }
2296 :
2297 0 : HcclResult HcclCommAicpu::GetAlltoAllTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
2298 : {
2299 0 : sendCount = param.All2AllDataDes.sendCount * topoInfo_.userRankSize;
2300 0 : recvCount = param.All2AllDataDes.sendCount * topoInfo_.userRankSize;
2301 0 : return HCCL_SUCCESS;
2302 : }
2303 :
2304 0 : HcclResult HcclCommAicpu::GetAlltoAllVTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
2305 : {
2306 0 : for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
2307 0 : u64 curSendCount = *(static_cast<const u64*>(param.All2AllDataDes.sendCounts) + i)
2308 0 : + *(static_cast<const u64*>(param.All2AllDataDes.sdispls) + i);
2309 0 : sendCount = std::max(sendCount, curSendCount);
2310 0 : u64 curRecvCount = *(static_cast<const u64*>(param.All2AllDataDes.recvCounts) + i)
2311 0 : + *(static_cast<const u64*>(param.All2AllDataDes.rdispls) + i);
2312 0 : recvCount = std::max(recvCount, curRecvCount);
2313 : }
2314 0 : return HCCL_SUCCESS;
2315 : }
2316 :
2317 0 : HcclResult HcclCommAicpu::SetAlltoAllInputAndOutPutMem(OpParam& param, AlgResourceResponse& algResource)
2318 : {
2319 0 : u32 sendTypeSize = 0, recvTypeSize = 0;
2320 0 : CHK_RET(SalGetDataTypeSize(param.All2AllDataDes.sendType, sendTypeSize));
2321 0 : CHK_RET(SalGetDataTypeSize(param.All2AllDataDes.recvType, recvTypeSize));
2322 0 : u64 sendCount = 0;
2323 0 : u64 recvCount = 0;
2324 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
2325 0 : CHK_RET(GetAlltoAllTotalCount(param, sendCount, recvCount));
2326 0 : } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
2327 0 : CHK_RET(GetAlltoAllVTotalCount(param, sendCount, recvCount));
2328 0 : } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC) {
2329 0 : CHK_RET(GetAlltoAllVCTotalCount(param, sendCount, recvCount));
2330 : }
2331 0 : u64 inputSize = sendCount * sendTypeSize;
2332 0 : u64 outputSize = recvCount * recvTypeSize;
2333 0 : algResource.paramInputMem = inputSize == 0 ? tinySendRecvMem_ : DeviceMem::create(param.inputPtr, inputSize);
2334 0 : algResource.paramOutputMem = outputSize == 0 ? tinySendRecvMem_ : DeviceMem::create(param.outputPtr, outputSize);
2335 0 : HCCL_DEBUG(
2336 : "[HcclCommAicpu][SetAlltoAllInputAndOutPutMem] Set memory for AllToAll, inputSize[%llu], inputPtr[%p],"
2337 : "outputPtr[%p]!",
2338 : inputSize, param.inputPtr, param.outputPtr);
2339 0 : return HCCL_SUCCESS;
2340 : }
2341 :
2342 0 : HcclResult HcclCommAicpu::CombineReportOpInfo(OpParam& param, bool isRetry, bool isRelay)
2343 : {
2344 0 : MsprofAicpuHCCLOPInfo hcclOpInfo{};
2345 0 : hcclOpInfo.relay = (isRelay) ? 1 : 0;
2346 0 : hcclOpInfo.retry = (isRetry) ? 1 : 0;
2347 0 : hcclOpInfo.dataType = param.DataDes.dataType;
2348 0 : hcclOpInfo.count = param.DataDes.count;
2349 0 : hcclOpInfo.groupName = groupHashId_;
2350 0 : hcclOpInfo.ranksize = topoInfo_.userRankSize;
2351 0 : std::string algTypeStr = TransferAlgType(algType_);
2352 0 : CHK_RET(dfx::ProfilingManager::ReportHcclOpInfo(hcclOpInfo, algTypeStr));
2353 0 : return HCCL_SUCCESS;
2354 0 : }
2355 :
2356 0 : HcclResult HcclCommAicpu::UpdateProfReportStartSqeIdx()
2357 : {
2358 0 : if (dfx::ProfilingManager::IsL1fromOffToOn()) {
2359 0 : std::vector<Stream> streams;
2360 0 : CHK_RET(GetStreamAll(streams));
2361 0 : for (auto& tmpStream : streams) {
2362 0 : HcclSqeContext* sqeContext = tmpStream.GetSqeContextPtr();
2363 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
2364 0 : CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(tmpStream.id(), sqeContextBuffer->tailSqeIdx));
2365 : }
2366 0 : }
2367 0 : return HCCL_SUCCESS;
2368 : }
2369 :
2370 0 : HcclResult HcclCommAicpu::Orchestrate(
2371 : const std::string& newTag, const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
2372 : AlgResourceResponse& algResource, const HcclOpResParam* commParam)
2373 : {
2374 0 : CHK_PTR_NULL(commParam);
2375 : // 算子下发信息记录在共享内存区
2376 0 : UpdateOpRingBufferIdx();
2377 0 : CHK_RET(aicpuShareData_.RecordOpInfo(
2378 : newTag, param, (isDeviceMode_ ? mc2OpIndex_ : hcclOpExecIndex_), localUserRank_, isCustom_));
2379 0 : CHK_RET(UpdateProfReportStartSqeIdx());
2380 :
2381 : // 每个算子都刷新一下profiling开关, 支持profiling从中间迭代采集
2382 0 : bool profL0Open = dfx::ProfilingManager::IsProfL0On();
2383 0 : bool profL1Open = dfx::ProfilingManager::IsProfL1On();
2384 0 : HCCL_DEBUG("profL0Open:%d, profL1Open:%d", profL0Open, profL1Open);
2385 :
2386 0 : LogControl logControl(false, false); // 重执行ERROR日志保底控制,析构时重置日志设置
2387 0 : HCCL_ENTRY_INFO(
2388 : commParam->opEntry, "[HcclCommAicpu][Orchestrate]start tag[%s] newTag[%s] algName[%s] identifier[%s]",
2389 : param.tag.c_str(), newTag.c_str(), algName.c_str(), identifier_.c_str());
2390 0 : HCCL_INFO(
2391 : "opRetryHandler.isInplacePreSync[%d] opRetryHandler.isPostSync[%d]",
2392 : algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
2393 0 : if (executor.get() == nullptr) {
2394 0 : executor = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
2395 0 : CHK_PRT_RET(
2396 : executor.get() == nullptr,
2397 : HCCL_ERROR(
2398 : "[HcclCommAicpu][Orchestrate]Fail to find executor "
2399 : "for algName[%s]",
2400 : algName.c_str()),
2401 : HCCL_E_PARA);
2402 0 : executor->SetAlgType(algType_);
2403 0 : executor->SetCCLInBuffer(cclbufferSize_);
2404 :
2405 0 : if (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
2406 0 : bool isSupportSDMAReduce = IsSupportSDMAReduce(
2407 0 : cclInputBuffer_.ptr(), cclOutputBuffer_.ptr(), param.DataDes.dataType, param.reduceType);
2408 0 : executor->SetIsSupportSDMAReduce(isSupportSDMAReduce);
2409 : }
2410 : }
2411 0 : if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV
2412 0 : || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC) {
2413 0 : CHK_RET(CalSendRecvInfoFor910B(algName, param, executor));
2414 0 : CHK_RET(SetAlltoAllInputAndOutPutMem(param, algResource));
2415 0 : if (algName == "RunAlltoAllVTwoLevelPipeline") {
2416 0 : CHK_RET(CalSendRecvInfoForAlltoall(param));
2417 0 : HCCL_DEBUG("[HcclCommAicpu][Orchestrate] running RunAlltoAllVTwoLevelPipeline, prepare SendRecvInfo.");
2418 0 : CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor*>(executor.get());
2419 0 : CHK_PTR_NULL(alltoAllExecutor);
2420 0 : CHK_RET(alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclbufferSize_));
2421 : }
2422 : }
2423 0 : auto waitStopExecCmdTimeoutMs = HcclGetWaitStopExecCmdTimeout();
2424 0 : auto waitStopExecCmdTimeout = std::chrono::milliseconds(waitStopExecCmdTimeoutMs);
2425 :
2426 0 : auto opStartTime = std::chrono::steady_clock::now(); // 记录重执行算子耗时
2427 0 : auto startTime = std::chrono::steady_clock::now();
2428 :
2429 0 : KfcError errorCode = KfcError::kNone;
2430 0 : uint32_t retryCnt = 0;
2431 0 : bool retryProcessing = false;
2432 0 : KfcCommand lastCmd = KfcCommand::kNone;
2433 0 : uint32_t beginSqePos = INVALID_UINT;
2434 0 : uint32_t endSqePos = INVALID_UINT;
2435 0 : HcclOpExecFSM state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT;
2436 0 : HcclResult ret = HCCL_SUCCESS;
2437 0 : dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneStart;
2438 0 : AicpuComContext* ctx = AicpuGetComContext();
2439 0 : AicpuHcclProcess::CallMC2MaintenanceThread(ctx);
2440 0 : u32 loopCnt = 0;
2441 0 : u32 loopNum = 1;
2442 0 : commParam_ = commParam;
2443 0 : CHK_RET(InitExecLoop(param, executor, loopNum));
2444 :
2445 : while (true) {
2446 0 : switch (state) {
2447 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT:
2448 0 : HCCL_INFO("hccl aicpu execute loop %u", loopCnt);
2449 0 : ret = HcclOpExecFsmInitProcess(newTag, param, algResource, state, errorCode);
2450 0 : break;
2451 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_LAUNCH:
2452 0 : ret = HcclOpExecFsmLaunchProcess(
2453 : algName, param, executor, algResource, state, errorCode, beginSqePos, endSqePos, retryCnt);
2454 0 : if (ret == HCCL_E_SUSPENDING && isDeviceMode_ && retryEnable_) {
2455 0 : return HCCL_E_SUSPENDING;
2456 : }
2457 0 : break;
2458 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END:
2459 0 : ret = HcclOpExecFsmWaitEndProcess(
2460 0 : param, algResource, state, errorCode, retryCnt, param.tag, beginSqePos);
2461 0 : if (state == HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING) {
2462 0 : startTime = std::chrono::steady_clock::now();
2463 : }
2464 0 : break;
2465 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING:
2466 0 : retryProcessing = true;
2467 0 : if ((std::chrono::steady_clock::now() - startTime) >= waitStopExecCmdTimeout) {
2468 0 : HCCL_ERROR("[OpRetry][AICPU]hccl aicpu wait stop exec timeout[%u ms].", waitStopExecCmdTimeoutMs);
2469 0 : errorCode = KfcError::kTimeout;
2470 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2471 : } else {
2472 0 : ret = HcclOpExecFsmStoppingProcess(param, state, errorCode, retryCnt);
2473 : }
2474 0 : break;
2475 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPED:
2476 0 : ret = HcclOpExecFsmStoppedProcess(state, errorCode, retryCnt, algName, param, beginSqePos, endSqePos);
2477 0 : if (state == HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY) {
2478 0 : startTime = std::chrono::steady_clock::now();
2479 : }
2480 0 : break;
2481 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_CHANGE_LINK:
2482 0 : ret = HcclOpExecChangeLinkProcess(newTag, state, errorCode, retryCnt, algResource, commParam, param);
2483 0 : HCCL_DEBUG(
2484 : "[OpRetry][AICPU]retry change link finish, retryCnt:%u, tag:%s, state:%d", retryCnt,
2485 : param.tag.c_str(), state);
2486 0 : break;
2487 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY: {
2488 0 : auto waitRetryCmdTimeoutMs = HcclGetWaitRetryCmdTimeout(retryCnt);
2489 0 : auto waitRetryCmdTimeout = std::chrono::milliseconds(waitRetryCmdTimeoutMs);
2490 0 : if ((std::chrono::steady_clock::now() - startTime) >= waitRetryCmdTimeout) {
2491 0 : HCCL_ERROR("[OpRetry][AICPU]hccl aicpu wait retry timeout[%u ms].", waitRetryCmdTimeoutMs);
2492 0 : errorCode = KfcError::kTimeout;
2493 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2494 : } else {
2495 0 : ret = HcclOpExecFsmWaitRetryProcess(param, state, errorCode, lastCmd);
2496 : }
2497 0 : } break;
2498 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_RETRY:
2499 : // 重执行前清理当前算子展开的SQE缓存 (if any), 防止命中非完整的cache
2500 0 : CHK_RET(aicpuCacheManager_.ClearOpUnfoldCacheEntry(
2501 : algName, param, algResource, isDeviceMode_, topoInfo_, topoMatcher_, algOpContext_,
2502 : GetWorkflowMode()));
2503 0 : ret = HcclOpExecFsmRetryProcess(
2504 : algName, param, executor, algResource, state, errorCode, retryCnt, beginSqePos, endSqePos);
2505 0 : break;
2506 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_END:
2507 0 : loopCnt++;
2508 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2509 0 : param.BatchSendRecvDataDes.curIterNum = loopCnt;
2510 0 : ResetBSRRetryCnt();
2511 : }
2512 0 : if (loopCnt < loopNum) {
2513 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT;
2514 0 : break;
2515 : }
2516 0 : if (retryCnt > 0) {
2517 0 : RecordReportStatus(dfx::ReportStatus::kRetrySuccess);
2518 0 : retryProcessing = false;
2519 0 : auto opEndTime = std::chrono::steady_clock::now();
2520 0 : auto duration = std::chrono::duration_cast<std::chrono::seconds>(opEndTime - opStartTime).count();
2521 0 : HCCL_RUN_INFO(
2522 : "[OpRetry][AICPU]retry exec success, retryCnt [%u], tag [%s], take time [%ld]s", retryCnt,
2523 : param.tag.c_str(), duration);
2524 : }
2525 0 : CHK_RET(CombineReportOpInfo(param, (retryCnt > 0), false));
2526 0 : return HcclOpExecFsmEndProcess(retryCnt);
2527 0 : case HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH:
2528 0 : HCCL_DEBUG("[NsRecovery][AICPU] stop the kernel");
2529 : // 停止前清理当前算子展开的SQE缓存 (if any), 防止host侧重新展开该算子并命中非完整的cache (例如step快恢)
2530 0 : CHK_RET(aicpuCacheManager_.ClearOpUnfoldCacheEntry(
2531 : algName, param, algResource, isDeviceMode_, topoInfo_, topoMatcher_, algOpContext_,
2532 : GetWorkflowMode()));
2533 0 : if (!needsResponseStopLaunch_) {
2534 0 : return HCCL_E_SUSPENDING;
2535 : } else {
2536 0 : HCCL_RUN_INFO("[NsRecovery][AICPU] stop the kernel for stop cmd");
2537 0 : needsResponseStopLaunch_ = false;
2538 0 : SetCommRecoveryFlag(true);
2539 0 : if (UpdateOpExecStatus(state, KfcStatus::kStoplaunch, errorCode, 0) == HCCL_SUCCESS) {
2540 0 : return HCCL_E_SUSPENDING;
2541 : } else {
2542 0 : break;
2543 : }
2544 : }
2545 0 : case HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR:
2546 : default: {
2547 0 : if (retryProcessing) {
2548 0 : RecordReportStatus(dfx::ReportStatus::kRetryFail);
2549 0 : retryProcessing = false;
2550 : }
2551 0 : UpdateOpExecStatus(state, excuteOpId_, KfcStatus::kRetryError, errorCode, retryCnt);
2552 0 : dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneFinished;
2553 0 : if (!isDeviceMode_) {
2554 0 : isOpLaunch = false;
2555 : }
2556 0 : HCCL_INFO("hccl aicpu set kfcStatus[%d]", dfxExtendInfo_.kfcStatus);
2557 0 : if (errorCode == KfcError::kExecConstraint) {
2558 0 : return HCCL_E_OPRETRY_FAIL;
2559 : }
2560 0 : return (ret == HCCL_SUCCESS) ? HCCL_E_INTERNAL : ret;
2561 : }
2562 : }
2563 0 : }
2564 : return ret;
2565 0 : }
2566 :
2567 1 : HcclResult HcclCommAicpu::InitBsrSendRecvOpIdAndExcuteOpId(
2568 : OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode)
2569 : {
2570 1 : auto hcclRet = InitBatchSendRecvOpId(param, algResource);
2571 1 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2572 : hcclRet, HCCL_ERROR("InitBatchSendRecvOpId failed, ret:%u", hcclRet), KfcError::kInner,
2573 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2574 1 : param.BatchSendRecvDataDes.curMode = BatchSendRecvCurMode::SEND_RECV;
2575 1 : if (param.BatchSendRecvDataDes.curIterNum == 0) {
2576 1 : bsrSendStream_ = algResource.slaveStreams[BSR_RETRY_SEND_STREAM_INDEX];
2577 1 : bsrRecvStream_ = algResource.slaveStreams[BSR_RETRY_RECV_STREAM_INDEX];
2578 : }
2579 1 : HCCL_INFO(
2580 : "BSR: iter %u, tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, excuteOpId_.tag, excuteOpId_.index);
2581 1 : HCCL_INFO(
2582 : "BSR: iter %u, send op Tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrSendOpId_.tag,
2583 : bsrSendOpId_.index);
2584 1 : HCCL_INFO(
2585 : "BSR: iter %u, recv op Tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrRecvOpId_.tag,
2586 : bsrRecvOpId_.index);
2587 1 : excuteOpId_.bsrInfo[HCCL_SEND].index = bsrSendOpId_.index;
2588 1 : excuteOpId_.bsrInfo[HCCL_RECV].index = bsrRecvOpId_.index;
2589 1 : excuteOpId_.bsrInfo[HCCL_SEND].tpQpn = bsrSendOpId_.bsrInfo[HCCL_SEND].tpQpn;
2590 1 : excuteOpId_.bsrInfo[HCCL_RECV].tpQpn = bsrRecvOpId_.bsrInfo[HCCL_RECV].tpQpn;
2591 1 : excuteOpId_.bsrInfo[HCCL_SEND].streamId = bsrSendOpId_.streamId;
2592 1 : excuteOpId_.bsrInfo[HCCL_RECV].streamId = bsrRecvOpId_.streamId;
2593 1 : excuteOpId_.bsrInfo[HCCL_SEND].srcRank = bsrSendOpId_.srcRank;
2594 1 : excuteOpId_.bsrInfo[HCCL_SEND].detRank = bsrSendOpId_.detRank;
2595 1 : excuteOpId_.bsrInfo[HCCL_RECV].srcRank = bsrRecvOpId_.srcRank;
2596 1 : excuteOpId_.bsrInfo[HCCL_RECV].detRank = bsrRecvOpId_.detRank;
2597 1 : CHK_SAFETY_FUNC_RET(memcpy_s(
2598 : excuteOpId_.bsrInfo[HCCL_SEND].bsrTag, sizeof(excuteOpId_.bsrInfo[HCCL_SEND].bsrTag), bsrSendOpId_.tag,
2599 : sizeof(bsrSendOpId_.tag)));
2600 1 : CHK_SAFETY_FUNC_RET(memcpy_s(
2601 : excuteOpId_.bsrInfo[HCCL_RECV].bsrTag, sizeof(excuteOpId_.bsrInfo[HCCL_RECV].bsrTag), bsrRecvOpId_.tag,
2602 : sizeof(bsrRecvOpId_.tag)));
2603 1 : return HCCL_SUCCESS;
2604 : }
2605 :
2606 1 : HcclResult HcclCommAicpu::HcclOpExecFsmInitProcess(
2607 : const std::string& newTag, OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState,
2608 : KfcError& errorCode)
2609 : {
2610 1 : excuteOpId_.index = isDeviceMode_ ? (++mc2OpIndex_) : hcclOpExecIndex_;
2611 1 : CHK_SAFETY_FUNC_RET(memset_s(excuteOpId_.tag, sizeof(excuteOpId_.tag), 0, sizeof(excuteOpId_.tag)));
2612 1 : CHK_SAFETY_FUNC_RET(memcpy_s(excuteOpId_.tag, sizeof(excuteOpId_.tag), param.tag.c_str(), param.tag.size()));
2613 1 : CHK_SAFETY_FUNC_RET(memset_s(excuteOpId_.newTag, sizeof(excuteOpId_.newTag), 0, sizeof(excuteOpId_.newTag)));
2614 1 : CHK_SAFETY_FUNC_RET(memcpy_s(excuteOpId_.newTag, sizeof(excuteOpId_.newTag), newTag.c_str(), newTag.size()));
2615 1 : excuteOpId_.isSendRecv = false;
2616 1 : excuteOpId_.streamId = ~0u;
2617 1 : excuteOpId_.opType = param.opType;
2618 1 : excuteOpId_.isBsrTaskStart = false;
2619 1 : if (param.opType == HcclCMDType::HCCL_CMD_SEND || param.opType == HcclCMDType::HCCL_CMD_RECEIVE) {
2620 0 : InitSendRecvOpId(param, excuteOpId_);
2621 1 : } else if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2622 1 : CHK_RET(InitBsrSendRecvOpIdAndExcuteOpId(param, algResource, fsmState, errorCode));
2623 : }
2624 1 : if (GetNsStopLaunchStatus()) {
2625 0 : HCCL_WARNING("the op should not be launched in the suspending status");
2626 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
2627 0 : return HCCL_SUCCESS;
2628 : }
2629 1 : auto ret = aicpuHdc_.InitOpExecStatus(kfcStatusTransferD2H_, excuteOpId_);
2630 1 : isOpLaunch = true;
2631 1 : HCCL_INFO("%s tag:%s, isDeviceMode:%d, index:%u", __func__, excuteOpId_.tag, isDeviceMode_, excuteOpId_.index);
2632 1 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2633 : ret, HCCL_ERROR("InitOpExecStatus failed, ret:%u", ret), KfcError::kInner,
2634 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2635 1 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_LAUNCH;
2636 1 : return ret;
2637 : }
2638 :
2639 0 : bool HcclCommAicpu::HcclOpCheckSupportRetry(HcclCMDType opType)
2640 : {
2641 : const std::set<HcclCMDType> HcclSupportRetryOpSet
2642 : = {HcclCMDType::HCCL_CMD_BROADCAST, HcclCMDType::HCCL_CMD_ALLREDUCE, HcclCMDType::HCCL_CMD_REDUCE,
2643 : HcclCMDType::HCCL_CMD_ALLGATHER, HcclCMDType::HCCL_CMD_REDUCE_SCATTER, HcclCMDType::HCCL_CMD_ALLTOALLV,
2644 : HcclCMDType::HCCL_CMD_ALLTOALLVC, HcclCMDType::HCCL_CMD_ALLTOALL, HcclCMDType::HCCL_CMD_GATHER,
2645 : HcclCMDType::HCCL_CMD_SCATTER, HcclCMDType::HCCL_CMD_SEND, HcclCMDType::HCCL_CMD_RECEIVE,
2646 0 : HcclCMDType::HCCL_CMD_BATCH_SEND_RECV};
2647 0 : return (HcclSupportRetryOpSet.find(opType) != HcclSupportRetryOpSet.end());
2648 0 : }
2649 :
2650 1 : HcclResult HcclCommAicpu::HcclOpExecFsmLaunchProcess(
2651 : const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
2652 : AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t& beginSqePos,
2653 : uint32_t& endSqePos, uint32_t retryCnt)
2654 : {
2655 1 : HCCL_DEBUG("hccl aicpu start launch task.");
2656 :
2657 1 : HcclResult ret = OrchestrateHcclOp(algName, param, executor, algResource, beginSqePos, endSqePos);
2658 1 : if (ret == HCCL_SUCCESS) { // 下发成功, 并且没有检测到异常cq或中断命令
2659 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
2660 1 : } else if (ret == HCCL_E_SUSPENDING) { // 检测到异常cq或中断命令
2661 1 : if (isDeviceMode_ && retryEnable_) {
2662 1 : HCCL_RUN_INFO("Orchestrate hccl op suspending, restart handle by mc2 process.");
2663 1 : return ret;
2664 : }
2665 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2666 : // batchsendrecv算子下发过程中出现异常,task下发未完成,send 和 recv 均需要重执行;
2667 : // 第一个g故障op重执行下发task完成后,需要主动上报故障,触发第二个op进行重执行
2668 0 : SetBSRSendOpExecException();
2669 0 : SetBSRRecvOpExecException();
2670 0 : HCCL_RUN_INFO("hccl aicpu abort launch batchsendrecv op, need retry");
2671 : }
2672 0 : CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
2673 : } else {
2674 0 : HCCL_ERROR("OrchestrateHcclOp failed, ret:%u", ret);
2675 0 : errorCode = KfcError::kInner;
2676 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2677 : }
2678 0 : return ret;
2679 : }
2680 :
2681 4 : HcclResult HcclCommAicpu::HcclOpExecFsmWaitEndProcess(
2682 : OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt,
2683 : std::string& tag, const uint32_t& beginSqePos)
2684 : {
2685 4 : HCCL_DEBUG("hccl aicpu wait task finish.");
2686 4 : auto ret = WaitFinishWhileLoop(mainStream_, algResource.slaveStreams, tag, beginSqePos, param);
2687 4 : if (ret == HCCL_SUCCESS) {
2688 0 : HCCL_DEBUG("hccl aicpu exec complete.");
2689 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_END;
2690 4 : } else if (ret == HCCL_E_SUSPENDING) {
2691 4 : HCCL_RUN_INFO("hccl aicpu force stop in wait end, retryCnt[%u]", retryCnt);
2692 4 : CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
2693 : } else {
2694 0 : HCCL_ERROR("WaitTaskFinish failed, ret:%u, identifier[%s]", ret, identifier_.c_str());
2695 0 : errorCode = KfcError::kExec;
2696 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2697 : }
2698 4 : return ret;
2699 : }
2700 :
2701 0 : HcclResult HcclCommAicpu::HcclOpExecFsmStoppingProcess(
2702 : const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt)
2703 : {
2704 0 : HCCL_DEBUG("hccl aicpu stopping.");
2705 0 : KfcCommand cmd = KfcCommand::kNone;
2706 0 : auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
2707 0 : if (ret != HCCL_SUCCESS) {
2708 0 : HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, ret:%u", ret);
2709 0 : errorCode = KfcError::kExec;
2710 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2711 0 : return ret;
2712 : }
2713 0 : if (cmd == KfcCommand::kExit) {
2714 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu exec fsm stop by exit cmd.");
2715 0 : errorCode = KfcError::kExit;
2716 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2717 0 : } else if (cmd == KfcCommand::kStopExec) {
2718 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu get stop exec cmd.");
2719 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPED;
2720 0 : } else if (cmd == KfcCommand::kStopLaunch) {
2721 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2722 0 : HcclOpIdentifier targetOp;
2723 0 : CHK_RET(aicpuHdc_.GetOpExecCtrlTargetOp(kfcControlTransferH2D_, targetOp));
2724 0 : std::string targetOpTag = std::string(reinterpret_cast<char*>(&targetOp.tag[0]));
2725 0 : if (targetOpTag != std::string(reinterpret_cast<char*>(&bsrTargetOpId_.tag[0]))) {
2726 0 : CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
2727 : }
2728 0 : }
2729 0 : } else if ((cmd == KfcCommand::kNone) || (cmd == KfcCommand::kRetry)) {
2730 0 : HCCL_DEBUG("hccl aicpu wait for stop exec cmd.");
2731 : // do nothing
2732 0 : } else if (cmd == KfcCommand::kReportRetryErr) {
2733 0 : HCCL_ERROR("[OpRetry][AICPU][HcclOpExecFsmStoppingProcess]hccl aicpu can not retry err cmd[%d]", cmd);
2734 0 : uint16_t rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2735 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2736 0 : errorCode = KfcError::kExit;
2737 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2738 0 : return HCCL_E_OPRETRY_FAIL;
2739 : } else {
2740 0 : HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, invalid cmd[%u]", cmd);
2741 0 : errorCode = KfcError::kExec;
2742 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2743 : }
2744 0 : return HCCL_SUCCESS;
2745 : }
2746 :
2747 0 : HcclResult HcclCommAicpu::LoadChangeLinkInfo(ChangeLinkInfo& changeLinkInfo)
2748 : {
2749 0 : HcclResult ret = aicpuHdc_.GetOpExecChangeLink(kfcControlTransferH2D_, changeLinkInfo);
2750 :
2751 : // DEBUG_INFO aicpu接收的changelinkinfo
2752 0 : std::string changeLinkInfoStr = "";
2753 0 : for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
2754 : changeLinkInfoStr
2755 0 : += (std::to_string(changeLinkInfo.remoteRankList[i]) + ":"
2756 0 : + std::to_string(changeLinkInfo.isUseDefaultPort[i]) + "; ");
2757 : }
2758 0 : HCCL_RUN_INFO(
2759 : "[%s]rank[%u], isChangeLinkFlag[%d], changeLinkInfoStr:%s", __func__, localUserRank_,
2760 : changeLinkInfo.isChangeLinkFlag, changeLinkInfoStr.c_str());
2761 :
2762 0 : return ret;
2763 0 : }
2764 :
2765 0 : HcclResult HcclCommAicpu::HcclOpExecChangeLinkProcess(
2766 : const std::string& newTag, HcclOpExecFSM& state, KfcError& errorCode, uint32_t& retryCnt,
2767 : AlgResourceResponse& algResource, const HcclOpResParam* commParam, const OpParam& param)
2768 : {
2769 0 : ChangeLinkInfo changeLinkInfo;
2770 0 : HcclResult ret = LoadChangeLinkInfo(changeLinkInfo);
2771 0 : if (ret != HCCL_SUCCESS) {
2772 0 : errorCode = KfcError::kExec;
2773 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2774 0 : return ret;
2775 : }
2776 0 : bool useBackupLink = false;
2777 0 : std::map<u32, bool> remoteRankPortMap;
2778 0 : for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
2779 0 : remoteRankPortMap.insert({changeLinkInfo.remoteRankList[i], changeLinkInfo.isUseDefaultPort[i]});
2780 0 : useBackupLink |= (!changeLinkInfo.isUseDefaultPort[i]);
2781 : }
2782 0 : ret = RefreshAlgResponseTransportRes(
2783 0 : newTag, algResource, remoteRankPortMap, changeLinkInfo.isChangeLinkFlag, commParam, param);
2784 0 : if (ret != HCCL_SUCCESS) {
2785 0 : errorCode = KfcError::kExec;
2786 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2787 0 : return ret;
2788 : }
2789 0 : if (useBackupLink) {
2790 0 : RecordReportStatus(dfx::ReportStatus::kRetryWithBackupLink);
2791 : }
2792 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2793 0 : retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
2794 : }
2795 0 : errorCode = KfcError::kNone;
2796 0 : CHK_RET(UpdateOpExecStatus(state, KfcStatus::kChanged, errorCode, retryCnt));
2797 0 : state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
2798 0 : return HCCL_SUCCESS;
2799 0 : }
2800 :
2801 0 : HcclResult HcclCommAicpu::BSRStopedProcess(HcclOpExecFSM& fsmState, KfcError& errorCode)
2802 : {
2803 : // 判断batchsendrecv算子的send 和recv 操作停止的位置是否满足重执行条件
2804 : // send / recv 的stream停止位置不能位于该算子的首个sqe 和末尾sqe
2805 : u32 bsrSendSqHead;
2806 : u32 bsrRecvSqHead;
2807 0 : auto ret = QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, bsrSendSqHead);
2808 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2809 : ret, HCCL_ERROR("[OpRetry][AICPU]quert send stream sq head failed, ret:%u", ret), KfcError::kExec,
2810 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2811 :
2812 0 : ret = QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, bsrRecvSqHead);
2813 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2814 : ret, HCCL_ERROR("[OpRetry][AICPU]quert recv stream sq head failed, ret:%u", ret), KfcError::kExec,
2815 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2816 :
2817 0 : ret = ((bsrSendOpBeginSqePos_ == bsrSendSqHead) || (bsrRecvOpBeginSqePos_ == bsrRecvSqHead)) ? HCCL_E_OPRETRY_FAIL :
2818 : HCCL_SUCCESS;
2819 0 : if (ret != HCCL_SUCCESS) {
2820 0 : uint16_t rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2821 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2822 : }
2823 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2824 : ret,
2825 : HCCL_ERROR(
2826 : "[OpRetry][AICPU]hccl aicpu wait start task is not complete, can not retry. params: send sq head "
2827 : "%u, recv sq head %u, send sq begin %u, recv sq begin %u",
2828 : bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrRecvOpBeginSqePos_),
2829 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2830 :
2831 0 : ret = ((bsrRetryOp_ == HCCL_SEND) && (bsrSendSqHead == bsrSendOpEndSqePos_)) ? HCCL_E_OPRETRY_FAIL : HCCL_SUCCESS;
2832 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2833 : ret,
2834 : HCCL_ERROR(
2835 : "[OpRetry][AICPU]hccl aicpu send record complete task is complete, can not retry. params: send sq "
2836 : "head %u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
2837 : bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
2838 : bsrRecvOpEndSqePos_),
2839 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2840 :
2841 0 : ret = ((bsrRetryOp_ == HCCL_RECV) && (bsrRecvSqHead == bsrRecvOpEndSqePos_)) ? HCCL_E_OPRETRY_FAIL : HCCL_SUCCESS;
2842 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2843 : ret,
2844 : HCCL_ERROR(
2845 : "[OpRetry][AICPU]hccl aicpu recv record complete task is complete, can not retry. params: send sq "
2846 : "head %u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
2847 : bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
2848 : bsrRecvOpEndSqePos_),
2849 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2850 :
2851 0 : HCCL_RUN_INFO(
2852 : "[OpRetry][AICPU]hccl aicpu op is running, can retry. params: send sq head "
2853 : "%u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
2854 : bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
2855 : bsrRecvOpEndSqePos_);
2856 0 : if (IsTaskExceptionForHccs()) {
2857 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu stop by sdma/write task exception, can retry.");
2858 : }
2859 0 : errorCode = KfcError::kNone;
2860 0 : uint32_t retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
2861 0 : CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStopExec, errorCode, retryCnt));
2862 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
2863 0 : return HCCL_SUCCESS;
2864 : }
2865 :
2866 0 : HcclResult HcclCommAicpu::HcclOpExecFsmStoppedProcess(
2867 : HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt, const std::string& algName, OpParam& param,
2868 : uint32_t beginSqePos, uint32_t endSqePos)
2869 : {
2870 0 : HCCL_DEBUG("hccl aicpu stop exec.");
2871 0 : KfcCommand cmd = KfcCommand::kNone;
2872 0 : auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
2873 0 : uint16_t rsErrorCode = 0;
2874 0 : if (ret != HCCL_SUCCESS) {
2875 0 : HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, ret:%u", ret);
2876 0 : errorCode = KfcError::kExec;
2877 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2878 0 : return ret;
2879 : }
2880 :
2881 0 : if (cmd == KfcCommand::kExit) {
2882 0 : HCCL_ERROR("[OpRetry][AICPU]hccl aicpu exec fsm stop by exit cmd.");
2883 0 : errorCode = KfcError::kExit;
2884 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2885 0 : return HCCL_SUCCESS;
2886 : }
2887 :
2888 0 : if (cmd == KfcCommand::kReportRetryErr) {
2889 0 : HCCL_ERROR("[OpRetry][AICPU][HcclOpExecFsmStoppedProcess]hccl aicpu can not retry err cmd[%d]", cmd);
2890 0 : rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2891 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2892 0 : errorCode = KfcError::kExit;
2893 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2894 0 : return HCCL_E_OPRETRY_FAIL;
2895 : }
2896 :
2897 0 : if (!HcclOpSupportRetry(algName, retryEnable_, param)) {
2898 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
2899 0 : if (param.isInplaceError) {
2900 0 : errorCode = KfcError::kExecConstraint;
2901 0 : rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2902 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2903 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2904 : HCCL_E_OPRETRY_FAIL,
2905 : HCCL_ERROR("[Opretry][AICPU][HcclOpExecFsmStoppedProcess]can not retry for inpace error."),
2906 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2907 0 : } else if (isPollutedZeroCopyOp(param)) {
2908 0 : errorCode = KfcError::kExecConstraint;
2909 0 : rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2910 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2911 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2912 : HCCL_E_OPRETRY_FAIL,
2913 : HCCL_ERROR("[Opretry][AICPU][HcclOpExecFsmStoppedProcess]can not retry for zero copy op."),
2914 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2915 : return HCCL_E_OPRETRY_FAIL;
2916 : } else {
2917 0 : errorCode = KfcError::kExec;
2918 : }
2919 0 : return HCCL_SUCCESS;
2920 : }
2921 :
2922 0 : uint32_t sqHead = 0xFFFFFFFF;
2923 0 : CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, sqHead));
2924 0 : if (sqHead == endSqePos) {
2925 0 : rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2926 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2927 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2928 : HCCL_E_OPRETRY_FAIL,
2929 : HCCL_ERROR(
2930 : "[OpRetry][AICPU]hccl aicpu record complete task is complete, can not retry. params: "
2931 : "sqHead %u, beginSqePos %u endSqePos %u",
2932 : sqHead, beginSqePos, endSqePos),
2933 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2934 0 : } else if (sqHead == beginSqePos) {
2935 0 : rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
2936 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
2937 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
2938 : HCCL_E_OPRETRY_FAIL,
2939 : HCCL_ERROR(
2940 : "[OpRetry][AICPU]hccl aicpu wait start task is not complete, can not retry. "
2941 : "params: sqHead %u, beginSqePos %u endSqePos %u",
2942 : sqHead, beginSqePos, endSqePos),
2943 : KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
2944 0 : } else if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
2945 0 : CHK_RET(BSRStopedProcess(fsmState, errorCode));
2946 0 : } else {
2947 0 : HCCL_RUN_INFO(
2948 : "[OpRetry][AICPU]hccl aicpu op is running, can retry. params: sqHead %u, beginSqePos %u "
2949 : "endSqePos %u",
2950 : sqHead, beginSqePos, endSqePos);
2951 0 : if (IsTaskExceptionForHccs()) {
2952 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu stop by sdma/write task exception, can retry.");
2953 : }
2954 0 : errorCode = KfcError::kNone;
2955 0 : CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStopExec, errorCode, retryCnt));
2956 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
2957 : }
2958 0 : return HCCL_SUCCESS;
2959 : }
2960 :
2961 0 : void HcclCommAicpu::NsCommStop()
2962 : {
2963 0 : if ((StreamsKill(devId_) != HCCL_SUCCESS) || (DeviceQuery(devId_, ts::APP_ABORT_KILL_FINISH, 0U) != HCCL_SUCCESS)) {
2964 0 : (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kError, KfcError::kExec, 0);
2965 0 : HCCL_ERROR("[NsRecovery][AICPU]Stop failed");
2966 0 : return;
2967 : }
2968 : // 停止条件算子
2969 0 : if (isDeviceMode_) {
2970 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kClearCommitTurn, {rpc_});
2971 : }
2972 0 : (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kStopExec, KfcError::kNone, 0);
2973 0 : (void)HcclOneSideServiceAicpu::DisableAllStreamFunc();
2974 0 : HCCL_RUN_INFO("[NsRecovery][AICPU]stopFunc Finished");
2975 : }
2976 :
2977 0 : void HcclCommAicpu::NsCommClean()
2978 : {
2979 : // 等待drv任务停止
2980 0 : if ((DeviceQuery(devId_, ts::APP_ABORT_TERMINATE_FINISH, 0U) != HCCL_SUCCESS) || (CleanStreamFunc() != HCCL_SUCCESS)
2981 0 : || (HcclOneSideServiceAicpu::CleanAllStreamFunc() != HCCL_SUCCESS) || (ResetSqBuff() != HCCL_SUCCESS)) {
2982 0 : (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kError, KfcError::kExec, 0);
2983 0 : HCCL_ERROR("[NsRecovery][AICPU]stream terminate failed");
2984 0 : return;
2985 : } else {
2986 0 : if (isDeviceMode_) {
2987 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kClearMsgArea, {rpc_});
2988 : }
2989 0 : HCCL_INFO("ClearFunc, after APP_ABORT_TERMINATE_FINISH");
2990 0 : dfxExtendInfo_.pollStatus = PollStatus::kDefault;
2991 0 : dfxExtendInfo_.cqeStatus = dfx::CqeStatus::kDefault;
2992 0 : (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kClear, KfcError::kNone, 0);
2993 0 : endStopLaunch = false;
2994 0 : isOpLaunch = false;
2995 0 : needsResponseStopLaunch_ = false;
2996 0 : errMessageReport_ = true;
2997 0 : HCCL_RUN_INFO("[NsRecovery][AICPU] clean Finish");
2998 : }
2999 : }
3000 :
3001 0 : HcclResult HcclCommAicpu::GetBackGroundCommand(BackgroundCommand& bgCmd)
3002 : {
3003 0 : return AicpuHdcUtils::GetBackGroundCommand(kfcControlTransferH2D_, bgCmd);
3004 : }
3005 :
3006 0 : HcclResult HcclCommAicpu::ResponseBackGroundStatus(KfcExecStatus& status)
3007 : {
3008 0 : return AicpuHdcUtils::ResponseBackGroundStatus(kfcStatusTransferD2H_, status);
3009 : }
3010 :
3011 0 : HcclResult HcclCommAicpu::GetKfcCommand(KfcCommand& cmd)
3012 : {
3013 0 : return AicpuHdcUtils::GetKfcCommand(kfcControlTransferH2D_, cmd);
3014 : }
3015 :
3016 0 : HcclResult HcclCommAicpu::SetStreamEnable(Stream& stream)
3017 : {
3018 0 : const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
3019 0 : HCCL_INFO("[SetStreamEnable] streamid[%d]", streamInfo.actualStreamId);
3020 0 : CHK_RET(ConfigSqStatusByType(GetDevId(), streamInfo.sqId, DRV_SQCQ_PROP_SQ_DISABLE_TO_ENABLE, 1));
3021 0 : HandleCqeException(stream, true);
3022 0 : return HCCL_SUCCESS;
3023 : }
3024 :
3025 0 : HcclResult HcclCommAicpu::CleanStreamFunc()
3026 : {
3027 0 : CHK_RET(SetStreamEnable(mainStream_));
3028 0 : for (auto& stream : slaveStreams_) {
3029 0 : CHK_RET(SetStreamEnable(stream));
3030 : }
3031 0 : CHK_RET(SetStreamEnable(orderStream_));
3032 0 : return HCCL_SUCCESS;
3033 : }
3034 :
3035 0 : std::string HcclCommAicpu::PrintInplaceStatus(u8 isInplaceStatus)
3036 : {
3037 0 : const u8 kNoOverlap = 0;
3038 0 : const u8 kAllToAllOverlap = 1;
3039 0 : const u8 kInplaceOverlap = 2;
3040 0 : switch (isInplaceStatus) {
3041 0 : case kNoOverlap:
3042 : // input和output不重叠
3043 0 : return "There is no overlap.";
3044 0 : case kAllToAllOverlap:
3045 : // alltoall类算子的input和output重叠
3046 0 : return "The param.inputPtr is equal to param.outputPtr, hence they overlap.";
3047 0 : case kInplaceOverlap:
3048 : // input和output重叠
3049 0 : return "It's inplace case. hence they overlap.";
3050 0 : default:
3051 0 : return "It's an unknown overlap case.";
3052 : }
3053 : return "";
3054 : }
3055 :
3056 0 : std::string HcclCommAicpu::PrintInplaceSupportRetryStatus(InplaceSupportRetryStatus inPlaceSupportRetryStatus)
3057 : {
3058 0 : switch (inPlaceSupportRetryStatus) {
3059 0 : case InplaceSupportRetryStatus::AG_BD_CASE: // 不需要去变成非DMA削减
3060 : // allgather or broadcast 算子
3061 0 : return "The Allgather or broadcast op supports inplace retry.";
3062 0 : case InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE1: // 需要去变成非DMA削减
3063 : // 使用AllReduceMeshSmallCountExecutor, ReduceScatterDeterExecutor
3064 : // 且环境变量配置RetryEnable:1
3065 0 : return "Since retryEnable:1, the executor without DMAReduce will be applied.";
3066 0 : case InplaceSupportRetryStatus::RETRY_0_NOT_ALLOW_NO_DMA_REDUCE_CASE1: // 不需要去变成非DMA削减
3067 : // 使用AllReduceMeshSmallCountExecutor, ReduceScatterDeterExecutor
3068 : // 且环境变量配置RetryEnable:0
3069 0 : return "Since retryEnable:0, ExecutorOnlySupportDMAReduce is not allowed for inplace case.";
3070 0 : case InplaceSupportRetryStatus::ALWAYS_NO_DMA_REDUCE: // 不需要去变成非DMA削减,本身就是
3071 : // 使用AllReduceComm/ReduceScatterComm
3072 0 : return "AllReduceComm or ReduceScatterComm is used for inplace case.";
3073 0 : case InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE2: // 需要去变成非DMA削减
3074 : // 使用其余在91093场景下使用的reduce scatter, allreduce executor
3075 : // 且环境变量配置RetryEnable:1
3076 0 : return "Since retryEnable:1, the executor will be applied without DMAReduce operation.";
3077 0 : case InplaceSupportRetryStatus::RETRY_0_NOT_ALLOW_NO_DMA_REDUCE_CASE2: // 不需要去变成非DMA削减
3078 : // 使用其余在91093场景下使用的reduce scatter, allreduce executor
3079 : // 且环境变量配置RetryEnable:0
3080 0 : return "Since retryEnable:0, the executor without DMAReduce operation can not be applied.";
3081 0 : case InplaceSupportRetryStatus::UNKONWN_EXECUTOR: // 不需要去变成非DMA削减
3082 : // 使用未知的executor
3083 0 : return "The unknown executor does not support for an inplace case yet.";
3084 0 : case InplaceSupportRetryStatus::USER_LARGER_THAN_CCL: // 不需要去变成非DMA削减
3085 : // UserInMem > CCLInMem 场景
3086 0 : return "UserInMem > CCLInMem case";
3087 0 : case InplaceSupportRetryStatus::NOT_BASIC_OP_CASE: // 不需要去变成非DMA削减
3088 : // 非 RS AR AG BD算子场景
3089 0 : return "Is not ReduceScatter, AllReduce, AllGather or Broadcast case";
3090 0 : default:
3091 0 : return "It's unknown case. They overlap.";
3092 : }
3093 : return "";
3094 : }
3095 :
3096 0 : bool HcclCommAicpu::IsNoNeedMonitor(void)
3097 : {
3098 0 : if (taskMonitorInterval_ == 0)
3099 0 : return true;
3100 :
3101 0 : KfcCommand kfcCmd = KfcCommand::kNone;
3102 0 : (void)GetKfcCommand(kfcCmd);
3103 0 : if (kfcCmd != KfcCommand::kNone)
3104 0 : return true;
3105 :
3106 0 : BackgroundCommand bgCmd = BackgroundCommand::kNone;
3107 0 : (void)GetBackGroundCommand(bgCmd);
3108 0 : if (bgCmd != BackgroundCommand::kNone)
3109 0 : return true;
3110 :
3111 0 : HcclComSuspendingFlag suspendingFlag = HcclComSuspendingFlag::isNull;
3112 0 : (void)GetSuspendingFlag(suspendingFlag);
3113 0 : if (suspendingFlag != HcclComSuspendingFlag::isNull)
3114 0 : return true;
3115 0 : return false;
3116 : }
3117 :
3118 0 : void HcclCommAicpu::InsertMonitorData(Stream& stream, HcclUs& curTime, u32 sqHead, uint16_t taskId, uint8_t type)
3119 : {
3120 0 : AicpuStreamMontior tmpTaskMonitor;
3121 0 : tmpTaskMonitor.historyTime = curTime;
3122 0 : tmpTaskMonitor.historyHead = sqHead;
3123 0 : tmpTaskMonitor.historyTaskId = taskId;
3124 0 : tmpTaskMonitor.historyType = type;
3125 0 : streamTaskMonitor_.insert(std::make_pair(stream.sqId(), tmpTaskMonitor));
3126 0 : return;
3127 : }
3128 :
3129 0 : bool HcclCommAicpu::IsNeedRefreshMonitorData(
3130 : AicpuStreamMontior& streamMontior, HcclUs& curTime, uint32_t remoteRank, uint16_t taskId, u32 sqHead, u32 sqTail,
3131 : uint8_t type)
3132 : {
3133 0 : auto& historyTime = streamMontior.historyTime;
3134 0 : auto& historyHead = streamMontior.historyHead;
3135 0 : auto& historyTaskId = streamMontior.historyTaskId;
3136 0 : auto& historyType = streamMontior.historyType;
3137 0 : if ((historyTaskId != taskId) || (sqHead != historyHead) || (sqHead == sqTail) || (historyType != type)
3138 0 : || ((type == RT_STARS_SQE_TYPE_NOTIFY_WAIT) && (remoteRank == INVALID_VALUE_RANKID))) {
3139 0 : historyTime = curTime;
3140 0 : historyHead = sqHead;
3141 0 : historyTaskId = taskId;
3142 0 : historyType = type;
3143 0 : return true;
3144 : }
3145 0 : return false;
3146 : }
3147 :
3148 0 : HcclResult HcclCommAicpu::StreamTaskMonitor(void)
3149 : {
3150 : // 通信域资源已经释放
3151 0 : CHK_PRT_RET(
3152 : !commOpenStatus, HCCL_DEBUG("[StreamTaskMonitor]group[%s] has been destroyed", identifier_.c_str()),
3153 : HCCL_SUCCESS);
3154 0 : if (IsNoNeedMonitor())
3155 0 : return HCCL_SUCCESS;
3156 0 : HCCL_DEBUG("StreamTaskMonitor print");
3157 0 : std::vector<Stream> totalStream = {mainStream_};
3158 0 : totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
3159 0 : HcclUs curTime = TIME_NOW();
3160 0 : for (auto& stream : totalStream) {
3161 0 : u32 sqHead = 0U, sqTail = 0U;
3162 0 : (void)QuerySqStatus(devId_, stream.sqId(), sqHead, sqTail);
3163 0 : HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
3164 0 : CHK_PTR_NULL(sqeContext);
3165 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
3166 0 : CHK_PTR_NULL(sqeContextBuffer);
3167 :
3168 0 : uint8_t type = 0;
3169 0 : uint16_t taskId = 0;
3170 0 : uint32_t remoteRank = 0;
3171 0 : std::string tmp = GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskId, remoteRank);
3172 0 : HCCL_DEBUG("GetTaskExceptionTaskInfo type %u taskId %u", type, taskId);
3173 0 : auto mapIt = streamTaskMonitor_.find(stream.sqId());
3174 0 : if (mapIt == streamTaskMonitor_.end()) {
3175 0 : InsertMonitorData(stream, curTime, sqHead, taskId, type);
3176 0 : continue;
3177 : }
3178 :
3179 0 : auto& streamMontior = mapIt->second;
3180 0 : if (IsNeedRefreshMonitorData(streamMontior, curTime, remoteRank, taskId, sqHead, sqTail, type)) {
3181 0 : continue;
3182 : }
3183 :
3184 0 : auto timeVal = DURATION_US(curTime - streamMontior.historyTime).count();
3185 0 : const int TIME_CONVERSION = 1000;
3186 0 : if (timeVal >= taskMonitorInterval_ * TIME_CONVERSION) {
3187 0 : HCCL_RUN_INFO(
3188 : "[StreamTaskMonitor]prof monitor streamId:%d, sqid:%d, head:%u, tail:%u, time %s us, %s", stream.id(),
3189 : stream.sqId(), sqHead, sqTail, std::to_string(timeVal).c_str(), tmp.c_str());
3190 0 : HCCL_RUN_INFO(
3191 : "[StreamTaskMonitor]prof monitor %s", GetTaskExceptionOpInfo(sqHead, sqeContextBuffer).c_str());
3192 0 : PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer, true);
3193 0 : streamMontior.historyTime = curTime;
3194 0 : streamMontior.historyHead = sqHead;
3195 0 : streamMontior.historyTaskId = taskId;
3196 0 : streamMontior.historyType = type;
3197 : }
3198 0 : }
3199 0 : return HCCL_SUCCESS;
3200 0 : }
3201 :
3202 0 : HcclResult HcclCommAicpu::SupportRetryWithInplaceCheck(const std::string& algName, OpParam& param)
3203 : {
3204 : // 不支持inplace的通信算子重执行
3205 0 : u8 isInplaceStatus = 0;
3206 0 : InplaceSupportRetryStatus inPlaceSupportRetryStatus = InplaceSupportRetryStatus::INPLACE_STATUS_END;
3207 0 : if (IsHcclOpInplace(param.opType, param, topoInfo_.userRank, topoInfo_.userRankSize, isInplaceStatus)) {
3208 0 : if (!FitRetryConditionforInPlaceOp(
3209 0 : param.opType, param, algName, cclbufferSize_, topoInfo_.userRankSize,
3210 0 : algOpContext_.opRetryHandler.retryEnable, inPlaceSupportRetryStatus)) {
3211 0 : HCCL_RUN_INFO(
3212 : "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
3213 : "opRetryHandler.inplaceSupportRetry[%d], opRetryHandler.inPlaceSupportRetryStatus[%s], "
3214 : "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
3215 : PrintInplaceStatus(isInplaceStatus).c_str(), 0,
3216 : PrintInplaceSupportRetryStatus(inPlaceSupportRetryStatus).c_str(),
3217 : algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
3218 : } else {
3219 0 : HCCL_RUN_INFO(
3220 : "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
3221 : "opRetryHandler.inplaceSupportRetry[%d], opRetryHandler.inPlaceSupportRetryStatus[%s], "
3222 : "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
3223 : PrintInplaceStatus(isInplaceStatus).c_str(), 1,
3224 : PrintInplaceSupportRetryStatus(inPlaceSupportRetryStatus).c_str(),
3225 : algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
3226 : }
3227 : } else {
3228 0 : HCCL_RUN_INFO(
3229 : "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
3230 : "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
3231 : PrintInplaceStatus(isInplaceStatus).c_str(), algOpContext_.opRetryHandler.isInplacePreSync,
3232 : algOpContext_.opRetryHandler.isPostSync);
3233 : }
3234 0 : return HCCL_SUCCESS;
3235 : }
3236 :
3237 0 : bool HcclCommAicpu::HcclOpSupportRetry(const std::string& algName, bool retryEnable, OpParam& param)
3238 : {
3239 0 : HCCL_RUN_INFO(
3240 : "[OpRetry][AICPU]hccl supports retry status: enable[%u], param.tag[%s].", retryEnable, param.tag.c_str());
3241 0 : if (!retryEnable) {
3242 0 : HCCL_ERROR("[OpRetry][AICPU]hccl aicpu can not retry, enable[%u].", retryEnable);
3243 0 : return false;
3244 : }
3245 0 : if (isPollutedZeroCopyOp(param)) {
3246 0 : HCCL_ERROR(
3247 : "[OpRetry][AICPU]hccl aicpu can not retry, isZeroCopy[%d], opType[%s].", param.isZeroCopy,
3248 : GetCMDTypeEnumStr(param.opType).c_str());
3249 0 : return false;
3250 : }
3251 :
3252 0 : CHK_RET(SupportRetryWithInplaceCheck(algName, param));
3253 : // 不支持inplace的通信算子重执行
3254 0 : if ((!algOpContext_.opRetryHandler.inplaceSupportRetry) && (!algOpContext_.opRetryHandler.isInplacePreSync)
3255 0 : && (!algOpContext_.opRetryHandler.isPostSync)) {
3256 0 : HCCL_ERROR(
3257 : "[OpRetry][AICPU]hccl aicpu can not retry, not support inplace case, opType[%s], "
3258 : "inputPtr[0x%016lx], outputPtr[0x%016lx], opRetryHandler.inplaceSupportRetry[%d], "
3259 : "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d]",
3260 : GetCMDTypeEnumStr(param.opType).c_str(), param.inputPtr, param.outputPtr,
3261 : algOpContext_.opRetryHandler.inplaceSupportRetry, algOpContext_.opRetryHandler.isInplacePreSync,
3262 : algOpContext_.opRetryHandler.isPostSync);
3263 0 : param.isInplaceError = true;
3264 0 : return false;
3265 : }
3266 :
3267 : // 不支持的通信算子重执行
3268 0 : if (HcclOpCheckSupportRetry(param.opType) == false) {
3269 0 : HCCL_ERROR(
3270 : "[OpRetry][AICPU]hccl aicpu can not retry, not support opType[%s].",
3271 : GetCMDTypeEnumStr(param.opType).c_str());
3272 0 : return false;
3273 : }
3274 0 : return true;
3275 : }
3276 :
3277 0 : bool HcclCommAicpu::isPollutedZeroCopyOp(OpParam& param)
3278 : {
3279 : // allreduce\reduce\reducescatter\reducescatterv with zerocopy can not support retry.
3280 0 : bool isPollutedOp
3281 0 : = ((param.opType == HcclCMDType::HCCL_CMD_ALLREDUCE) || (param.opType == HcclCMDType::HCCL_CMD_REDUCE)
3282 0 : || (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER)
3283 0 : || (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V));
3284 0 : return param.isZeroCopy && isPollutedOp;
3285 : }
3286 :
3287 0 : HcclResult HcclCommAicpu::UpdateOpExecStatus(
3288 : HcclOpExecFSM& fsmState, HcclOpIdentifier& opId, KfcStatus state, KfcError& errorCode, uint32_t retryCnt)
3289 : {
3290 0 : HCCL_INFO(
3291 : "UpdateOpExecStatus fsmState %d, tag %s, index %u, state %d, errorCode %d, retryCnt %u.", fsmState, opId.tag,
3292 : opId.index, state, errorCode, retryCnt);
3293 0 : auto ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, opId, state, errorCode, retryCnt);
3294 :
3295 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
3296 : ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
3297 :
3298 0 : return ret;
3299 : }
3300 :
3301 : HcclResult
3302 7 : HcclCommAicpu::UpdateOpExecStatus(HcclOpExecFSM& fsmState, KfcStatus state, KfcError& errorCode, uint32_t retryCnt)
3303 : {
3304 7 : HCCL_INFO(
3305 : "UpdateOpExecStatus fsmState %d, state %d, errorCode %d, retryCnt %u.", fsmState, state, errorCode, retryCnt);
3306 7 : auto ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, state, errorCode, retryCnt);
3307 7 : if (ret != HCCL_SUCCESS) {
3308 0 : HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret);
3309 0 : errorCode = KfcError::kExec;
3310 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
3311 : }
3312 7 : return ret;
3313 : }
3314 :
3315 : static constexpr u32 HCCL_AICPU_WAIT_HOST_BASE_TIME_MS = 200 * 1000;
3316 : static constexpr u32 TIME_S_TO_MS = 1000;
3317 14 : u32 HcclCommAicpu::HcclGetWaitStopExecCmdTimeout()
3318 : {
3319 14 : return std::max(static_cast<u32>(linkTimeOut_.count()), HCCL_AICPU_WAIT_HOST_BASE_TIME_MS);
3320 : }
3321 :
3322 7 : u32 HcclCommAicpu::HcclGetWaitRetryCmdTimeout(uint32_t retryCnt)
3323 : {
3324 7 : if (retryCnt == 0) {
3325 7 : return HcclGetWaitStopExecCmdTimeout() + retryHoldTime_;
3326 : } else {
3327 0 : return HcclGetWaitStopExecCmdTimeout() + retryIntervalTime_;
3328 : }
3329 : }
3330 :
3331 0 : HcclResult HcclCommAicpu::HcclOpExecFsmWaitRetryProcess(
3332 : const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, KfcCommand& lastCmd)
3333 : {
3334 0 : HCCL_DEBUG("hccl aicpu wait for retry cmd.");
3335 0 : KfcCommand cmd = KfcCommand::kNone;
3336 0 : auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
3337 0 : if (ret != HCCL_SUCCESS) {
3338 0 : HCCL_ERROR("GetOpExecCtrlCmd failed, ret:%u", ret);
3339 0 : errorCode = KfcError::kExec;
3340 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
3341 0 : return ret;
3342 : }
3343 0 : if (cmd == KfcCommand::kRetry) {
3344 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv retry cmd from host.");
3345 0 : dfxExtendInfo_.pollStatus = PollStatus::kDefault;
3346 0 : dfxExtendInfo_.cqeStatus = dfx::CqeStatus::kDefault;
3347 0 : ret = ResetOpRetryException(param.opType);
3348 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
3349 : ret, HCCL_ERROR("reset stream buff failed, ret:%u", ret), KfcError::kInner,
3350 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
3351 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_RETRY;
3352 0 : } else if (cmd == KfcCommand::kChangeLink && lastCmd != KfcCommand::kChangeLink) { // 防止重复执行
3353 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv change link cmd, identify[%s]", identifier_.c_str());
3354 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_CHANGE_LINK;
3355 0 : } else if (cmd == KfcCommand::kExit) {
3356 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv exit cmd from host.");
3357 0 : errorCode = KfcError::kExit;
3358 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
3359 0 : } else if (cmd == KfcCommand::kReportRetryErr) {
3360 0 : HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu get report retry err cmd.");
3361 0 : CHK_PRT(SendTaskExceptionByMBox(TS_ERROR_RETRY_CONSTRAINT));
3362 0 : errorCode = KfcError::kExit;
3363 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
3364 0 : return HCCL_E_OPRETRY_FAIL;
3365 0 : } else if (cmd == KfcCommand::NsStopLaunch && endStopLaunch == false) {
3366 0 : HCCL_RUN_INFO("[NsRecovery][AICPU]hccl aicpu force stop in launch loop.");
3367 0 : endStopLaunch = true;
3368 0 : needsResponseStopLaunch_ = true;
3369 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
3370 : } else {
3371 : // do nothing
3372 : }
3373 0 : lastCmd = cmd;
3374 0 : return HCCL_SUCCESS;
3375 : }
3376 :
3377 2 : HcclResult HcclCommAicpu::ResetOpRetryException(HcclCMDType opType)
3378 : {
3379 2 : if (opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) {
3380 0 : CHK_RET(ResetBSRException());
3381 : } else {
3382 6 : std::vector<Stream> totalStream = {mainStream_};
3383 2 : totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
3384 4 : for (auto& stream : totalStream) {
3385 2 : CHK_RET(CleanStream(stream));
3386 2 : CHK_RET(ClearStreamCqeException(stream));
3387 : }
3388 2 : }
3389 2 : return HCCL_SUCCESS;
3390 2 : }
3391 :
3392 0 : HcclResult HcclCommAicpu::ResetSqBuff()
3393 : {
3394 0 : CHK_RET(CleanStream(mainStream_));
3395 0 : for (auto& stream : slaveStreams_) {
3396 0 : CHK_RET(CleanStream(stream));
3397 : }
3398 0 : CHK_RET(CleanStream(orderStream_));
3399 0 : HCCL_INFO("reset stream sq buffer success.");
3400 0 : return HCCL_SUCCESS;
3401 : }
3402 :
3403 0 : HcclResult HcclCommAicpu::UpdateSqStatus(Stream& stream)
3404 : {
3405 0 : HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
3406 0 : CHK_PTR_NULL(sqeContext);
3407 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
3408 0 : CHK_PTR_NULL(sqeContextBuffer);
3409 0 : auto& head = sqeContextBuffer->sqHead;
3410 0 : auto& tail = sqeContextBuffer->sqTail;
3411 :
3412 0 : CHK_RET(QuerySqStatusByType(devId_, stream.sqId(), DRV_SQCQ_PROP_SQ_TAIL, head));
3413 0 : CHK_RET(QuerySqStatusByType(devId_, stream.sqId(), DRV_SQCQ_PROP_SQ_HEAD, tail));
3414 0 : HCCL_INFO("UpdateSqStatus, sqid:%u head:%u tail:%u.", stream.sqId(), head, tail);
3415 0 : return HCCL_SUCCESS;
3416 : }
3417 :
3418 0 : HcclResult HcclCommAicpu::HcclOpExecFsmRetryProcess(
3419 : const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
3420 : AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t& retryCnt,
3421 : uint32_t& beginSqePos, uint32_t& endSqePos)
3422 : {
3423 0 : retryCnt++;
3424 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3425 0 : UpdateBSRRetryCnt();
3426 : }
3427 0 : HCCL_RUN_INFO("[OpRetry][AICPU]retry launch start, retryCnt:%u, tag[%s].", retryCnt, param.tag.c_str());
3428 :
3429 0 : auto ret = RetryOrchestrateHcclOp(algName, param, executor, algResource, beginSqePos, endSqePos);
3430 0 : if (ret == HCCL_SUCCESS) {
3431 0 : errorCode = KfcError::kNone;
3432 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3433 : // 是否有前一个重执行阶段积累的故障未上报,需要再次触发重执行
3434 0 : CHK_RET(CommitBSRStoredException(fsmState, errorCode));
3435 0 : } else {
3436 0 : CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kRuning, errorCode, retryCnt));
3437 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
3438 : }
3439 0 : } else if (ret == HCCL_E_SUSPENDING) {
3440 0 : HCCL_RUN_INFO("hccl aicpu force stop in retry launch process");
3441 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3442 : // batchsendrecv算子下发过程中出现异常,task下发未完成,send 和 recv 均需要重执行
3443 0 : if (bsrRetryOp_ == HCCL_SEND) {
3444 0 : SetBSRSendOpExecException();
3445 : } else {
3446 0 : SetBSRRecvOpExecException();
3447 : }
3448 0 : HCCL_RUN_INFO("hccl aicpu abort launch batchsendrecv op, need retry.");
3449 : }
3450 0 : CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
3451 : } else {
3452 0 : HCCL_ERROR("RetryLaunchHcclOp failed, ret:%u", ret);
3453 0 : errorCode = KfcError::kInner;
3454 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
3455 : }
3456 0 : return ret;
3457 : }
3458 :
3459 0 : HcclResult HcclCommAicpu::HcclOpExecFsmEndProcess(uint32_t retryCnt)
3460 : {
3461 : auto ret
3462 0 : = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, excuteOpId_, KfcStatus::kEnd, KfcError::kNone, retryCnt);
3463 0 : if (!isDeviceMode_) {
3464 0 : isOpLaunch = false;
3465 : }
3466 0 : dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneFinished;
3467 0 : HCCL_DEBUG("---------- end AICPU_HcclOpExecFsmEndProcess ----------");
3468 0 : return ret;
3469 : }
3470 :
3471 0 : HcclResult HcclCommAicpu::PrintTaskExceptionAllThreads()
3472 : {
3473 : // 非独立算子场景,跳过
3474 0 : CHK_PRT_RET(
3475 : !GetIsInitIndOp(), HCCL_RUN_INFO("[%s] IndOp group[%s] not init, skip", __func__, identifier_.c_str()),
3476 : HCCL_SUCCESS);
3477 :
3478 0 : for (auto& thread : threads_) {
3479 0 : CHK_RET(taskExecption_.PrintTaskException(*(thread->GetStream())));
3480 : }
3481 0 : return HCCL_SUCCESS;
3482 : }
3483 :
3484 0 : void HcclCommAicpu::PrintTaskExceptionAllComm()
3485 : {
3486 0 : std::shared_lock<std::shared_mutex> rwlock(AicpuHcclProcess::AicpuGetCommMutex());
3487 :
3488 : // 先打印本通信域的taskException
3489 0 : (void)PrintTaskExceptionAllStreams();
3490 0 : (void)PrintTaskExceptionAllThreads();
3491 :
3492 : // 再打印其他通信域的taskException
3493 0 : std::vector<std::pair<std::string, hccl::HcclCommAicpu*>> aicpuCommInfo;
3494 0 : (void)AicpuHcclProcess::AicpuGetCommAll(aicpuCommInfo);
3495 0 : for (auto& commInfo : aicpuCommInfo) {
3496 0 : hccl::HcclCommAicpu* hcclAicpu = commInfo.second;
3497 0 : if (hcclAicpu == nullptr || hcclAicpu->identifier_ == identifier_) {
3498 0 : continue;
3499 : }
3500 0 : (void)hcclAicpu->PrintTaskExceptionAllThreads();
3501 0 : (void)hcclAicpu->PrintTaskExceptionAllStreams();
3502 : }
3503 0 : }
3504 :
3505 0 : void HcclCommAicpu::PrintAicpuCommExecStatus()
3506 : {
3507 0 : std::shared_lock<std::shared_mutex> rwlock(AicpuHcclProcess::AicpuGetCommMutex());
3508 :
3509 : // 记录通信域占核情况
3510 0 : int64_t inExecGroupNum = 0;
3511 0 : int64_t aicpuCoreNum = 0;
3512 0 : (void)hrtHalGetDeviceInfo(devId_, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuCoreNum);
3513 :
3514 0 : std::vector<std::pair<std::string, hccl::HcclCommAicpu*>> aicpuCommInfo;
3515 0 : (void)AicpuHcclProcess::AicpuGetCommAll(aicpuCommInfo);
3516 0 : for (auto& commInfo : aicpuCommInfo) {
3517 0 : hccl::HcclCommAicpu* hcclAicpu = commInfo.second;
3518 0 : if (hcclAicpu == nullptr || !hcclAicpu->GetCommInfoStatus()) {
3519 0 : continue;
3520 : }
3521 :
3522 : // 获取并打印通信域是否在执行中,以及最后一次下发的算子
3523 0 : bool isInExec = AicpuHcclProcess::GetCommExecStatus(hcclAicpu->identifier_);
3524 0 : inExecGroupNum += isInExec ? 1 : 0;
3525 0 : std::string execStatus = isInExec ? "inExec" : "unExec";
3526 0 : HCCL_RUN_INFO(
3527 : "AicpuComm: group[%s], status[%s], op[%s], aicpuCoreNum[%lld]", hcclAicpu->identifier_.c_str(),
3528 : execStatus.c_str(), hcclAicpu->GetExcuteOp().c_str(), aicpuCoreNum);
3529 0 : }
3530 :
3531 : // AICPU核被占满,部分通信域得不到调度,可能导致通信阻塞,打印维测信息
3532 0 : if (inExecGroupNum >= aicpuCoreNum && static_cast<int64_t>(aicpuCommInfo.size()) > aicpuCoreNum) {
3533 0 : HCCL_RUN_WARNING(
3534 : "In Execution group num[%lld], total group num[%u], bigger than Aicpu cores num[%lld]. "
3535 : "Aicpu core being fully utilized may cause tasks to get stuck, and it is necessary to reduce the num of "
3536 : "comm.",
3537 : inExecGroupNum, aicpuCommInfo.size(), aicpuCoreNum);
3538 : }
3539 0 : }
3540 :
3541 0 : HcclResult HcclCommAicpu::PrintTaskExceptionAllStreams()
3542 : {
3543 : // 通信域资源已经释放
3544 0 : CHK_PRT_RET(
3545 : !commOpenStatus,
3546 : HCCL_RUN_INFO("[PrintTaskExceptionAllStreams]group[%s] has been destroyed", identifier_.c_str()), HCCL_SUCCESS);
3547 0 : CHK_RET(UtraceInfo_->Flush());
3548 0 : std::vector<Stream> totalStream = {mainStream_};
3549 : HcclResult ret;
3550 0 : totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
3551 0 : for (auto& stream : totalStream) {
3552 0 : HCCL_RUN_INFO("[PrintTaskExceptionAllStreams]group[%s] streamid[%d] print", identifier_.c_str(), stream.id());
3553 0 : u32 sqHead = 0U;
3554 0 : u32 sqTail = 0U;
3555 0 : ret = QuerySqStatus(devId_, stream.sqId(), sqHead, sqTail);
3556 0 : if (ret != HCCL_SUCCESS || sqHead == sqTail) { // 此流为空时,不打印
3557 0 : HCCL_RUN_INFO(
3558 : "[PrintTaskExceptionAllStreams] group[%s] streamid[%d] is empty"
3559 : "or QuerySqStatus failed, ret[%d]",
3560 : identifier_.c_str(), stream.id(), ret);
3561 0 : continue;
3562 : }
3563 0 : HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
3564 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
3565 0 : CHK_PTR_NULL(sqeContextBuffer);
3566 0 : if (stream.id() == mainStream_.id()) {
3567 0 : SqeInfo sqeInfo;
3568 0 : ret = SqeContextUtils::QuerySqeInfo(
3569 0 : sqeContextBuffer->rtsMirrorBuffer + sqHead * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[sqHead],
3570 : sqeContextBuffer->addInfo[sqHead], &sqeInfo);
3571 0 : if (ret != HCCL_SUCCESS) {
3572 0 : HCCL_ERROR("[%s]QuerySqeInfo failed, ret[%d]", __func__, ret);
3573 : } else {
3574 : // 根据主流卡在host notify上,则说明未被执行到不打印
3575 0 : if (sqeInfo.type == RT_STARS_SQE_TYPE_NOTIFY_WAIT && sqeInfo.notifyId == opNotifies_[0]->notifyId_) {
3576 0 : HCCL_RUN_INFO(
3577 : "[PrintTaskExceptionAllStreams] group[%s] op is not activated, do nothing",
3578 : identifier_.c_str());
3579 0 : return HCCL_SUCCESS;
3580 : }
3581 : // 根据主流当前位置,判断该算子是否已经打印过taskException
3582 0 : if (IsRepeatedOpTaskException(sqHead, sqeContextBuffer)) {
3583 0 : HCCL_INFO(
3584 : "[PrintTaskExceptionAllStreams] group[%s] op has been printed, do nothing",
3585 : identifier_.c_str());
3586 0 : return HCCL_SUCCESS;
3587 : }
3588 : }
3589 : }
3590 :
3591 0 : uint8_t type = 0;
3592 0 : uint16_t taskId = 0;
3593 0 : uint32_t remoteRank = 0;
3594 0 : HCCL_ERROR(
3595 : "[TaskException]base information is streamId:%d, sqid:%d, head:%u, tail:%u, %s", stream.id(), stream.sqId(),
3596 : sqHead, sqTail, GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskId, remoteRank).c_str());
3597 0 : PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer);
3598 : }
3599 0 : return HCCL_SUCCESS;
3600 0 : }
3601 :
3602 0 : bool HcclCommAicpu::IsRepeatedOpTaskException(u32 idx, SqeRingBuffer* sqeContextBuffer)
3603 : {
3604 0 : const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[idx].opRingBufferIdx);
3605 0 : CHK_PRT_RET(opInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), false);
3606 0 : std::string opTag = opInfo->tagBuff;
3607 0 : u32 opIndex = opInfo->opIndex;
3608 0 : bool opHasPrinted = opTaskException_.find(opTag) != opTaskException_.end() && opTaskException_[opTag] == opIndex;
3609 0 : opTaskException_[opTag] = opIndex;
3610 0 : CHK_PRT_CONT(
3611 : opHasPrinted, HCCL_RUN_INFO(
3612 : "[IsRepeatedOpTaskException]group[%s], op[%s], opIndex[%u] "
3613 : "has been printed",
3614 : identifier_.c_str(), opInfo->tagBuff, opInfo->opIndex));
3615 0 : return opHasPrinted;
3616 0 : }
3617 :
3618 0 : void HcclCommAicpu::PrepareMc2Handler()
3619 : {
3620 0 : auto& handler = algOpContext_.mc2Handler;
3621 0 : handler.stepSize = 0U;
3622 0 : if (!isDeviceMode_) {
3623 0 : HCCL_INFO("Unset step size for non-MC2.");
3624 0 : return;
3625 : }
3626 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetStepSize, {rpc_, reinterpret_cast<u64>(&handler), GetRankSize()});
3627 : }
3628 :
3629 0 : HcclResult HcclCommAicpu::OrchestrateHcclOp(
3630 : const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
3631 : AlgResourceResponse& algResource, uint32_t& beginSqePos, uint32_t& endSqePos)
3632 : {
3633 0 : LogControl logControl(false, false); // 重执行ERROR日志控制,析构时重置日志设置
3634 0 : PrepareMc2Handler();
3635 0 : HcclResult ret = HCCL_SUCCESS;
3636 : // task的尾指针,已便重执行stop时判断是否已执行该task,如果该task已执行完成则可支持通信重执行
3637 0 : CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, beginSqePos));
3638 :
3639 0 : const bool retryForBatchSndRcv = (param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV && retryEnable_);
3640 0 : if (retryForBatchSndRcv) {
3641 0 : CHK_RET(QueryBatchSendRecvPairBeginPos());
3642 0 : if (param.BatchSendRecvDataDes.curIterNum == 0) {
3643 : // batchsendrecv算子拆分为多轮执行,只有第一个step和最后一个step需要和主stream交互
3644 0 : CHK_RET(NotifyWait());
3645 : }
3646 0 : HCCL_INFO(
3647 : "batch send recv op: step %u, mode:%u", param.BatchSendRecvDataDes.curIterNum,
3648 : param.BatchSendRecvDataDes.curMode);
3649 : } else {
3650 0 : CHK_RET(NotifyWait());
3651 : // 重执行场景, 算子计数在host侧; MC2场景也不开启卡住检测能力
3652 0 : if (opCounterInfo_.isEnableCounter && !retryEnable_ && !isDeviceMode_) {
3653 0 : CHK_RET(HcclReduceAsync(
3654 : dispatcher_, reinterpret_cast<void*>(opCounterInfo_.addOneMem),
3655 : opCounterInfo_.memSize / sizeof(int32_t), HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM, mainStream_,
3656 : reinterpret_cast<void*>(opCounterInfo_.headCountMem), INVALID_VALUE_RANKID, LinkType::LINK_ONCHIP,
3657 : INLINE_REDUCE_BIT));
3658 : }
3659 : }
3660 :
3661 : // 打印当前展开的算子信息
3662 0 : HCCL_INFO(
3663 : "[HcclCommAicpu][OrchestrateHcclOp] opUnfoldIdx_[%u] opType[%d] curRank[%u] rankSize[%u] algName[%s]",
3664 : opUnfoldIdx_, param.opType, topoInfo_.userRank, GetRankSize(), algName.c_str());
3665 0 : HCCL_INFO(
3666 : "[HcclCommAicpu][OrchestrateHcclOp] inputPtr[0x%016llx] inputSize[%llu] outputPtr[0x%016llx] outputSize[%llu]",
3667 : param.inputPtr, param.inputSize, param.outputPtr, param.outputSize);
3668 0 : opUnfoldIdx_ += 1;
3669 :
3670 : // 检查算子展开的动态缓存, 确认是否可以跳过算子展开
3671 0 : bool needExecute = true;
3672 0 : bool isCacheMiss = false;
3673 0 : auto setProfStartCallback = [this]() {
3674 0 : return this->InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeStart, {});
3675 0 : };
3676 0 : CHK_RET(aicpuCacheManager_.LookupOpUnfoldCache(
3677 : algName, param, algResource, needExecute, isCacheMiss, mainStream_, slaveStreams_, dispatcher_, isDeviceMode_,
3678 : topoInfo_, topoMatcher_, algOpContext_, ZeroCopyExchanger_, GetWorkflowMode(), tinySendRecvMem_,
3679 : setProfStartCallback));
3680 :
3681 : // 根据needExecute有条件的执行算子展开
3682 : // 需要算子执行的场景: (i) expansion mode为AI_CPU_NO_CACHE; (ii) uncacheable算子/场景; (iii) cache miss
3683 0 : if (needExecute) {
3684 : // Cache miss前执行cache相关的预处理
3685 0 : if (isCacheMiss) {
3686 0 : CHK_RET(aicpuCacheManager_.PreProcessForCacheMiss(param, executor));
3687 : }
3688 :
3689 : // executor设置AlgOpContext
3690 0 : CHK_RET(executor->SetAlgOpContext(algOpContext_));
3691 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeStart, {});
3692 0 : ret = executor->Orchestrate(param, algResource);
3693 0 : if (ret != HCCL_SUCCESS) {
3694 0 : HCCL_ERROR(
3695 : "[HcclCommAicpu][Orchestrate]executor process failed algName[%s], ret = %u", algName.c_str(), ret);
3696 0 : printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
3697 0 : return ret;
3698 : }
3699 :
3700 : // Cache miss后执行cache相关的后处理
3701 0 : if (isCacheMiss) {
3702 0 : CHK_RET(aicpuCacheManager_.PostProcessForCacheMiss(
3703 : param, executor, mainStream_, slaveStreams_, dispatcher_, topoInfo_, algOpContext_, GetWorkflowMode()));
3704 : }
3705 : } // 正常算子展开
3706 :
3707 : // batchsendrecv算子拆分为多轮执行,只有第一个step和最后一个step需要和主stream交互
3708 0 : if (!retryForBatchSndRcv || param.BatchSendRecvDataDes.curIterNum + 1 >= bsrSendRecvPairs_.size()) {
3709 : // 重执行场景, 算子计数在host侧 MC2场景也不开
3710 0 : if (opCounterInfo_.isEnableCounter && !retryEnable_ && !isDeviceMode_) {
3711 0 : CHK_RET(HcclReduceAsync(
3712 : dispatcher_, reinterpret_cast<void*>(opCounterInfo_.addOneMem),
3713 : opCounterInfo_.memSize / sizeof(int32_t), HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM, mainStream_,
3714 : reinterpret_cast<void*>(opCounterInfo_.tailCountMem), INVALID_VALUE_RANKID, LinkType::LINK_ONCHIP,
3715 : INLINE_REDUCE_BIT));
3716 : }
3717 0 : CHK_RET(NotifyPost());
3718 : }
3719 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeOrch, {});
3720 0 : ret = LaunchTask(dispatcher_, const_cast<Stream&>(mainStream_));
3721 0 : if (ret != HCCL_SUCCESS) {
3722 0 : HCCL_ERROR("[HcclCommAicpu][LaunchTask]algName[%s] ret = %u", algName.c_str(), ret);
3723 0 : printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
3724 0 : return ret;
3725 : }
3726 0 : ret = LaunchSlaveStreamTask(algResource);
3727 0 : if (ret != HCCL_SUCCESS) {
3728 0 : HCCL_ERROR("[HcclCommAicpu][LaunchSlaveStreamTask]algName[%s] ret = %u", algName.c_str(), ret);
3729 0 : printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
3730 0 : return ret;
3731 : }
3732 0 : (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeEnd, {});
3733 0 : if (retryForBatchSndRcv) {
3734 0 : CHK_RET(QueryBatchSendRecvPairEndPos());
3735 : }
3736 :
3737 0 : CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, endSqePos));
3738 :
3739 0 : HCCL_INFO(
3740 : "hccl aicpu launch hccl op task success. stream sqid:%u begin:%u end:%u", mainStream_.sqId(), beginSqePos,
3741 : endSqePos);
3742 0 : return HCCL_SUCCESS;
3743 0 : }
3744 :
3745 0 : HcclResult HcclCommAicpu::RetryOrchestrateHcclOp(
3746 : const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
3747 : AlgResourceResponse& algResource, uint32_t& beginSqePos, uint32_t& endSqePos)
3748 : {
3749 0 : LogControl logControl(false, false); // 重执行ERROR日志控制,析构时重置日志设置
3750 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3751 : param.BatchSendRecvDataDes.curMode
3752 0 : = (bsrRetryOp_ == HCCL_SEND) ? BatchSendRecvCurMode::SEND : BatchSendRecvCurMode::RECV;
3753 0 : if (param.BatchSendRecvDataDes.curMode == BatchSendRecvCurMode::SEND) {
3754 0 : HCCL_INFO(
3755 : "BSR: iter %u, retry send op tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrSendOpId_.tag,
3756 : bsrSendOpId_.index);
3757 : } else {
3758 0 : HCCL_INFO(
3759 : "BSR: iter %u, retry recv op tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrRecvOpId_.tag,
3760 : bsrRecvOpId_.index);
3761 : }
3762 : }
3763 :
3764 0 : CHK_RET(AddRetryExecFlipTask(algResource));
3765 0 : HcclResult ret = executor->Orchestrate(param, algResource);
3766 0 : if (ret != HCCL_SUCCESS) {
3767 0 : HCCL_ERROR("[HcclCommAicpu][Orchestrate]executor process failed algName[%s]", algName.c_str());
3768 0 : return ret;
3769 : }
3770 :
3771 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3772 : // batchsendrecv算子重执行时,aicpu 主stream没有clean,不需要重新下发notify record
3773 : // do nothing
3774 : } else {
3775 0 : CHK_RET(NotifyPost());
3776 : }
3777 0 : CHK_RET(LaunchTask(dispatcher_, const_cast<Stream&>(mainStream_)));
3778 0 : CHK_RET(LaunchSlaveStreamTask(algResource));
3779 :
3780 0 : CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, endSqePos));
3781 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
3782 0 : CHK_RET(QueryBatchSendRecvPairEndPos());
3783 : }
3784 :
3785 0 : HCCL_RUN_INFO(
3786 : "[OpRetry][AICPU]hccl aicpu retry launch hccl op task success. stream sqid:%u begin:%u end:%u",
3787 : mainStream_.sqId(), beginSqePos, endSqePos);
3788 0 : return HCCL_SUCCESS;
3789 0 : }
3790 :
3791 4 : bool HcclCommAicpu::IsTaskExceptionForHccs()
3792 : {
3793 4 : if (dfxExtendInfo_.cqeStatus != dfx::CqeStatus::kCqeException) {
3794 4 : return false;
3795 : }
3796 :
3797 : // NOTE: 需要task exception补全dfx能力,定位故障task的remote rank;
3798 : // 目前暂不具备识别是否跨片的能力,默认失败的task均为跨片操作。
3799 0 : if (dfxExtendInfo_.cqeException.sqeType == RT_STARS_SQE_TYPE_SDMA
3800 0 : && (dfxExtendInfo_.cqeException.errorCode == RT_SDMA_COMPDATAERR
3801 0 : || dfxExtendInfo_.cqeException.errorCode == RT_SDMA_COMPERR)) {
3802 0 : return true;
3803 : }
3804 0 : return false;
3805 : }
3806 :
3807 3 : void HcclCommAicpu::SetAlgType(u64 algType)
3808 : {
3809 3 : algType_.algoLevel0 = static_cast<AlgTypeLevel0>(static_cast<u32>(algType) & ((1 << HCCL_LEVEL_ALGO_WIDTH) - 1));
3810 3 : algType_.algoLevel1 = static_cast<AlgTypeLevel1>(
3811 3 : (static_cast<u32>(algType) >> HCCL_LEVEL_ALGO_WIDTH) & ((1 << HCCL_LEVEL_ALGO_WIDTH) - 1));
3812 : algType_.algoLevel2
3813 3 : = static_cast<AlgTypeLevel2>(static_cast<u32>(algType) >> (HCCL_LEVEL_ALGO_WIDTH + HCCL_LEVEL_ALGO_WIDTH));
3814 3 : HCCL_INFO("[HcclCommAicpu][SetAlgType]algType:%u", algType);
3815 3 : }
3816 :
3817 0 : void HcclCommAicpu::SetDebugMode(u8 debugMode) { debugMode_ = debugMode; }
3818 :
3819 0 : void HcclCommAicpu::SetSendRecvInfoPtr(void* sendRecvInfoPtr) { sendRecvInfoPtr_ = sendRecvInfoPtr; }
3820 :
3821 4 : bool HcclCommAicpu::IsNoNeedWait(void)
3822 : {
3823 4 : return isDeviceMode_ || (debugMode_ != MC2_DEBUG_WAIT_COMM && retryEnable_ == false);
3824 : }
3825 :
3826 45 : bool HcclCommAicpu::GetOpRetryEnable() { return retryEnable_; }
3827 :
3828 4 : HcclResult HcclCommAicpu::ReportHcclTaskInfo(Stream& mainStream, std::vector<Stream>& subStreams)
3829 : {
3830 4 : if (dfx::ProfilingManager::GetProfL1State()) {
3831 0 : CHK_RET(dfx::ProfilingManager::ReportTaskInfo(mainStream.id(), mainStream.GetSqeContextPtr()));
3832 0 : for (auto& subStream : subStreams) {
3833 0 : CHK_RET(dfx::ProfilingManager::ReportTaskInfo(subStream.id(), subStream.GetSqeContextPtr()));
3834 : }
3835 : }
3836 4 : return HCCL_SUCCESS;
3837 : }
3838 :
3839 4 : HcclResult HcclCommAicpu::ClearLocalBuff(Stream& mainStream, std::vector<Stream>& subStreams)
3840 : {
3841 4 : CHK_RET(mainStream.ClearLocalBuff());
3842 4 : CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(mainStream.id(), 0));
3843 4 : for (auto& subStream : subStreams) {
3844 0 : CHK_RET(subStream.ClearLocalBuff());
3845 0 : CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(subStream.id(), 0));
3846 : }
3847 4 : return HCCL_SUCCESS;
3848 : }
3849 :
3850 4 : HcclResult HcclCommAicpu::WaitFinishWhileLoop(
3851 : Stream& mainStream, std::vector<Stream>& subStreams, std::string& tag, const uint32_t& beginSqePos, OpParam& param)
3852 : {
3853 : // 上报Profiling HCCL INFO信息
3854 4 : CHK_RET(ReportHcclTaskInfo(mainStream, subStreams));
3855 4 : CHK_RET(ClearLocalBuff(mainStream, subStreams));
3856 4 : if (IsNoNeedWait()) {
3857 0 : return HCCL_SUCCESS;
3858 : }
3859 4 : const uint64_t startUsec = GetCurCpuTimestamp();
3860 4 : uint64_t lastUsec = startUsec;
3861 4 : int32_t sqId = mainStream.sqId();
3862 4 : uint32_t sqHead = 0;
3863 4 : uint32_t sqTail = 0;
3864 4 : CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_TAIL, sqTail));
3865 4 : CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_HEAD, sqHead));
3866 4 : while (sqHead != sqTail) {
3867 4 : HcclResult ret = CheckOpExecStatus(); // 检查执行状态,判断是否有异常cq或中断命令
3868 4 : CHK_PRT_RET(
3869 : ret != HCCL_SUCCESS,
3870 : HCCL_RUN_INFO("[HcclCommAicpu][WaitFinishWhileLoop]CheckOpExecStatus exception, ret[%u]", ret), ret);
3871 :
3872 0 : CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_HEAD, sqHead));
3873 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && (retryEnable_) && (sqHead != beginSqePos)
3874 0 : && (!excuteOpId_.isBsrTaskStart)) {
3875 : // 更新D2H通道里的信息opid中isBsrTaskStart = true
3876 0 : excuteOpId_.isBsrTaskStart = true;
3877 : HcclResult ret1
3878 0 : = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, excuteOpId_, KfcStatus::kRuning, KfcError::kNone, 0);
3879 0 : CHK_PRT_RET(ret1 != HCCL_SUCCESS, HCCL_ERROR("update OpExecStatus failed, ret:%u", ret1), ret1);
3880 0 : HCCL_INFO(
3881 : "[HcclCommAicpu][WaitFinishWhileLoop]bsr start task is completed. devId:%d sqid:%d, head:%u,"
3882 : "beginSqePos[%u] group[%s] tag[%s]",
3883 : devId_, sqId, sqHead, beginSqePos, identifier_.c_str(), tag.c_str());
3884 : }
3885 0 : uint64_t curUsec = GetCurCpuTimestamp();
3886 0 : if (curUsec - lastUsec > static_cast<uint64_t>(NSEC_PER_SEC) * dfx::kPrintSqInterval) {
3887 0 : lastUsec = curUsec;
3888 0 : HCCL_RUN_INFO(
3889 : "[HcclCommAicpu][WaitFinishWhileLoop]Current state. devId:%d sqid:%d, head:%u, tail:%u, "
3890 : "group[%s] tag[%s]",
3891 : devId_, sqId, sqHead, sqTail, identifier_.c_str(), tag.c_str());
3892 : }
3893 0 : CHK_RET(CheckTaskTimeout(mainStream, startUsec));
3894 : }
3895 0 : return HCCL_SUCCESS;
3896 : }
3897 :
3898 0 : HcclResult HcclCommAicpu::CheckTaskTimeout(const Stream& mainStream, const uint64_t startUsec)
3899 : {
3900 0 : if (sqeWaitTimeOut_ != 0
3901 0 : && (GetCurCpuTimestamp() - startUsec > static_cast<uint64_t>(NSEC_PER_SEC) * sqeWaitTimeOut_)) {
3902 0 : uint32_t status = 0U;
3903 0 : int32_t sqId = mainStream.sqId();
3904 0 : auto ret = QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_CQE_STATUS, status);
3905 0 : if (ret != 0) {
3906 0 : HCCL_ERROR("[HcclCommAicpu]QuerySqStatusByType status failed. ret = %u sqid:%d", ret, sqId);
3907 : }
3908 :
3909 0 : HCCL_ERROR("[HcclCommAicpu]KFC timeout.. group[%s].", identifier_.c_str());
3910 0 : printTaskExceptionForErr_ = true;
3911 0 : return HCCL_E_TIMEOUT;
3912 : }
3913 0 : return HCCL_SUCCESS;
3914 : }
3915 :
3916 0 : HcclResult HcclCommAicpu::AddRetryExecFlipTask(AlgResourceResponse& algResource)
3917 : {
3918 0 : CHK_RET(AddRetryPreamble(dispatcher_, mainStream_));
3919 0 : for (u32 i = 0; i < algResource.slaveStreams.size(); ++i) {
3920 0 : HcclResult ret = AddRetryPreamble(dispatcher_, algResource.slaveStreams[i]);
3921 0 : if (ret != HCCL_SUCCESS) {
3922 0 : HCCL_ERROR(
3923 : "[HcclCommAicpu][RetryOrchestrateHcclOp] launch place holder failed, sqid:%u, ret:%u",
3924 : algResource.slaveStreams[i].sqId(), ret);
3925 0 : return ret;
3926 : }
3927 : }
3928 0 : return HCCL_SUCCESS;
3929 : }
3930 :
3931 2 : HcclResult HcclCommAicpu::LaunchSlaveStreamTask(AlgResourceResponse& algResource)
3932 : {
3933 : // 单算子模式中在算法编排中已经执行过LaunchTask,所以这里不需要再执行
3934 : // 只有图模式需要再额外执行一次对从流中的task下发
3935 2 : if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
3936 1 : HCCL_INFO("[HcclCommAicpu][LaunchSlaveStreamTask] op base mode don't need launch slave stream task");
3937 1 : return HCCL_SUCCESS;
3938 : }
3939 :
3940 1 : for (u32 i = 0; i < algResource.slaveStreams.size(); ++i) {
3941 0 : HcclResult ret = LaunchTask(dispatcher_, algResource.slaveStreams[i]);
3942 0 : if (ret != HCCL_SUCCESS) {
3943 0 : HCCL_ERROR(
3944 : "[HcclCommAicpu][LaunchSlaveStreamTask] launch task failed, sqid:%u, ret:%u",
3945 : algResource.slaveStreams[i].sqId(), ret);
3946 0 : return ret;
3947 : }
3948 : }
3949 :
3950 1 : return HCCL_SUCCESS;
3951 : }
3952 :
3953 : HcclResult
3954 0 : HcclCommAicpu::GetAlltoAllvSendRecvInfo(const void* sendRecvInfoPtr, HcclDataType sendType, HcclDataType recvType)
3955 : {
3956 0 : allMeshAggregationSendRecvInfo_.clear();
3957 0 : u64 stepSize = sizeof(u64) * topoInfo_.userRankSize;
3958 0 : const u32 addrItemNum = 4;
3959 0 : const u32 recvLengthStep = 2;
3960 0 : const u32 recvOffsetStep = 3;
3961 0 : for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
3962 0 : SendRecvInfo sendRecvInfo;
3963 0 : sendRecvInfo.sendLength.resize(topoInfo_.userRankSize);
3964 0 : sendRecvInfo.sendOffset.resize(topoInfo_.userRankSize);
3965 0 : sendRecvInfo.recvLength.resize(topoInfo_.userRankSize);
3966 0 : sendRecvInfo.recvOffset.resize(topoInfo_.userRankSize);
3967 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
3968 : sendRecvInfo.sendLength.data(), stepSize,
3969 : static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + 0 * stepSize, stepSize));
3970 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
3971 : sendRecvInfo.sendOffset.data(), stepSize,
3972 : static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + stepSize, stepSize));
3973 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
3974 : sendRecvInfo.recvLength.data(), stepSize,
3975 : static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + recvLengthStep * stepSize,
3976 : stepSize));
3977 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
3978 : sendRecvInfo.recvOffset.data(), stepSize,
3979 : static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + recvOffsetStep * stepSize,
3980 : stepSize));
3981 0 : allMeshAggregationSendRecvInfo_.push_back(std::move(sendRecvInfo));
3982 0 : }
3983 :
3984 0 : for (auto& sendRecvInfo : allMeshAggregationSendRecvInfo_) {
3985 0 : for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
3986 0 : sendRecvInfo.sendCounts.push_back(sendRecvInfo.sendLength[i] / SIZE_TABLE[sendType]);
3987 0 : sendRecvInfo.sendDispls.push_back(sendRecvInfo.sendOffset[i] / SIZE_TABLE[sendType]);
3988 0 : sendRecvInfo.recvCounts.push_back(sendRecvInfo.recvLength[i] / SIZE_TABLE[recvType]);
3989 0 : sendRecvInfo.recvDispls.push_back(sendRecvInfo.recvOffset[i] / SIZE_TABLE[recvType]);
3990 0 : HCCL_INFO(
3991 : "[GetAlltoAllvSendRecvInfo] rank[%u], sendCounts[%llu], sendDispls[%llu], "
3992 : "recvCounts[%llu], recvDispls[%llu]",
3993 : i, sendRecvInfo.sendCounts[i], sendRecvInfo.sendDispls[i], sendRecvInfo.recvCounts[i],
3994 : sendRecvInfo.recvDispls[i]);
3995 0 : HCCL_INFO(
3996 : "[GetAlltoAllvSendRecvInfo] rank[%u], sendLength[%llu], sendOffset[%llu], "
3997 : "recvLength[%llu], recvOffset[%llu]",
3998 : i, sendRecvInfo.sendLength[i], sendRecvInfo.sendOffset[i], sendRecvInfo.recvLength[i],
3999 : sendRecvInfo.recvOffset[i]);
4000 : }
4001 : }
4002 0 : CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
4003 0 : return HCCL_SUCCESS;
4004 : }
4005 :
4006 : HcclResult
4007 0 : HcclCommAicpu::GetAlltoAllvcSendRecvInfo(const void* sendCountMatrix, HcclDataType sendType, HcclDataType recvType)
4008 : {
4009 0 : allMeshAggregationSendRecvInfo_.clear();
4010 0 : for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
4011 0 : SendRecvInfo sendRecvInfo;
4012 0 : sendRecvInfo.sendCounts.resize(topoInfo_.userRankSize);
4013 0 : sendRecvInfo.sendDispls.resize(topoInfo_.userRankSize);
4014 0 : sendRecvInfo.sendLength.resize(topoInfo_.userRankSize);
4015 0 : sendRecvInfo.sendOffset.resize(topoInfo_.userRankSize);
4016 0 : u64 curSendDispls = 0;
4017 0 : u64 curSendOffset = 0;
4018 0 : sendRecvInfo.recvCounts.resize(topoInfo_.userRankSize);
4019 0 : sendRecvInfo.recvDispls.resize(topoInfo_.userRankSize);
4020 0 : sendRecvInfo.recvLength.resize(topoInfo_.userRankSize);
4021 0 : sendRecvInfo.recvOffset.resize(topoInfo_.userRankSize);
4022 0 : u64 curRecvDispls = 0;
4023 0 : u64 curRecvOffset = 0;
4024 0 : for (u32 j = 0; j < topoInfo_.userRankSize; j++) {
4025 0 : u64 curSendCounts = *(static_cast<const u64*>(sendCountMatrix) + i * topoInfo_.userRankSize + j);
4026 0 : u64 curSendLength = curSendCounts * SIZE_TABLE[sendType];
4027 0 : sendRecvInfo.sendCounts[j] = curSendCounts;
4028 0 : sendRecvInfo.sendDispls[j] = curSendDispls;
4029 0 : sendRecvInfo.sendLength[j] = curSendLength;
4030 0 : sendRecvInfo.sendOffset[j] = curSendOffset;
4031 0 : curSendDispls += curSendCounts;
4032 0 : curSendOffset += curSendLength;
4033 0 : u64 curRecvCounts = *(static_cast<const u64*>(sendCountMatrix) + i + topoInfo_.userRankSize * j);
4034 0 : u64 curRecvLength = curRecvCounts * SIZE_TABLE[recvType];
4035 0 : sendRecvInfo.recvCounts[j] = curRecvCounts;
4036 0 : sendRecvInfo.recvDispls[j] = curRecvDispls;
4037 0 : sendRecvInfo.recvLength[j] = curRecvLength;
4038 0 : sendRecvInfo.recvOffset[j] = curRecvOffset;
4039 0 : curRecvDispls += curRecvCounts;
4040 0 : curRecvOffset += curRecvLength;
4041 0 : HCCL_DEBUG(
4042 : "GetAlltoAllvcSendRecvInfo rank[%u], sendCounts[%llu], sendDispls[%llu] "
4043 : "recvCounts[%llu], recvDispls[%llu]",
4044 : i, sendRecvInfo.sendCounts[j], sendRecvInfo.sendDispls[j], sendRecvInfo.recvCounts[j],
4045 : sendRecvInfo.recvDispls[j]);
4046 : }
4047 0 : allMeshAggregationSendRecvInfo_.push_back(sendRecvInfo);
4048 0 : }
4049 0 : CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
4050 0 : return HCCL_SUCCESS;
4051 : }
4052 :
4053 0 : HcclResult HcclCommAicpu::CheckSendRecvParams(const std::vector<SendRecvInfo>& allMeshAggregationSendRecvInfo)
4054 : {
4055 0 : u32 rankSize = allMeshAggregationSendRecvInfo.size();
4056 0 : for (u32 i = 0; i < rankSize; i++) {
4057 0 : u32 sendsSize = allMeshAggregationSendRecvInfo[i].sendLength.size();
4058 0 : u32 recvsSize = allMeshAggregationSendRecvInfo[i].recvLength.size();
4059 0 : if (rankSize != sendsSize || rankSize != recvsSize) {
4060 0 : HCCL_ERROR(
4061 : "[AlltoAllV][CheckSendRecvParam] rankSize[%u], sendsSize[%u], recvsSize[%u] are not match Index[%u]",
4062 : rankSize, sendsSize, recvsSize, i);
4063 0 : return HCCL_E_PARA;
4064 : }
4065 0 : for (u32 j = 0; j < sendsSize; j++) {
4066 0 : if (allMeshAggregationSendRecvInfo[i].sendLength[j] != allMeshAggregationSendRecvInfo[j].recvLength[i]) {
4067 0 : HCCL_ERROR(
4068 : "SendLength[%u][%u]: %llu and recvLength[%u][%u]: %llu are not match", i, j,
4069 : allMeshAggregationSendRecvInfo[i].sendLength[j], j, i,
4070 : allMeshAggregationSendRecvInfo[j].recvLength[i]);
4071 0 : return HCCL_E_PARA;
4072 : }
4073 : }
4074 : }
4075 0 : return HCCL_SUCCESS;
4076 : }
4077 0 : HcclResult HcclCommAicpu::GetStreamAll(std::vector<Stream>& streams)
4078 : {
4079 0 : streams.assign(slaveStreams_.begin(), slaveStreams_.end());
4080 0 : streams.push_back(mainStream_);
4081 0 : return HCCL_SUCCESS;
4082 : }
4083 :
4084 : // 校验是否有ERROR CQE和停止/退出命令,注册到dispatcher层调用
4085 0 : HcclResult HcclCommAicpu::CheckOpExecStatusCallback()
4086 : {
4087 0 : HcclResult ret = CheckOpExecStatus();
4088 0 : bool logLevel = (ret == HCCL_E_SUSPENDING);
4089 : // 返回HCCL_E_SUSPENDING时,需要跨作用域修改ERROR日志->RUN_WARNING
4090 0 : LogControl(logLevel, logLevel);
4091 0 : return ret;
4092 : }
4093 :
4094 4 : HcclResult HcclCommAicpu::CheckOpExecStatus()
4095 : {
4096 : // 检测是否有ERROR CQE
4097 4 : if (dfxExtendInfo_.pollStatus == PollStatus::kStopAsException) {
4098 0 : if (IsTaskExceptionForHccs() && retryEnable_) {
4099 0 : HCCL_RUN_INFO(
4100 : "[OpRetry][AICPU]hccl aicpu stop wait task exec finish, for task exception, identify[%s]",
4101 : identifier_.c_str());
4102 0 : return HCCL_E_SUSPENDING;
4103 : } else {
4104 0 : if (!printTaskExceptionForErr_) {
4105 0 : printTaskExceptionForErr_ = true;
4106 0 : HCCL_ERROR(
4107 : "hccl aicpu exec failed, for task exception, identify[%s], cqeStatus[%d], sqeType[%u], "
4108 : "errorCode[%u]",
4109 : identifier_.c_str(), dfxExtendInfo_.cqeStatus, dfxExtendInfo_.cqeException.sqeType,
4110 : dfxExtendInfo_.cqeException.errorCode);
4111 : }
4112 0 : return HCCL_E_INTERNAL;
4113 : }
4114 : }
4115 :
4116 : // 检测是否有停止/退出命令
4117 4 : KfcCommand cmd = KfcCommand::kNone;
4118 4 : CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd));
4119 4 : if (cmd == KfcCommand::kStopLaunch && retryEnable_) {
4120 4 : HCCL_RUN_INFO(
4121 : "[OpRetry][AICPU]hccl aicpu stop wait finish, for recv stop launch cmd, identify[%s]", identifier_.c_str());
4122 4 : return HCCL_E_SUSPENDING;
4123 0 : } else if ((cmd == KfcCommand::NsStopLaunch) && (endStopLaunch == false)) {
4124 0 : needsResponseStopLaunch_ = true;
4125 0 : endStopLaunch = true;
4126 0 : HCCL_RUN_INFO("hccl aicpu stop wait finish, for recv stop launch cmd");
4127 0 : return HCCL_E_SUSPENDING;
4128 0 : } else if (cmd == KfcCommand::kDestroyComm) {
4129 0 : HCCL_ERROR("hccl aicpu stop wait finish, for recv destroy comm cmd");
4130 0 : return HCCL_E_INTERNAL;
4131 0 : } else if (cmd == KfcCommand::kExit) {
4132 0 : HCCL_ERROR("hccl aicpu stop wait finish, for recv exit cmd, identify[%s]", identifier_.c_str());
4133 0 : return HCCL_E_INTERNAL;
4134 : }
4135 0 : return HCCL_SUCCESS;
4136 : }
4137 :
4138 4 : HcclResult HcclCommAicpu::UpdateSuspendStatus(
4139 : const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt)
4140 : {
4141 4 : if (needsResponseStopLaunch_ == true) {
4142 0 : HCCL_RUN_INFO("[NsRecovery][AICPU]hccl aicpu force stop in launch loop");
4143 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
4144 4 : } else if (retryEnable_) {
4145 4 : HCCL_RUN_INFO(
4146 : "[OpRetry][AICPU]hccl aicpu force stop for stop cmd or recoverable task exception, identify[%s]",
4147 : identifier_.c_str());
4148 4 : errorCode = IsTaskExceptionForHccs() ? KfcError::kSdma : errorCode;
4149 :
4150 4 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)) {
4151 0 : HcclResult ret = GetBSRRetryOpId(param, bsrTargetOpId_);
4152 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
4153 : ret, HCCL_ERROR("get batchsendrecv target op failed, ret:%u", ret), KfcError::kExec,
4154 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
4155 0 : uint32_t bsrRetryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
4156 0 : bsrTargetOpId_.isBsrTaskStart = true;
4157 0 : ret = aicpuHdc_.SetOpExecStatus(
4158 0 : kfcStatusTransferD2H_, bsrTargetOpId_, KfcStatus::kStoplaunch, errorCode, bsrRetryCnt);
4159 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
4160 : ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec,
4161 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
4162 : } else {
4163 4 : CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStoplaunch, errorCode, retryCnt));
4164 : }
4165 4 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING;
4166 : } else {
4167 0 : HCCL_RUN_INFO(
4168 : "[HcclCommAicpu][UpdateSuspendStatus] aicpu force stop in launch loop; needsResponseStopLaunch_[%u] "
4169 : "retryEnable_[%u]",
4170 : needsResponseStopLaunch_, retryEnable_);
4171 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
4172 : }
4173 4 : return HCCL_SUCCESS;
4174 : }
4175 :
4176 0 : HcclResult HcclCommAicpu::TasktypeTransferD2H(const uint8_t sqeType, TaskType& taskType)
4177 : {
4178 0 : switch (sqeType) {
4179 0 : case RT_STARS_SQE_TYPE_PLACE_HOLDER:
4180 : case RT_STARS_SQE_TYPE_NOTIFY_WAIT:
4181 0 : taskType = TaskType::TASK_NOTIFY_WAIT;
4182 0 : break;
4183 0 : case RT_STARS_SQE_TYPE_SDMA:
4184 0 : taskType = TaskType::TASK_SDMA;
4185 0 : break;
4186 0 : case RT_STARS_SQE_TYPE_NOTIFY_RECORD:
4187 0 : taskType = TaskType::TASK_NOTIFY_RECORD;
4188 0 : break;
4189 0 : case RT_STARS_SQE_TYPE_WRITE_VALUE:
4190 0 : taskType = TaskType::TASK_NOTIFY_WAIT;
4191 0 : break;
4192 0 : default:
4193 0 : HCCL_ERROR("TasktypeTransferD2H sqeType[%d] error.", sqeType);
4194 0 : return HCCL_E_PARA;
4195 : }
4196 0 : return HCCL_SUCCESS;
4197 : }
4198 :
4199 0 : HcclResult HcclCommAicpu::GenTaskExceptionInfo(u8 sqeType, hccl::Stream& stream, u32 head)
4200 : {
4201 0 : HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
4202 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
4203 0 : CHK_PTR_NULL(sqeContextBuffer);
4204 :
4205 0 : const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[head].opRingBufferIdx);
4206 0 : std::string opTag = opInfo == nullptr ? "unKnown" : opInfo->tagBuff;
4207 :
4208 : // 获取需要上报的关键信息
4209 0 : ErrorMessageReport emrInfo{};
4210 0 : SqeInfo sqeInfo;
4211 0 : SqeContextUtils::QuerySqeInfo(
4212 0 : sqeContextBuffer->rtsMirrorBuffer + head * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[head],
4213 : sqeContextBuffer->addInfo[head], &sqeInfo);
4214 0 : emrInfo.remoteUserRank = sqeContextBuffer->rtsDfxInfo[head].remoteRank;
4215 0 : emrInfo.streamId = stream.id();
4216 0 : emrInfo.taskId = sqeInfo.taskId;
4217 0 : emrInfo.notifyId = sqeInfo.notifyId;
4218 0 : emrInfo.rankId = localUserRank_;
4219 0 : emrInfo.rankSize = topoInfo_.userRankSize;
4220 0 : emrInfo.algType = algType_;
4221 0 : emrInfo.opIndex = opInfo == nullptr ? 0 : opInfo->opIndex;
4222 0 : emrInfo.count = opInfo == nullptr ? 0 : opInfo->count;
4223 0 : emrInfo.dataType = opInfo == nullptr ? 0 : opInfo->dataType;
4224 0 : emrInfo.dstAddr = opInfo == nullptr ? 0 : opInfo->dstAddr;
4225 0 : emrInfo.srcAddr = opInfo == nullptr ? 0 : opInfo->srcAddr;
4226 0 : emrInfo.reduceType = opInfo == nullptr ? 255 : opInfo->reduceType; // 255 为 HcclReduceOp::HCCL_REDUCE_RESERVED
4227 0 : CHK_RET(TasktypeTransferD2H(sqeType, emrInfo.taskType));
4228 :
4229 0 : CHK_SAFETY_FUNC_RET(memcpy_s(emrInfo.tag, sizeof(emrInfo.tag), opTag.c_str(), opTag.size()));
4230 0 : CHK_SAFETY_FUNC_RET(memcpy_s(emrInfo.group, sizeof(emrInfo.group), identifier_.c_str(), identifier_.size()));
4231 0 : CHK_RET(aicpuHdc_.SetErrorMessage(kfcStatusTransferD2H_, emrInfo));
4232 0 : return HCCL_SUCCESS;
4233 0 : }
4234 :
4235 0 : HcclResult HcclCommAicpu::PrintTaskExceptionByTaskId(u8 sqeType, u16 taskId, hccl::Stream& stream, u32 tail)
4236 : {
4237 0 : HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
4238 0 : CHK_PTR_NULL(sqeContext);
4239 0 : HCCL_ERROR("[HcclCommAicpu][PrintTaskExceptionByTaskId]streamId:%d tail:%u cqeType:%u", stream.id(), tail, sqeType);
4240 0 : SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
4241 0 : CHK_PTR_NULL(sqeContextBuffer);
4242 0 : uint8_t* sqeMirrorBufferAddr = sqeContextBuffer->rtsMirrorBuffer + (tail - 1) * HCCL_SQE_SIZE;
4243 0 : rtStarsSqeHeader_t* const sqeHeader = (rtStarsSqeHeader_t* const)sqeMirrorBufferAddr;
4244 :
4245 0 : s32 taskNum = sqeHeader->taskId - taskId;
4246 0 : HCCL_DEBUG("[HcclCommAicpu]tail sqe taskId[%u] cqe taskId[%u] cqe type[%u]", sqeHeader->taskId, taskId, sqeType);
4247 0 : s32 sqeIdx = tail - taskNum - 1;
4248 0 : u32 sqHead = (sqeIdx + HCCL_SQE_MAX_CNT) % HCCL_SQE_MAX_CNT;
4249 0 : uint8_t type = 0;
4250 0 : uint16_t taskIdTmp = 0;
4251 0 : uint32_t remoteRank = 0;
4252 0 : HCCL_ERROR(
4253 : "[TaskException][AICPU]base information is streamId:%d, sqid:%d, head:%u, tail:%u, %s", stream.id(),
4254 : stream.sqId(), sqHead, tail,
4255 : GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskIdTmp, remoteRank).c_str());
4256 0 : PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer);
4257 0 : return HCCL_SUCCESS;
4258 : }
4259 :
4260 0 : std::string HcclCommAicpu::GetTaskExceptionOpInfo(u32 idx, SqeRingBuffer* sqeContextBuffer)
4261 : {
4262 0 : const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[idx].opRingBufferIdx);
4263 0 : CHK_PRT_RET(opInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), "unKnown");
4264 :
4265 0 : std::stringstream ss;
4266 0 : ss << "tag:" << opInfo->tagBuff << ", ";
4267 0 : ss << "group:" << identifier_ << ", ";
4268 0 : ss << "isCustom:" << opInfo->isCustom << ", ";
4269 0 : ss << "opLaunchIdx:" << opInfo->opIndex << ", ";
4270 0 : ss << "opExecIdx:" << opInfo->opExecIndex << ", ";
4271 0 : ss << "count:" << opInfo->count << ", ";
4272 0 : ss << "dataType:" << static_cast<u16>(opInfo->dataType) << ", ";
4273 0 : ss << "opType:" << static_cast<u16>(opInfo->opType) << ", ";
4274 0 : ss << "rootId:" << opInfo->rootId << ", ";
4275 0 : ss << "dstAddr:0x" << std::hex << opInfo->dstAddr << ", ";
4276 0 : ss << "srcAddr:0x" << std::hex << opInfo->srcAddr << ".";
4277 0 : return ss.str();
4278 0 : }
4279 :
4280 0 : std::string HcclCommAicpu::GetTaskExceptionTaskInfo(
4281 : u32 sqHead, SqeRingBuffer* sqeContextBuffer, uint8_t& type, uint16_t& taskId, uint32_t& remoteRank)
4282 : {
4283 0 : SqeInfo sqeInfo;
4284 0 : SqeContextUtils::QuerySqeInfo(
4285 0 : sqeContextBuffer->rtsMirrorBuffer + sqHead * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[sqHead],
4286 : sqeContextBuffer->addInfo[sqHead], &sqeInfo);
4287 0 : type = sqeInfo.type;
4288 0 : taskId = sqeInfo.taskId;
4289 0 : remoteRank = sqeContextBuffer->rtsDfxInfo[sqHead].remoteRank;
4290 0 : std::stringstream ss;
4291 0 : ss << "type:" << SqeContextUtils::RtsqTaskTypeToStr(sqeInfo.type) << ", ";
4292 0 : ss << "localRank:" << localUserRank_ << ", ";
4293 0 : ss << "remoteRank:" << remoteRank << ", ";
4294 0 : ss << "taskId:" << sqeInfo.taskId << ", ";
4295 0 : ss << "notifyId:" << sqeInfo.notifyId << ", ";
4296 0 : ss << "length:" << sqeInfo.length << ", ";
4297 0 : ss << "addr1High:0x" << std::hex << sqeInfo.addr1High << ", ";
4298 0 : ss << "addr1Low:0x" << std::hex << sqeInfo.addr1Low << ", ";
4299 0 : ss << "addr2High:0x" << std::hex << sqeInfo.addr2High << ", ";
4300 0 : ss << "addr2Low:0x" << std::hex << sqeInfo.addr2Low << ".";
4301 0 : return ss.str();
4302 0 : }
4303 :
4304 : // 获取指定索引的算子信息
4305 0 : const AicpuOpInfo* HcclCommAicpu::GetOpInfoFromSqIdx(u32 sqIdx, SqeRingBuffer* sqeContextBuffer)
4306 : {
4307 0 : return aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[sqIdx].opRingBufferIdx);
4308 : }
4309 :
4310 : // 打印算子数据信息
4311 0 : void HcclCommAicpu::PrintOpDataInfo(u32 sqIdx, SqeRingBuffer* sqeContextBuffer, bool isMonitor)
4312 : {
4313 0 : std::string opInfo = GetTaskExceptionOpInfo(sqIdx, sqeContextBuffer);
4314 0 : if (isMonitor) {
4315 0 : HCCL_RUN_INFO("[StreamTaskMonitor]opData information is %s", opInfo.c_str());
4316 : } else {
4317 0 : HCCL_ERROR("[TaskException]opData information is %s", opInfo.c_str());
4318 : }
4319 0 : }
4320 :
4321 : // 打印task序列行
4322 0 : void HcclCommAicpu::PrintTaskLine(bool isMonitor, u32 lineNum, u32 totalPrinted, const std::string& taskLine) const
4323 : {
4324 0 : if (isMonitor) {
4325 0 : HCCL_RUN_INFO("[StreamTaskMonitor]task sequence[%u/%u] is %s", lineNum, totalPrinted, taskLine.c_str());
4326 : } else {
4327 0 : HCCL_ERROR("[TaskException]task sequence[%u/%u] is %s", lineNum, totalPrinted, taskLine.c_str());
4328 : }
4329 0 : }
4330 :
4331 : // 更新算子上下文
4332 0 : void HcclCommAicpu::UpdateOpContext(
4333 : u32& opIndex, std::string& opTag, u32& lineCount, std::vector<std::string>& currentOpTasks, u32 newOpIndex,
4334 : const std::string& newOpTag) const
4335 : {
4336 0 : opIndex = newOpIndex;
4337 0 : opTag = newOpTag;
4338 0 : lineCount = 0;
4339 0 : currentOpTasks.clear();
4340 0 : currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ")");
4341 0 : }
4342 :
4343 : // 准备下一行数据
4344 0 : void HcclCommAicpu::PrepareNextLine(u32 opIndex, u32& lineCount, std::vector<std::string>& currentOpTasks) const
4345 : {
4346 0 : lineCount++;
4347 0 : currentOpTasks.clear();
4348 0 : currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ") continued");
4349 0 : }
4350 :
4351 : // 拼接task列表为字符串
4352 0 : std::string HcclCommAicpu::ConcatTaskLine(const std::vector<std::string>& tasks) const
4353 : {
4354 0 : std::string taskLine;
4355 0 : for (const auto& task : tasks) {
4356 0 : taskLine += task;
4357 : }
4358 0 : return taskLine;
4359 0 : }
4360 :
4361 : // 打印剩余未满行的tasks
4362 0 : void HcclCommAicpu::PrintRemainingTasks(
4363 : bool isMonitor, u32 lineCount, u32 printedCount, const std::vector<std::string>& currentOpTasks) const
4364 : {
4365 : // size > 1 表示除了OP头还有task
4366 0 : if (currentOpTasks.size() > 1) {
4367 0 : std::string taskLine = ConcatTaskLine(currentOpTasks);
4368 0 : PrintTaskLine(isMonitor, lineCount + 1, printedCount, taskLine);
4369 0 : }
4370 0 : }
4371 :
4372 0 : void HcclCommAicpu::PrintTaskExceptionTaskQue(u32 sqIdx, SqeRingBuffer* sqeContextBuffer, bool isMonitor)
4373 : {
4374 0 : const u32 sqeNum = 200;
4375 0 : const u32 maxTasksPerLine = 50;
4376 :
4377 : // 获取初始算子信息
4378 0 : const AicpuOpInfo* lastOpInfo = GetOpInfoFromSqIdx(sqIdx, sqeContextBuffer);
4379 0 : CHK_PRT_RET(lastOpInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), );
4380 :
4381 : // 初始化状态
4382 0 : u32 opIndex = lastOpInfo->opIndex;
4383 0 : std::string opTag = lastOpInfo->tagBuff;
4384 0 : u32 lineCount = 0;
4385 0 : u32 printedCount = 0;
4386 0 : u32 extraSlotPerLine = 2;
4387 0 : std::vector<std::string> currentOpTasks;
4388 0 : currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ")");
4389 :
4390 : // 主循环:遍历并打印
4391 0 : for (u32 i = 0; i < sqeNum; i++) {
4392 : // 计算新索引并获取算子信息
4393 0 : u32 newSqIdx = (sqIdx - i + HCCL_SQE_MAX_CNT) % HCCL_SQE_MAX_CNT;
4394 0 : const AicpuOpInfo* newOpInfo = GetOpInfoFromSqIdx(newSqIdx, sqeContextBuffer);
4395 0 : CHK_PRT_RET(newOpInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), );
4396 :
4397 0 : u32 sizeAfterAdd = currentOpTasks.size() + 1;
4398 0 : if (sizeAfterAdd >= (maxTasksPerLine + extraSlotPerLine)
4399 0 : || (i > 0 && (newOpInfo->opIndex != opIndex || newOpInfo->tagBuff != opTag))) {
4400 : // 打印算子信息(仅第一次)
4401 0 : if (lineCount == 0) {
4402 0 : PrintOpDataInfo(sqIdx, sqeContextBuffer, isMonitor);
4403 : }
4404 :
4405 : // 拼接并打印task行
4406 0 : std::string taskLine = ConcatTaskLine(currentOpTasks);
4407 0 : PrintTaskLine(isMonitor, lineCount + 1, printedCount, taskLine);
4408 :
4409 : // 更新状态
4410 0 : if (newOpInfo->opIndex != opIndex || newOpInfo->tagBuff != opTag) {
4411 0 : UpdateOpContext(opIndex, opTag, lineCount, currentOpTasks, newOpInfo->opIndex, newOpInfo->tagBuff);
4412 : } else {
4413 0 : PrepareNextLine(opIndex, lineCount, currentOpTasks);
4414 : }
4415 0 : }
4416 : // 添加task到序列
4417 0 : currentOpTasks.push_back("," + GetTaskBriefsInfo(newSqIdx, sqeContextBuffer));
4418 0 : printedCount++;
4419 : }
4420 : // 打印剩余tasks
4421 0 : PrintRemainingTasks(isMonitor, lineCount, printedCount, currentOpTasks);
4422 0 : }
4423 :
4424 0 : std::string HcclCommAicpu::GetTaskBriefsInfo(u32 idx, SqeRingBuffer* sqeContextBuffer)
4425 : {
4426 0 : uint8_t* sqeMirrorBufferAddr = sqeContextBuffer->rtsMirrorBuffer + idx * HCCL_SQE_SIZE;
4427 0 : rtStarsSqeHeader_t* const sqeHeader = (rtStarsSqeHeader_t* const)sqeMirrorBufferAddr;
4428 0 : uint8_t sqeType = sqeHeader->type;
4429 :
4430 0 : SqeInfo sqeInfo;
4431 0 : SqeContextUtils::QuerySqeInfo(
4432 0 : sqeContextBuffer->rtsMirrorBuffer + idx * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[idx],
4433 : sqeContextBuffer->addInfo[idx], &sqeInfo);
4434 0 : uint8_t subType = sqeInfo.subType;
4435 :
4436 0 : std::stringstream ss;
4437 0 : std::string taskName = "UN";
4438 0 : switch (sqeType) {
4439 0 : case RT_STARS_SQE_TYPE_NOTIFY_RECORD:
4440 0 : taskName = "NR"; // Notify Record
4441 0 : break;
4442 0 : case RT_STARS_SQE_TYPE_WRITE_VALUE:
4443 0 : if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_NOTIFY_RECORD_IPC_NO_PCIE) {
4444 0 : taskName = "NR";
4445 0 : } else if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_EVENT_RESET) {
4446 0 : taskName = "NW"; // Notify Wait
4447 0 : } else if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_RDMA_DB_SEND) {
4448 0 : taskName = "RS"; // Rdma Send
4449 : }
4450 0 : break;
4451 0 : case RT_STARS_SQE_TYPE_NOTIFY_WAIT:
4452 0 : taskName = "NW";
4453 0 : break;
4454 0 : case RT_STARS_SQE_TYPE_EVENT_WAIT:
4455 0 : taskName = "NW";
4456 0 : break;
4457 0 : case RT_STARS_SQE_TYPE_SDMA:
4458 0 : taskName = "SD"; // SDMA
4459 0 : break;
4460 0 : case RT_STARS_SQE_TYPE_COND:
4461 0 : taskName = "CO";
4462 0 : break;
4463 0 : case RT_STARS_SQE_TYPE_PLACE_HOLDER:
4464 0 : taskName = "PH";
4465 0 : break;
4466 0 : default:
4467 0 : taskName = std::to_string(sqeType);
4468 0 : break;
4469 : }
4470 :
4471 0 : ss << taskName << "(";
4472 0 : if (sqeContextBuffer->rtsDfxInfo[idx].remoteRank != INVALID_VALUE_RANKID) {
4473 0 : ss << sqeContextBuffer->rtsDfxInfo[idx].remoteRank;
4474 : } else {
4475 0 : ss << "/";
4476 : }
4477 0 : ss << ",";
4478 0 : if (sqeContextBuffer->rtsDfxInfo[idx].notifyId != INVALID_VALUE_RANKID) {
4479 0 : ss << sqeContextBuffer->rtsDfxInfo[idx].notifyId;
4480 : } else {
4481 0 : ss << "/";
4482 : }
4483 0 : ss << ")";
4484 0 : return ss.str();
4485 0 : }
4486 :
4487 1 : void HcclCommAicpu::RecordReportStatus(dfx::ReportStatus status)
4488 : {
4489 1 : std::unique_lock<std::mutex> lock(reportQueueMutex_);
4490 1 : while (reportStatusQueue_.size() >= MAX_REPORT_STATUS) {
4491 0 : HCCL_WARNING(
4492 : "[HcclCommAicpu][RecordReportStatus] retry status queue reach the limit[%u], "
4493 : "the front status[%u] is dropped.",
4494 : MAX_REPORT_STATUS, reportStatusQueue_.front());
4495 0 : reportStatusQueue_.pop();
4496 : }
4497 1 : reportStatusQueue_.push(status);
4498 1 : HCCL_INFO("[HcclCommAicpu][RecordReportStatus]push[%u], retry queue size()[%u]", status, reportStatusQueue_.size());
4499 1 : }
4500 :
4501 0 : void HcclCommAicpu::GetReportStatusQueue(std::queue<dfx::ReportStatus>& reportStatusQue)
4502 : {
4503 0 : std::unique_lock<std::mutex> lock(reportQueueMutex_);
4504 0 : std::swap(reportStatusQueue_, reportStatusQue);
4505 0 : }
4506 :
4507 0 : void HcclCommAicpu::SetStreamCqeExceptionStatus(const Stream& stream, CqeExceptionStatus cqeStatus)
4508 : {
4509 0 : HCCL_RUN_INFO("SetStreamCqeExceptionStatus: stream sq id %u, cqe exception %u", stream.sqId(), cqeStatus);
4510 0 : auto iter = streamCqeExceptionStatus_.find(stream.sqId());
4511 0 : if (iter != streamCqeExceptionStatus_.end()) {
4512 0 : iter->second = cqeStatus;
4513 : } else {
4514 0 : streamCqeExceptionStatus_.insert({stream.sqId(), cqeStatus});
4515 : }
4516 0 : return;
4517 : }
4518 :
4519 0 : CqeExceptionStatus HcclCommAicpu::GetStreamCqeExceptionStatus(const Stream& stream)
4520 : {
4521 0 : auto iter = streamCqeExceptionStatus_.find(stream.sqId());
4522 0 : if (iter != streamCqeExceptionStatus_.end()) {
4523 0 : return iter->second;
4524 : } else {
4525 0 : return CqeExceptionStatus::kNone;
4526 : }
4527 : }
4528 :
4529 0 : void HcclCommAicpu::ResetStreamCqeExceptionStatus(const Stream& stream)
4530 : {
4531 0 : auto iter = streamCqeExceptionStatus_.find(stream.sqId());
4532 0 : if (iter != streamCqeExceptionStatus_.end()) {
4533 0 : iter->second = CqeExceptionStatus::kNone;
4534 : }
4535 0 : HCCL_INFO("ResetStreamCqeExceptionStatus: stream sq id %u", stream.sqId());
4536 0 : return;
4537 : }
4538 :
4539 0 : void HcclCommAicpu::SetBSRSendOpExecException()
4540 : {
4541 0 : HCCL_INFO("set send stream exec exception");
4542 0 : bsrSendOpExecException_ = true;
4543 0 : return;
4544 : }
4545 :
4546 0 : void HcclCommAicpu::SetBSRRecvOpExecException()
4547 : {
4548 0 : HCCL_INFO("set recv stream exec exception");
4549 0 : bsrRecvOpExecException_ = true;
4550 0 : return;
4551 : }
4552 :
4553 0 : bool HcclCommAicpu::GetBSRSendOpExecException()
4554 : {
4555 0 : bool ret = (GetStreamCqeExceptionStatus(bsrSendStream_) == CqeExceptionStatus::kSdmaErr) || bsrSendOpExecException_;
4556 0 : HCCL_INFO(
4557 : "GetBSRSendOpExecException: stream %u cqe status %u, send exec status %u", bsrSendStream_.sqId(),
4558 : GetStreamCqeExceptionStatus(bsrSendStream_), bsrSendOpExecException_);
4559 0 : return ret;
4560 : }
4561 :
4562 0 : bool HcclCommAicpu::GetBSRRecvOpExecException()
4563 : {
4564 0 : HCCL_INFO(
4565 : "GetBSRRecvOpExecException: stream %u cqe status %u, recv exec status %u", bsrRecvStream_.sqId(),
4566 : GetStreamCqeExceptionStatus(bsrRecvStream_), bsrRecvOpExecException_);
4567 0 : return (GetStreamCqeExceptionStatus(bsrRecvStream_) == CqeExceptionStatus::kSdmaErr) || bsrRecvOpExecException_;
4568 : }
4569 :
4570 0 : HcclResult HcclCommAicpu::CleanStream(Stream& stream)
4571 : {
4572 0 : CHK_RET(stream.ClearLocalBuff());
4573 0 : CHK_RET(UpdateSqStatus(stream));
4574 0 : ResetStreamCqeExceptionStatus(stream);
4575 0 : HCCL_INFO("CleanStream %u success.", stream.sqId());
4576 0 : return HCCL_SUCCESS;
4577 : }
4578 :
4579 0 : HcclResult HcclCommAicpu::ClearStreamCqeException(Stream& stream)
4580 : {
4581 0 : HandleCqeException(stream, true);
4582 0 : return HCCL_SUCCESS;
4583 : }
4584 :
4585 0 : HcclResult HcclCommAicpu::ResetBSRSendOpExecException()
4586 : {
4587 0 : bsrSendOpExecException_ = false;
4588 0 : CHK_RET(CleanStream(bsrSendStream_));
4589 0 : CHK_RET(ClearStreamCqeException(bsrSendStream_));
4590 0 : HCCL_INFO("ResetBSRSendOpExecException success.");
4591 0 : return HCCL_SUCCESS;
4592 : }
4593 :
4594 0 : HcclResult HcclCommAicpu::ResetBSRRecvOpExecException()
4595 : {
4596 0 : bsrRecvOpExecException_ = false;
4597 0 : CHK_RET(CleanStream(bsrRecvStream_));
4598 0 : CHK_RET(ClearStreamCqeException(bsrRecvStream_));
4599 0 : HCCL_INFO("ResetBSRRecvOpExecException success.");
4600 0 : return HCCL_SUCCESS;
4601 : }
4602 :
4603 0 : HcclResult HcclCommAicpu::ResetBSRException()
4604 : {
4605 0 : if (bsrRetryOp_ == HCCL_SEND) {
4606 0 : CHK_RET(ResetBSRSendOpExecException());
4607 0 : HCCL_INFO("reset batchsendrecv exception success, tag:%s, index:%u", bsrSendOpId_.tag, bsrSendOpId_.index);
4608 0 : } else if (bsrRetryOp_ == HCCL_RECV) {
4609 0 : CHK_RET(ResetBSRRecvOpExecException());
4610 0 : HCCL_INFO("reset batchsendrecv exception success, tag:%s, index:%u", bsrRecvOpId_.tag, bsrRecvOpId_.index);
4611 : } else {
4612 0 : HCCL_INFO("reset batchsendrecv exception success, tag:%s", bsrTargetOpId_.tag);
4613 : }
4614 0 : return HCCL_SUCCESS;
4615 : }
4616 :
4617 0 : void HcclCommAicpu::UpdateBSRRetryCnt()
4618 : {
4619 0 : if (bsrRetryOp_ == HCCL_SEND) {
4620 0 : bsrSendRetryCnt_++;
4621 : } else {
4622 0 : bsrRecvRetryCnt_++;
4623 : }
4624 0 : HCCL_INFO("UpdateBSRRetryCnt, SendCnt[%u], RecvCnt[%u]", bsrRecvRetryCnt_, bsrRecvRetryCnt_);
4625 0 : return;
4626 : }
4627 :
4628 0 : void HcclCommAicpu::ResetBSRRetryCnt()
4629 : {
4630 0 : bsrSendRetryCnt_ = 0;
4631 0 : bsrRecvRetryCnt_ = 0;
4632 0 : return;
4633 : }
4634 :
4635 0 : void HcclCommAicpu::InitSendRecvOpId(const OpParam& param, HcclOpIdentifier& opId)
4636 : {
4637 : // send算子入参中只有dst对端rank号,而recv算子入参中只有src源端rank号
4638 0 : if (param.opType == HcclCMDType::HCCL_CMD_SEND) {
4639 0 : opId.detRank = param.dstRank;
4640 0 : opId.srcRank = topoInfo_.userRank;
4641 : } else {
4642 0 : opId.srcRank = param.srcRank;
4643 0 : opId.detRank = topoInfo_.userRank;
4644 : }
4645 0 : opId.isSendRecv = true;
4646 0 : HCCL_DEBUG(
4647 : "[HcclCommAicpu][InitSendRecvOpId]src=[%u] dst=[%u] isSendRecv=[%u]", opId.srcRank, opId.detRank,
4648 : opId.isSendRecv);
4649 0 : return;
4650 : }
4651 :
4652 0 : u32 HcclCommAicpu::HcclUpdateBatchSendRecvOpIndex(std::map<u32, u32>& bsrIndexMap, u32 peerRank)
4653 : {
4654 0 : u32 ret = 0;
4655 0 : auto opIndexMapIter = bsrIndexMap.find(peerRank);
4656 0 : if (opIndexMapIter != bsrIndexMap.end()) {
4657 0 : (opIndexMapIter->second)++;
4658 0 : ret = opIndexMapIter->second;
4659 : } else {
4660 0 : bsrIndexMap.insert({peerRank, 1});
4661 0 : ret = 1;
4662 : }
4663 0 : return ret;
4664 : }
4665 :
4666 0 : u32 HcclCommAicpu::HcclUpdateBatchSendRecvOpIndex(HcclSendRecvType opType, u32 srcRank, u32 dstRank)
4667 : {
4668 0 : u32 peerRank = (opType == HcclSendRecvType::HCCL_SEND) ? dstRank : srcRank;
4669 0 : auto& opIndexMap = (opType == HcclSendRecvType::HCCL_SEND) ? bsrSendIndexMap_ : bsrRecvIndexMap_;
4670 :
4671 0 : return HcclUpdateBatchSendRecvOpIndex(opIndexMap, peerRank);
4672 : }
4673 : HcclResult
4674 0 : HcclCommAicpu::GetBsrTransportQpn(const HcclSendRecvItem* sendrecvPair, AlgResourceResponse& algResource, u32& qpn)
4675 : {
4676 0 : CHK_PTR_NULL(sendrecvPair);
4677 0 : LINK targetLink;
4678 0 : u32 commIndex = 0;
4679 0 : u32 remoteRank = sendrecvPair->remoteRank;
4680 0 : u32 localRank = topoInfo_.userRank;
4681 0 : HcclSendRecvType sendRecvType = sendrecvPair->sendRecvType;
4682 0 : HCCL_DEBUG(
4683 : "[GetBsrTransportQpn] bsrOptype =[%d], localRank=[%u] remoteRank=[%u]", sendRecvType, localRank, remoteRank);
4684 :
4685 0 : if ((sendRecvType == HcclSendRecvType::HCCL_SEND && remoteRank < localRank)
4686 0 : || (sendRecvType == HcclSendRecvType::HCCL_RECV && remoteRank > localRank)) {
4687 0 : commIndex = COMM_INDEX_0;
4688 : } else {
4689 0 : commIndex = COMM_INDEX_1;
4690 : }
4691 0 : CHK_PRT_RET(
4692 : commIndex >= algResource.opTransportResponse[COMM_COMBINE_ORDER].size(),
4693 : HCCL_ERROR(
4694 : "[GetBsrTransportQpn] batchsendrecv op commIndex[%u] is larger than "
4695 : "opTransportResponse size[%zu]",
4696 : commIndex, algResource.opTransportResponse[COMM_COMBINE_ORDER].size()),
4697 : HCCL_E_PARA);
4698 : SingleSubCommTransport& commCombined
4699 0 : = static_cast<SingleSubCommTransport&>(algResource.opTransportResponse[COMM_COMBINE_ORDER][commIndex]);
4700 :
4701 0 : CHK_PRT_RET(
4702 : sendrecvPair->remoteRank >= commCombined.userRank2subCommRank.size(),
4703 : HCCL_ERROR(
4704 : "[GetBsrTransportQpn]batchsendrecv op remoteUserRank[%u] is larger than "
4705 : "userRank2subCommRank map size[%zu]",
4706 : sendrecvPair->remoteRank, commCombined.userRank2subCommRank.size()),
4707 : HCCL_E_PARA);
4708 :
4709 0 : u32 rank = commCombined.userRank2subCommRank[sendrecvPair->remoteRank];
4710 0 : CHK_PRT_RET(
4711 : rank >= commCombined.links.size(),
4712 : HCCL_ERROR(
4713 : "[GetBsrTransportQpn] batchsendrecv op remoteUserRank[%u], get rank[%u],"
4714 : "the size of combinedComm links is [%zu]",
4715 : sendrecvPair->remoteRank, rank, commCombined.links.size()),
4716 : HCCL_E_PARA);
4717 0 : targetLink = commCombined.links[rank];
4718 :
4719 0 : CHK_SMART_PTR_NULL(targetLink);
4720 0 : if (targetLink->GetLinkType() == LinkType::LINK_ROCE) {
4721 0 : CHK_RET(targetLink->GetTransportId(qpn));
4722 : }
4723 0 : HCCL_DEBUG(
4724 : "[HcclCommAicpu][GetBsrTransportQpn] localrank=[%u] remoteuserRank=[%u] remoteRank=[%u],sendrecvType=[%d] qpn "
4725 : "=[%u], comindex [%u]",
4726 : topoInfo_.userRank, sendrecvPair->remoteRank, remoteRank, sendrecvPair->sendRecvType, qpn, commIndex);
4727 0 : return HCCL_SUCCESS;
4728 0 : }
4729 0 : HcclResult HcclCommAicpu::InitBatchSendRecvOpId(
4730 : const OpParam& param, const HcclSendRecvItem* sendrecvPair, HcclOpIdentifier& opId, u32 streamId,
4731 : AlgResourceResponse& algResource)
4732 : {
4733 0 : CHK_PTR_NULL(sendrecvPair);
4734 0 : if (sendrecvPair->sendRecvType == HcclSendRecvType::HCCL_RECV) {
4735 0 : opId.srcRank = sendrecvPair->remoteRank;
4736 0 : opId.detRank = topoInfo_.userRank;
4737 : } else {
4738 0 : opId.srcRank = topoInfo_.userRank;
4739 0 : opId.detRank = sendrecvPair->remoteRank;
4740 : }
4741 0 : opId.index = HcclUpdateBatchSendRecvOpIndex(sendrecvPair->sendRecvType, opId.srcRank, opId.detRank);
4742 0 : opId.isSendRecv = true;
4743 0 : opId.opType = HcclCMDType::HCCL_CMD_BATCH_SEND_RECV;
4744 0 : std::string sendrecvTag = param.tag + "_BSR_" + std::to_string(opId.srcRank) + "_" + std::to_string(opId.detRank);
4745 0 : CHK_SAFETY_FUNC_RET(memcpy_s(opId.tag, sizeof(opId.tag), sendrecvTag.c_str(), sendrecvTag.size()));
4746 0 : std::string sendrecvNewTag = param.tag + "_device";
4747 0 : CHK_SAFETY_FUNC_RET(memcpy_s(opId.newTag, sizeof(opId.newTag), sendrecvNewTag.c_str(), sendrecvNewTag.size()));
4748 :
4749 0 : u32 qpn = 0;
4750 0 : if ((opId.srcRank != opId.detRank) && (!param.BatchSendRecvDataDes.isDirectRemoteRank[sendrecvPair->remoteRank])) {
4751 0 : CHK_RET(GetBsrTransportQpn(sendrecvPair, algResource, qpn));
4752 : }
4753 :
4754 0 : auto& bsrinfo = opId.bsrInfo[sendrecvPair->sendRecvType];
4755 0 : bsrinfo.detRank = opId.detRank;
4756 0 : bsrinfo.srcRank = opId.srcRank;
4757 0 : bsrinfo.index = opId.index;
4758 0 : bsrinfo.streamId = streamId;
4759 0 : bsrinfo.tpQpn = qpn;
4760 0 : CHK_SAFETY_FUNC_RET(memcpy_s(bsrinfo.bsrTag, sizeof(bsrinfo.bsrTag), sendrecvTag.c_str(), sendrecvTag.size()));
4761 :
4762 0 : HCCL_INFO(
4763 : "[HcclCommAicpu][InitBatchSendRecvOpId] tag=[%s] index=[%u] src=[%u] det=[%u] qpn =[%u]", opId.tag, opId.index,
4764 : opId.srcRank, opId.detRank, qpn);
4765 0 : return HCCL_SUCCESS;
4766 0 : }
4767 :
4768 0 : HcclResult HcclCommAicpu::InitBatchSendRecvOpId(const OpParam& param, AlgResourceResponse& algResource)
4769 : {
4770 0 : CHK_SAFETY_FUNC_RET(
4771 : memset_s(reinterpret_cast<void*>(&bsrSendOpId_), sizeof(bsrSendOpId_), 0, sizeof(bsrSendOpId_)));
4772 0 : CHK_SAFETY_FUNC_RET(
4773 : memset_s(reinterpret_cast<void*>(&bsrRecvOpId_), sizeof(bsrRecvOpId_), 0, sizeof(bsrRecvOpId_)));
4774 :
4775 0 : CHK_PRT_RET(
4776 : (algResource.slaveStreams.size() < BSR_RETRY_STREAM_NUM),
4777 : HCCL_ERROR("in batchsendrecv op, slave stream is not enough."), HCCL_E_INTERNAL);
4778 0 : bsrSendOpId_.streamId = algResource.slaveStreams[BSR_RETRY_SEND_STREAM_INDEX].id();
4779 0 : bsrRecvOpId_.streamId = algResource.slaveStreams[BSR_RETRY_RECV_STREAM_INDEX].id();
4780 :
4781 0 : u32 iter = param.BatchSendRecvDataDes.curIterNum;
4782 0 : std::vector<std::vector<HcclSendRecvItem*>>& pairs = bsrSendRecvPairs_;
4783 0 : CHK_PRT_RET(
4784 : (pairs.size() <= iter),
4785 : HCCL_ERROR("batchsendrecv sendrecv pairs size[%u] less than or equal to curiter[%u]", pairs.size(), iter),
4786 : HCCL_E_INTERNAL);
4787 :
4788 0 : for (auto& pair : pairs[iter]) {
4789 0 : HcclOpIdentifier& opId = (pair->sendRecvType == HcclSendRecvType::HCCL_SEND) ? bsrSendOpId_ : bsrRecvOpId_;
4790 0 : auto streamId
4791 0 : = (pair->sendRecvType == HcclSendRecvType::HCCL_SEND) ? bsrSendOpId_.streamId : bsrRecvOpId_.streamId;
4792 0 : CHK_RET(InitBatchSendRecvOpId(param, pair, opId, streamId, algResource));
4793 : }
4794 :
4795 : // 补全batchsendrecv中sendrecv的bsrInfo, 两边都发生故障的时候要用
4796 0 : bsrSendOpId_.bsrInfo[HCCL_RECV].index = bsrRecvOpId_.index;
4797 0 : bsrSendOpId_.bsrInfo[HCCL_RECV].streamId = bsrRecvOpId_.streamId;
4798 0 : bsrSendOpId_.bsrInfo[HCCL_RECV].srcRank = bsrRecvOpId_.srcRank;
4799 0 : bsrSendOpId_.bsrInfo[HCCL_RECV].detRank = bsrRecvOpId_.detRank;
4800 0 : bsrSendOpId_.bsrInfo[HCCL_RECV].tpQpn = bsrRecvOpId_.bsrInfo[HCCL_RECV].tpQpn;
4801 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
4802 : bsrSendOpId_.bsrInfo[HCCL_RECV].bsrTag, sizeof(bsrSendOpId_.bsrInfo[HCCL_RECV].bsrTag), bsrRecvOpId_.tag,
4803 : sizeof(bsrRecvOpId_.tag)));
4804 :
4805 0 : bsrRecvOpId_.bsrInfo[HCCL_SEND].index = bsrSendOpId_.index;
4806 0 : bsrRecvOpId_.bsrInfo[HCCL_SEND].streamId = bsrSendOpId_.streamId;
4807 0 : bsrRecvOpId_.bsrInfo[HCCL_SEND].srcRank = bsrSendOpId_.srcRank;
4808 0 : bsrRecvOpId_.bsrInfo[HCCL_SEND].detRank = bsrSendOpId_.detRank;
4809 0 : bsrRecvOpId_.bsrInfo[HCCL_SEND].tpQpn = bsrSendOpId_.bsrInfo[HCCL_SEND].tpQpn;
4810 0 : CHK_SAFETY_FUNC_RET(memcpy_s(
4811 : bsrRecvOpId_.bsrInfo[HCCL_SEND].bsrTag, sizeof(bsrRecvOpId_.bsrInfo[HCCL_SEND].bsrTag), bsrSendOpId_.tag,
4812 : sizeof(bsrSendOpId_.tag)));
4813 0 : return HCCL_SUCCESS;
4814 : }
4815 :
4816 0 : HcclResult HcclCommAicpu::QueryBatchSendRecvPairBeginPos()
4817 : {
4818 : // 前面已经生成 batchsendrecv 的 send & recv opid 时已经校验过slave stream num数,此处不再重复校验
4819 0 : CHK_RET(QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrSendOpBeginSqePos_));
4820 0 : CHK_RET(QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrRecvOpBeginSqePos_));
4821 :
4822 0 : HCCL_INFO(
4823 : "QueryBatchSendRecvPairBeginPos send sqePos[%u] recv sqePos[%u]", bsrSendOpBeginSqePos_, bsrRecvOpBeginSqePos_);
4824 0 : return HCCL_SUCCESS;
4825 : }
4826 :
4827 0 : HcclResult HcclCommAicpu::QueryBatchSendRecvPairEndPos()
4828 : {
4829 : // 前面已经生成 batchsendrecv 的 send & recv opid 时已经校验过slave stream num数,此处不再重复校验
4830 0 : CHK_RET(QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrSendOpEndSqePos_));
4831 0 : CHK_RET(QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrRecvOpEndSqePos_));
4832 :
4833 0 : HCCL_INFO("QueryBatchSendRecvPairEndPos send sqePos[%u] recv sqePos[%u]", bsrSendOpEndSqePos_, bsrRecvOpEndSqePos_);
4834 0 : return HCCL_SUCCESS;
4835 : }
4836 :
4837 0 : HcclResult HcclCommAicpu::CommitBSRStoredException(HcclOpExecFSM& fsmState, KfcError& errorCode)
4838 : {
4839 0 : if (GetBSRSendOpExecException()) {
4840 0 : bsrRetryOp_ = HCCL_SEND;
4841 0 : errorCode = KfcError::kSdma;
4842 0 : HCCL_INFO("CommitBSRStoredException: send stream remain retry error.");
4843 0 : } else if (GetBSRRecvOpExecException()) {
4844 0 : bsrRetryOp_ = HCCL_RECV;
4845 0 : errorCode = KfcError::kSdma;
4846 0 : HCCL_INFO("CommitBSRStoredException: recv stream remain retry error.");
4847 : }
4848 :
4849 0 : u32 retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
4850 0 : if (errorCode != KfcError::kNone) {
4851 0 : bsrTargetOpId_ = (bsrRetryOp_ == HCCL_SEND) ? bsrSendOpId_ : bsrRecvOpId_;
4852 0 : HCCL_RUN_INFO(
4853 : "CommitBSRStoredException: stored op tag %s index %u , report retry error. curSendRetryCnt[%u],"
4854 : "curRecvRetryCnt[%u]",
4855 : bsrTargetOpId_.tag, bsrTargetOpId_.index, bsrSendRetryCnt_, bsrRecvRetryCnt_);
4856 0 : auto ret = aicpuHdc_.SetOpExecStatus(
4857 0 : kfcStatusTransferD2H_, bsrTargetOpId_, KfcStatus::kStoplaunch, errorCode, retryCnt);
4858 0 : HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
4859 : ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec,
4860 : HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
4861 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING;
4862 : } else {
4863 0 : CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kRuning, errorCode, retryCnt));
4864 0 : fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
4865 : }
4866 0 : return HCCL_SUCCESS;
4867 : }
4868 :
4869 0 : HcclResult HcclCommAicpu::GetBSRRetryOpId(const OpParam& param, HcclOpIdentifier& targetOpId)
4870 : {
4871 0 : KfcCommand cmd = KfcCommand::kNone;
4872 0 : CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd));
4873 0 : if (cmd == KfcCommand::kStopLaunch) {
4874 0 : HcclOpIdentifier targetOp;
4875 0 : CHK_RET(aicpuHdc_.GetOpExecCtrlTargetOp(kfcControlTransferH2D_, targetOp));
4876 0 : std::string targetOpTag = std::string(reinterpret_cast<char*>(&targetOp.tag[0]));
4877 0 : if (targetOpTag == std::string(reinterpret_cast<char*>(&bsrSendOpId_.tag[0]))) {
4878 0 : bsrRetryOp_ = HCCL_SEND;
4879 0 : } else if (targetOpTag == std::string(reinterpret_cast<char*>(&bsrRecvOpId_.tag[0]))) {
4880 0 : bsrRetryOp_ = HCCL_RECV;
4881 0 : } else if (targetOpTag == param.tag) {
4882 0 : if (targetOp.detRank == bsrSendOpId_.detRank) {
4883 0 : bsrRetryOp_ = HCCL_SEND;
4884 0 : } else if (targetOp.srcRank == bsrRecvOpId_.srcRank) {
4885 0 : bsrRetryOp_ = HCCL_RECV;
4886 : } else {
4887 0 : HCCL_ERROR(
4888 : "hccl aicpu can not retry, got stop launch command, but target op srcRank[%u] and"
4889 : "dstRank[%u] is not match with send (dst:%u) or recv (src:%u) op",
4890 : targetOp.srcRank, targetOp.detRank, bsrSendOpId_.detRank, bsrRecvOpId_.srcRank);
4891 0 : return HCCL_E_INTERNAL;
4892 : }
4893 : } else {
4894 : // tag 不匹配,报错退出
4895 0 : HCCL_ERROR(
4896 : "hccl aicpu can not retry, got stop launch command, but target op tag[%s] is not match with"
4897 : "send (tag:%s) or recv (tag:%s) or batchsendrecv (tag:%s)",
4898 : targetOpTag.c_str(), bsrSendOpId_.tag, bsrRecvOpId_.tag, param.tag.c_str());
4899 0 : return HCCL_E_INTERNAL;
4900 : }
4901 0 : HCCL_RUN_INFO("hccl aicpu got command %u at op[tag: %s, index: %u].", cmd, targetOpTag.c_str(), targetOp.index);
4902 0 : } else {
4903 0 : if (GetBSRSendOpExecException()) {
4904 0 : bsrRetryOp_ = HCCL_SEND;
4905 0 : } else if (GetBSRRecvOpExecException()) {
4906 0 : bsrRetryOp_ = HCCL_RECV;
4907 : } else {
4908 : // 其他场景,报错退出
4909 0 : HCCL_ERROR("hccl aicpu find task exception, but send and recv op has no exception");
4910 0 : return HCCL_E_INTERNAL;
4911 : }
4912 : }
4913 0 : if (bsrRetryOp_ == HCCL_SEND) {
4914 0 : targetOpId = bsrSendOpId_;
4915 : } else {
4916 0 : targetOpId = bsrRecvOpId_;
4917 : }
4918 0 : HCCL_RUN_INFO(
4919 : "GetBSRRetryOpId: bsrRetryOpType %u, targetOpId: tag %s, index %u", bsrRetryOp_, targetOpId.tag,
4920 : targetOpId.index);
4921 0 : return HCCL_SUCCESS;
4922 : }
4923 :
4924 0 : HcclResult HcclCommAicpu::InitExecLoop(OpParam& param, std::unique_ptr<CollExecutorBase>& executor, u32& loopNum)
4925 : {
4926 0 : if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
4927 0 : CHK_RET(executor->CreatePairWiseList(
4928 : param.BatchSendRecvDataDes.sendRecvItemsPtr, param.BatchSendRecvDataDes.itemNum));
4929 0 : CHK_RET(executor->GetPairWiseList(bsrSendRecvPairs_));
4930 0 : CHK_PRT_RET(
4931 : bsrSendRecvPairs_.empty(), HCCL_ERROR("[HcclCommAicpu][InitExecLoop]batchsendrecv pairs is empty"),
4932 : HCCL_E_INTERNAL);
4933 :
4934 0 : for (size_t i = 0; i < bsrSendRecvPairs_.size(); i++) {
4935 0 : CHK_PRT_RET(
4936 : (bsrSendRecvPairs_[i].size() > BSR_RETRY_SENDRECV_PAIR_NUM_MAX) || bsrSendRecvPairs_[i].empty(),
4937 : HCCL_ERROR("batchsendrecv pairs[%u] size[%u] is out of range [1,2]", i, bsrSendRecvPairs_.size()),
4938 : HCCL_E_INTERNAL);
4939 :
4940 0 : for (size_t j = 0; j < bsrSendRecvPairs_[i].size(); j++) {
4941 0 : CHK_PTR_NULL(bsrSendRecvPairs_[i][j]);
4942 : }
4943 :
4944 0 : CHK_PRT_RET(
4945 : ((bsrSendRecvPairs_[i].size() == BSR_RETRY_SENDRECV_PAIR_NUM_MAX)
4946 : && (bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_0]->sendRecvType
4947 : == bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_1]->sendRecvType)),
4948 : HCCL_ERROR(
4949 : "batchsendrecv pairs[%u] sendRecvType[%u] is same", i,
4950 : bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_0]->sendRecvType),
4951 : HCCL_E_INTERNAL);
4952 : }
4953 :
4954 0 : param.BatchSendRecvDataDes.curIterNum = 0;
4955 0 : loopNum = bsrSendRecvPairs_.size();
4956 0 : } else {
4957 0 : loopNum = 1;
4958 : }
4959 0 : HCCL_INFO("InitExecLoop: execute loop num %u", loopNum);
4960 0 : return HCCL_SUCCESS;
4961 : }
4962 :
4963 1 : HcclResult HcclCommAicpu::ParseHierarchicalAlgOption(u32* ahcConfInfo)
4964 : {
4965 1 : u32 algOptionSize = ahcConfInfo[TOP_HIERARCHICAL_CONF_lENGTH_INDEX];
4966 1 : if (algOptionSize >= (TOP_HIERARCHICAL_CONF_SIZE - 1)) {
4967 1 : HCCL_ERROR(
4968 : "[HcclCommAicpu][ParseHierarchicalAlgOption] hierarchicalAlgOption size[%lu] exceed maxsize[%lu]",
4969 : algOptionSize, (TOP_HIERARCHICAL_CONF_SIZE - 1));
4970 1 : return HCCL_E_INTERNAL;
4971 : }
4972 :
4973 0 : std::map<AHCConcOpType, TemplateType> hierarchicalAlgOption;
4974 0 : for (u32 i = TOP_HIERARCHICAL_CONF_INFO_INDEX; i < (TOP_HIERARCHICAL_CONF_INFO_INDEX + algOptionSize); i++) {
4975 0 : AHCConcOpType ahcConcOpType;
4976 0 : ahcConcOpType.ahcLevel = static_cast<AHCLevel>(
4977 0 : (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_LEVEL_LOCATION) >> TOP_HIERARCHICAL_CONF_LEVEL_SHIFT);
4978 0 : ahcConcOpType.concType = static_cast<ConcType>(
4979 0 : (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_CONC_TYPE_LOCATION) >> TOP_HIERARCHICAL_CONF_CONC_TYPE_SHIFT);
4980 0 : ahcConcOpType.ahcOpType = static_cast<AHCOpType>(
4981 0 : (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_OP_TYPE_LOCATION) >> TOP_HIERARCHICAL_CONF_OP_TYPE_SHIFT);
4982 0 : TemplateType templateType = static_cast<TemplateType>(
4983 0 : (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_TEMPLATE_TYPE_LOCATION)
4984 : >> TOP_HIERARCHICAL_CONF_TEMPLATE_TYPE_SHIFT);
4985 :
4986 0 : hierarchicalAlgOption[ahcConcOpType] = templateType;
4987 0 : HCCL_DEBUG(
4988 : "[HcclCommAicpu][ParseHierarchicalAlgOption]: index[%u] ahcLevel[%u] concType[%u] ahcOpType[%u], "
4989 : "templateType[%u]",
4990 : i, ahcConcOpType.ahcLevel, ahcConcOpType.concType, ahcConcOpType.ahcOpType, templateType);
4991 : }
4992 0 : topoMatcher_->SetAHCAlgOption(hierarchicalAlgOption);
4993 0 : return HCCL_SUCCESS;
4994 0 : }
4995 :
4996 0 : void HcclCommAicpu::PollCqeException(
4997 : hccl::Stream& stream, bool isReadClear, rtLogicCqReport_t& cqeException, CqeStatus& cqeStatus)
4998 : {
4999 0 : const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
5000 : // 以下条件满足其中之一,进行Poll CQE:1、AICPU/Custom读清CQ 2、AICPU进程读取CQ信息
5001 0 : bool isPollCqe = true;
5002 0 : while (isPollCqe) {
5003 0 : LogControl logControl(false, retryEnable_); // 使能重执行场景,修改ERROR->RUN_WARNING,析构时自动恢复
5004 : CqeQueryInput cqeQueryInput;
5005 0 : dfx_tracer::ExecutorTracer::SetCqeQueryInput(GetDevId(), streamInfo, cqeQueryInput);
5006 0 : constexpr u32 reportSize = 256;
5007 : rtLogicCqReport_t streamReport[reportSize];
5008 0 : cqeQueryInput.cqeAddr = reinterpret_cast<uint8_t*>(streamReport); // 用于存放接收到的cq
5009 0 : cqeStatus = CqReportRecv(cqeQueryInput, cqeException);
5010 0 : isPollCqe = (cqeStatus == dfx::CqeStatus::kCqeException && isReadClear); // 读清CQ场景,继续查询
5011 0 : }
5012 0 : }
5013 :
5014 0 : void HcclCommAicpu::ExchangeCqeContext(
5015 : hccl::Stream& stream, rtLogicCqReport_t& cqeException, CqeStatus& cqeStatus, ErrCqeContext& cqeCtx)
5016 : {
5017 0 : HcclResult ret = HCCL_SUCCESS;
5018 : // aicpu进程把读取到的异常cq,写入共享内存
5019 0 : if (cqeStatus == dfx::CqeStatus::kCqeException) {
5020 0 : ret = stream.SetCqeContext(ErrCqeContext(
5021 0 : static_cast<u32>(cqeStatus), cqeException.taskId, cqeException.errorCode, cqeException.sqeType));
5022 : }
5023 :
5024 : // aicpu进程和custom进程,都从共享内存中读取cqe信息
5025 0 : if (ret != HCCL_SUCCESS || stream.GetCqeContext(cqeCtx) != HCCL_SUCCESS) {
5026 : // 写入/读取共享内存失败,标记流状态,避免背景线程继续轮询这条流,导致刷屏
5027 0 : SetStreamCqeExceptionStatus(stream, CqeExceptionStatus::kOther);
5028 0 : HCCL_ERROR(
5029 : "%s fail, set streamCqeExceptionStatus streamId[%u] exception status[%d]", __func__, stream.id(),
5030 : CqeExceptionStatus::kOther);
5031 0 : return;
5032 : }
5033 : }
5034 :
5035 0 : void HcclCommAicpu::HandleCqeException(hccl::Stream& stream, bool isReadClear)
5036 : {
5037 0 : std::unique_lock<std::mutex> lock(queryCqeMutex_);
5038 :
5039 : // poll cqe信息
5040 : rtLogicCqReport_t cqeException;
5041 0 : CqeStatus cqeStatus = CqeStatus::kDefault;
5042 0 : PollCqeException(stream, isReadClear, cqeException, cqeStatus);
5043 :
5044 : // 以下两种情况直接返回,不处理cq信息:1、读清CQ场景只读取不处理 2、本地记录流上已经有异常信息(避免刷屏)
5045 0 : if (isReadClear || GetStreamCqeExceptionStatus(stream) != CqeExceptionStatus::kNone) {
5046 0 : return;
5047 : }
5048 :
5049 : // aicpu和custom同步异常cqe信息,并记录在本地
5050 0 : ErrCqeContext cqeCtx;
5051 0 : ExchangeCqeContext(stream, cqeException, cqeStatus, cqeCtx);
5052 0 : cqeStatus = static_cast<dfx::CqeStatus>(cqeCtx.cqeStatus);
5053 :
5054 : // 处理流上的异常cq
5055 0 : if (cqeStatus != dfx::CqeStatus::kDefault) {
5056 0 : bool isSdmaTypeErr = cqeStatus == dfx::CqeStatus::kCqeException && cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA;
5057 0 : bool isCompDataErr = cqeCtx.errorCode == RT_SDMA_COMPDATAERR || cqeCtx.errorCode == RT_SDMA_COMPERR
5058 0 : || cqeCtx.errorCode == RT_SDMA_DATAERR;
5059 0 : bool isSdmaCompDataErr = isSdmaTypeErr && isCompDataErr;
5060 :
5061 0 : ReportErrCqe(stream, cqeCtx);
5062 :
5063 : // 标记发生ErrCqe的流
5064 0 : hccl::CqeExceptionStatus cqeExceptionStatus
5065 0 : = isSdmaCompDataErr ? hccl::CqeExceptionStatus::kSdmaErr : hccl::CqeExceptionStatus::kOther;
5066 0 : SetStreamCqeExceptionStatus(stream, cqeExceptionStatus);
5067 :
5068 : // 通知kfc线程
5069 0 : dfxExtendInfo_.cqeException.sqeType = cqeCtx.sqeType;
5070 0 : dfxExtendInfo_.cqeException.errorCode = cqeCtx.errorCode;
5071 0 : dfxExtendInfo_.cqeStatus = cqeStatus;
5072 0 : dfxExtendInfo_.pollStatus = PollStatus::kStopAsException;
5073 0 : HCCL_INFO(
5074 : "update dfxExtendInfo, group %s, streamId %u, cqeStatus %d, sqetype %u, errorCode %u", identifier_.c_str(),
5075 : stream.id(), cqeStatus, cqeCtx.sqeType, cqeCtx.errorCode);
5076 : }
5077 0 : }
5078 :
5079 0 : void HcclCommAicpu::ReportErrCqe(hccl::Stream& stream, ErrCqeContext& cqeCtx)
5080 : {
5081 0 : dfx::CqeStatus cqeStatus = static_cast<dfx::CqeStatus>(cqeCtx.cqeStatus);
5082 0 : const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
5083 0 : u32 head = 0;
5084 0 : u32 tail = 0;
5085 0 : QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_HEAD, head);
5086 0 : QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_TAIL, tail);
5087 :
5088 0 : bool isSdmaTypeErr = cqeStatus == dfx::CqeStatus::kCqeException && cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA;
5089 0 : bool isCompDataErr = cqeCtx.errorCode == RT_SDMA_COMPDATAERR || cqeCtx.errorCode == RT_SDMA_COMPERR
5090 0 : || cqeCtx.errorCode == RT_SDMA_DATAERR;
5091 0 : bool isSdmaCompDataErr = isSdmaTypeErr && isCompDataErr;
5092 :
5093 : // 发生sdma、notify_wait、place_holder、write_value错误,上报error message
5094 0 : bool isComReportErrMesg
5095 : = cqeStatus == dfx::CqeStatus::kCqeException
5096 0 : && (cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA || cqeCtx.sqeType == RT_STARS_SQE_TYPE_NOTIFY_WAIT
5097 0 : || cqeCtx.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER || cqeCtx.sqeType == RT_STARS_SQE_TYPE_WRITE_VALUE);
5098 :
5099 : // 使能重执行且触发SDMA ERROR的场景,修改ERROR->RUN_WARNING
5100 0 : LogControl retryLog(false, retryEnable_ && isSdmaCompDataErr);
5101 :
5102 : // 只在AICPU进程上报taskException,Custom进程不上报
5103 0 : if (isComReportErrMesg && errMessageReport_) {
5104 : // 记录关键信息,并通过D2H通信通道交给host内存
5105 0 : GenTaskExceptionInfo(cqeCtx.sqeType, stream, head);
5106 : // 通知ts错误信息,触发非SDMA错误、不使能重执行触发SDMA错误、使能重执行触发无法重执行的错误时,进行故障上报
5107 0 : if (!isSdmaTypeErr || (isSdmaTypeErr && (!retryEnable_ || !isCompDataErr))) {
5108 0 : HcclResult ret = SendTaskExceptionByMBox(cqeCtx.errorCode);
5109 0 : HCCL_RUN_INFO(
5110 : "[HcclCommAicpu][SendTaskExceptionByMBox]group[%s]:"
5111 : "Try to send task exception by mailbox, errType[%u], errCode[%u], streamId[%d]",
5112 : identifier_.c_str(), cqeCtx.sqeType, cqeCtx.errorCode, stream.id());
5113 0 : CHK_PRT_CONT(
5114 : ret != HCCL_SUCCESS,
5115 : HCCL_ERROR(
5116 : "[OpRetry][AICPU]group[%s]:Send task exception by mailBox failed, streamId[%d]",
5117 : identifier_.c_str(), stream.id()));
5118 : }
5119 : // 当前阶段, 每个通信域在plog打印一次,error message作为host上报,只打印首次
5120 0 : errMessageReport_ = false;
5121 : }
5122 :
5123 : // 发生ErrCqe之后,统一在AICPU进程上报taskException
5124 0 : if (cqeStatus == dfx::CqeStatus::kCqeException) {
5125 0 : if (IsNoNeedWait() && cqeCtx.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER) {
5126 0 : PrintTaskExceptionAllComm(); // 超时场景打印所有通信域的taskException
5127 0 : PrintAicpuCommExecStatus();
5128 0 : } else if (IsNoNeedWait()) {
5129 0 : ErrCqeContext cqeCtx;
5130 0 : stream.GetCqeContext(cqeCtx);
5131 0 : PrintTaskExceptionByTaskId(cqeCtx.sqeType, cqeCtx.taskId, stream, tail); // 仅打印本条流的taskException
5132 : }
5133 : }
5134 :
5135 0 : CHK_PRT_CONT(
5136 : !retryEnable_ && isSdmaCompDataErr,
5137 : HCCL_RUN_INFO(
5138 : "[OpRetry][AICPU]group[%s] hccl aicpu can not retry, retryEnable is false.", identifier_.c_str()));
5139 :
5140 0 : CHK_PRT_CONT(
5141 : retryEnable_ && isSdmaTypeErr && !isCompDataErr,
5142 : HCCL_RUN_INFO(
5143 : "[OpRetry][AICPU]group[%s] hccl aicpu can not retry, errCode is [%u].", identifier_.c_str(),
5144 : cqeCtx.errorCode));
5145 :
5146 0 : HCCL_ERROR(
5147 : "Exception happened, group %s, sqid %d, cqeStatus %d, sqetype %u, errorCode %u, head %u, tail %u",
5148 : identifier_.c_str(), streamInfo.sqId, cqeStatus, cqeCtx.sqeType, cqeCtx.errorCode, head, tail);
5149 0 : }
5150 :
5151 0 : HcclResult HcclCommAicpu::SendTaskExceptionByMBox(const uint16_t& rsErrorCode)
5152 : {
5153 0 : u32 localDeviceId = 0;
5154 : HcclSignalInfo notifyInfo;
5155 0 : opNotifies_[1]->GetNotifyData(notifyInfo);
5156 :
5157 0 : HCCL_INFO("[HcclCommAicpu][SendTaskExceptionByMBox] HostToDeviceLogicId[%u]", notifyInfo.devId);
5158 0 : CHK_RET(hrtDrvGetLocalDevIDByHostDevID(notifyInfo.devId, &localDeviceId));
5159 0 : CHK_RET(hccl_plf::SendTaskExceptionByMBox(
5160 : localDeviceId, opNotifies_[1]->notifyId_, notifyInfo.tsId, userStreamId_, rsErrorCode));
5161 0 : return HCCL_SUCCESS;
5162 : }
5163 :
5164 0 : void HcclCommAicpu::HandleIndOpCqe()
5165 : {
5166 0 : std::unique_lock<std::mutex> lock(queryCqeMutex_);
5167 0 : std::shared_lock<std::shared_mutex> rwLock(threadAicpuMutex_);
5168 0 : for (auto& thread : threads_) {
5169 0 : if (thread == nullptr) {
5170 0 : continue;
5171 : }
5172 0 : Stream stream = *thread->GetStream();
5173 : // 流上已有异常信息,不再重复读取
5174 0 : if (GetStreamCqeExceptionStatus(stream) != CqeExceptionStatus::kNone) {
5175 0 : continue;
5176 : }
5177 :
5178 : // poll cqe信息
5179 : rtLogicCqReport_t cqeException;
5180 : CqeQueryInput cqeQueryInput;
5181 0 : dfx_tracer::ExecutorTracer::SetCqeQueryInput(GetDevId(), stream.GetHcclStreamInfo(), cqeQueryInput);
5182 0 : constexpr u32 reportSize = 256;
5183 : rtLogicCqReport_t streamReport[reportSize];
5184 0 : cqeQueryInput.cqeAddr = reinterpret_cast<uint8_t*>(streamReport); // 用于存放接收到的cq
5185 0 : CqeStatus cqeStatus = CqReportRecv(cqeQueryInput, cqeException);
5186 : // 未读取到异常信息,返回
5187 0 : if (cqeStatus == dfx::CqeStatus::kDefault) {
5188 0 : continue;
5189 : }
5190 0 : ReportIndOpCqe(stream, cqeException, cqeStatus);
5191 0 : }
5192 0 : }
5193 :
5194 0 : void HcclCommAicpu::ReportIndOpCqe(hccl::Stream& stream, const rtLogicCqReport_t& cqeException, CqeStatus cqeStatus)
5195 : {
5196 0 : const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
5197 0 : u32 head = 0;
5198 0 : u32 tail = 0;
5199 0 : QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_HEAD, head);
5200 0 : QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_TAIL, tail);
5201 :
5202 : // 打印taskException信息
5203 0 : if (cqeStatus == dfx::CqeStatus::kCqeException) {
5204 0 : if (cqeException.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER) {
5205 0 : PrintTaskExceptionAllComm(); // 超时场景打印所有通信域的taskException
5206 0 : PrintAicpuCommExecStatus();
5207 : } else {
5208 0 : taskExecption_.PrintTaskExceptionByTaskId(cqeException.sqeType, cqeException.taskId, stream, tail);
5209 : }
5210 : }
5211 :
5212 : // 打印重执行提示信息
5213 0 : bool isSdmaTypeErr = cqeStatus == dfx::CqeStatus::kCqeException && cqeException.sqeType == RT_STARS_SQE_TYPE_SDMA;
5214 0 : bool isCompDataErr = cqeException.errorCode == RT_SDMA_COMPDATAERR || cqeException.errorCode == RT_SDMA_COMPERR;
5215 0 : bool isSdmaCompDataErr = isSdmaTypeErr && isCompDataErr;
5216 0 : if (retryEnable_ && isSdmaCompDataErr) {
5217 0 : uint16_t rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
5218 0 : CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
5219 0 : HCCL_RUN_INFO("[OpRetry][AICPU]group[%s] can not retry, IndOp does not support opRetry", identifier_.c_str());
5220 : }
5221 :
5222 : // 标记发生ErrCqe的流
5223 0 : hccl::CqeExceptionStatus cqeExceptionStatus
5224 0 : = isSdmaCompDataErr ? hccl::CqeExceptionStatus::kSdmaErr : hccl::CqeExceptionStatus::kOther;
5225 0 : SetStreamCqeExceptionStatus(stream, cqeExceptionStatus);
5226 :
5227 0 : HCCL_ERROR(
5228 : "Exception happened, group %s, streamId %u, sqid %d, cqeStatus %d, sqetype %u, errorCode %u, "
5229 : "head %u, tail %u",
5230 : identifier_.c_str(), stream.id(), streamInfo.sqId, cqeStatus, cqeException.sqeType, cqeException.errorCode,
5231 : head, tail);
5232 0 : }
5233 :
5234 0 : HcclResult HcclCommAicpu::RefreshLinkForSwitchNic(
5235 : const std::string& newTag, const TransportRequest& transportRequest, const std::map<u32, bool>& remoteRankPortMap,
5236 : bool isSecondBuild, LINK& switchLink)
5237 : {
5238 0 : u32 remoteRankId = transportRequest.remoteUserRank;
5239 0 : auto iterRemoteRank = remoteRankPortMap.find(remoteRankId);
5240 0 : bool needSwitch = iterRemoteRank != remoteRankPortMap.end();
5241 0 : bool isBackup = needSwitch && !(iterRemoteRank->second);
5242 0 : HCCL_INFO(
5243 : "[HcclCommAicpu][%s] newTag[%s], localRank[%u], remoteRank[%u], input memory type[%u], "
5244 : "output memory type[%u], isRdma[%u], isSecondBuild[%u], needSwitch[%u], isBackup[%u].",
5245 : __func__, newTag.c_str(), localUserRank_, remoteRankId, transportRequest.inputMemType,
5246 : transportRequest.outputMemType, transportRequest.isUsedRdma, isSecondBuild, needSwitch, isBackup);
5247 :
5248 0 : if (transportRequest.isUsedRdma && needSwitch) {
5249 0 : auto* linkRes = isBackup ? &linkRdmaResBackUp_ : &linkRdmaRes_;
5250 0 : auto iterRankLinks = linkRes->find(remoteRankId);
5251 0 : CHK_PRT_RET(
5252 : iterRankLinks == linkRes->end(),
5253 : HCCL_ERROR(
5254 : "[HcclCommAicpu][%s] comm[%s], local rank[%u], fail to find relative link for remote rank[%u], "
5255 : "isBackup[%u]",
5256 : __func__, identifier_.c_str(), localUserRank_, remoteRankId, isBackup),
5257 : HCCL_E_INTERNAL);
5258 0 : auto iterRankTagLinks = iterRankLinks->second.find(newTag);
5259 0 : CHK_PRT_RET(
5260 : iterRankTagLinks == iterRankLinks->second.end(),
5261 : HCCL_ERROR(
5262 : "[HcclCommAicpu][%s] comm[%s], local rank[%u], "
5263 : "fail to find relative tag[%s] of links for remote rank[%u], isBackup[%u]",
5264 : __func__, identifier_.c_str(), localUserRank_, newTag.c_str(), remoteRankId, isBackup),
5265 : HCCL_E_INTERNAL);
5266 0 : CHK_PRT_RET(
5267 : isSecondBuild && iterRankLinks->second[newTag].size() < 2U,
5268 : HCCL_ERROR(
5269 : "[HcclCommAicpu][%s] comm[%s], local rank[%u], isSecondBuild[%u], "
5270 : "fail to find second link for remmote rank[%u]",
5271 : __func__, identifier_.c_str(), localUserRank_, isSecondBuild, remoteRankId),
5272 : HCCL_E_INTERNAL);
5273 :
5274 0 : switchLink = isSecondBuild ? iterRankLinks->second[newTag][1] : iterRankLinks->second[newTag][0];
5275 0 : CHK_SMART_PTR_NULL(switchLink);
5276 :
5277 0 : auto iterAck = receivedAcks_.find(remoteRankId);
5278 0 : CHK_PRT_RET(
5279 : iterAck == receivedAcks_.end(), HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, remoteRankId),
5280 : HCCL_E_NOT_FOUND);
5281 0 : switchLink->SetSupportDataReceivedAck(iterAck->second);
5282 : }
5283 0 : return HCCL_SUCCESS;
5284 : }
5285 :
5286 0 : HcclResult HcclCommAicpu::ReAllocTransportForSwitchNic(
5287 : const std::string& newTag, AlgResourceResponse& algResResponse, std::map<u32, bool>& remoteRankPortMap)
5288 : {
5289 0 : HCCL_INFO(
5290 : "[HcclCommAicpu][%s] Entry realloc transport for switch nic, comm identifier[%s], localRank[%u], tag[%s]",
5291 : __func__, identifier_.c_str(), localUserRank_, newTag.c_str());
5292 0 : std::set<u32> bsrTansportRank;
5293 0 : for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
5294 0 : for (auto& singleSubCommTransport : levelNSubCommTransport) {
5295 0 : for (size_t i = 0; i < singleSubCommTransport.transportRequests.size(); i++) {
5296 0 : auto& transportRequest = singleSubCommTransport.transportRequests[i];
5297 0 : if (transportRequest.isValid) {
5298 0 : receivedAcks_[transportRequest.remoteUserRank] = singleSubCommTransport.supportDataReceivedAck;
5299 0 : bool isSecondBuild = false;
5300 0 : if (transportRequest.isUsedRdma && newTag.find("BatchSendRecv") != std::string::npos
5301 0 : && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
5302 : // 仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
5303 0 : isSecondBuild = true;
5304 : }
5305 0 : bsrTansportRank.insert(transportRequest.remoteUserRank);
5306 0 : CHK_RET(RefreshLinkForSwitchNic(
5307 : newTag, transportRequest, remoteRankPortMap, isSecondBuild, singleSubCommTransport.links[i]));
5308 : }
5309 : }
5310 : }
5311 : }
5312 :
5313 0 : return HCCL_SUCCESS;
5314 0 : }
5315 :
5316 : HcclResult
5317 0 : HcclCommAicpu::RefreshRoceTransportsForSwitchNic(std::unordered_map<std::string, OpCommTransport>& reservedLinks)
5318 : {
5319 0 : ChangeLinkInfo changeLinkInfo;
5320 0 : HcclResult ret = LoadChangeLinkInfo(changeLinkInfo);
5321 :
5322 0 : CHK_PRT_RET(
5323 : changeLinkInfo.isChangeLinkFlag == false,
5324 : HCCL_ERROR(
5325 : "[HcclCommAicpu][%s] some error happened on host, switch nic has failed on rank[%u]. "
5326 : "The error message will be broadcast to other ranks in comm[%s].",
5327 : __func__, localUserRank_, identifier_.c_str()),
5328 : HCCL_E_PARA);
5329 :
5330 0 : CHK_PRT_RET(
5331 : ret != HCCL_SUCCESS,
5332 : HCCL_ERROR(
5333 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], "
5334 : "load change link info failed.",
5335 : __func__, identifier_.c_str(), localUserRank_),
5336 : ret);
5337 :
5338 0 : std::map<u32, bool> remoteRankPortMap;
5339 0 : for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
5340 0 : remoteRankPortMap.emplace(changeLinkInfo.remoteRankList[i], changeLinkInfo.isUseDefaultPort[i]);
5341 0 : HCCL_INFO(
5342 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], remote rank[%u], isUseDefaultPort[%u].", __func__,
5343 : identifier_.c_str(), localUserRank_, changeLinkInfo.remoteRankList[i], changeLinkInfo.isUseDefaultPort[i]);
5344 : }
5345 :
5346 : // 对resMap中所有tag的transport link根据主备进行刷新
5347 0 : for (auto& resMapIt : resMap_) {
5348 0 : HCCL_RUN_INFO(
5349 : "[HcclCommAicpu][%s] rank[%u] refresh algResResponse of tag[%s].", __func__, localUserRank_,
5350 : resMapIt.first.c_str());
5351 0 : reservedLinks.emplace(resMapIt.first, resMapIt.second.opTransportResponse);
5352 0 : CHK_RET(ReAllocTransportForSwitchNic(resMapIt.first, resMapIt.second, remoteRankPortMap));
5353 : }
5354 0 : return HCCL_SUCCESS;
5355 0 : }
5356 :
5357 0 : HcclResult HcclCommAicpu::RevertTransportsForSwitchNic(std::unordered_map<std::string, OpCommTransport>& reservedLinks)
5358 : {
5359 0 : if (reservedLinks.size() == 0) {
5360 0 : HCCL_INFO(
5361 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], reserved link is empty, "
5362 : "no need to revert transport.",
5363 : __func__, identifier_.c_str(), localUserRank_);
5364 0 : return HCCL_SUCCESS;
5365 : }
5366 0 : for (auto& resMapIt : resMap_) {
5367 0 : HCCL_RUN_INFO(
5368 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], revert transport in algResResponse of tag[%s].",
5369 : __func__, identifier_.c_str(), localUserRank_, resMapIt.first.c_str());
5370 0 : auto linkIt = reservedLinks.find(resMapIt.first);
5371 0 : if (linkIt == reservedLinks.end()) {
5372 0 : HCCL_RUN_WARNING(
5373 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], fail to find transport to revert.", __func__,
5374 : identifier_.c_str(), localUserRank_);
5375 0 : continue;
5376 : }
5377 0 : resMapIt.second.opTransportResponse = linkIt->second;
5378 : }
5379 0 : return HCCL_SUCCESS;
5380 : }
5381 :
5382 0 : HcclResult HcclCommAicpu::SwitchNicWaitHandleCommand(std::unordered_map<std::string, OpCommTransport>& reservedLinks)
5383 : {
5384 0 : auto waitSwitchCmdTimeoutMs = HcclGetWaitRetryCmdTimeout(0);
5385 0 : auto waitSwitchCmdTimeout = std::chrono::milliseconds(waitSwitchCmdTimeoutMs);
5386 :
5387 0 : HcclResult ret = HCCL_E_INTERNAL;
5388 0 : auto startTime = std::chrono::steady_clock::now();
5389 : while (true) {
5390 0 : KfcCommand switchHandleCmd = KfcCommand::kNone;
5391 0 : CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, switchHandleCmd));
5392 0 : if (switchHandleCmd == KfcCommand::kWaitSwitchNic) {
5393 0 : HCCL_INFO(
5394 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], hccl aicpu recv switch nic handle command.",
5395 : __func__, identifier_.c_str(), localUserRank_);
5396 0 : ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kWaitSwitchRes, KfcError::kNone, 0);
5397 0 : if (ret != HCCL_SUCCESS) {
5398 0 : (void)RevertTransportsForSwitchNic(reservedLinks);
5399 0 : return ret;
5400 : }
5401 0 : return HCCL_SUCCESS;
5402 0 : } else if ((std::chrono::steady_clock::now() - startTime) >= waitSwitchCmdTimeout) {
5403 0 : HCCL_ERROR(
5404 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], "
5405 : "hccl aicpu wait switch nic handle command timeout[%u ms], local nic switch is reverted.",
5406 : __func__, identifier_.c_str(), localUserRank_, waitSwitchCmdTimeoutMs);
5407 0 : (void)RevertTransportsForSwitchNic(reservedLinks);
5408 0 : return HCCL_E_TIMEOUT;
5409 : }
5410 0 : }
5411 :
5412 : return ret;
5413 : }
5414 :
5415 0 : HcclResult HcclCommAicpu::SwitchNicWaitResult(std::unordered_map<std::string, OpCommTransport>& reservedLinks)
5416 : {
5417 0 : auto waitSwitchResultTimeoutSecond = GetExternalInputHcclLinkTimeOut() * 2U;
5418 0 : const auto waitSwitchResultTimeout = std::chrono::seconds(waitSwitchResultTimeoutSecond);
5419 :
5420 0 : auto startTime = std::chrono::steady_clock::now();
5421 : while (true) {
5422 0 : KfcCommand switchResultCmd = KfcCommand::kNone;
5423 0 : CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, switchResultCmd));
5424 0 : if (switchResultCmd == KfcCommand::kAllSwitched) {
5425 0 : HCCL_INFO(
5426 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], "
5427 : "hccl aicpu switch nic success, all nic switch transport.",
5428 : __func__, identifier_.c_str(), localUserRank_);
5429 0 : return HCCL_SUCCESS;
5430 0 : } else if (switchResultCmd == KfcCommand::kSwitchFail) {
5431 0 : HCCL_ERROR(
5432 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], "
5433 : "hccl aicpu comm switch nic error, local nic switch is reverted.",
5434 : __func__, identifier_.c_str(), localUserRank_);
5435 0 : (void)RevertTransportsForSwitchNic(reservedLinks);
5436 0 : return HCCL_E_INTERNAL;
5437 0 : } else if ((std::chrono::steady_clock::now() - startTime) >= waitSwitchResultTimeout) {
5438 0 : HCCL_ERROR(
5439 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], "
5440 : "hccl aicpu wait switch nic result timeout[%u s].",
5441 : __func__, identifier_.c_str(), localUserRank_, waitSwitchResultTimeoutSecond);
5442 0 : (void)RevertTransportsForSwitchNic(reservedLinks);
5443 0 : return HCCL_E_TIMEOUT;
5444 : }
5445 0 : }
5446 :
5447 : return HCCL_E_INTERNAL;
5448 : }
5449 :
5450 0 : HcclResult HcclCommAicpu::SwitchNic()
5451 : {
5452 0 : KfcStatus state = KfcStatus::kSwitchError;
5453 0 : std::unordered_map<std::string, OpCommTransport> reservedLinks;
5454 0 : HcclResult ret = RefreshRoceTransportsForSwitchNic(reservedLinks);
5455 0 : if (ret != HCCL_SUCCESS) {
5456 0 : HCCL_ERROR(
5457 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], refresh roce transports failed.", __func__,
5458 : identifier_.c_str(), localUserRank_);
5459 0 : state = KfcStatus::kSwitchError;
5460 0 : ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, state, KfcError::kNone, 0);
5461 : } else {
5462 0 : HCCL_INFO(
5463 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], refresh roce transports success.", __func__,
5464 : identifier_.c_str(), localUserRank_);
5465 0 : state = KfcStatus::kPlanSwitch;
5466 0 : ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, state, KfcError::kNone, 0);
5467 : }
5468 :
5469 0 : if (ret != HCCL_SUCCESS) {
5470 0 : HCCL_ERROR(
5471 : "[HcclCommAicpu][SwitchNic] comm identifier[%s], rank[%u], "
5472 : "send switch status[%u] to host fail.",
5473 : __func__, identifier_.c_str(), localUserRank_, state);
5474 : }
5475 :
5476 0 : CHK_RET(SwitchNicWaitHandleCommand(reservedLinks));
5477 :
5478 0 : return SwitchNicWaitResult(reservedLinks);
5479 0 : }
5480 :
5481 0 : HcclResult HcclCommAicpu::ResumeChangeLink()
5482 : {
5483 0 : ChangeLinkInfo changeLinkInfo;
5484 0 : HcclResult ret = LoadChangeLinkInfo(changeLinkInfo);
5485 0 : bool useBackupLink = false;
5486 0 : std::map<u32, bool> remoteRankPortMap;
5487 0 : if (ret != HCCL_SUCCESS) {
5488 0 : HCCL_ERROR(
5489 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], load change link info failed.", __func__,
5490 : identifier_.c_str(), localUserRank_);
5491 0 : return ret;
5492 : }
5493 0 : for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
5494 0 : remoteRankPortMap.insert({changeLinkInfo.remoteRankList[i], changeLinkInfo.isUseDefaultPort[i]});
5495 0 : useBackupLink |= (!changeLinkInfo.isUseDefaultPort[i]);
5496 : }
5497 0 : ret = RefreshCommResponseTransportRes(remoteRankPortMap);
5498 0 : if (ret != HCCL_SUCCESS) {
5499 0 : HCCL_ERROR(
5500 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], refresh roce transports failed.", __func__,
5501 : identifier_.c_str(), localUserRank_);
5502 0 : return ret;
5503 : } else {
5504 0 : HCCL_INFO(
5505 : "[HcclCommAicpu][%s] comm identifier[%s], rank[%u], refresh roce transports success.", __func__,
5506 : identifier_.c_str(), localUserRank_);
5507 0 : return HCCL_SUCCESS;
5508 : }
5509 0 : }
5510 :
5511 0 : HcclResult HcclCommAicpu::RefreshCommResponseTransportRes(std::map<u32, bool>& remoteRankPortMap)
5512 : {
5513 0 : PetersonLockGuard guard(hostDeviceLock_.get());
5514 0 : CHK_PRT_RET(guard.IsLockFailed(), HCCL_ERROR("[%s] hostDeviceLock lock failed", __func__), HCCL_E_INTERNAL);
5515 0 : OpParam param;
5516 : // 提前清理所有tag的链路,避免冲突
5517 0 : for (auto& resMapIt : resMap_) {
5518 0 : HCCL_RUN_INFO("[%s] clean roce resource of tag[%s].", __func__, resMapIt.first.c_str());
5519 0 : CleanRoceResource(resMapIt.first, resMapIt.second, remoteRankPortMap, param);
5520 : }
5521 0 : for (auto& resMapIt : resMap_) {
5522 0 : HCCL_RUN_INFO("[%s] refresh algResResponse of tag[%s].", __func__, resMapIt.first.c_str());
5523 0 : CHK_RET(ReAllocTransportResource(resMapIt.first, resMapIt.second, remoteRankPortMap, commParam_, param));
5524 : }
5525 0 : return HCCL_SUCCESS;
5526 0 : }
5527 :
5528 0 : HcclResult HcclCommAicpu::InitAicpuIndOp(CommAicpuParam* commAicpuParam)
5529 : {
5530 0 : if (indOpCommInitialized_) {
5531 0 : HCCL_RUN_INFO("[%s][InitAicpuIndOp]Group[%s] already initialized, skip reinit", __func__, identifier_.c_str());
5532 0 : return HCCL_SUCCESS;
5533 : }
5534 0 : CHK_PTR_NULL(commAicpuParam);
5535 0 : topoInfo_.deviceLogicId = commAicpuParam->deviceLogicId;
5536 0 : topoInfo_.devicePhyId = commAicpuParam->devicePhyId;
5537 0 : topoInfo_.deviceType = static_cast<DevType>(commAicpuParam->deviceType);
5538 0 : identifier_ = std::string(commAicpuParam->hcomId);
5539 0 : topoInfo_.userRankSize = commAicpuParam->userRankSize;
5540 0 : topoInfo_.userRank = commAicpuParam->userRank;
5541 0 : notifys_.reserve(hccl::HCCL_THREAD_NOTIFY_MAX_NUM);
5542 0 : if (topoInfo_.deviceType == DevType::DEV_TYPE_910_93 || topoInfo_.deviceType == DevType::DEV_TYPE_910B) {
5543 0 : notifySize_ = NOTIFY_SIZE_FOUR;
5544 : } else {
5545 0 : notifySize_ = NOTIFY_SIZE_EIGHT;
5546 : }
5547 :
5548 0 : CHK_RET(hrtSetWorkModeAicpu(true));
5549 0 : CHK_RET(hrtSetlocalDevice(topoInfo_.deviceLogicId));
5550 0 : CHK_RET(hrtSetlocalDeviceType(topoInfo_.deviceType));
5551 0 : CHK_RET(hrtDrvGetLocalDevIDByHostDevID(topoInfo_.devicePhyId, &devId_));
5552 0 : CHK_RET(taskExecption_.Init(devId_, topoInfo_.userRank, identifier_));
5553 0 : CHK_RET(RegisterProfCallBack());
5554 :
5555 0 : if (topoInfo_.deviceType == DevType::DEV_TYPE_950 || topoInfo_.deviceType == DevType::DEV_TYPE_960) {
5556 0 : HCCL_INFO("[HcclCommAicpu][InitAicpuIndOp] InitAicpuIndOpV2 start");
5557 0 : indOpCommInitialized_ = true;
5558 0 : return HCCL_SUCCESS;
5559 : }
5560 :
5561 0 : HCCL_INFO("[HcclCommAicpu][InitAicpuIndOp] InitAicpuIndOp start");
5562 0 : if (!FindDispatcherByCommId(&dispatcherCtx_, identifier_.c_str())) {
5563 0 : CHK_RET(CreateDispatcherCtx(&dispatcherCtx_, devId_, identifier_.c_str()));
5564 : }
5565 0 : CHK_PTR_NULL(dispatcherCtx_);
5566 0 : hccl::DispatcherCtx* Ctx_temp = static_cast<DispatcherCtx*>(dispatcherCtx_);
5567 0 : HCCL_INFO("[%s] Ctx_temp[%p]", __func__, (void*)Ctx_temp);
5568 0 : (void)RegisterLoadTaskCallBack(Ctx_temp->GetDispatcher(), nullptr, dfx::TaskProfilingCallBack); // 注册dispatcher
5569 0 : if (commAicpuParam->kfcControlTransferH2DParams.buffLen != 0 && kfcControlTransferH2D_ == nullptr) {
5570 0 : EXCEPTION_CATCH((kfcControlTransferH2D_ = std::make_shared<hccl::HDCommunicate>()), return HCCL_E_PTR);
5571 0 : CHK_SMART_PTR_NULL(kfcControlTransferH2D_);
5572 0 : CHK_RET(kfcControlTransferH2D_->InitDevice(commAicpuParam->kfcControlTransferH2DParams));
5573 : }
5574 0 : if (commAicpuParam->kfcStatusTransferD2HParams.buffLen != 0 && kfcStatusTransferD2H_ == nullptr) {
5575 0 : EXCEPTION_CATCH((kfcStatusTransferD2H_ = std::make_shared<hccl::HDCommunicate>()), return HCCL_E_PTR);
5576 0 : CHK_SMART_PTR_NULL(kfcStatusTransferD2H_);
5577 0 : CHK_RET(kfcStatusTransferD2H_->InitDevice(commAicpuParam->kfcStatusTransferD2HParams));
5578 : }
5579 :
5580 0 : indOpCommInitialized_ = true;
5581 :
5582 : // 在indOpCommInitialized_变为true后拉起背景线程
5583 0 : AicpuComContext* ctx = AicpuGetComContext();
5584 0 : AicpuHcclProcess::CallMC2MaintenanceThread(ctx);
5585 :
5586 0 : HCCL_RUN_INFO(
5587 : "%s group[%s] success!, deviceLogicId[%u], devicePhyId[%u], deviceType[%u], notifySize[%u], "
5588 : "dispatcherCtx[%p]",
5589 : __func__, identifier_.c_str(), topoInfo_.deviceLogicId, topoInfo_.devicePhyId, topoInfo_.deviceType,
5590 : notifySize_, dispatcherCtx_);
5591 :
5592 0 : return HCCL_SUCCESS;
5593 : }
5594 :
5595 0 : HcclResult HcclCommAicpu::InitThreads(ThreadMgrAicpuParam* param)
5596 : {
5597 0 : CHK_PTR_NULL(param);
5598 0 : u32 threadNum = param->threadNum;
5599 0 : std::vector<std::shared_ptr<Thread>> outThreads;
5600 0 : outThreads.reserve(threadNum);
5601 0 : std::string hcomId(param->hcomId);
5602 0 : for (u32 i = 0; i < threadNum; ++i) {
5603 0 : std::string thdUniqueId(param->threadParam[i], THREAD_UNIQUE_ID_MAX_SIZE);
5604 0 : if (UNLIKELY(HcclCheckLogLevel(HCCL_LOG_INFO))) {
5605 0 : std::ostringstream oss;
5606 0 : oss << "threadParam[" << i << "] raw bytes: ";
5607 0 : for (u32 j = 0; j < THREAD_UNIQUE_ID_MAX_SIZE; ++j) {
5608 0 : oss << std::hex << std::setw(2) << std::setfill('0')
5609 0 : << static_cast<unsigned int>(static_cast<unsigned char>(param->threadParam[i][j])) << " ";
5610 : }
5611 0 : HCCL_INFO("[HcclCommAicpu][%s] %s", __func__, oss.str().c_str());
5612 0 : }
5613 0 : std::shared_ptr<AicpuTsThread> thread;
5614 0 : EXCEPTION_CATCH((thread = std::make_shared<AicpuTsThread>(thdUniqueId)), return HCCL_E_PTR);
5615 0 : thread->SetCommEngine(param->engine);
5616 0 : HcclResult ret = thread->Init();
5617 0 : if (ret != HCCL_SUCCESS) {
5618 0 : HCCL_ERROR(
5619 : "[HcclCommAicpu][%s] comm identifier[%s], init threads num[%u] failed at index %u", __func__,
5620 : hcomId.c_str(), param->threadNum, i);
5621 0 : return ret;
5622 : }
5623 0 : outThreads.emplace_back(thread);
5624 0 : }
5625 :
5626 0 : ThreadHandle* threadArray = static_cast<ThreadHandle*>(param->deviceHandle);
5627 : // 空指针校验
5628 0 : CHK_PTR_NULL(threadArray);
5629 0 : for (size_t i = 0; i < threadNum; ++i) {
5630 0 : threadArray[i] = reinterpret_cast<ThreadHandle>(outThreads[i].get()); // 拷贝裸指针
5631 0 : HCCL_INFO("[HcclCommAicpu][%s] threadArray[%u] = [%lu]", __func__, i, threadArray[i]);
5632 : }
5633 0 : std::unique_lock<std::shared_mutex> rwLock(threadAicpuMutex_);
5634 0 : threads_.insert(
5635 0 : threads_.end(), std::make_move_iterator(outThreads.begin()), std::make_move_iterator(outThreads.end()));
5636 0 : HCCL_INFO(
5637 : "[HcclCommAicpu][%s] comm identifier[%s], init threads num[%u] success", __func__, hcomId.c_str(), threadNum);
5638 : // 为上报翻转初始化资源
5639 0 : if (topoInfo_.deviceType != DevType::DEV_TYPE_950 && topoInfo_.deviceType != DevType::DEV_TYPE_960) {
5640 0 : CHK_RET(InitProfthreadResource(threadNum));
5641 : }
5642 0 : return HCCL_SUCCESS;
5643 0 : }
5644 :
5645 0 : HcclResult HcclCommAicpu::InitProfthreadResource(u32 threadNum)
5646 : {
5647 0 : groupHashId_ = dfx::ProfilingManager::GetProfHashId(identifier_.c_str(), identifier_.length());
5648 0 : HCCL_INFO(
5649 : "[%s], group[%s], groupHash[%llu], threadNum[%u] ", __func__, identifier_.c_str(), groupHashId_, threadNum);
5650 0 : dfx::ProfCommInfo profInfo{groupHashId_, topoInfo_.userRankSize, topoInfo_.userRank};
5651 : // 添加检查确保 threadNum 不超过线程总数
5652 0 : if (threadNum > threads_.size()) {
5653 0 : HCCL_ERROR("[%s] threadNum Err", __func__);
5654 0 : return HCCL_E_PARA;
5655 : }
5656 : // 从后往前迭代指定数量
5657 0 : auto begin = threads_.rbegin();
5658 0 : auto end = begin + threadNum;
5659 0 : for (auto it = begin; it != end; ++it) {
5660 0 : CHK_RET(dfx::ProfilingManager::AddProfInfoByStreamId((*it)->GetStream()->id(), identifier_, profInfo));
5661 : }
5662 0 : dfx::ProfilingExtendInfoHelper::InitProfItemId();
5663 0 : return HCCL_SUCCESS;
5664 : }
5665 :
5666 0 : HcclResult HcclCommAicpu::AllocChannelResource(HcclIndOpChannelRemoteResV3* commParam)
5667 : {
5668 0 : CHK_PTR_NULL(commParam);
5669 0 : if (commParam->engine != COMM_ENGINE_AICPU && commParam->engine != COMM_ENGINE_AICPU_TS) {
5670 0 : HCCL_ERROR(
5671 : "[HcclCommAicpu][%s] engine type[%s] is not supported", __func__,
5672 : GetEnumToString(GetCommEngineStatusStrMap(), commParam->engine).c_str());
5673 0 : return HCCL_E_PARA;
5674 : }
5675 :
5676 0 : if (commParam->listNum != 0 && commParam->remoteResV2 == nullptr) {
5677 0 : HCCL_ERROR("[HcclCommAicpu][%s] listNum[%u], remoteResV2 is nullptr", __func__, commParam->listNum);
5678 0 : return HCCL_E_PARA;
5679 : }
5680 :
5681 0 : multiQpThreshold_ = commParam->multiQpThreshold;
5682 0 : localUserRank_ = commParam->localUserRank;
5683 0 : HCCL_INFO(
5684 : "%s multiQpThreshold[%u], localUserRank[%u], deviceLogicId[%d], devicePhyId[%u], deviceType[%d], "
5685 : "listNum[%u]",
5686 : __func__, multiQpThreshold_, localUserRank_, topoInfo_.deviceLogicId, topoInfo_.devicePhyId,
5687 : topoInfo_.deviceType, commParam->listNum);
5688 0 : for (u32 idx = 0; idx < commParam->listNum; idx++) {
5689 0 : HCCL_INFO(
5690 : "%s listNum[%u], listIdx[%u], remoteWorldRank[%u], remoteRank[%u], isUsedRdma[%d]", __func__,
5691 : commParam->listNum, idx, commParam->remoteResV2[idx].remoteWorldRank,
5692 : commParam->remoteResV2[idx].remoteRank, commParam->remoteResV2[idx].isUsedRdma);
5693 :
5694 0 : rankData_[commParam->remoteResV2[idx].remoteRank].remoteWorldRank = commParam->remoteResV2[idx].remoteWorldRank;
5695 0 : rankData_[commParam->remoteResV2[idx].remoteRank].remoteUsrRankId = commParam->remoteResV2[idx].remoteRank;
5696 0 : if (commParam->remoteResV2[idx].isUsedRdma) {
5697 0 : CHK_RET(InitRoceChannel(commParam, idx));
5698 : } else {
5699 0 : CHK_RET(InitP2pChannel(commParam, idx));
5700 : }
5701 : }
5702 0 : return HCCL_SUCCESS;
5703 : }
5704 :
5705 0 : HcclResult HcclCommAicpu::InitP2pChannel(HcclIndOpChannelRemoteResV3* commParam, uint32_t channelIndex)
5706 : {
5707 0 : CHK_PTR_NULL(commParam);
5708 0 : CHK_PTR_NULL(commParam->channelList);
5709 0 : HcclIndOpChannelRemoteResV2& remoteResV2 = commParam->remoteResV2[channelIndex];
5710 0 : u32 linkType = static_cast<u32>(remoteResV2.channelP2p.transportAttr.linkType);
5711 0 : std::string channelKey = std::string(commParam->channelTag) + ":" + std::to_string(commParam->engine) + ":"
5712 0 : + std::to_string(remoteResV2.remoteRank) + ":" + std::to_string(linkType);
5713 0 : HCCL_INFO("%s channelKey[%s]", __func__, channelKey.c_str());
5714 0 : if (channelHandleMap_.find(channelKey) != channelHandleMap_.end()) {
5715 0 : HCCL_ERROR("[%s]the channel has existed.", __func__);
5716 0 : return HCCL_E_INTERNAL;
5717 : }
5718 :
5719 0 : HcclChannelP2p& channelP2p = remoteResV2.channelP2p;
5720 0 : if (channelP2p.localIpcSignal[0].resId == INVALID_U64) {
5721 0 : HCCL_ERROR("[%s]the Channel is invalid", __func__);
5722 0 : return HCCL_E_INTERNAL;
5723 : }
5724 :
5725 : // 创建Transport对象
5726 0 : MachinePara machinePara;
5727 0 : CHK_RET(SetTransportMachinePara(machinePara, remoteResV2.remoteRank, commParam->channelTag));
5728 0 : machinePara.notifyNum = remoteResV2.p2pNotifyNum;
5729 : // 获取localMem & remoteMem
5730 0 : TransportDeviceP2pData transDevP2pData;
5731 0 : transDevP2pData.inputBufferPtr = reinterpret_cast<void*>(channelP2p.remoteHcclbuffer.addr);
5732 0 : transDevP2pData.outputBufferPtr = reinterpret_cast<void*>(channelP2p.remoteHcclbuffer.addr);
5733 0 : if (transDevP2pData.inputBufferPtr == nullptr || transDevP2pData.outputBufferPtr == nullptr) {
5734 0 : HCCL_ERROR(
5735 : "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevP2pData.inputBufferPtr,
5736 : transDevP2pData.outputBufferPtr);
5737 0 : return HCCL_E_PARA;
5738 : }
5739 : // 获取Notify资源
5740 0 : CHK_RET(SetChannelP2pNotify(transDevP2pData, remoteResV2.p2pNotifyNum, channelP2p)); // 待确认notify是否
5741 : // 获取transportAttr信息
5742 0 : transDevP2pData.transportAttr = channelP2p.transportAttr;
5743 : // 创建Transport对象
5744 0 : std::shared_ptr<Transport> link;
5745 0 : TransportPara para{};
5746 0 : const std::unique_ptr<NotifyPool> notifyPool;
5747 0 : DispatcherCtx* ctx = static_cast<DispatcherCtx*>(dispatcherCtx_);
5748 0 : CHK_PRT(ctx->SetDispatcherHcclQos(remoteResV2.channelP2p.qos)); // 调度器添加hcclQos
5749 0 : CHK_PTR_NULL(ctx);
5750 0 : link.reset(new (std::nothrow) Transport(
5751 0 : TransportType::TRANS_TYPE_DEVICE_P2P, para, ctx->GetDispatcher(), notifyPool, machinePara, transDevP2pData));
5752 0 : CHK_SMART_PTR_NULL(link);
5753 0 : CHK_RET(link->Init()); // 初始化需要增加远端用户注册内存
5754 :
5755 0 : ChannelHandle channelHandle = reinterpret_cast<ChannelHandle>(link.get());
5756 0 : channelHandleMap_[channelKey] = channelHandle;
5757 0 : linkMap_[channelHandle] = link;
5758 :
5759 : // 恢复出的channelHandle回填到commParam中
5760 0 : CHK_PTR_NULL(commParam->channelList);
5761 0 : ChannelHandle* channelList = reinterpret_cast<ChannelHandle*>(commParam->channelList);
5762 0 : channelList[channelIndex] = channelHandle;
5763 :
5764 0 : return HCCL_SUCCESS;
5765 0 : }
5766 :
5767 0 : HcclResult HcclCommAicpu::SetChannelP2pNotify(
5768 : TransportDeviceP2pData& transDevP2pData, u64& p2pNotifyNum, HcclChannelP2p& channelP2p)
5769 : {
5770 0 : u64 actualNotifyNum = 0;
5771 : // 获取Ipc notify信息
5772 0 : CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
5773 0 : std::shared_ptr<LocalNotify> ipcPreWaitNotify = std::make_shared<LocalNotify>();
5774 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.localIpcSignal[actualNotifyNum], ipcPreWaitNotify));
5775 0 : transDevP2pData.ipcPreWaitNotify = ipcPreWaitNotify;
5776 :
5777 0 : std::shared_ptr<RemoteNotify> ipcPreRecordNotify = std::make_shared<RemoteNotify>();
5778 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.remoteIpcSignal[actualNotifyNum], ipcPreRecordNotify));
5779 0 : transDevP2pData.ipcPreRecordNotify = ipcPreRecordNotify;
5780 0 : actualNotifyNum++;
5781 :
5782 0 : CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
5783 0 : std::shared_ptr<LocalNotify> ipcPostWaitNotify = std::make_shared<LocalNotify>();
5784 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.localIpcSignal[actualNotifyNum], ipcPostWaitNotify));
5785 0 : transDevP2pData.ipcPostWaitNotify = ipcPostWaitNotify;
5786 :
5787 0 : std::shared_ptr<RemoteNotify> ipcPostRecordNotify = std::make_shared<RemoteNotify>();
5788 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.remoteIpcSignal[actualNotifyNum], ipcPostRecordNotify));
5789 0 : transDevP2pData.ipcPostRecordNotify = ipcPostRecordNotify;
5790 0 : actualNotifyNum++;
5791 :
5792 0 : transDevP2pData.userLocalNotify.resize(p2pNotifyNum, nullptr);
5793 0 : transDevP2pData.userRemoteNotify.resize(p2pNotifyNum, nullptr);
5794 :
5795 0 : for (u32 idx = 0; idx < p2pNotifyNum; idx++) {
5796 0 : std::shared_ptr<LocalNotify> ipcWaitNotify = std::make_shared<LocalNotify>();
5797 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.localIpcSignal[actualNotifyNum], ipcWaitNotify));
5798 0 : transDevP2pData.userLocalNotify[idx] = ipcWaitNotify;
5799 :
5800 0 : std::shared_ptr<RemoteNotify> ipcRecordNotify = std::make_shared<RemoteNotify>();
5801 0 : CHK_RET(InitAndVerifySingleSignal(channelP2p.remoteIpcSignal[actualNotifyNum], ipcRecordNotify));
5802 0 : transDevP2pData.userRemoteNotify[idx] = ipcRecordNotify;
5803 :
5804 0 : actualNotifyNum++;
5805 0 : }
5806 :
5807 0 : HCCL_DEBUG(
5808 : "%s get p2pNotify success, p2pNotifyNum[%llu], actualNotifyNum[%llu]", __func__, p2pNotifyNum, actualNotifyNum);
5809 0 : return HCCL_SUCCESS;
5810 0 : }
5811 :
5812 0 : HcclResult HcclCommAicpu::InitRoceChannel(HcclIndOpChannelRemoteResV3* commParam, uint32_t channelIndex)
5813 : {
5814 0 : HcclIndOpChannelRemoteResV2& remoteResV2 = commParam->remoteResV2[channelIndex];
5815 0 : std::string channelKey = std::string(commParam->channelTag) + ":" + std::to_string(commParam->engine) + ":"
5816 0 : + std::to_string(remoteResV2.remoteRank) + ":"
5817 0 : + std::to_string(CommProtocol::COMM_PROTOCOL_ROCE);
5818 0 : if (channelHandleMap_.find(channelKey) != channelHandleMap_.end()) {
5819 0 : HCCL_ERROR("[%s]the channel has existed.", __func__);
5820 0 : return HCCL_E_INTERNAL;
5821 : }
5822 :
5823 0 : HcclChannelRoce& channelRoce = remoteResV2.channelRoce;
5824 0 : if (channelRoce.localNotifyList == 0) {
5825 0 : HCCL_ERROR("[%s]the Channel is invalid", __func__);
5826 0 : return HCCL_E_INTERNAL;
5827 : }
5828 0 : HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(channelRoce.localNotifyList);
5829 0 : if (localNotifyList[0].resId == INVALID_U64) {
5830 0 : HCCL_INFO("[%s]the channel notify resource is invalid", __func__);
5831 0 : return HCCL_E_INTERNAL;
5832 : }
5833 :
5834 : // 创建Transport对象
5835 0 : MachinePara machinePara;
5836 0 : CHK_RET(SetTransportMachinePara(machinePara, remoteResV2.remoteRank, commParam->channelTag)); // 待确认是否填充完毕
5837 0 : machinePara.notifyNum = remoteResV2.roceNotifyNum;
5838 : // 获取localMem & remoteMem
5839 0 : TransportDeviceIbverbsData transDevIbverbsData;
5840 0 : transDevIbverbsData.inputBufferPtr = reinterpret_cast<void*>(channelRoce.remoteHcclbuffer.addr);
5841 0 : transDevIbverbsData.outputBufferPtr = reinterpret_cast<void*>(channelRoce.remoteHcclbuffer.addr);
5842 0 : if (transDevIbverbsData.inputBufferPtr == nullptr || transDevIbverbsData.outputBufferPtr == nullptr) {
5843 0 : HCCL_ERROR(
5844 : "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevIbverbsData.inputBufferPtr,
5845 : transDevIbverbsData.outputBufferPtr);
5846 0 : return HCCL_E_PARA;
5847 : }
5848 0 : transDevIbverbsData.localInputMem = channelRoce.localHcclbuffer;
5849 0 : transDevIbverbsData.localOutputMem = channelRoce.localHcclbuffer;
5850 0 : transDevIbverbsData.localNotifyValueAddr = channelRoce.notifyValue;
5851 0 : transDevIbverbsData.notifyValueKey = channelRoce.notifyValueKey;
5852 0 : transDevIbverbsData.remoteInputKey = channelRoce.remoteHcclbuffer.key;
5853 0 : transDevIbverbsData.remoteOutputKey = channelRoce.remoteHcclbuffer.key;
5854 : // 需要添加远端用户注册内存
5855 :
5856 : // 获取QPinfo
5857 0 : u32 roceQpNumSum = channelRoce.qpsPerConnection + static_cast<u32>(channelRoce.qpsPerConnection != 1);
5858 0 : transDevIbverbsData.qpInfo.resize(roceQpNumSum);
5859 0 : std::copy_n(channelRoce.QpInfo, roceQpNumSum, transDevIbverbsData.qpInfo.begin());
5860 0 : transDevIbverbsData.multiQpThreshold = multiQpThreshold_;
5861 0 : transDevIbverbsData.qpsPerConnection = channelRoce.qpsPerConnection;
5862 :
5863 : // 获取notify
5864 0 : u64& roceNotifyNum = remoteResV2.roceNotifyNum; // 是否需要待确认
5865 0 : CHK_RET(SetChannelRoceNotify(transDevIbverbsData, roceNotifyNum, channelRoce));
5866 :
5867 : // 创建Transport对象
5868 0 : std::shared_ptr<Transport> link;
5869 0 : TransportPara para{};
5870 0 : para.timeout = linkTimeOut_; // 暂无法设置
5871 0 : const std::unique_ptr<NotifyPool> notifyPool;
5872 0 : DispatcherCtx* ctx = static_cast<DispatcherCtx*>(dispatcherCtx_);
5873 0 : CHK_PTR_NULL(ctx);
5874 0 : link.reset(new (std::nothrow) Transport(
5875 : TransportType::TRANS_TYPE_DEVICE_IBVERBS, para, ctx->GetDispatcher(), notifyPool, machinePara,
5876 0 : TransportDeviceP2pData(), transDevIbverbsData));
5877 0 : CHK_SMART_PTR_NULL(link);
5878 0 : CHK_RET(link->Init()); // 初始化需要增加远端用户注册内存
5879 :
5880 0 : ChannelHandle channelHandle = reinterpret_cast<ChannelHandle>(link.get());
5881 0 : channelHandleMap_[channelKey] = channelHandle;
5882 0 : linkMap_[channelHandle] = link;
5883 :
5884 : // 恢复出的channelHandle回填到commParam中
5885 0 : ChannelHandle* channelList = reinterpret_cast<ChannelHandle*>(commParam->channelList);
5886 0 : channelList[channelIndex] = channelHandle;
5887 :
5888 0 : return HCCL_SUCCESS;
5889 0 : }
5890 :
5891 0 : HcclResult HcclCommAicpu::SetChannelRoceNotify(
5892 : TransportDeviceIbverbsData& transDevIbverbsData, u64& roceNotifyNum, HcclChannelRoce& channelRoce)
5893 : {
5894 0 : u64 actualNotifyNum = 0;
5895 0 : if (channelRoce.localNotifyList == 0 || channelRoce.remoteNotifyList == 0) {
5896 0 : HCCL_DEBUG("[%s] Empty local and remote notify lists, skipping notify resource creation.", __func__);
5897 0 : return HCCL_SUCCESS;
5898 : }
5899 0 : HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(channelRoce.localNotifyList);
5900 0 : AddrKey* remoteNotifyList = reinterpret_cast<AddrKey*>(channelRoce.remoteNotifyList);
5901 0 : if (localNotifyList == nullptr || remoteNotifyList == nullptr) {
5902 0 : HCCL_ERROR("[%s]nullptr found in localNotifyList or remoteNotifyList from device mem, check.", __func__);
5903 0 : return HCCL_E_INTERNAL;
5904 : }
5905 : // 获取RDMA Notify信息
5906 0 : std::shared_ptr<LocalNotify> ackNotify = std::make_shared<LocalNotify>();
5907 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], ackNotify));
5908 0 : transDevIbverbsData.ackNotify = ackNotify;
5909 0 : transDevIbverbsData.remoteAckNotifyDetails = remoteNotifyList[actualNotifyNum];
5910 0 : actualNotifyNum++;
5911 :
5912 0 : std::shared_ptr<LocalNotify> dataNotify = std::make_shared<LocalNotify>();
5913 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataNotify));
5914 0 : transDevIbverbsData.dataNotify = dataNotify;
5915 0 : transDevIbverbsData.remoteDataNotifyDetails = remoteNotifyList[actualNotifyNum];
5916 0 : actualNotifyNum++;
5917 :
5918 0 : std::shared_ptr<LocalNotify> dataAckNotify = std::make_shared<LocalNotify>();
5919 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataAckNotify));
5920 0 : transDevIbverbsData.dataAckNotify = dataAckNotify;
5921 0 : transDevIbverbsData.remoteDataAckNotifyDetails = remoteNotifyList[actualNotifyNum];
5922 0 : transDevIbverbsData.notifySize = notifySize_;
5923 0 : actualNotifyNum++;
5924 :
5925 0 : transDevIbverbsData.userLocalNotify.resize(channelRoce.qpsPerConnection);
5926 0 : transDevIbverbsData.userRemoteNotifyDetails.resize(channelRoce.qpsPerConnection);
5927 : // 当前多QP下每个QP会多申请一个DataNotify
5928 0 : u64 singleQpNotifySize = channelRoce.singleQPNotifyNum + static_cast<u32>(channelRoce.qpsPerConnection > 1);
5929 0 : for (u32 qpIndex = 0; qpIndex < channelRoce.qpsPerConnection; qpIndex++) {
5930 0 : transDevIbverbsData.userLocalNotify[qpIndex].resize(singleQpNotifySize, nullptr);
5931 0 : transDevIbverbsData.userRemoteNotifyDetails[qpIndex].resize(singleQpNotifySize);
5932 0 : for (u32 i = 0, idx = actualNotifyNum + singleQpNotifySize * qpIndex; i < singleQpNotifySize; ++idx, ++i) {
5933 0 : std::shared_ptr<LocalNotify> locNotify = std::make_shared<LocalNotify>();
5934 0 : CHK_RET(InitAndVerifySingleSignal(localNotifyList[idx], locNotify));
5935 0 : transDevIbverbsData.userLocalNotify[qpIndex][i] = locNotify;
5936 0 : transDevIbverbsData.userRemoteNotifyDetails[qpIndex][i] = remoteNotifyList[idx];
5937 0 : }
5938 : }
5939 0 : roceNotifyNum = channelRoce.singleQPNotifyNum;
5940 0 : HCCL_DEBUG("[%s]get roceNotify success, roceNotifyNum[%u]", __func__, roceNotifyNum);
5941 0 : return HCCL_SUCCESS;
5942 0 : }
5943 :
5944 0 : HcclResult HcclCommAicpu::NotifyAlloc(NotifyMgrAicpuParam* param)
5945 : {
5946 0 : u32 notifyNum = param->notifyNum;
5947 0 : std::string notifysStr = std::string(param->notifyParam, NOTIFY_UNIQUE_ID_MAX_SIZE);
5948 0 : std::string hcomId(param->hcomId);
5949 0 : size_t notifySize = notifys_.size();
5950 0 : HCCL_INFO(
5951 : "[HcclCommAicpu][%s] comm identifier[%s], alloc notifys num[%u] begin, before notifySize[%u]", __func__,
5952 : hcomId.c_str(), notifyNum, notifySize);
5953 0 : if (UNLIKELY(HcclCheckLogLevel(HCCL_LOG_INFO))) {
5954 0 : std::ostringstream oss;
5955 0 : oss << "notifyParam" << " raw bytes: ";
5956 0 : for (u32 i = 0; i < NOTIFY_UNIQUE_ID_MAX_SIZE; ++i) {
5957 0 : oss << std::hex << std::setw(2) << std::setfill('0')
5958 0 : << static_cast<unsigned int>(static_cast<unsigned char>(param->notifyParam[i])) << " ";
5959 : }
5960 0 : HCCL_INFO("[HcclCommAicpu][%s] %s", __func__, oss.str().c_str());
5961 0 : }
5962 0 : HcclResult ret = NotifyManager::ParseBinNotifys(notifysStr, notifys_);
5963 0 : if (ret != HCCL_SUCCESS) {
5964 0 : HCCL_ERROR(
5965 : "[HcclCommAicpu][%s] comm identifier[%s], alloc notifys num[%u] failed %u", __func__, hcomId.c_str(),
5966 : notifyNum, ret);
5967 0 : return ret;
5968 : }
5969 0 : HCCL_INFO(
5970 : "[HcclCommAicpu][%s] comm identifier[%s], alloc notifys num[%u] end, after notifySize[%u]", __func__,
5971 : hcomId.c_str(), notifyNum, notifys_.size());
5972 0 : NotifyHandle* notifyArray = static_cast<NotifyHandle*>(param->deviceHandle);
5973 0 : CHK_PTR_NULL(notifyArray);
5974 : // 空指针校验
5975 0 : for (size_t i = 0; i < notifyNum; ++i) {
5976 0 : notifyArray[i] = reinterpret_cast<NotifyHandle>(notifys_[i + notifySize].get()); // 拷贝裸指针
5977 0 : HCCL_INFO("[HcclCommAicpu][%s] notifyArray[%u] = [%lu]", __func__, i + notifySize, notifyArray[i]);
5978 : }
5979 :
5980 0 : HCCL_INFO(
5981 : "[HcclCommAicpu][%s] comm identifier[%s], alloc notifys num[%u] success", __func__, hcomId.c_str(), notifyNum);
5982 0 : return HCCL_SUCCESS;
5983 0 : }
5984 :
5985 0 : HcclResult HcclCommAicpu::NotifyFree(NotifyMgrAicpuParam* param)
5986 : {
5987 0 : u32 notifyNum = param->notifyNum;
5988 0 : NotifyHandle* notifyArray = static_cast<NotifyHandle*>(param->deviceHandle);
5989 0 : std::string hcomId(param->hcomId);
5990 : // 空指针校验
5991 0 : CHK_PTR_NULL(notifyArray);
5992 0 : for (size_t i = 0; i < notifyNum; ++i) {
5993 0 : LocalNotify* notify = reinterpret_cast<LocalNotify*>(notifyArray[i]);
5994 0 : HCCL_INFO("[HcclCommAicpu][%s] notifyArray[%u]=[%lu]", __func__, i, notifyArray[i]);
5995 0 : auto it = std::find_if(notifys_.begin(), notifys_.end(), [notify](const std::unique_ptr<LocalNotify>& ptr) {
5996 0 : return ptr.get() == notify;
5997 : });
5998 0 : if (it != notifys_.end()) {
5999 0 : HCCL_INFO(
6000 : "[HcclCommAicpu][%s] comm identifier[%s], free notifys[%u] success", __func__, hcomId.c_str(),
6001 : notifyArray[i]);
6002 0 : notifys_.erase(it);
6003 : } else {
6004 0 : HCCL_RUN_WARNING("[HcclCommAicpu][%s] localNotify[%u] not found in notifys_", __func__, i);
6005 : }
6006 : }
6007 :
6008 0 : HCCL_INFO(
6009 : "[HcclCommAicpu][%s] comm identifier[%s], free notifys num[%u] success", __func__, hcomId.c_str(), notifyNum);
6010 0 : return HCCL_SUCCESS;
6011 0 : }
6012 :
6013 0 : HcclResult HcclCommAicpu::RegisterOpInfo(void* opInfo, u32 size)
6014 : {
6015 0 : CHK_RET(taskExecption_.RegisterOpInfo(opInfo, size));
6016 0 : u32 opIdx = taskExecption_.GetOpRingBufferIdx();
6017 0 : CHK_RET(SetDispatcherCtxOpIdx(opIdx));
6018 0 : HCCL_INFO("%s success, group[%s], opRingBufferId[%u]", __func__, identifier_.c_str(), opIdx);
6019 0 : return HCCL_SUCCESS;
6020 : }
6021 :
6022 0 : HcclResult HcclCommAicpu::RegOpTaskException(HcommGetOpInfoCallback callback)
6023 : {
6024 0 : CHK_RET(taskExecption_.RegisterOpInfoCallback(callback));
6025 0 : return HCCL_SUCCESS;
6026 : }
6027 :
6028 0 : HcclResult HcclCommAicpu::SetDispatcherCtxOnThread()
6029 : {
6030 : // 设置 DispatcherCtx 到线程变量
6031 0 : CHK_RET(SetDispatcherCtx(dispatcherCtx_));
6032 0 : return HCCL_SUCCESS;
6033 : }
6034 : } // namespace hccl
|