LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/device/framework - aicpu_communicator.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 18.1 % 3511 636
Test Date: 2026-08-29 17:38:31 Functions: 28.6 % 231 66

            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          385 : HcclCommAicpu::HcclCommAicpu() { HCCL_RUN_INFO("Construct HcclCommAicpu complete."); }
      76              : 
      77          306 : HcclCommAicpu::~HcclCommAicpu()
      78              : {
      79           34 :     if (UtraceInfo_ != nullptr) {
      80           11 :         UtraceInfo_->DeInit();
      81           11 :         UtraceInfo_ = nullptr;
      82              :     }
      83           34 :     if (dispatcher_ != nullptr) {
      84           11 :         HcclDispatcherDestroy(dispatcher_);
      85           11 :         dispatcher_ = nullptr;
      86              :     }
      87           34 :     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           34 :     commPlaneVector_.clear();
      94           34 :     isBridgeVector_.clear();
      95           34 :     indOpCommInitialized_ = false;
      96           34 :     initialized_ = false;
      97              : 
      98           34 :     HCCL_RUN_INFO("Destruct HcclCommAicpu group[%s] success!", identifier_.c_str());
      99          374 : }
     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            2 : void HcclCommAicpu::PrepareOpRetryHandler(
     437              :     u8 inplaceSupportRetry, u8 retryEnable, u8 inPlaceSupportRetryStatus, u8 isInplacePreSync, u8 isPostSync)
     438              : {
     439            2 :     algOpContext_.opRetryHandler.inplaceSupportRetry = static_cast<bool>(inplaceSupportRetry);
     440            2 :     algOpContext_.opRetryHandler.retryEnable = static_cast<bool>(retryEnable);
     441              :     algOpContext_.opRetryHandler.inPlaceSupportRetryStatus
     442            2 :         = static_cast<InplaceSupportRetryStatus>(inPlaceSupportRetryStatus);
     443            2 :     algOpContext_.opRetryHandler.isInplacePreSync = static_cast<bool>(isInplacePreSync);
     444            2 :     algOpContext_.opRetryHandler.isPostSync = static_cast<bool>(isPostSync);
     445            2 :     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            2 : }
     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 notify 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 exceed max number, 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 notify failed, resId[%u], group[%s]",
     640              :                 commParam->localRes.localSignals[i].resId, identifier_.c_str()),
     641              :             ret);
     642              :     }
     643           11 :     u32 hostPid = 0;
     644           11 :     CHK_RET(HrtHalDrvQueryProcessHostPid(getpid(), &devId_, nullptr, &hostPid, nullptr));
     645           11 :     HCCL_INFO("[HcclCommAicpu][InitOpNotifyObj] success, group[%s]", identifier_.c_str());
     646           11 :     return HCCL_SUCCESS;
     647              : }
     648              : 
     649           11 : HcclResult HcclCommAicpu::InitLocalNotifyObj(const HcclOpResParam* commParam)
     650              : {
     651           11 :     HcclResult ret = HCCL_SUCCESS;
     652              : 
     653           11 :     if (commParam->localRes.signalNum > LOCAL_NOTIFY_MAX_NUM) {
     654            0 :         HCCL_ERROR(
     655              :             "[HcclCommAicpu][InitLocalNotifyObj] local notify count exceeds max number, numbers[%u], max "
     656              :             "numbers[%u], group[%s]",
     657              :             commParam->localRes.signalNum, LOCAL_NOTIFY_MAX_NUM, identifier_.c_str());
     658            0 :         return HCCL_E_PARA;
     659              :     }
     660          715 :     for (u32 i = 0; i < commParam->localRes.signalNum; i++) {
     661          704 :         if (notifysToObj_.find(commParam->localRes.localSignals[i].resId) == notifysToObj_.end()) {
     662          704 :             ret = InitAndVerifySignal(commParam->localRes.localSignals[i], localNotifies_);
     663          704 :             CHK_PRT_RET(
     664              :                 ret != HCCL_SUCCESS,
     665              :                 HCCL_ERROR(
     666              :                     "[HcclCommAicpu][InitLocalNotifyObj] check localRes prenotify failed, resId[%u]",
     667              :                     commParam->localRes.localSignals[i].resId),
     668              :                 ret);
     669          704 :             notifysToObj_.insert(commParam->localRes.localSignals[i].resId);
     670              :         }
     671              :     }
     672           11 :     HCCL_DEBUG(
     673              :         "[HcclCommAicpu][InitLocalNotifyObj] success, group[%s], signal numbers[%u]", identifier_.c_str(),
     674              :         commParam->localRes.signalNum);
     675           11 :     return HCCL_SUCCESS;
     676              : }
     677              : 
     678           22 : HcclResult HcclCommAicpu::ParseTlvToVector(
     679              :     u64 srcTlv, u64 srcTlvTotalLength, std::vector<std::vector<std::vector<u32>>>& vectorInfo)
     680              : {
     681           22 :     u64 parseLength = 0;
     682           22 :     u8* srcTlvptr = reinterpret_cast<u8*>(srcTlv);
     683           22 :     if (srcTlvptr == nullptr) {
     684            0 :         HCCL_ERROR("[HcclCommAicpu][ParseTlvToVector]tlv ptr is null.");
     685            0 :         return HCCL_E_PARA;
     686              :     }
     687           22 :     u64 unPareseLength = srcTlvTotalLength;
     688          143 :     while (unPareseLength > 0) {
     689          121 :         CommonTlv* commonTlv = reinterpret_cast<CommonTlv*>(srcTlvptr + parseLength);
     690          121 :         if (unPareseLength <= (sizeof(LENGTH_TYPE) + sizeof(TAG_TYPE))) {
     691            0 :             HCCL_ERROR(
     692              :                 "[HcclCommAicpu][ParseTlvToVector] Tlv length is error, tag[%s], totalLength[%lu], "
     693              :                 "unParseLength[%lu], already parsed Length[%lu]",
     694              :                 identifier_.c_str(), srcTlvTotalLength, unPareseLength, parseLength);
     695            0 :             return HCCL_E_PARA;
     696              :         }
     697          121 :         if (commonTlv->length > unPareseLength || commonTlv->length % sizeof(RANK_TYPE) != 0) {
     698            0 :             HCCL_ERROR(
     699              :                 "[HcclCommAicpu][ParseTlvToVector] parse Tlv error, group[%s], total Length[%lu], tlvLength[%lu], "
     700              :                 "unParsed Length[%lu], already parsed Length[%lu]",
     701              :                 identifier_.c_str(), srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
     702            0 :             return HCCL_E_PARA;
     703              :         }
     704          121 :         u16 level0 = (commonTlv->type & TOP_COMM_LEVEL0_LOCATION) >> TOP_COMM_LEVEL0_SHIFT;
     705          121 :         u16 level1 = (commonTlv->type & TOP_COMM_LEVEL1_LOCATION);
     706          121 :         u64 itemNum = (commonTlv->length - sizeof(TAG_TYPE) - sizeof(LENGTH_TYPE)) / sizeof(RANK_TYPE);
     707          242 :         std::vector<RANK_TYPE> values{&commonTlv->value, (&commonTlv->value) + itemNum};
     708          121 :         if (level0 >= vectorInfo.size()) {
     709           99 :             vectorInfo.resize(level0 + 1);
     710              :         }
     711          121 :         if (level1 >= vectorInfo[level0].size()) {
     712          121 :             vectorInfo[level0].resize(level1 + 1);
     713              :         }
     714          121 :         vectorInfo[level0][level1] = std::move(values);
     715          121 :         parseLength += commonTlv->length;
     716          121 :         unPareseLength -= commonTlv->length;
     717          121 :         HCCL_DEBUG(
     718              :             "[HcclCommAicpu][ParseTlvToVector] parse Tlv group[%s], level0[%u], level1[%u], total Length[%lu], "
     719              :             "tlvLength[%lu], unParsed Length[%lu], already parsed Length[%lu]",
     720              :             identifier_.c_str(), level0, level1, srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
     721          121 :     }
     722          143 :     for (u32 idx = 0; idx < vectorInfo.size(); idx++) {
     723          242 :         for (u32 ringidx = 0; ringidx < vectorInfo[idx].size(); ringidx++) {
     724          121 :             HCCL_DEBUG(
     725              :                 "[HcclCommAicpu][ParseTlvToVector] idx[%u] ringidx[%u] size[%u]", idx, ringidx,
     726              :                 vectorInfo[idx][ringidx].size());
     727              :         }
     728              :     }
     729           22 :     HCCL_INFO("[HcclCommAicpu][ParseTlvToVector] success, group[%s]", identifier_.c_str());
     730           22 :     return HCCL_SUCCESS;
     731              : }
     732              : 
     733           11 : HcclResult HcclCommAicpu::ParseTlvToSubGroupVector(
     734              :     u64 srcTlv, u64 srcTlvTotalLength, std::vector<std::vector<std::vector<std::vector<u32>>>>& vectorInfo)
     735              : {
     736           11 :     u64 parseLength = 0;
     737           11 :     u8* srcTlvptr = reinterpret_cast<u8*>(srcTlv);
     738           11 :     if (srcTlvptr == nullptr) {
     739            0 :         HCCL_ERROR("[HcclCommAicpu][ParseTlvToSubGroupVector]tlv ptr is null.");
     740            0 :         return HCCL_E_PARA;
     741              :     }
     742           11 :     u64 unPareseLength = srcTlvTotalLength;
     743           33 :     while (unPareseLength > 0) {
     744           22 :         CommonTlv* commonTlv = reinterpret_cast<CommonTlv*>(srcTlvptr + parseLength);
     745           22 :         if (unPareseLength <= (sizeof(LENGTH_TYPE) + sizeof(TAG_TYPE))) {
     746            0 :             HCCL_ERROR(
     747              :                 "[HcclCommAicpu][ParseTlvToSubGroupVector] Tlv length is error, tag[%s], totalLength[%lu], "
     748              :                 "unParseLength[%lu], already parsed Length[%lu]",
     749              :                 identifier_.c_str(), srcTlvTotalLength, unPareseLength, parseLength);
     750            0 :             return HCCL_E_PARA;
     751              :         }
     752           22 :         if (commonTlv->length > unPareseLength || commonTlv->length % sizeof(RANK_TYPE) != 0) {
     753            0 :             HCCL_ERROR(
     754              :                 "[HcclCommAicpu][ParseTlvToSubGroupVector] parse Tlv error, group[%s], total Length[%lu], "
     755              :                 "tlvLength[%lu], "
     756              :                 "unParsed Length[%lu], already parsed Length[%lu]",
     757              :                 identifier_.c_str(), srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
     758            0 :             return HCCL_E_PARA;
     759              :         }
     760           22 :         u16 level0 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL0_LOCATION)
     761           22 :                      >> (TOP_HIERARCHICAL_COMM_LEVEL0_SHIFT + TOP_HIERARCHICAL_COMM_LEVEL1_SHIFT);
     762           22 :         u16 level1 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL1_LOCATION) >> TOP_HIERARCHICAL_COMM_LEVEL1_SHIFT;
     763           22 :         u16 level2 = (commonTlv->type & TOP_HIERARCHICAL_COMM_LEVEL2_LOCATION);
     764           22 :         u64 itemNum = (commonTlv->length - sizeof(TAG_TYPE) - sizeof(LENGTH_TYPE)) / sizeof(RANK_TYPE);
     765           44 :         std::vector<RANK_TYPE> values{&commonTlv->value, (&commonTlv->value) + itemNum};
     766           22 :         if (level0 >= vectorInfo.size()) {
     767           11 :             vectorInfo.resize(level0 + 1);
     768              :         }
     769           22 :         if (level1 >= vectorInfo[level0].size()) {
     770           11 :             vectorInfo[level0].resize(level1 + 1);
     771              :         }
     772           22 :         if (level2 >= vectorInfo[level0][level1].size()) {
     773           22 :             vectorInfo[level0][level1].resize(level2 + 1);
     774              :         }
     775           22 :         vectorInfo[level0][level1][level2] = std::move(values);
     776           22 :         parseLength += commonTlv->length;
     777           22 :         unPareseLength -= commonTlv->length;
     778           22 :         HCCL_DEBUG(
     779              :             "[HcclCommAicpu][ParseTlvToSubGroupVector] parse Tlv group[%s], level0[%u], level1[%u], total Length[%lu], "
     780              :             "tlvLength[%lu], unParsed Length[%lu], already parsed Length[%lu]",
     781              :             identifier_.c_str(), level0, level1, srcTlvTotalLength, commonTlv->length, unPareseLength, parseLength);
     782           22 :     }
     783           22 :     for (u32 level0Idx = 0; level0Idx < vectorInfo.size(); level0Idx++) {
     784           22 :         for (u32 level1Idx = 0; level1Idx < vectorInfo[level0Idx].size(); level1Idx++) {
     785           33 :             for (u32 level2Idx = 0; level2Idx < vectorInfo[level0Idx][level1Idx].size(); level2Idx++) {
     786           22 :                 HCCL_DEBUG(
     787              :                     "[HcclCommAicpu][ParseTlvToSubGroupVector] level0Idx[%u] level1Idx[%u] level2Idx[%u] size[%u]",
     788              :                     level0Idx, level1Idx, level2Idx, vectorInfo[level0Idx][level1Idx][level2Idx].size());
     789              :             }
     790              :         }
     791              :     }
     792           11 :     HCCL_INFO("[HcclCommAicpu][ParseTlvToSubGroupVector] success, group[%s]", identifier_.c_str());
     793           11 :     return HCCL_SUCCESS;
     794              : }
     795              : 
     796           11 : HcclResult HcclCommAicpu::InitTopoInfo(const HcclOpResParam* commParam)
     797              : {
     798           11 :     topoInfo_.userRank = commParam->topoInfo.userRank;
     799           11 :     topoInfo_.userRankSize = commParam->topoInfo.userRankSize;
     800           11 :     topoInfo_.deviceLogicId = commParam->topoInfo.deviceLogicId;
     801           11 :     topoInfo_.isSingleMeshAggregation = commParam->topoInfo.isSingleMeshAggregation;
     802           11 :     topoInfo_.deviceNumPerAggregation = commParam->topoInfo.deviceNumPerAggregation;
     803           11 :     topoInfo_.superPodNum = commParam->topoInfo.superPodNum;
     804           11 :     topoInfo_.devicePhyId = commParam->topoInfo.devicePhyId;
     805           11 :     topoInfo_.deviceType = static_cast<DevType>(commParam->topoInfo.deviceType);
     806           11 :     topoInfo_.topoType = static_cast<TopoType>(commParam->topoInfo.topoType);
     807           11 :     topoInfo_.is310P3Common = (topoInfo_.deviceType == DevType::DEV_TYPE_310P3);
     808           11 :     topoInfo_.serverNum = commParam->topoInfo.serverNum;
     809           11 :     topoInfo_.meshAggregationRankSize = commParam->topoInfo.meshAggregationRankSize;
     810           11 :     topoInfo_.multiModuleDiffDeviceNumMode = commParam->topoInfo.multiModuleDiffDeviceNumMode;
     811           11 :     topoInfo_.multiSuperPodDiffServerNumMode = commParam->topoInfo.multiSuperPodDiffServerNumMode;
     812           11 :     topoInfo_.realUserRank = commParam->topoInfo.realUserRank;
     813           11 :     topoInfo_.isDiffDeviceModule = commParam->topoInfo.isDiffDeviceModule;
     814           11 :     topoInfo_.isDiffDeviceType = commParam->topoInfo.isDiffDeviceType;
     815           11 :     topoInfo_.gcdDeviceNumPerAggregation = commParam->topoInfo.gcdDeviceNumPerAggregation;
     816           11 :     topoInfo_.moduleNum = commParam->topoInfo.moduleNum;
     817           11 :     topoInfo_.useSuperPodMode = true;
     818           11 :     topoInfo_.isARSDoubleRing = commParam->isARSDoubleRing;
     819           11 :     topoInfo_.multiSuperPodDiffDeviceNumMode = commParam->multiSuperPodDiffDeviceNumMode;
     820           11 :     if (commParam->topoInfo.isUsedRdmaRankPairNum % KEY_VALUE_TO_VECTOR_MODULUS != 0) {
     821            0 :         HCCL_ERROR(
     822              :             "[HcclCommAicpu][InitTopoInfo]rdma rank pair number[%lu] is error.",
     823              :             commParam->topoInfo.isUsedRdmaRankPairNum);
     824            0 :         return HCCL_E_PARA;
     825              :     }
     826           11 :     u32* isUsedRdmaRankPairPtr = reinterpret_cast<u32*>(commParam->topoInfo.isUsedRdmaRankPair);
     827           11 :     if (isUsedRdmaRankPairPtr == nullptr) {
     828            0 :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]rdma rank pair ptr is null.");
     829            0 :         return HCCL_E_PARA;
     830              :     }
     831           55 :     for (u64 i = 0; i < commParam->topoInfo.isUsedRdmaRankPairNum; i += KEY_VALUE_TO_VECTOR_MODULUS) {
     832           44 :         topoInfo_.isUsedRdmaMap.insert({isUsedRdmaRankPairPtr[i], static_cast<bool>(isUsedRdmaRankPairPtr[i + 1])});
     833              :     }
     834              : 
     835           11 :     if (commParam->topoInfo.pairLinkCounterNum % KEY_VALUE_TO_VECTOR_MODULUS != 0) {
     836            0 :         HCCL_ERROR(
     837              :             "[HcclCommAicpu][InitTopoInfo]pair link count number[%lu] is error.",
     838              :             commParam->topoInfo.pairLinkCounterNum);
     839            0 :         return HCCL_E_PARA;
     840              :     }
     841           11 :     u32* pairLinkCounterPtr = reinterpret_cast<u32*>(commParam->topoInfo.pairLinkCounter);
     842           11 :     if (pairLinkCounterPtr == nullptr) {
     843            0 :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]pair link counter ptr is null.");
     844            0 :         return HCCL_E_PARA;
     845              :     }
     846              : 
     847           55 :     for (u64 i = 0; i < commParam->topoInfo.pairLinkCounterNum; i += KEY_VALUE_TO_VECTOR_MODULUS) {
     848           44 :         topoInfo_.pairLinkCounter.insert({pairLinkCounterPtr[i], pairLinkCounterPtr[i + 1]});
     849              :     }
     850              : 
     851           11 :     u32* nicListPtr = reinterpret_cast<u32*>(commParam->topoInfo.nicList);
     852           11 :     if (nicListPtr == nullptr) {
     853            0 :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]nic list ptr is null.");
     854            0 :         return HCCL_E_PARA;
     855              :     }
     856           22 :     std::vector<u32> niclist{nicListPtr, nicListPtr + commParam->topoInfo.nicNum};
     857           11 :     topoInfo_.nicList = std::move(niclist);
     858              : 
     859           11 :     bool* bridgeRankPtr = reinterpret_cast<bool*>(commParam->topoInfo.bridgeRank);
     860           11 :     if (bridgeRankPtr != nullptr) {
     861           11 :         isBridgeVector_.resize(commParam->topoInfo.bridgeRankNum);
     862           33 :         for (u32 i = 0; i < commParam->topoInfo.bridgeRankNum; ++i) {
     863           22 :             isBridgeVector_[i] = bridgeRankPtr[i];
     864           22 :             HCCL_DEBUG("[HcclCommAicpu][InitTopoInfo] bridge rank info idx[%u] value[%u]", i, isBridgeVector_[i]);
     865              :         }
     866              :     } else {
     867            0 :         HCCL_RUN_INFO("[HcclCommAicpu][InitTopoInfo] bridge rank number is 0, group[%s]", identifier_.c_str());
     868              :     }
     869              : 
     870           11 :     HcclResult ret = HCCL_SUCCESS;
     871           11 :     ret = ParseTlvToVector(commParam->topoInfo.complanRank, commParam->topoInfo.complanRankLength, commPlaneVector_);
     872           11 :     CHK_PRT_RET(
     873              :         ret != HCCL_SUCCESS,
     874              :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init CommPlane error group[%s]", identifier_.c_str()), ret);
     875              : 
     876           22 :     ret = ParseTlvToVector(
     877           11 :         commParam->topoInfo.serverAndsuperPodRank, commParam->topoInfo.serverAndsuperPodRankLength,
     878           11 :         serverAndsuperPodToRank_);
     879           11 :     CHK_PRT_RET(
     880              :         ret != HCCL_SUCCESS,
     881              :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init server and superPod rank error group[%s]", identifier_.c_str()),
     882              :         ret);
     883              : 
     884           22 :     ret = ParseTlvToSubGroupVector(
     885           11 :         commParam->hierarchicalAlgInfo.commplaneSubGroupRank,
     886           11 :         commParam->hierarchicalAlgInfo.commplaneSubGroupRankLength, topoInfo_.CommPlaneSubGroupVector);
     887           11 :     CHK_PRT_RET(
     888              :         ret != HCCL_SUCCESS,
     889              :         HCCL_ERROR("[HcclCommAicpu][InitTopoInfo]Init CommPlaneSubGroup error group[%s]", identifier_.c_str()), ret);
     890              : 
     891           11 :     HCCL_INFO(
     892              :         "[HcclCommAicpu][InitTopoInfo] success, group[%s], device Type[%u]", identifier_.c_str(),
     893              :         commParam->topoInfo.deviceType);
     894           11 :     return HCCL_SUCCESS;
     895           11 : }
     896              : 
     897           11 : HcclResult HcclCommAicpu::InitCclbuffer(const HcclOpResParam* commParam)
     898              : {
     899           11 :     if (commParam->localWindowsIn == 0 || commParam->localWindowsOut == 0 || cclInputBuffer_.ptr() != nullptr
     900           22 :         || cclOutputBuffer_.ptr() != nullptr) {
     901            0 :         HCCL_INFO(
     902              :             "[HcclCommAicpu][InitCclBuffer] don't need init cclbuffer "
     903              :             "ccl winIn[0x%lx] winout[0x%lx] cclin ptr[%p] cclout ptr[%p]",
     904              :             commParam->localWindowsIn, commParam->localWindowsOut, cclInputBuffer_.ptr(), cclOutputBuffer_.ptr());
     905            0 :         return HCCL_SUCCESS;
     906              :     }
     907              : 
     908           11 :     auto cclInPtr = reinterpret_cast<void*>(commParam->localWindowsIn);
     909           11 :     auto cclOutPtr = reinterpret_cast<void*>(commParam->localWindowsOut);
     910           11 :     cclInputBuffer_ = DeviceMem::create(cclInPtr, commParam->winSize);
     911           11 :     cclOutputBuffer_ = DeviceMem::create(cclOutPtr, commParam->winSize);
     912           11 :     cclbufferSize_ = commParam->winSize;
     913           11 :     HCCL_INFO(
     914              :         "[HcclCommAicpu][InitCclbuffer] success, group[%s], cclin[%llu], cclout[%llu], size[%lu]", identifier_.c_str(),
     915              :         commParam->localWindowsIn, commParam->localWindowsOut, commParam->winSize);
     916           11 :     return HCCL_SUCCESS;
     917              : }
     918              : 
     919           11 : HcclResult HcclCommAicpu::InitConfigInfo(const HcclOpResParam* commParam)
     920              : {
     921           11 :     deterministic_ = commParam->config.deterministic;
     922           11 :     interHccsDisable_ = commParam->config.interHccsDisable;
     923           11 :     multiQpThreshold_ = commParam->config.multiQpThreshold;
     924           11 :     inlineReducEnable_ = true;
     925           11 :     fftsEnable_ = false;
     926           11 :     taskMonitorInterval_ = commParam->config.taskMonitorInterval;
     927           11 :     algoInfo_.inlineReduceSwitchOn = true;
     928           11 :     algoInfo_.identifier = commParam->hcomId;
     929           11 :     algoInfo_.isSupportAtomicWrite = static_cast<bool>(commParam->config.isSupportAtomicWrite);
     930           11 :     notifySize_ = commParam->notifysize;
     931           11 :     slaveStreams_.reserve(LOCAL_STREAM_MAX_NUM);
     932           11 :     localNotifies_.reserve(LOCAL_NOTIFY_MAX_NUM);
     933           11 :     SetExternalInputDebugConfig(commParam->debugConfig);
     934           11 :     InitDebugConfigByValue(commParam->debugConfig);
     935           11 :     HCCL_INFO(
     936              :         "[HcclCommAicpu][Init]success, group[%s] reserve noipc notifys[%lu], slave streams[%lu].", identifier_.c_str(),
     937              :         LOCAL_NOTIFY_MAX_NUM, LOCAL_STREAM_MAX_NUM);
     938           11 :     return HCCL_SUCCESS;
     939              : }
     940              : 
     941           15 : void HcclCommAicpu::SetDumpDebug(bool dumpDebug) { dumpDebug_ = dumpDebug; }
     942              : 
     943              : template <typename T>
     944              : HcclResult
     945          726 : HcclCommAicpu::InitAndVerifySignal(const HcclSignalInfo& signalInfo, std::vector<std::shared_ptr<T>>& notifyVec)
     946              : {
     947          726 :     if (signalInfo.resId == INVALID_U64) {
     948              :         // 无效值不做校验
     949            0 :         HCCL_INFO("[HcclCommAicpu][InitAndVerifySignal] resId is invalid, need not check");
     950            0 :         return HCCL_SUCCESS;
     951              :     }
     952              : 
     953          726 :     std::shared_ptr<T> notify;
     954          726 :     EXCEPTION_CATCH((notify = std::make_shared<T>()), return HCCL_E_PTR);
     955          726 :     CHK_SMART_PTR_NULL(notify);
     956          726 :     HcclSignalInfo notifySignalInfo = signalInfo;
     957          726 :     CHK_RET(notify->Init(notifySignalInfo, NotifyLoadType::DEVICE_NOTIFY));
     958          726 :     notifyVec.push_back(notify);
     959          726 :     HCCL_INFO(
     960              :         "[HcclCommAicpu][InitAndVerifySignal] success group[%s], resId[%u], tsId:%d, devId[%u]", identifier_.c_str(),
     961              :         signalInfo.resId, signalInfo.tsId, signalInfo.devId);
     962              : 
     963          726 :     return HCCL_SUCCESS;
     964          726 : }
     965              : 
     966           33 : void HcclCommAicpu::HandleExistTagReAlloc(
     967              :     HccltagLocalResV2* tagRes, const std::string& tag, bool reAllocFlag, ListCommon*& curList, bool& needSkip)
     968              : {
     969           33 :     needSkip = false;
     970              :     // 如果 tag 已经存在且需要重新申请内存, 删除旧的资源与记录
     971           33 :     if (localTagResToObj_.find(tag) != localTagResToObj_.end() && reAllocFlag) {
     972            0 :         u64 currSize = tagRes->ScratchmemSize;
     973            0 :         u64 existSize = tagScratchMem_[tag]->size();
     974              :         // 新内存更大,删除旧记录,保留新的
     975            0 :         if (currSize > existSize) {
     976            0 :             localTagResToObj_.erase(tag);
     977            0 :             tagScratchMem_.erase(tag);
     978            0 :             HCCL_DEBUG(
     979              :                 "[HcclCommAicpu][%s] tag exists, replace old small mem, tag[%s], old[%lu] new[%lu]", __func__,
     980              :                 tag.c_str(), existSize, currSize);
     981              :         } else {
     982              :             // 旧内存更大,需要跳过
     983            0 :             HCCL_DEBUG(
     984              :                 "[HcclCommAicpu][%s] tag exists, keep larger old mem, skip new, tag[%s], old[%lu] new[%lu]", __func__,
     985              :                 tag.c_str(), existSize, currSize);
     986            0 :             curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
     987            0 :             needSkip = true;
     988              :         }
     989              :     }
     990           33 : }
     991              : 
     992           11 : HcclResult HcclCommAicpu::InitLocalTagRes(const ListCommon& head, bool reAllocFlag)
     993              : {
     994           11 :     ListCommon* curList = reinterpret_cast<ListCommon*>(head.nextDevice);
     995           11 :     if (curList == nullptr) {
     996            0 :         HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes]list ptr is null.");
     997            0 :         return HCCL_E_PARA;
     998              :     }
     999           44 :     while (curList != &head) {
    1000           33 :         HccltagLocalResV2* tagRes = list_entry(curList, HccltagLocalResV2, nextTagRes);
    1001           33 :         std::string tag = tagRes->tag;
    1002           33 :         bool needSkip = false;
    1003           33 :         HandleExistTagReAlloc(tagRes, tag, reAllocFlag, curList, needSkip);
    1004           33 :         if (needSkip) {
    1005            0 :             continue;
    1006              :         }
    1007           33 :         if (localTagResToObj_.find(tag) == localTagResToObj_.end()
    1008           33 :             || localTagResToObj_[tag].find(tagRes->Scratchmem) == localTagResToObj_[tag].end()) {
    1009           33 :             auto scratchMemPtr = reinterpret_cast<void*>(tagRes->Scratchmem);
    1010           33 :             if (scratchMemPtr == nullptr) {
    1011            0 :                 HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes]scratch mem ptr is null.");
    1012            0 :                 return HCCL_E_PARA;
    1013              :             }
    1014           33 :             DeviceMem loalScratchmem = DeviceMem::create(scratchMemPtr, tagRes->ScratchmemSize);
    1015           33 :             std::shared_ptr<DeviceMem> loalScratchmemPtr;
    1016           33 :             EXCEPTION_CATCH(
    1017              :                 (loalScratchmemPtr = std::make_shared<DeviceMem>(std::move(loalScratchmem))), return HCCL_E_PTR);
    1018           33 :             CHK_SMART_PTR_NULL(loalScratchmemPtr);
    1019           33 :             if (tagScratchMem_.find(tag) == tagScratchMem_.end()) {
    1020           33 :                 tagScratchMem_.insert({tag, loalScratchmemPtr});
    1021              :             }
    1022           33 :             std::unordered_set<u64> tmpTagRes;
    1023           33 :             tmpTagRes.insert(tagRes->Scratchmem);
    1024           33 :             localTagResToObj_[tag] = tmpTagRes;
    1025           33 :             HCCL_DEBUG(
    1026              :                 "[HcclCommAicpu][InitLocalTagRes] parse remote resource, tag[%s], Scratchmem[%p], "
    1027              :                 "ScratchmemSize[%lu]",
    1028              :                 tag.c_str(), tagRes->Scratchmem, tagRes->ScratchmemSize);
    1029           33 :         }
    1030           33 :         curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
    1031           33 :         if (curList == nullptr) {
    1032            0 :             HCCL_ERROR("[HcclCommAicpu][InitLocalTagRes] next list ptr is null.");
    1033            0 :             return HCCL_E_PARA;
    1034              :         }
    1035           33 :     };
    1036           11 :     HCCL_INFO("[HcclCommAicpu][InitLocalTagRes] success, group[%s]", identifier_.c_str());
    1037           11 :     return HCCL_SUCCESS;
    1038              : }
    1039              : 
    1040            0 : HcclResult HcclCommAicpu::CheckNotifyOrQPMaxNum(u64& existNum, const u64& MaxNum, const bool& isNotifyRes)
    1041              : {
    1042            0 :     std::string resType = isNotifyRes ? "Notify" : "QP";
    1043            0 :     if (existNum + 1 > MaxNum) {
    1044            0 :         HCCL_ERROR(
    1045              :             "[%s]%s resources are insufficient, existNum[%llu], MaxNum is [%llu]", __func__, resType.c_str(), existNum,
    1046              :             MaxNum);
    1047            0 :         return HCCL_E_INTERNAL;
    1048              :     }
    1049            0 :     HCCL_DEBUG(
    1050              :         "[%s]%s resources are sufficient, existNum[%llu], MaxNum is [%llu]", __func__, resType.c_str(), existNum,
    1051              :         MaxNum);
    1052            0 :     return HCCL_SUCCESS;
    1053            0 : }
    1054              : 
    1055            0 : HcclResult HcclCommAicpu::SetTransportMachinePara(
    1056              :     MachinePara& machinePara, u32& rankId, const std::string& newTag, TransportLinkType linkType)
    1057              : {
    1058            0 :     machinePara.linkAttribute = 0x03; /* 0x03同时支持目的端和源端发起 */
    1059            0 :     if (rankData_.find(rankId) == rankData_.end()) {
    1060            0 :         HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
    1061            0 :         return HCCL_E_NOT_FOUND;
    1062              :     }
    1063              : 
    1064            0 :     machinePara.localUserrank = localUserRank_;
    1065            0 :     machinePara.remoteWorldRank = rankData_[rankId].remoteWorldRank;
    1066            0 :     machinePara.remoteUserrank = rankData_[rankId].remoteUsrRankId;
    1067            0 :     machinePara.deviceLogicId = topoInfo_.deviceLogicId;
    1068            0 :     machinePara.localDeviceId = topoInfo_.devicePhyId;
    1069            0 :     machinePara.deviceType = topoInfo_.deviceType;
    1070            0 :     machinePara.tag = newTag;
    1071            0 :     machinePara.isAicpuModeEn = true;
    1072            0 :     if (linkType == TransportLinkType::RESERVED) {
    1073              :         // 非910_93 2die sio与hccs并发场景,specifyLink设置为RESERVED_LINK_TYPE,平台层将按实际链路类型建链
    1074            0 :         machinePara.specifyLink = LinkTypeInServer::RESERVED_LINK_TYPE;
    1075              :     } else {
    1076              :         // 910_93 2die sio与hccs并发场景,
    1077              :         // 并发链路中的的hccs链路specifyLink设置为HCCS_SW_TYPE,平台层将使用hccs链路来建链;
    1078              :         // 并发链路中的的sio链路specifyLink设置为SIO_TYPE,平台层将使用sio链路来建链
    1079              :         machinePara.specifyLink
    1080            0 :             = (linkType == TransportLinkType::SIO) ? LinkTypeInServer::SIO_TYPE : LinkTypeInServer::HCCS_SW_TYPE;
    1081              :     }
    1082              : 
    1083            0 :     HCCL_INFO(
    1084              :         "%s success, group[%s], rankId[%u], linkAttribute[%x], localUserRank[%u], remoteWorldRank[%u], "
    1085              :         "remoteUserrank[%u], deviceLogicId[%d], localDeviceId[%d], deviceType[%d], newTag[%s], specifyLink[%d], "
    1086              :         "isAicpuModeEn[%d]",
    1087              :         __func__, identifier_.c_str(), rankId, machinePara.linkAttribute, machinePara.localUserrank,
    1088              :         machinePara.remoteWorldRank, machinePara.remoteUserrank, machinePara.deviceLogicId, machinePara.localDeviceId,
    1089              :         machinePara.deviceType, machinePara.tag.c_str(), machinePara.specifyLink, machinePara.isAicpuModeEn);
    1090            0 :     return HCCL_SUCCESS;
    1091              : }
    1092              : 
    1093              : template <typename T>
    1094            0 : HcclResult HcclCommAicpu::InitAndVerifySingleSignal(const HcclSignalInfo& signalInfo, std::shared_ptr<T>& notify)
    1095              : {
    1096            0 :     if (signalInfo.resId == INVALID_U64) {
    1097              :         // 无效值不做校验
    1098            0 :         HCCL_DEBUG("[%s]resId[%llu] is invalid, need not check", __func__, signalInfo.resId);
    1099            0 :         return HCCL_SUCCESS;
    1100              :     }
    1101            0 :     HcclSignalInfo tmpSignalInfo = signalInfo;
    1102              : 
    1103            0 :     EXCEPTION_CATCH((notify = std::make_shared<T>()), return HCCL_E_PTR);
    1104            0 :     CHK_SMART_PTR_NULL(notify);
    1105            0 :     CHK_RET(notify->Init(tmpSignalInfo, NotifyLoadType::DEVICE_NOTIFY));
    1106            0 :     CHK_RET(notify->GetNotifyData(tmpSignalInfo));
    1107            0 :     HCCL_DEBUG(
    1108              :         "[%s] success group[%s], resId[%llu], tsId:%d, devId[%u]", __func__, identifier_.c_str(), tmpSignalInfo.resId,
    1109              :         tmpSignalInfo.tsId, tmpSignalInfo.devId);
    1110              : 
    1111            0 :     return HCCL_SUCCESS;
    1112              : }
    1113              : 
    1114            0 : HcclResult HcclCommAicpu::SetTagRemoteRes(u32& rankId, const std::string& tag, HccltagRemoteResV2* tagRes)
    1115              : {
    1116            0 :     if (rankTagRemoteRes_.find(rankId) == rankTagRemoteRes_.end()
    1117            0 :         || rankTagRemoteRes_[rankId].find(tag) == rankTagRemoteRes_[rankId].end()) {
    1118            0 :         HccltagRemoteResV3 tempTagRemoteRes;
    1119            0 :         tempTagRemoteRes.tagRemoteResPtr = tagRes;
    1120            0 :         rankTagRemoteRes_[rankId][tag] = tempTagRemoteRes;
    1121              :     }
    1122            0 :     HCCL_DEBUG("[%s]get TagRemoteRes success, rankId[%u], tag[%s]", __func__, rankId, tag.c_str());
    1123            0 :     return HCCL_SUCCESS;
    1124              : }
    1125              : 
    1126            0 : HcclResult HcclCommAicpu::SetTransportPtpNotify(
    1127              :     TransportDeviceP2pData& transDevP2pData, u64& p2pNotifyNum, HcclLinkP2pV2& linkP2p, u32 notifyNum)
    1128              : {
    1129            0 :     u64 actualNotifyNum = 0;
    1130              :     // 获取Ipc notify信息
    1131            0 :     CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
    1132            0 :     std::shared_ptr<LocalNotify> ipcPreWaitNotify = std::make_shared<LocalNotify>();
    1133            0 :     CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcPreWaitNotify));
    1134            0 :     transDevP2pData.ipcPreWaitNotify = ipcPreWaitNotify;
    1135              : 
    1136            0 :     std::shared_ptr<RemoteNotify> ipcPreRecordNotify = std::make_shared<RemoteNotify>();
    1137            0 :     CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcPreRecordNotify));
    1138            0 :     transDevP2pData.ipcPreRecordNotify = ipcPreRecordNotify;
    1139            0 :     actualNotifyNum++;
    1140              : 
    1141            0 :     CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
    1142            0 :     std::shared_ptr<LocalNotify> ipcPostWaitNotify = std::make_shared<LocalNotify>();
    1143            0 :     CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcPostWaitNotify));
    1144            0 :     transDevP2pData.ipcPostWaitNotify = ipcPostWaitNotify;
    1145              : 
    1146            0 :     std::shared_ptr<RemoteNotify> ipcPostRecordNotify = std::make_shared<RemoteNotify>();
    1147            0 :     CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcPostRecordNotify));
    1148            0 :     transDevP2pData.ipcPostRecordNotify = ipcPostRecordNotify;
    1149            0 :     actualNotifyNum++;
    1150              : 
    1151            0 :     transDevP2pData.userLocalNotify.resize(notifyNum, nullptr);
    1152            0 :     transDevP2pData.userRemoteNotify.resize(notifyNum, nullptr);
    1153              : 
    1154            0 :     for (u32 idx = 0; idx < notifyNum; idx++) {
    1155            0 :         CHK_RET(CheckNotifyOrQPMaxNum(actualNotifyNum, LINK_P2P_MAX_NUM, true));
    1156            0 :         std::shared_ptr<LocalNotify> ipcWaitNotify = std::make_shared<LocalNotify>();
    1157            0 :         CHK_RET(InitAndVerifySingleSignal(linkP2p.localIpcSignal[actualNotifyNum], ipcWaitNotify));
    1158            0 :         transDevP2pData.userLocalNotify[idx] = ipcWaitNotify;
    1159              : 
    1160            0 :         std::shared_ptr<RemoteNotify> ipcRecordNotify = std::make_shared<RemoteNotify>();
    1161            0 :         CHK_RET(InitAndVerifySingleSignal(linkP2p.remoteIpcSignal[actualNotifyNum], ipcRecordNotify));
    1162            0 :         transDevP2pData.userRemoteNotify[idx] = ipcRecordNotify;
    1163              : 
    1164            0 :         actualNotifyNum++;
    1165            0 :     }
    1166              : 
    1167            0 :     HCCL_DEBUG("[%s]get p2pNotify success, actualNotifyNum[%u]", __func__, actualNotifyNum);
    1168            0 :     p2pNotifyNum = actualNotifyNum;
    1169              : 
    1170            0 :     return HCCL_SUCCESS;
    1171            0 : }
    1172              : 
    1173            0 : HcclResult HcclCommAicpu::SetTransportRoceQP(
    1174              :     TransportDeviceIbverbsData& transDevIbverbsData, u64& roceQpNum, HcclLinkRoceV2* linkRoce)
    1175              : {
    1176            0 :     roceQpNum = linkRoce->qpsPerConnection;
    1177            0 :     u32 roceQpNumSum = linkRoce->qpsPerConnection + static_cast<u32>(linkRoce->qpsPerConnection != 1);
    1178            0 :     transDevIbverbsData.qpInfo.resize(roceQpNumSum);
    1179            0 :     std::copy_n(linkRoce->QpInfo, roceQpNumSum, transDevIbverbsData.qpInfo.begin());
    1180            0 :     transDevIbverbsData.multiQpThreshold = multiQpThreshold_;
    1181            0 :     transDevIbverbsData.qpsPerConnection = linkRoce->qpsPerConnection;
    1182            0 :     HCCL_INFO(
    1183              :         "[%s]transDevIbverbsData.qpInfo.qpPtr[%llu], transDevIbverbsData.qpInfo.sqIndex[%u], "
    1184              :         "transDevIbverbsData.qpInfo.dbIndex[%u], roceQpNum[%llu], roceQpNumSum[%u], multiQpThreshold_[%u]",
    1185              :         __func__, transDevIbverbsData.qpInfo[0].qpPtr, transDevIbverbsData.qpInfo[0].sqIndex,
    1186              :         transDevIbverbsData.qpInfo[0].dbIndex, roceQpNum, roceQpNumSum, multiQpThreshold_);
    1187            0 :     return HCCL_SUCCESS;
    1188              : }
    1189              : 
    1190            0 : HcclResult HcclCommAicpu::SetTransportRoceNotify(
    1191              :     TransportDeviceIbverbsData& transDevIbverbsData, u64& roceNotifyNum, HcclLinkRoceV2* linkRoce,
    1192              :     [[maybe_unused]] u32 notifyNum)
    1193              : {
    1194            0 :     u64 actualNotifyNum = 0;
    1195            0 :     if (linkRoce->localNotifyList == 0 || linkRoce->remoteNotifyList == 0) {
    1196            0 :         HCCL_DEBUG("[%s] Empty local and remote notify lists, skipping notify resource creation.", __func__);
    1197            0 :         return HCCL_SUCCESS;
    1198              :     }
    1199            0 :     HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(linkRoce->localNotifyList);
    1200            0 :     AddrKey* remoteNotifyList = reinterpret_cast<AddrKey*>(linkRoce->remoteNotifyList);
    1201            0 :     if (localNotifyList == nullptr || remoteNotifyList == nullptr) {
    1202            0 :         HCCL_ERROR("[%s]nullptr found in localNotifyList or remoteNotifyList from device mem, check.", __func__);
    1203            0 :         return HCCL_E_INTERNAL;
    1204              :     }
    1205              :     // 获取RDMA Notify信息
    1206            0 :     std::shared_ptr<LocalNotify> ackNotify = std::make_shared<LocalNotify>();
    1207            0 :     CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], ackNotify));
    1208            0 :     transDevIbverbsData.ackNotify = ackNotify;
    1209            0 :     transDevIbverbsData.remoteAckNotifyDetails = remoteNotifyList[actualNotifyNum];
    1210            0 :     actualNotifyNum++;
    1211              : 
    1212            0 :     std::shared_ptr<LocalNotify> dataNotify = std::make_shared<LocalNotify>();
    1213            0 :     CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataNotify));
    1214            0 :     transDevIbverbsData.dataNotify = dataNotify;
    1215            0 :     transDevIbverbsData.remoteDataNotifyDetails = remoteNotifyList[actualNotifyNum];
    1216            0 :     actualNotifyNum++;
    1217              : 
    1218            0 :     std::shared_ptr<LocalNotify> dataAckNotify = std::make_shared<LocalNotify>();
    1219            0 :     CHK_RET(InitAndVerifySingleSignal(localNotifyList[actualNotifyNum], dataAckNotify));
    1220            0 :     transDevIbverbsData.dataAckNotify = dataAckNotify;
    1221            0 :     transDevIbverbsData.remoteDataAckNotifyDetails = remoteNotifyList[actualNotifyNum];
    1222            0 :     transDevIbverbsData.notifySize = notifySize_;
    1223            0 :     actualNotifyNum++;
    1224              : 
    1225            0 :     transDevIbverbsData.userLocalNotify.resize(linkRoce->qpsPerConnection);
    1226            0 :     transDevIbverbsData.userRemoteNotifyDetails.resize(linkRoce->qpsPerConnection);
    1227              :     // 当前多QP下每个QP会多申请一个DataNotify
    1228            0 :     u64 singleQpNotifySize = linkRoce->singleQPNotifyNum + static_cast<u32>(linkRoce->qpsPerConnection > 1);
    1229            0 :     for (u32 qpIndex = 0; qpIndex < linkRoce->qpsPerConnection; qpIndex++) {
    1230            0 :         transDevIbverbsData.userLocalNotify[qpIndex].resize(singleQpNotifySize, nullptr);
    1231            0 :         transDevIbverbsData.userRemoteNotifyDetails[qpIndex].resize(singleQpNotifySize);
    1232            0 :         for (u32 i = 0, idx = actualNotifyNum + singleQpNotifySize * qpIndex; i < singleQpNotifySize; ++idx, ++i) {
    1233            0 :             std::shared_ptr<LocalNotify> locNotify = std::make_shared<LocalNotify>();
    1234            0 :             CHK_RET(InitAndVerifySingleSignal(localNotifyList[idx], locNotify));
    1235            0 :             transDevIbverbsData.userLocalNotify[qpIndex][i] = locNotify;
    1236            0 :             transDevIbverbsData.userRemoteNotifyDetails[qpIndex][i] = remoteNotifyList[idx];
    1237            0 :         }
    1238              :     }
    1239            0 :     roceNotifyNum = linkRoce->singleQPNotifyNum;
    1240            0 :     HCCL_DEBUG("[%s]get roceNotify success, roceNotifyNum[%u]", __func__, roceNotifyNum);
    1241            0 :     return HCCL_SUCCESS;
    1242            0 : }
    1243              : 
    1244            0 : HcclResult HcclCommAicpu::InitLinkP2p(
    1245              :     HccltagRemoteResV2* tagRes, u32& rankId, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
    1246              : {
    1247            0 :     std::unordered_map<u32, std::unordered_map<std::string, std::shared_ptr<Transport>>>& linkRes
    1248              :         = (linkType == TransportLinkType::SIO) ? linkResSio_ : linkRes_;
    1249            0 :     HcclLinkP2pV2& linkP2p = (linkType == TransportLinkType::SIO) ? tagRes->linkP2pSio : tagRes->linkP2p;
    1250              : 
    1251            0 :     if (linkRes.find(rankId) == linkRes.end() || linkRes[rankId].find(newTag) == linkRes[rankId].end()) {
    1252              :         // 优先校验notify去判定link是否有效
    1253            0 :         if (linkP2p.localIpcSignal[0].resId == INVALID_U64) {
    1254            0 :             HCCL_INFO(
    1255              :                 "[%s]the link is invalid, no need to create transport, rankId[%u], newTag[%s]", __func__, rankId,
    1256              :                 newTag.c_str());
    1257            0 :             return HCCL_SUCCESS;
    1258              :         }
    1259              :         // 创建Transport对象
    1260            0 :         MachinePara machinePara;
    1261            0 :         CHK_RET(SetTransportMachinePara(machinePara, rankId, newTag, linkType));
    1262            0 :         machinePara.notifyNum = notifyNum;
    1263              :         // 获取localMem & remoteMem
    1264            0 :         TransportDeviceP2pData transDevP2pData;
    1265            0 :         transDevP2pData.inputBufferPtr = reinterpret_cast<void*>((linkP2p.remoteMem)[INPUT].addr);
    1266            0 :         transDevP2pData.outputBufferPtr = reinterpret_cast<void*>((linkP2p.remoteMem)[OUTPUT].addr);
    1267            0 :         if (transDevP2pData.inputBufferPtr == nullptr || transDevP2pData.outputBufferPtr == nullptr) {
    1268            0 :             HCCL_ERROR(
    1269              :                 "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevP2pData.inputBufferPtr,
    1270              :                 transDevP2pData.outputBufferPtr);
    1271            0 :             return HCCL_E_PARA;
    1272              :         }
    1273              :         // 获取Notify资源
    1274            0 :         CHK_RET(SetTagRemoteRes(rankId, newTag, tagRes));
    1275            0 :         HccltagRemoteResV3* tagRemoteRes = &(rankTagRemoteRes_[rankId][newTag]);
    1276            0 :         CHK_RET(SetTransportPtpNotify(transDevP2pData, tagRemoteRes->p2pNotifyNum, linkP2p, notifyNum));
    1277              :         //  获取transportAttr信息
    1278            0 :         transDevP2pData.transportAttr = linkP2p.transportAttr;
    1279              :         //  创建Transport对象
    1280            0 :         std::shared_ptr<Transport> link;
    1281            0 :         TransportPara para{};
    1282            0 :         const std::unique_ptr<NotifyPool> notifyPool;
    1283            0 :         link.reset(new (std::nothrow) Transport(
    1284            0 :             TransportType::TRANS_TYPE_DEVICE_P2P, para, dispatcher_, notifyPool, machinePara, transDevP2pData));
    1285            0 :         CHK_SMART_PTR_NULL(link);
    1286            0 :         CHK_RET(link->Init());
    1287            0 :         linkRes[rankId][newTag] = link;
    1288            0 :         HCCL_INFO("[%s]linkRes_, rankId[%u], newTag[%s]", __func__, rankId, newTag.c_str());
    1289            0 :     }
    1290            0 :     return HCCL_SUCCESS;
    1291              : }
    1292            0 : HcclResult HcclCommAicpu::InitLinkRoce(
    1293              :     HccltagRemoteResV2* tagRes, HcclLinkRoceV2* linkRoce, u32& rankId, const std::string& newTag, u32 notifyNum,
    1294              :     const bool isBackup, const bool isSecond)
    1295              : {
    1296              :     // 优先校验notify去判定link是否有效
    1297            0 :     if (linkRoce->localNotifyList == 0) {
    1298            0 :         HCCL_INFO(
    1299              :             "[%s]the link is invalid, no need to create transport, rankId[%u], newTag[%s], isBackup[%d]", __func__,
    1300              :             rankId, newTag.c_str(), isBackup);
    1301            0 :         return HCCL_SUCCESS;
    1302              :     }
    1303            0 :     HcclSignalInfo* localNotifyList = reinterpret_cast<HcclSignalInfo*>(linkRoce->localNotifyList);
    1304            0 :     if (localNotifyList[0].resId == INVALID_U64) {
    1305            0 :         HCCL_INFO(
    1306              :             "[%s]the link notify resource is invalid, no need to create transport, rankId[%u], newTag[%s], "
    1307              :             "resId[%llu], "
    1308              :             "isBackup[%d]",
    1309              :             __func__, rankId, newTag.c_str(), localNotifyList[0].resId, isBackup);
    1310            0 :         return HCCL_SUCCESS;
    1311              :     }
    1312              : 
    1313              :     // 创建Transport对象
    1314            0 :     MachinePara machinePara;
    1315            0 :     CHK_RET(SetTransportMachinePara(machinePara, rankId, newTag));
    1316            0 :     machinePara.notifyNum = notifyNum;
    1317              :     // 获取localMem & remoteMem
    1318            0 :     TransportDeviceIbverbsData transDevIbverbsData;
    1319            0 :     transDevIbverbsData.inputBufferPtr = reinterpret_cast<void*>((linkRoce->remoteMem)[INPUT].addr);
    1320            0 :     transDevIbverbsData.outputBufferPtr = reinterpret_cast<void*>((linkRoce->remoteMem)[OUTPUT].addr);
    1321            0 :     if (transDevIbverbsData.inputBufferPtr == nullptr || transDevIbverbsData.outputBufferPtr == nullptr) {
    1322            0 :         HCCL_ERROR(
    1323              :             "[%s]input ptr[%p] or output ptr[%p] is null.", __func__, transDevIbverbsData.inputBufferPtr,
    1324              :             transDevIbverbsData.outputBufferPtr);
    1325            0 :         return HCCL_E_PARA;
    1326              :     }
    1327            0 :     transDevIbverbsData.localInputMem = (linkRoce->localMem)[INPUT];
    1328            0 :     transDevIbverbsData.localOutputMem = (linkRoce->localMem)[OUTPUT];
    1329            0 :     transDevIbverbsData.localNotifyValueAddr = linkRoce->notifyValue;
    1330            0 :     transDevIbverbsData.notifyValueKey = linkRoce->notifyValueKey;
    1331            0 :     transDevIbverbsData.remoteInputKey = (linkRoce->remoteMem)[INPUT].key;
    1332            0 :     transDevIbverbsData.remoteOutputKey = (linkRoce->remoteMem)[OUTPUT].key;
    1333              :     // 获取QPinfo
    1334            0 :     CHK_RET(SetTagRemoteRes(rankId, newTag, tagRes));
    1335            0 :     HccltagRemoteResV3* tagRemoteRes = &(rankTagRemoteRes_[rankId][newTag]);
    1336            0 :     u64& roceQpNum = isBackup ? tagRemoteRes->qpNumBackup : tagRemoteRes->qpNum;
    1337            0 :     CHK_RET(SetTransportRoceQP(transDevIbverbsData, roceQpNum, linkRoce));
    1338              :     // 获取notify
    1339            0 :     u64& roceNotifyNum = isBackup ? tagRemoteRes->roceNotifyNumBackup : tagRemoteRes->roceNotifyNum;
    1340            0 :     CHK_RET(SetTransportRoceNotify(transDevIbverbsData, roceNotifyNum, linkRoce, notifyNum));
    1341            0 :     HCCL_INFO("[%s]transDevIbverbsData isBackup[%d]", __func__, isBackup);
    1342              :     // 获取atomic write
    1343            0 :     transDevIbverbsData.useAtomicWrite = linkRoce->useAtomicWrite;
    1344              :     // 创建Transport对象
    1345            0 :     std::shared_ptr<Transport> link;
    1346            0 :     TransportPara para{};
    1347            0 :     para.timeout = linkTimeOut_;
    1348            0 :     const std::unique_ptr<NotifyPool> notifyPool;
    1349            0 :     link.reset(new (std::nothrow) Transport(
    1350            0 :         TransportType::TRANS_TYPE_DEVICE_IBVERBS, para, dispatcher_, notifyPool, machinePara, TransportDeviceP2pData(),
    1351            0 :         transDevIbverbsData));
    1352            0 :     CHK_SMART_PTR_NULL(link);
    1353            0 :     CHK_RET(link->Init());
    1354            0 :     if (isBackup) {
    1355            0 :         linkRdmaResBackUp_[rankId][newTag].push_back(link);
    1356            0 :         HCCL_INFO(
    1357              :             "[%s]linkRdmaResBackUp_, rankId[%u], newTag[%s], isBackup[%d], isSecond[%d], qpNum[%u], notifyNum[%u]",
    1358              :             __func__, rankId, newTag.c_str(), isBackup, isSecond, roceQpNum, roceNotifyNum);
    1359              :     } else {
    1360            0 :         linkRdmaRes_[rankId][newTag].push_back(link);
    1361            0 :         HCCL_INFO(
    1362              :             "[%s]linkRdmaRes_, rankId[%u], newTag[%s], isBackup[%d], isSecond[%d], qpNum[%u], notifyNum[%u]", __func__,
    1363              :             rankId, newTag.c_str(), isBackup, isSecond, roceQpNum, roceNotifyNum);
    1364              :     }
    1365            0 :     return HCCL_SUCCESS;
    1366            0 : }
    1367              : 
    1368            0 : HcclResult HcclCommAicpu::InitLinkRoce(
    1369              :     HccltagRemoteResV2* tagRes, u32& rankId, const std::string& newTag, u32 notifyNum, const bool isBackup)
    1370              : {
    1371            0 :     auto tempLinkRes = isBackup ? linkRdmaResBackUp_ : linkRdmaRes_;
    1372            0 :     if (tempLinkRes.find(rankId) == tempLinkRes.end()
    1373            0 :         || tempLinkRes[rankId].find(newTag) == tempLinkRes[rankId].end()) {
    1374            0 :         bool isBatchSendRecv = newTag.find("BatchSendRecv") != std::string::npos;
    1375            0 :         if (isBatchSendRecv) {
    1376              :             // 如果是batchsendrecv,相同rank,需要刷新两次transport,如果是主的话就刷新0,2 备就刷新1,3
    1377            0 :             if (isBackup) {
    1378            0 :                 CHK_RET(InitLinkRoce(
    1379              :                     tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP]), rankId, newTag, notifyNum, isBackup));
    1380            0 :                 CHK_RET(InitLinkRoce(
    1381              :                     tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP + 2]), rankId, newTag, notifyNum, isBackup,
    1382              :                     true));
    1383              :             } else {
    1384            0 :                 CHK_RET(InitLinkRoce(
    1385              :                     tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT]), rankId, newTag, notifyNum, isBackup));
    1386            0 :                 CHK_RET(InitLinkRoce(
    1387              :                     tagRes, &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT + 2]), rankId, newTag, notifyNum, isBackup,
    1388              :                     true));
    1389              :             }
    1390              :         } else {
    1391              :             // 非batchsendrecv只刷新主0,备1
    1392            0 :             HcclLinkRoceV2* linkRoce = isBackup ? &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_BACKUP]) :
    1393              :                                                   &(tagRes->linkRoce[AICPU_RETRY_LINKROCE_DEFAULT]);
    1394            0 :             CHK_RET(InitLinkRoce(tagRes, linkRoce, rankId, newTag, notifyNum, isBackup));
    1395              :         }
    1396              :     }
    1397            0 :     return HCCL_SUCCESS;
    1398            0 : }
    1399              : 
    1400            0 : HcclResult HcclCommAicpu::InitRemoteTagRes(
    1401              :     u32& rankId, const ListCommon& head, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
    1402              : {
    1403            0 :     HCCL_RUN_INFO(
    1404              :         "[%s] Entry parse remote resource rankId[%u], group[%s], newTag[%s], head[%p], "
    1405              :         "linkType[%d]",
    1406              :         __func__, rankId, identifier_.c_str(), newTag.c_str(), &head, linkType);
    1407            0 :     ListCommon* curList = reinterpret_cast<ListCommon*>(head.nextDevice);
    1408            0 :     if (curList == nullptr) {
    1409            0 :         HCCL_ERROR("[%s]cur list ptr is null.", __func__);
    1410            0 :         return HCCL_E_PARA;
    1411              :     }
    1412              : 
    1413            0 :     HccltagRemoteResV2* tagRes = nullptr;
    1414            0 :     while (curList != &head) {
    1415            0 :         HccltagRemoteResV2* tagResTemp = list_entry(curList, HccltagRemoteResV2, nextTagRes);
    1416            0 :         if (strcmp(tagResTemp->tag, newTag.c_str()) == 0) {
    1417            0 :             tagRes = tagResTemp;
    1418            0 :             break;
    1419              :         }
    1420              : 
    1421            0 :         curList = reinterpret_cast<ListCommon*>(curList->nextDevice);
    1422            0 :         if (curList == nullptr) {
    1423            0 :             HCCL_ERROR("[%s]next list ptr is null.", __func__);
    1424            0 :             return HCCL_E_PARA;
    1425              :         }
    1426              :     }
    1427              : 
    1428            0 :     if (tagRes == nullptr) {
    1429            0 :         HCCL_ERROR(
    1430              :             "[%s]newTag[%s] not found, rankId[%u], head[%p], curList[%p], nextList[%llu], notifyNum[%u], "
    1431              :             "linkType[%d]",
    1432              :             __func__, newTag.c_str(), rankId, &head, curList, curList->nextDevice, notifyNum, linkType);
    1433            0 :         return HCCL_E_PARA;
    1434              :     }
    1435              : 
    1436            0 :     HCCL_INFO(
    1437              :         "[%s]newTag[%s], rankId[%u], head[%p], curList[%p], nextList[%llu], notifyNum[%u], linkType[%d]", __func__,
    1438              :         newTag.c_str(), rankId, &head, curList, curList->nextDevice, notifyNum, linkType);
    1439            0 :     if (linkType != TransportLinkType::RDMA) {
    1440              :         // 创建P2P链路
    1441            0 :         CHK_RET(InitLinkP2p(tagRes, rankId, newTag, notifyNum, linkType));
    1442              :     } else {
    1443              :         // 创建roce链路
    1444            0 :         CHK_RET(InitLinkRoce(tagRes, rankId, newTag, notifyNum));
    1445              :         // 创建roce链路(备用链路)
    1446            0 :         CHK_RET(InitLinkRoce(tagRes, rankId, newTag, notifyNum, true));
    1447              :     }
    1448            0 :     HCCL_INFO(
    1449              :         "[%s] End parse remote resource rankId[%u] tag[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
    1450              :         newTag.c_str());
    1451            0 :     return HCCL_SUCCESS;
    1452              : }
    1453              : 
    1454            0 : HcclResult HcclCommAicpu::RefreshTransportsResForRank(
    1455              :     const HcclOpResParam* commParam, u32 rankId, const std::string& newTag, u32 notifyNum, TransportLinkType linkType)
    1456              : {
    1457            0 :     if (rankId >= AICPU_MAX_RANK_NUM) {
    1458            0 :         HCCL_ERROR(
    1459              :             "[%s] rankId[%u] overflow for group[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
    1460              :             newTag.c_str());
    1461            0 :         return HCCL_E_PARA;
    1462              :     }
    1463            0 :     if (commParam->remoteRes[rankId].nextDevicePtr == 0) {
    1464            0 :         return HCCL_SUCCESS;
    1465              :     }
    1466            0 :     HcclRankRelationResV2* rankRelationResPtr
    1467            0 :         = reinterpret_cast<HcclRankRelationResV2*>(commParam->remoteRes[rankId].nextDevicePtr);
    1468            0 :     if (rankRelationResPtr == nullptr) {
    1469            0 :         HCCL_ERROR(
    1470              :             "[%s]rank relation resource ptr is null, commParam->remoteRes[rankId].nextDevicePtr[%p],"
    1471              :             " rankId[%u]",
    1472              :             __func__, reinterpret_cast<HcclRankRelationResV2*>(commParam->remoteRes[rankId].nextDevicePtr), rankId);
    1473            0 :         return HCCL_E_PARA;
    1474              :     }
    1475              : 
    1476              :     // 1. init公共参数(对应remoteWorldRank,remoteUsrRankId暂不处理:windowsIn,windowsOut)
    1477            0 :     rankData_[rankId].remoteWorldRank = rankRelationResPtr->remoteWorldRank;
    1478            0 :     rankData_[rankId].remoteUsrRankId = rankRelationResPtr->remoteUsrRankId;
    1479              :     // 2. 遍历链表,获取HccltagRemoteResV2创建Tranport对象
    1480            0 :     if (reinterpret_cast<ListCommon*>(rankRelationResPtr->nextTagRes.nextDevice) != &(rankRelationResPtr->nextTagRes)) {
    1481            0 :         HCCL_DEBUG(
    1482              :             "[%s] Start to parse rankId[%u] tag resources, head[%p], nextDevice[%p], pre Device[%p], group[%s]",
    1483              :             __func__, rankId, &rankRelationResPtr->nextTagRes, rankRelationResPtr->nextTagRes.nextDevice,
    1484              :             rankRelationResPtr->nextTagRes.preDevice, identifier_.c_str());
    1485            0 :         CHK_RET(InitRemoteTagRes(rankId, rankRelationResPtr->nextTagRes, newTag, notifyNum, linkType));
    1486              :     } else {
    1487            0 :         HCCL_ERROR(
    1488              :             "[%s]could not find member in rankRelationRes list, rankId[%u], head[%p], nextDevice[%p]", __func__, rankId,
    1489              :             &rankRelationResPtr->nextTagRes, rankRelationResPtr->nextTagRes.nextDevice);
    1490            0 :         return HCCL_E_PARA;
    1491              :     }
    1492            0 :     HCCL_INFO(
    1493              :         "[%s] process success rankId[%u], group[%s], newTag[%s]", __func__, rankId, identifier_.c_str(),
    1494              :         newTag.c_str());
    1495            0 :     return HCCL_SUCCESS;
    1496              : }
    1497              : 
    1498            0 : HcclResult HcclCommAicpu::GetRdmaLinksByRankAndTag(
    1499              :     const HcclOpResParam* commParam, CommTransportsType type, u32 rankId, const std::string& newTag, LINK& link,
    1500              :     bool isBackup, u32 notifyNum, bool isSecond)
    1501              : {
    1502            0 :     HCCL_INFO(
    1503              :         "[%s] Start to rdma get Link group[%s], rankId[%u], newTag[%s], isBackup[%d], deviceLogicId[%d],"
    1504              :         "notifyNum[%u], isSecond[%d]",
    1505              :         __func__, identifier_.c_str(), rankId, newTag.c_str(), isBackup, commParam->topoInfo.deviceLogicId, notifyNum,
    1506              :         isSecond);
    1507              : 
    1508            0 :     auto* linkRes = isBackup ? &linkRdmaResBackUp_ : &linkRdmaRes_;
    1509            0 :     auto iterRankLinks = linkRes->find(rankId);
    1510            0 :     if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
    1511            0 :         HCCL_INFO(
    1512              :             "[%s] could not find link resource, rankId[%u], group[%s], newTag[%s]", __func__, rankId,
    1513              :             identifier_.c_str(), newTag.c_str());
    1514            0 :         CHK_RET(RefreshTransportsResForRank(commParam, rankId, newTag, notifyNum, TransportLinkType::RDMA));
    1515            0 :         iterRankLinks = linkRes->find(rankId);
    1516            0 :         if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
    1517            0 :             HCCL_ERROR(
    1518              :                 "[%s] refresh transport failed, newTag[%s], remoteUserRankId[%u]", __func__, newTag.c_str(), rankId);
    1519            0 :             return HCCL_E_INTERNAL;
    1520              :         }
    1521              :     }
    1522            0 :     if (isSecond && iterRankLinks->second[newTag].size() <= 1) {
    1523            0 :         HCCL_ERROR("[%s] get rdma Link failed, newTag[%s], remoteUserRankId[%u]", __func__, newTag.c_str(), rankId);
    1524            0 :         return HCCL_E_INTERNAL;
    1525              :     }
    1526              : 
    1527            0 :     link = isSecond ? iterRankLinks->second[newTag][1] : iterRankLinks->second[newTag][0];
    1528              : 
    1529            0 :     if (receivedAcks_.find(rankId) == receivedAcks_.end()) {
    1530            0 :         HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
    1531            0 :         return HCCL_E_NOT_FOUND;
    1532              :     }
    1533            0 :     link->SetSupportDataReceivedAck(receivedAcks_[rankId]);
    1534            0 :     HCCL_DEBUG(
    1535              :         "[HcclCommAicpu][GetLinksByRankAndTag]rankid[%d] supportDataReceivedAck is %d", rankId, receivedAcks_[rankId]);
    1536            0 :     HCCL_INFO(
    1537              :         "[%s] group[%s], newTag[%s], rankId[%u] type[%u] success!", __func__, identifier_.c_str(), newTag.c_str(),
    1538              :         rankId, type);
    1539            0 :     return HCCL_SUCCESS;
    1540              : }
    1541              : 
    1542            0 : HcclResult HcclCommAicpu::GetSdmaLinksByRankAndTag(
    1543              :     const HcclOpResParam* commParam, CommTransportsType type, u32 rankId, const std::string& newTag, LINK& link,
    1544              :     bool isBackup, u32 notifyNum, TransportLinkType linkType)
    1545              : {
    1546            0 :     HCCL_INFO(
    1547              :         "[%s] Start to get sdma Link group[%s], rankId[%u], newTag[%s], isBackup[%d], deviceLogicId[%d], "
    1548              :         "notifyNum[%u], linkType[%d]",
    1549              :         __func__, identifier_.c_str(), rankId, newTag.c_str(), isBackup, commParam->topoInfo.deviceLogicId, notifyNum,
    1550              :         linkType);
    1551              : 
    1552            0 :     auto* linkRes = &linkRes_;
    1553            0 :     if (linkType == TransportLinkType::SIO) { // HCCS SIO并发场景,HCCS链路与SIO链路分开管理
    1554            0 :         linkRes = &linkResSio_;
    1555              :     }
    1556            0 :     auto iterRankLinks = linkRes->find(rankId);
    1557            0 :     if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
    1558            0 :         HCCL_INFO(
    1559              :             "[%s] could not find link resource, rankId[%u], group[%s], newTag[%s]", __func__, rankId,
    1560              :             identifier_.c_str(), newTag.c_str());
    1561            0 :         CHK_RET(RefreshTransportsResForRank(commParam, rankId, newTag, notifyNum, linkType));
    1562            0 :         iterRankLinks = linkRes->find(rankId);
    1563            0 :         if (iterRankLinks == linkRes->end() || iterRankLinks->second.find(newTag) == iterRankLinks->second.end()) {
    1564            0 :             HCCL_ERROR(
    1565              :                 "[%s] refresh transport failed, newTag[%s], remoteUserRankId[%u], %p", __func__, newTag.c_str(), rankId,
    1566              :                 linkRes);
    1567            0 :             return HCCL_E_INTERNAL;
    1568              :         }
    1569              :     }
    1570              : 
    1571            0 :     link = iterRankLinks->second[newTag];
    1572            0 :     if (receivedAcks_.find(rankId) == receivedAcks_.end()) {
    1573            0 :         HCCL_ERROR("[%s]there is no link with rankId[%u]", __func__, rankId);
    1574            0 :         return HCCL_E_NOT_FOUND;
    1575              :     }
    1576            0 :     link->SetSupportDataReceivedAck(receivedAcks_[rankId]);
    1577            0 :     HCCL_DEBUG(
    1578              :         "[HcclCommAicpu][GetLinksByRankAndTag]rankid[%d] supportDataReceivedAck is %d", rankId, receivedAcks_[rankId]);
    1579            0 :     HCCL_INFO(
    1580              :         "[%s] group[%s], newTag[%s], rankId[%u] type[%u] success!", __func__, identifier_.c_str(), newTag.c_str(),
    1581              :         rankId, type);
    1582            0 :     return HCCL_SUCCESS;
    1583              : }
    1584              : 
    1585            0 : HcclResult HcclCommAicpu::CleanRoceResource(
    1586              :     const std::string& newTag, AlgResourceResponse& algResResponse,
    1587              :     [[maybe_unused]] const std::map<u32, bool>& remoteRankPortMap, [[maybe_unused]] const OpParam& param)
    1588              : {
    1589            0 :     HCCL_INFO("[%s] Entry alloc transport group[%s], tag[%s]", __func__, identifier_.c_str(), newTag.c_str());
    1590              : 
    1591            0 :     for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
    1592            0 :         for (auto& singleSubCommTransport : levelNSubCommTransport) {
    1593            0 :             for (auto& transportRequest : singleSubCommTransport.transportRequests) {
    1594            0 :                 if (transportRequest.isValid && transportRequest.isUsedRdma) {
    1595            0 :                     u32 remoteUserRank = transportRequest.remoteUserRank;
    1596            0 :                     linkRdmaRes_[remoteUserRank].erase(newTag);
    1597            0 :                     linkRdmaResBackUp_[remoteUserRank].erase(newTag);
    1598              :                 }
    1599              :             }
    1600              :         }
    1601              :     }
    1602              : 
    1603            0 :     return HCCL_SUCCESS;
    1604              : }
    1605              : 
    1606            1 : HcclResult HcclCommAicpu::CleanAllRoceResource()
    1607              : {
    1608            1 :     HCCL_INFO("Clean all link rdna resources");
    1609              :     // 清空主链路资源
    1610            1 :     linkRdmaRes_.clear();
    1611              :     // 清空备链路资源
    1612            1 :     linkRdmaResBackUp_.clear();
    1613            1 :     return HCCL_SUCCESS;
    1614              : }
    1615              : 
    1616            2 : HcclResult HcclCommAicpu::ClearOpResource(const std::string& tag)
    1617              : {
    1618              :     // 与 GetAlgResponseRes/AllocAlgResource/ReAllocTransportResource 互斥,避免读写竞争 resMap_/linkRes_
    1619            2 :     std::lock_guard<std::mutex> lock(preemptMutexForResMap_);
    1620              : 
    1621            6 :     auto eraseTagFromAll = [this](const std::string& t) -> bool {
    1622            6 :         bool hit = false;
    1623              :         // 主资源map:vector<LINK>析构会让shared_ptr<Transport>引用-1,归零时触发driver资源释放
    1624            6 :         if (resMap_.erase(t) > 0) {
    1625            1 :             hit = true;
    1626              :         }
    1627              :         // SDMA HCCS链路缓存:报错日志中driver halResAddrMap ioctl失败的根本累积点
    1628            9 :         for (auto& rankIt : linkRes_) {
    1629            3 :             if (rankIt.second.erase(t) > 0) {
    1630            1 :                 hit = true;
    1631              :             }
    1632              :         }
    1633              :         // SDMA SIO并发链路缓存
    1634            9 :         for (auto& rankIt : linkResSio_) {
    1635            3 :             if (rankIt.second.erase(t) > 0) {
    1636            1 :                 hit = true;
    1637              :             }
    1638              :         }
    1639              :         // RDMA主备链路缓存(CleanAllRoceResource按通信域全清,本接口按tag细粒度清)
    1640            9 :         for (auto& rankIt : linkRdmaRes_) {
    1641            3 :             if (rankIt.second.erase(t) > 0) {
    1642            1 :                 hit = true;
    1643              :             }
    1644              :         }
    1645            9 :         for (auto& rankIt : linkRdmaResBackUp_) {
    1646            3 :             if (rankIt.second.erase(t) > 0) {
    1647            1 :                 hit = true;
    1648              :             }
    1649              :         }
    1650              :         // 本地scratchMem和localTagResToObj按tag索引
    1651            6 :         if (tagScratchMem_.erase(t) > 0) {
    1652            1 :             hit = true;
    1653              :         }
    1654            6 :         if (localTagResToObj_.erase(t) > 0) {
    1655            1 :             hit = true;
    1656              :         }
    1657            9 :         for (auto& rankIt : rankTagRemoteRes_) {
    1658            3 :             if (rankIt.second.erase(t) > 0) {
    1659            1 :                 hit = true;
    1660              :             }
    1661              :         }
    1662            6 :         return hit;
    1663            2 :     };
    1664              : 
    1665              :     // 与 host 端 ClearOpResource 对齐:尝试 base/_host/_device 三种后缀
    1666            2 :     bool found = false;
    1667            2 :     found = eraseTagFromAll(tag) || found;
    1668            2 :     found = eraseTagFromAll(tag + "_host") || found;
    1669            2 :     found = eraseTagFromAll(tag + "_device") || found;
    1670            2 :     if (!found) {
    1671            1 :         HCCL_WARNING(
    1672              :             "[HcclCommAicpu][ClearOpResource] no entries matched tag[%s] "
    1673              :             "(also tried _host/_device variants), group[%s]",
    1674              :             tag.c_str(), identifier_.c_str());
    1675              :     } else {
    1676            1 :         HCCL_INFO(
    1677              :             "[HcclCommAicpu][ClearOpResource] cleared resources for tag[%s], group[%s]", tag.c_str(),
    1678              :             identifier_.c_str());
    1679              :     }
    1680            2 :     return HCCL_SUCCESS;
    1681            2 : }
    1682              : 
    1683              : // 借轨重新刷新资源
    1684            0 : HcclResult HcclCommAicpu::ReAllocTransportResource(
    1685              :     const std::string& newTag, AlgResourceResponse& algResResponse, std::map<u32, bool>& remoteRankPortMap,
    1686              :     const HcclOpResParam* commParam, const OpParam& param)
    1687              : {
    1688            0 :     HCCL_INFO("[%s] Entry alloc transport group[%s], tag[%s]", __func__, identifier_.c_str(), newTag.c_str());
    1689            0 :     std::set<u32> bsrTansportRank;
    1690            0 :     for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
    1691            0 :         for (auto& singleSubCommTransport : levelNSubCommTransport) {
    1692            0 :             singleSubCommTransport.links.clear();
    1693            0 :             singleSubCommTransport.links.reserve(singleSubCommTransport.transportRequests.size());
    1694            0 :             for (auto& transportRequest : singleSubCommTransport.transportRequests) {
    1695            0 :                 singleSubCommTransport.links.push_back(nullptr);
    1696            0 :                 if (transportRequest.isValid) {
    1697            0 :                     HCCL_INFO(
    1698              :                         "[%s] alloc transport, newTag[%s], rankId[%u], "
    1699              :                         "input memory type[%u], output memory type[%u], ",
    1700              :                         __func__, newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
    1701              :                         transportRequest.outputMemType);
    1702            0 :                     receivedAcks_[transportRequest.remoteUserRank] = singleSubCommTransport.supportDataReceivedAck;
    1703            0 :                     bool isBackup = remoteRankPortMap.find(transportRequest.remoteUserRank) != remoteRankPortMap.end()
    1704            0 :                                     && !remoteRankPortMap[transportRequest.remoteUserRank];
    1705            0 :                     bool isSecondBuild = false;
    1706            0 :                     bool isBatchSendRecv = newTag.find("BatchSendRecv") != std::string::npos;
    1707            0 :                     if (transportRequest.isUsedRdma && isBatchSendRecv
    1708            0 :                         && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
    1709              :                         // 仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
    1710            0 :                         isSecondBuild = true;
    1711              :                     }
    1712              :                     // A3 bsr远端是DirectNpu 链路的话则跳过
    1713            0 :                     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
    1714            0 :                         && (param.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
    1715            0 :                         continue;
    1716              :                     }
    1717            0 :                     bsrTansportRank.insert(transportRequest.remoteUserRank);
    1718            0 :                     CHK_RET(CreateLink(
    1719              :                         newTag, transportRequest, commParam, singleSubCommTransport.links.back(),
    1720              :                         transportRequest.notifyNum, isBackup, isSecondBuild));
    1721              :                 }
    1722              :             }
    1723              :         }
    1724              :     }
    1725              : 
    1726            0 :     return HCCL_SUCCESS;
    1727            0 : }
    1728              : 
    1729            0 : HcclResult HcclCommAicpu::AllocTransportResource(
    1730              :     const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
    1731              :     AlgResourceResponse& algResResponse)
    1732              : {
    1733            0 :     HCCL_INFO("[%s] Entry alloc transport group[%s]", __func__, identifier_.c_str());
    1734            0 :     algResResponse.opTransportResponse = resRequest.opTransport;
    1735              : 
    1736            0 :     std::set<u32> bsrTansportRank;
    1737            0 :     for (auto& levelNSubCommTransport : algResResponse.opTransportResponse) {
    1738            0 :         for (auto& singleSubCommTransport : levelNSubCommTransport) {
    1739            0 :             singleSubCommTransport.links.clear();
    1740            0 :             singleSubCommTransport.links.reserve(singleSubCommTransport.transportRequests.size());
    1741            0 :             for (auto& transportRequest : singleSubCommTransport.transportRequests) {
    1742            0 :                 singleSubCommTransport.links.push_back(nullptr);
    1743            0 :                 if (transportRequest.isValid) {
    1744            0 :                     localUserRank_ = transportRequest.localUserRank;
    1745            0 :                     receivedAcks_[transportRequest.remoteUserRank] = singleSubCommTransport.supportDataReceivedAck;
    1746            0 :                     HCCL_DEBUG(
    1747              :                         "[%s] alloc transport, newTag[%s], rankId[%u], input memory type[%u], "
    1748              :                         "output memory type[%u], ",
    1749              :                         __func__, newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
    1750              :                         transportRequest.outputMemType);
    1751              : 
    1752            0 :                     bool isSecondBuild = false;
    1753            0 :                     if (transportRequest.isUsedRdma && opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV
    1754            0 :                         && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
    1755              :                         // 仅仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
    1756            0 :                         isSecondBuild = true;
    1757              :                     }
    1758              :                     // A3 bsr远端是DirectNpu 链路的话则跳过
    1759            0 :                     if ((opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
    1760            0 :                         && (opParam.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
    1761            0 :                         continue;
    1762              :                     }
    1763            0 :                     bsrTansportRank.insert(transportRequest.remoteUserRank);
    1764            0 :                     CHK_RET(CreateLink(
    1765              :                         newTag, transportRequest, commParam, singleSubCommTransport.links.back(),
    1766              :                         transportRequest.notifyNum, false, isSecondBuild));
    1767              :                 }
    1768              :             }
    1769              :         }
    1770              :     }
    1771              : 
    1772            0 :     return HCCL_SUCCESS;
    1773            0 : }
    1774              : 
    1775              : // 在resMap_[tag]对应原有通信资源的基础上继续增量建链,目前batchsendrecv会用到本接口
    1776            0 : HcclResult HcclCommAicpu::IncreAllocTransportResource(
    1777              :     const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
    1778              :     AlgResourceResponse& algResResponse)
    1779              : {
    1780            0 :     HCCL_INFO("[HcclCommAicpu][IncreAllocTransportResource] Entry alloc transport group[%s]", identifier_.c_str());
    1781            0 :     std::set<u32> bsrTansportRank;
    1782            0 :     for (u32 levelIndex = 0; levelIndex < resRequest.opTransport.size(); levelIndex++) {
    1783            0 :         for (u32 ringIndex = 0; ringIndex < resRequest.opTransport[levelIndex].size(); ringIndex++) {
    1784            0 :             SingleSubCommTransport& reqSingleSubComm = resRequest.opTransport[levelIndex][ringIndex];
    1785            0 :             SingleSubCommTransport& respSingleSubComm = algResResponse.opTransportResponse[levelIndex][ringIndex];
    1786            0 :             for (u32 rankIndex = 0; rankIndex < reqSingleSubComm.transportRequests.size(); rankIndex++) {
    1787            0 :                 TransportRequest& transportRequest = reqSingleSubComm.transportRequests[rankIndex];
    1788            0 :                 CHK_PRT_RET(
    1789              :                     rankIndex >= respSingleSubComm.links.size(),
    1790              :                     HCCL_ERROR(
    1791              :                         "[HcclCommAicpu][IncreAllocTransportResource] The remote rank_id[%u] is larger than "
    1792              :                         "the existent respSingleSubComm map size[%u]",
    1793              :                         rankIndex, respSingleSubComm.links.size()),
    1794              :                     HCCL_E_PARA);
    1795            0 :                 if (respSingleSubComm.links[rankIndex] != nullptr
    1796            0 :                     && respSingleSubComm.links[rankIndex]->GetLinkType() != hccl::LinkType::LINK_RESERVED) {
    1797            0 :                     HCCL_INFO(
    1798              :                         "[IncreAlloc] The link to remote userRank[%u] has existed", transportRequest.remoteUserRank);
    1799            0 :                     continue;
    1800              :                 }
    1801            0 :                 if (transportRequest.isValid) {
    1802            0 :                     receivedAcks_[transportRequest.remoteUserRank] = reqSingleSubComm.supportDataReceivedAck;
    1803            0 :                     respSingleSubComm.transportRequests[rankIndex] = transportRequest;
    1804            0 :                     HCCL_DEBUG(
    1805              :                         "[HcclCommAicpu][IncreAllocTransportResource] alloc transport, newTag[%s], rankId[%u], "
    1806              :                         "input memory type[%u], output memory type[%u], ",
    1807              :                         newTag.c_str(), transportRequest.remoteUserRank, transportRequest.inputMemType,
    1808              :                         transportRequest.outputMemType);
    1809            0 :                     bool isSecondBuild = false;
    1810            0 :                     if (transportRequest.isUsedRdma && opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV
    1811            0 :                         && bsrTansportRank.find(transportRequest.remoteUserRank) != bsrTansportRank.end()) {
    1812              :                         // 仅仅在batchsendrecv rdma下发的时候需要第二次刷新,实际第一次下发都刷好了,第二次就是get一下
    1813            0 :                         isSecondBuild = true;
    1814              :                     }
    1815              :                     // A3 bsr远端是DirectNpu 链路的话则跳过
    1816            0 :                     if ((opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)
    1817            0 :                         && (opParam.BatchSendRecvDataDes.isDirectRemoteRank[transportRequest.remoteUserRank])) {
    1818            0 :                         continue;
    1819              :                     }
    1820            0 :                     bsrTansportRank.insert(transportRequest.remoteUserRank);
    1821            0 :                     CHK_RET(CreateLink(
    1822              :                         newTag, transportRequest, commParam, respSingleSubComm.links[rankIndex],
    1823              :                         transportRequest.notifyNum, false, isSecondBuild));
    1824              :                 }
    1825              :             }
    1826              :         }
    1827              :     }
    1828            0 :     return HCCL_SUCCESS;
    1829            0 : }
    1830              : 
    1831            0 : HcclResult HcclCommAicpu::CreateLink(
    1832              :     const std::string& newTag, TransportRequest& transportRequest, const HcclOpResParam* commParam, LINK& link,
    1833              :     u32 notifyNum, bool isBackup, bool isSecond) // 主备的选择
    1834              : {
    1835            0 :     if (transportRequest.isUsedRdma) {
    1836            0 :         CHK_RET(GetRdmaLinksByRankAndTag(
    1837              :             commParam, CommTransportsType::SPECIAL, transportRequest.remoteUserRank, newTag, link, isBackup, notifyNum,
    1838              :             isSecond));
    1839              :     } else {
    1840            0 :         CHK_RET(GetSdmaLinksByRankAndTag(
    1841              :             commParam, CommTransportsType::SPECIAL, transportRequest.remoteUserRank, newTag, link, isBackup, notifyNum,
    1842              :             transportRequest.linkType));
    1843              :     }
    1844              : 
    1845            0 :     HCCL_DEBUG("[%s] alloc special transport success!, tag[%s]", __func__, newTag.c_str());
    1846            0 :     return HCCL_SUCCESS;
    1847              : }
    1848              : 
    1849            0 : HcclResult HcclCommAicpu::AllocLocalNotifysResource(
    1850              :     const std::string& newTag, const HcclOpResParam* commParam, const u32 notifyNum,
    1851              :     std::vector<std::shared_ptr<LocalNotify>>& notifiesMain, std::vector<std::shared_ptr<LocalNotify>>& notifiesAux)
    1852              : {
    1853            0 :     HCCL_INFO(
    1854              :         "[HcclCommAicpu][AllocLocalNotifysResource]requesting for [%u] notifies, tag[%s].", notifyNum, newTag.c_str());
    1855            0 :     if (localNotifies_.capacity() < notifyNum) {
    1856            0 :         HCCL_ERROR(
    1857              :             "[HcclCommAicpu][AllocLocalNotifysResource]request number exceeds max notify number, alloc failed. Max "
    1858              :             "number is [%u],request num[%u], tag[%s]",
    1859              :             localNotifies_.capacity(), notifyNum, newTag.c_str());
    1860            0 :         return HCCL_E_PARA;
    1861              :     }
    1862              : 
    1863            0 :     if (localNotifies_.size() < notifyNum) {
    1864            0 :         if (InitLocalNotifyObj(commParam) != HCCL_SUCCESS || localNotifies_.size() < notifyNum) {
    1865            0 :             HCCL_ERROR(
    1866              :                 "[HcclCommAicpu][AllocLocalNotifysResource] the need of notify is more than the available, group[%s], "
    1867              :                 "need[%u], total[%u]",
    1868              :                 newTag.c_str(), notifyNum, localNotifies_.size());
    1869            0 :             return HCCL_E_INTERNAL;
    1870              :         }
    1871              :     }
    1872              : 
    1873            0 :     u32 halfNotifyNum = notifyNum >> 1;
    1874            0 :     notifiesMain.resize(halfNotifyNum);
    1875            0 :     notifiesAux.resize(halfNotifyNum);
    1876            0 :     for (u32 i = 0; i < halfNotifyNum; i++) {
    1877            0 :         notifiesMain[i] = localNotifies_[i << 1];
    1878            0 :         notifiesAux[i] = localNotifies_[(i << 1) + 1];
    1879              :     }
    1880            0 :     HCCL_INFO(
    1881              :         "[HcclCommAicpu][AllocLocalNotifysResource]find enough notifies, numbers[%u], tag[%s].", notifyNum,
    1882              :         newTag.c_str());
    1883            0 :     return HCCL_SUCCESS;
    1884              : }
    1885              : 
    1886            0 : HcclResult HcclCommAicpu::AllocStreamsResource(
    1887              :     const std::string& newTag, const HcclOpResParam* commParam, const u32 streamNum, std::vector<Stream>& streams)
    1888              : {
    1889            0 :     HCCL_INFO(
    1890              :         "[HcclCommAicpu][AllocStreamsResource]requesting for [%u] slave streams, newTag[%s], group[%s].", streamNum,
    1891              :         newTag.c_str(), identifier_.c_str());
    1892            0 :     if (streamNum == 0) {
    1893            0 :         return HCCL_SUCCESS;
    1894              :     }
    1895            0 :     if (slaveStreams_.capacity() < streamNum) {
    1896            0 :         HCCL_ERROR(
    1897              :             "[HcclCommAicpu][AllocStreamsResource]request number exceeds max substream number, alloc failed. Max "
    1898              :             "number is [%u],request num[%u], tag[%s]",
    1899              :             slaveStreams_.capacity(), streamNum, newTag.c_str());
    1900            0 :         return HCCL_E_PARA;
    1901              :     }
    1902            0 :     if (slaveStreams_.size() < streamNum) {
    1903            0 :         if (InitSlaveStreamObjs(commParam) != HCCL_SUCCESS || slaveStreams_.size() < streamNum) {
    1904            0 :             HCCL_ERROR(
    1905              :                 "[HcclCommAicpu][AllocStreamsResource] the need of streams is more than the "
    1906              :                 "available, tag[%s], need[%u], total[%u]",
    1907              :                 newTag.c_str(), streamNum, slaveStreams_.size());
    1908            0 :             return HCCL_E_INTERNAL;
    1909              :         }
    1910              :     }
    1911            0 :     streams = std::vector<Stream>(slaveStreams_.begin(), slaveStreams_.begin() + streamNum);
    1912            0 :     HCCL_INFO(
    1913              :         "[HcclCommAicpu][AllocStreamsResource]find enough slave streams [%u], tag[%s].", streamNum, newTag.c_str());
    1914            0 :     return HCCL_SUCCESS;
    1915              : }
    1916              : 
    1917            0 : HcclResult HcclCommAicpu::AllocScratchMemResource(
    1918              :     const std::string& newTag, const HcclOpResParam* commParam, const u64& scratchMemSize, DeviceMem& scratchMem,
    1919              :     bool reAllocFlag)
    1920              : {
    1921            0 :     HCCL_INFO(
    1922              :         "[HcclCommAicpu][AllocScratchMemResource]requesting for [%llu] bytes scratch mem, tag[%s].", scratchMemSize,
    1923              :         newTag.c_str());
    1924            0 :     if (scratchMemSize != 0) {
    1925            0 :         if (tagScratchMem_.find(newTag) == tagScratchMem_.end()) {
    1926            0 :             HcclResult ret = InitLocalTagRes(commParam->localRes.nextTagRes);
    1927            0 :             CHK_PRT_RET(
    1928              :                 ret != HCCL_SUCCESS,
    1929              :                 HCCL_ERROR(
    1930              :                     "[HcclCommAicpu][AllocScratchMemResource]InitLocalTagRes error group[%s]", identifier_.c_str()),
    1931              :                 ret);
    1932              :         }
    1933              : 
    1934            0 :         if (tagScratchMem_.find(newTag) == tagScratchMem_.end()) {
    1935            0 :             HCCL_ERROR(
    1936              :                 "[HcclCommAicpu][AllocScratchMemResource]alloc scratch memory failed."
    1937              :                 "requesting for [%llu] bytes, tag[%s].",
    1938              :                 scratchMemSize, newTag.c_str());
    1939            0 :             return HCCL_E_NOT_FOUND;
    1940              :         }
    1941              : 
    1942            0 :         if (reAllocFlag) {
    1943            0 :             HCCL_INFO(
    1944              :                 "[HcclCommAicpu][AllocScratchMemResource]need to reAlloc mem [%llu] bytes scratch mem, tag[%s].",
    1945              :                 scratchMemSize, newTag.c_str());
    1946            0 :             HcclResult ret = InitLocalTagRes(commParam->localRes.nextTagRes, reAllocFlag);
    1947            0 :             CHK_PRT_RET(
    1948              :                 ret != HCCL_SUCCESS,
    1949              :                 HCCL_ERROR(
    1950              :                     "[HcclCommAicpu][AllocScratchMemResource]InitLocalTagRes error group[%s]", identifier_.c_str()),
    1951              :                 ret);
    1952              :         }
    1953              : 
    1954              :         // 因为aicpu_communicator中会对scratchMem做对齐,所以tagScratchMem_中的大小会偏小(被对齐截断一部分)
    1955              :         // 但是两者的差值应该不能超过2个CCE_REDUCE_ALIGN_SIZE,否则应该是不对的
    1956            0 :         if (scratchMemSize - tagScratchMem_[newTag]->size() > (CCE_REDUCE_ALIGN_SIZE + CCE_REDUCE_ALIGN_SIZE)) {
    1957            0 :             HCCL_ERROR(
    1958              :                 "[HcclCommAicpu][AllocScratchMemResource]alloc tag[%s] scratch memory failed."
    1959              :                 "requesting [%llu] bytes actual [%llu] bytes",
    1960              :                 newTag.c_str(), scratchMemSize, tagScratchMem_[newTag]->size());
    1961            0 :             return HCCL_E_PARA;
    1962              :         }
    1963            0 :         scratchMem = DeviceMem::create(tagScratchMem_[newTag]->ptr(), tagScratchMem_[newTag]->size());
    1964              :     }
    1965            0 :     HCCL_INFO(
    1966              :         "[HcclCommAicpu][AllocScratchMemResource]find enough [%llu] bytes scratch mem, tag[%s].", scratchMemSize,
    1967              :         newTag.c_str());
    1968            0 :     return HCCL_SUCCESS;
    1969              : }
    1970              : 
    1971            0 : HcclResult HcclCommAicpu::AllocAlgResource(
    1972              :     const std::string& newTag, const OpParam& opParam, const HcclOpResParam* commParam, AlgResourceRequest& resRequest,
    1973              :     AlgResourceResponse& algResResponse)
    1974              : {
    1975            0 :     algResResponse.cclInputMem = cclInputBuffer_;
    1976            0 :     algResResponse.cclOutputMem = cclOutputBuffer_;
    1977            0 :     algResResponse.paramInputMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
    1978            0 :     algResResponse.paramOutputMem = DeviceMem::create(opParam.outputPtr, opParam.outputSize);
    1979              : 
    1980            0 :     PetersonLockGuard guard(hostDeviceLock_.get());
    1981            0 :     CHK_PRT_RET(
    1982              :         guard.IsLockFailed(), HCCL_ERROR("[HcclCommAicpu][AllocAlgResource] hostDeviceLock lock failed"),
    1983              :         HCCL_E_INTERNAL);
    1984              : 
    1985            0 :     CHK_RET(AllocScratchMemResource(newTag, commParam, resRequest.scratchMemSize, algResResponse.scratchMem));
    1986            0 :     CHK_RET(AllocStreamsResource(newTag, commParam, resRequest.streamNum, algResResponse.slaveStreams));
    1987            0 :     CHK_RET(AllocLocalNotifysResource(
    1988              :         newTag, commParam, resRequest.notifyNum, algResResponse.notifiesMain, algResResponse.notifiesAux));
    1989            0 :     CHK_RET(AllocTransportResource(newTag, opParam, commParam, resRequest, algResResponse));
    1990            0 :     HCCL_INFO("[HcclCommAicpu][AllocAlgResource] alloc resource success tag[%s].", newTag.c_str());
    1991            0 :     return HCCL_SUCCESS;
    1992            0 : }
    1993              : 
    1994            0 : HcclResult HcclCommAicpu::CalcResRequest(
    1995              :     const std::string& algName, const OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    1996              :     AlgResourceRequest& resourceRequest)
    1997              : {
    1998            0 :     if (executor.get() == nullptr) {
    1999            0 :         executor = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
    2000            0 :         CHK_PRT_RET(
    2001              :             executor.get() == nullptr,
    2002              :             HCCL_ERROR("[HcclCommAicpu][CalcResRequest]Fail to find executor for algName[%s]", algName.c_str()),
    2003              :             HCCL_E_PARA);
    2004            0 :         executor->SetAlgType(algType_);
    2005            0 :         executor->SetCCLInBuffer(cclbufferSize_);
    2006              : 
    2007            0 :         if (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
    2008            0 :             bool isSupportSDMAReduce = false;
    2009            0 :             if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
    2010              :                 isSupportSDMAReduce
    2011            0 :                     = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
    2012              :             } else {
    2013            0 :                 isSupportSDMAReduce = IsSupportSDMAReduce(
    2014            0 :                     cclInputBuffer_.ptr(), cclOutputBuffer_.ptr(), param.DataDes.dataType, param.reduceType);
    2015              :             }
    2016            0 :             executor->SetIsSupportSDMAReduce(isSupportSDMAReduce);
    2017              :         }
    2018              :     }
    2019            0 :     CHK_RET(CalSendRecvInfoFor910B(algName, param, executor));
    2020            0 :     return executor->CalcResRequest(param, resourceRequest);
    2021              : }
    2022              : 
    2023            0 : u32 HcclCommAicpu::CalculateOpExecIndex(const OpParam& opParam, u32 userRank)
    2024              : {
    2025            0 :     u32 opIndex = 0;
    2026            0 :     s32 commIndex = 0;
    2027              :     // 用于重执行和taskException打印的算子计数,bsr/sendrecv/其他算子分别计数
    2028            0 :     if (opParam.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) {
    2029            0 :         commIndex = -1; // batchSendRecv使用 key = -1
    2030            0 :     } else if (opParam.opType == HcclCMDType::HCCL_CMD_SEND) {
    2031            0 :         commIndex = opParam.dstRank;
    2032            0 :     } else if (opParam.opType == HcclCMDType::HCCL_CMD_RECEIVE) {
    2033            0 :         commIndex = opParam.srcRank;
    2034              :     } else {
    2035            0 :         commIndex = userRank;
    2036              :     }
    2037              : 
    2038            0 :     auto it = opExecIndexMap_.find(commIndex);
    2039            0 :     if (it != opExecIndexMap_.end()) {
    2040            0 :         opIndex = ++(it->second);
    2041              :     } else {
    2042            0 :         opExecIndexMap_.insert({commIndex, 1});
    2043            0 :         opIndex = 1;
    2044              :     }
    2045              : 
    2046            0 :     HCCL_DEBUG(
    2047              :         "%s tag:%s opType:%u commIndex:%d opIndex:%u", __func__, opParam.tag.c_str(), opParam.opType, commIndex,
    2048              :         opIndex);
    2049            0 :     return opIndex;
    2050              : }
    2051              : 
    2052            2 : HcclResult HcclCommAicpu::PrepareSymmetricMemory(const OpParam& param, OpCommTransport& opTransportResponse)
    2053              : {
    2054            2 :     CHK_PRT_RET(
    2055              :         opTransportResponse.size() == 0,
    2056              :         HCCL_ERROR("[HcclCommAicpu][PrepareSymmetricMemory] opTransportResponse size is 0"), HCCL_E_PARA);
    2057              : 
    2058              :     const std::unordered_set<LinkType> supportedLinkTypes
    2059            2 :         = {LinkType::LINK_HCCS, LinkType::LINK_SIO, LinkType::LINK_HCCS_SW};
    2060            2 :     for (u32 levelIdx = 0; levelIdx < opTransportResponse.size(); levelIdx++) {
    2061            2 :         for (auto& singleSubCommTransport : opTransportResponse[levelIdx]) {
    2062            1 :             if (singleSubCommTransport.isZeroCopy == false) {
    2063            1 :                 continue;
    2064              :             }
    2065            0 :             for (u64 i = 0; i < singleSubCommTransport.links.size(); ++i) {
    2066            0 :                 LINK& link = singleSubCommTransport.links[i];
    2067            0 :                 if (link == nullptr || !singleSubCommTransport.transportRequests[i].isValid
    2068            0 :                     || supportedLinkTypes.count(link->GetLinkType()) == 0) {
    2069            0 :                     continue; // 无效或者不支持的链路
    2070              :                 }
    2071            0 :                 u32 peerRank = link->GetRemoteRank();
    2072            0 :                 void* remoteIn = nullptr;
    2073            0 :                 CHK_RET(HcclSymWinGetPeerPointer(param.inputSymWindow, param.inputOffset, peerRank, &remoteIn));
    2074            0 :                 void* remoteOut = nullptr;
    2075            0 :                 CHK_RET(HcclSymWinGetPeerPointer(param.outputSymWindow, param.outputOffset, peerRank, &remoteOut));
    2076              : 
    2077            0 :                 CHK_PRT_RET(
    2078              :                     remoteIn == nullptr || remoteOut == nullptr,
    2079              :                     HCCL_ERROR(
    2080              :                         "[HcclCommAicpu][PrepareSymmetricMemory] remoteRank[%d] in[%p] out[%p] is invalid", peerRank,
    2081              :                         remoteIn, remoteOut),
    2082              :                     HCCL_E_INTERNAL);
    2083            0 :                 HCCL_INFO(
    2084              :                     "[HcclCommAicpu][PrepareSymmetricMemory] remoteRank[%d] in[%p] out[%p]", peerRank, remoteIn,
    2085              :                     remoteOut);
    2086            0 :                 CHK_RET(link->UpdateRemoteAddr(remoteIn, remoteOut));
    2087              :             }
    2088              :         }
    2089              :     }
    2090            1 :     return HCCL_SUCCESS;
    2091            1 : }
    2092              : 
    2093            1 : HcclResult HcclCommAicpu::ExecOp(
    2094              :     const std::string& newTag, const std::string& algName, OpParam& opParam, const HcclOpResParam* commParam)
    2095              : {
    2096            1 :     std::unique_ptr<CollExecutorBase> executor;
    2097              :     hccl::AlgResourceResponse* algResResponse;
    2098            1 :     CHK_RET(GetAlgResponseRes(newTag, algName, opParam, commParam, executor, algResResponse));
    2099              : 
    2100            1 :     if (isZeroCopy_ || isSymmetricMemory_) {
    2101            1 :         if (isSymmetricMemory_) {
    2102            1 :             CHK_RET(PrepareSymmetricMemory(opParam, algResResponse->opTransportResponse));
    2103              :         } else {
    2104            0 :             HcclResult ret = PrepareZeroCopyExchanger(newTag, opParam, algResResponse);
    2105            0 :             CHK_PRT_RET(
    2106              :                 ret != HCCL_SUCCESS,
    2107              :                 HCCL_ERROR(
    2108              :                     "[HcclCommAicpu][ExecOp] newTag[%s], localRankId[%u]", newTag.c_str(), commParam->localUsrRankId),
    2109              :                 ret);
    2110              :         }
    2111              : 
    2112              :         // 零拷贝场景scratchMem的大小会与用户的输入大小不同,会导致后续算法展开模块计算出错
    2113              :         // 但是该场景下不会直接访问scratchMem,因此直接使用输入作为scratchMem,使得后续计算正确
    2114            0 :         if (opParam.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
    2115            0 :             algResResponse->scratchMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
    2116            0 :             HCCL_INFO(
    2117              :                 "[HcclCommAicpu][ExecOp] ZeroCopy reduce-scatter use userInput as scratchMem, inputPtr[%p] "
    2118              :                 "inputSize[%lu]",
    2119              :                 opParam.inputPtr, opParam.inputSize);
    2120              :         }
    2121              : 
    2122            0 :         algResResponse->paramInputMem = DeviceMem::create(opParam.inputPtr, opParam.inputSize);
    2123            0 :         algResResponse->paramOutputMem = DeviceMem::create(opParam.outputPtr, opParam.outputSize);
    2124            0 :         HCCL_INFO(
    2125              :             "[HcclCommAicpu][ExecOp] zero copy modify paramInput paramOutput to algResResp inputPtr[%p] inputSize[%lu] "
    2126              :             "outputPtr[%p] outputSize[%lu]",
    2127              :             algResResponse->paramInputMem.ptr(), algResResponse->paramInputMem.size(),
    2128              :             algResResponse->paramOutputMem.ptr(), algResResponse->paramOutputMem.size());
    2129              :     }
    2130              : 
    2131            0 :     hcclOpExecIndex_ = CalculateOpExecIndex(opParam, localUserRank_);
    2132            0 :     HcclResult ret = Orchestrate(newTag, algName, opParam, executor, *algResResponse, commParam);
    2133            0 :     if (ret != HCCL_SUCCESS) {
    2134            0 :         HCCL_ERROR(
    2135              :             "[HcclCommAicpu][ExecOp] executor op fail, tag[%s], algName[%s], identifier[%s]", newTag.c_str(),
    2136              :             algName.c_str(), identifier_.c_str());
    2137            0 :         CHK_PRT_CONT(
    2138              :             retryEnable_, HCCL_ERROR("[HcclCommAicpu][ExecOp] executor op fail, some error logs may be recorded in the "
    2139              :                                      "log/run/device directory, search keyword [ErrToWarn]"));
    2140            0 :         if (printTaskExceptionForErr_) {
    2141            0 :             PrintTaskExceptionAllComm();
    2142            0 :             PrintAicpuCommExecStatus();
    2143            0 :             printTaskExceptionForErr_ = false;
    2144              :         }
    2145            0 :         return ret;
    2146              :     }
    2147              : 
    2148            0 :     HCCL_ENTRY_INFO(
    2149              :         commParam->opEntry,
    2150              :         "[HcclCommAicpu][ExecOp] executor op success tag[%s], newTag[%s], algName[%s], identifier[%s].",
    2151              :         opParam.tag.c_str(), newTag.c_str(), algName.c_str(), identifier_.c_str());
    2152            0 :     return HCCL_SUCCESS;
    2153            1 : }
    2154              : 
    2155            0 : HcclResult HcclCommAicpu::RefreshAlgResponseTransportRes(
    2156              :     const std::string& newTag, AlgResourceResponse& algResResponse, std::map<u32, bool>& remoteRankPortMap,
    2157              :     bool isChangeLinkFlag, const HcclOpResParam* commParam, const OpParam& param)
    2158              : {
    2159            0 :     CHK_PTR_NULL(commParam);
    2160            0 :     auto iter = resMap_.find(newTag);
    2161            0 :     CHK_PRT_RET(
    2162              :         iter == resMap_.end(), HCCL_ERROR("[%s]Fail to find algResResponse for tag[%s]", __func__, newTag.c_str()),
    2163              :         HCCL_E_PARA);
    2164              : 
    2165            0 :     PetersonLockGuard guard(hostDeviceLock_.get());
    2166            0 :     CHK_PRT_RET(guard.IsLockFailed(), HCCL_ERROR("[%s] hostDeviceLock lock failed", __func__), HCCL_E_INTERNAL);
    2167            0 :     if (!isChangeLinkFlag) {
    2168            0 :         CleanRoceResource(newTag, algResResponse, remoteRankPortMap, param);
    2169            0 :         CHK_RET(ReAllocTransportResource(newTag, algResResponse, remoteRankPortMap, commParam, param));
    2170            0 :         HCCL_RUN_INFO("[%s] ChangeLinkFlag[%d], current tag[%s].", __func__, isChangeLinkFlag, newTag.c_str());
    2171              :     } else {
    2172              :         // 提前清理所有tag的链路,避免冲突
    2173            0 :         for (auto& resMapIt : resMap_) {
    2174            0 :             HCCL_RUN_INFO("[%s] clean roce resource of tag[%s].", __func__, resMapIt.first.c_str());
    2175            0 :             CleanRoceResource(resMapIt.first, resMapIt.second, remoteRankPortMap, param);
    2176              :         }
    2177              :         // 对resMap中所有tag的transport link根据主备进行刷新
    2178            0 :         for (auto& resMapIt : resMap_) {
    2179            0 :             HCCL_RUN_INFO("[%s] refresh algResResponse of tag[%s].", __func__, resMapIt.first.c_str());
    2180            0 :             CHK_RET(ReAllocTransportResource(resMapIt.first, resMapIt.second, remoteRankPortMap, commParam, param));
    2181            0 :             if (resMapIt.first == newTag) {
    2182            0 :                 HCCL_RUN_INFO("[%s] current tag[%s].", __func__, newTag.c_str());
    2183            0 :                 algResResponse = resMapIt.second;
    2184              :             }
    2185              :         }
    2186              :     }
    2187              : 
    2188            0 :     HCCL_RUN_INFO("[%s] alloc resource success tag[%s].", __func__, newTag.c_str());
    2189            0 :     return HCCL_SUCCESS;
    2190            0 : }
    2191              : 
    2192            0 : HcclResult HcclCommAicpu::CalSendRecvInfoForAlltoall(const OpParam& param)
    2193              : {
    2194            0 :     if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
    2195              :         std::vector<u64> sendCountMatrix(
    2196            0 :             topoInfo_.userRankSize * topoInfo_.userRankSize, param.All2AllDataDes.sendCount);
    2197            0 :         CHK_RET(GetAlltoAllvcSendRecvInfo(
    2198              :             static_cast<void*>(sendCountMatrix.data()), param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
    2199            0 :     } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
    2200            0 :         CHK_PTR_NULL(sendRecvInfoPtr_);
    2201            0 :         CHK_RET(
    2202              :             GetAlltoAllvSendRecvInfo(sendRecvInfoPtr_, param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
    2203              :     } else {
    2204            0 :         CHK_RET(GetAlltoAllvcSendRecvInfo(
    2205              :             param.All2AllDataDes.sendCountMatrix, param.All2AllDataDes.sendType, param.All2AllDataDes.recvType));
    2206              :     }
    2207            0 :     return HCCL_SUCCESS;
    2208              : }
    2209              : 
    2210            0 : HcclResult HcclCommAicpu::CalSendRecvInfoFor910B(
    2211              :     const std::string& algName, const OpParam& param, std::unique_ptr<CollExecutorBase>& executor)
    2212              : {
    2213              :     // A2 AICPU才有机会走入RunAlltoAllVStaged
    2214            0 :     if (algName == "RunAlltoAllVStaged" || algName == "RunAlltoAllVFullMesh") {
    2215            0 :         CHK_PRT_RET(
    2216              :             executor.get() == nullptr,
    2217              :             HCCL_ERROR("[HcclCommAicpu][%s]Fail to find executor for algName[%s]", __func__, algName.c_str()),
    2218              :             HCCL_E_PARA);
    2219            0 :         CHK_RET(CalSendRecvInfoForAlltoall(param));
    2220            0 :         CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor*>(executor.get());
    2221            0 :         CHK_PTR_NULL(alltoAllExecutor);
    2222            0 :         CHK_RET(alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclbufferSize_));
    2223            0 :         HCCL_DEBUG("[HcclCommAicpu][%s] running algName[%s], prepare SendRecvInfo.", __func__, algName.c_str());
    2224            0 :         return HCCL_SUCCESS;
    2225              :     }
    2226            0 :     return HCCL_SUCCESS;
    2227              : }
    2228              : 
    2229            0 : HcclResult HcclCommAicpu::GetAlgResponseRes(
    2230              :     const std::string& newTag, const std::string& algName, const OpParam& opParam, const HcclOpResParam* commParam,
    2231              :     std::unique_ptr<CollExecutorBase>& executor, AlgResourceResponse*& algResResponse)
    2232              : {
    2233            0 :     HCCL_INFO("[%s] algName[%s]", __func__, algName.c_str());
    2234            0 :     CHK_PTR_NULL(commParam);
    2235              :     // 刷新CCLBuffer
    2236            0 :     CHK_RET(InitCclbuffer(commParam));
    2237            0 :     auto iter = resMap_.find(newTag);
    2238            0 :     if (iter == resMap_.end()) {
    2239            0 :         std::lock_guard<std::mutex> lock(preemptMutexForResMap_);
    2240            0 :         iter = resMap_.find(newTag);
    2241            0 :         if (iter == resMap_.end()) {
    2242            0 :             HCCL_RUN_INFO("[%s] Alloc resource for alg[%s], tag[%s]", __func__, algName.c_str(), newTag.c_str());
    2243            0 :             AlgResourceRequest resRequest;
    2244            0 :             CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
    2245            0 :             CHK_RET(AllocAlgResource(newTag, opParam, commParam, resRequest, resMap_[newTag]));
    2246            0 :             iter = resMap_.find(newTag);
    2247            0 :         } else {
    2248            0 :             HCCL_INFO("[%s] Repeatedly inited for alg [%s] is not allowed.", __func__, algName.c_str());
    2249              :         }
    2250            0 :     } else if (algName == "BatchSendRecv" || algName == "BatchSendRecvRetry" || algName == "BatchSendRecvGroup") {
    2251              :         // 如果是非aclgraph模式,而且不需要增量建链,则跳过CalcResRequest这个计算,节省时间。在非aclgraph模式下,跳过是安全的。
    2252            0 :         bool canSkipCalcResRequest = !opParam.isCapture && !opParam.needIncreLink;
    2253            0 :         if (!canSkipCalcResRequest) { // 如果不能跳过计算,则走一遍计算的流程,否则就跳过以下计算
    2254            0 :             AlgResourceRequest resRequest;
    2255            0 :             HCCL_INFO("[%s]IncreAlloc resource for alg[%s], tag[%s]", __func__, algName.c_str(), newTag.c_str());
    2256            0 :             CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
    2257            0 :             CHK_RET(IncreAllocTransportResource(newTag, opParam, commParam, resRequest, resMap_[newTag]));
    2258            0 :         }
    2259            0 :     } else if (algName == "RunAlltoAllVStaged" || algName == "RunAlltoAllVFullMesh") {
    2260            0 :         AlgResourceRequest resRequest;
    2261            0 :         CHK_RET(CalcResRequest(algName, opParam, executor, resRequest));
    2262            0 :         HCCL_INFO(
    2263              :             "[%s] check if need refresh resource for alg[%s], tag[%s], old[%lu], new[%lu]", __func__, algName.c_str(),
    2264              :             newTag.c_str(), resMap_[newTag].scratchMem.size(), resRequest.scratchMemSize);
    2265            0 :         bool reAllocFlag = !(resMap_[newTag].scratchMem.size() == resRequest.scratchMemSize);
    2266            0 :         if (reAllocFlag) {
    2267            0 :             PetersonLockGuard guard(hostDeviceLock_.get());
    2268            0 :             CHK_PRT_RET(
    2269              :                 guard.IsLockFailed(), HCCL_ERROR("[HcclCommAicpu][AllocAlgResource] hostDeviceLock lock failed"),
    2270              :                 HCCL_E_INTERNAL);
    2271            0 :             CHK_RET(AllocScratchMemResource(
    2272              :                 newTag, commParam, resRequest.scratchMemSize, resMap_[newTag].scratchMem, true));
    2273            0 :             HCCL_INFO(
    2274              :                 "[%s] refresh resource success for alg[%s], tag[%s], scratchMemSize[%lu], ptr[%p]", __func__,
    2275              :                 algName.c_str(), newTag.c_str(), resRequest.scratchMemSize, resMap_[newTag].scratchMem.ptr());
    2276            0 :         }
    2277            0 :     }
    2278            0 :     CHK_PRT_RET(
    2279              :         iter == resMap_.end(), HCCL_ERROR("[%s]Fail to find algResResponse for tag[%s]", __func__, newTag.c_str()),
    2280              :         HCCL_E_PARA);
    2281            0 :     algResResponse = &iter->second;
    2282            0 :     HCCL_INFO("[HcclCommAicpu][GetAlgResponseRes] success!");
    2283            0 :     return HCCL_SUCCESS;
    2284              : }
    2285              : 
    2286            0 : HcclResult HcclCommAicpu::GetAlltoAllVCTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
    2287              : {
    2288            0 :     for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
    2289            0 :         sendCount += *(
    2290            0 :             static_cast<const u64*>(param.All2AllDataDes.sendCountMatrix) + topoInfo_.userRank * topoInfo_.userRankSize
    2291            0 :             + i);
    2292            0 :         recvCount += *(
    2293            0 :             static_cast<const u64*>(param.All2AllDataDes.sendCountMatrix) + topoInfo_.userRank
    2294            0 :             + topoInfo_.userRankSize * i);
    2295              :     }
    2296            0 :     return HCCL_SUCCESS;
    2297              : }
    2298              : 
    2299            0 : HcclResult HcclCommAicpu::GetAlltoAllTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
    2300              : {
    2301            0 :     sendCount = param.All2AllDataDes.sendCount * topoInfo_.userRankSize;
    2302            0 :     recvCount = param.All2AllDataDes.sendCount * topoInfo_.userRankSize;
    2303            0 :     return HCCL_SUCCESS;
    2304              : }
    2305              : 
    2306            0 : HcclResult HcclCommAicpu::GetAlltoAllVTotalCount(OpParam& param, u64& sendCount, u64& recvCount)
    2307              : {
    2308            0 :     for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
    2309            0 :         u64 curSendCount = *(static_cast<const u64*>(param.All2AllDataDes.sendCounts) + i)
    2310            0 :                            + *(static_cast<const u64*>(param.All2AllDataDes.sdispls) + i);
    2311            0 :         sendCount = std::max(sendCount, curSendCount);
    2312            0 :         u64 curRecvCount = *(static_cast<const u64*>(param.All2AllDataDes.recvCounts) + i)
    2313            0 :                            + *(static_cast<const u64*>(param.All2AllDataDes.rdispls) + i);
    2314            0 :         recvCount = std::max(recvCount, curRecvCount);
    2315              :     }
    2316            0 :     return HCCL_SUCCESS;
    2317              : }
    2318              : 
    2319            0 : HcclResult HcclCommAicpu::SetAlltoAllInputAndOutPutMem(OpParam& param, AlgResourceResponse& algResource)
    2320              : {
    2321            0 :     u32 sendTypeSize = 0, recvTypeSize = 0;
    2322            0 :     CHK_RET(SalGetDataTypeSize(param.All2AllDataDes.sendType, sendTypeSize));
    2323            0 :     CHK_RET(SalGetDataTypeSize(param.All2AllDataDes.recvType, recvTypeSize));
    2324            0 :     u64 sendCount = 0;
    2325            0 :     u64 recvCount = 0;
    2326            0 :     if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
    2327            0 :         CHK_RET(GetAlltoAllTotalCount(param, sendCount, recvCount));
    2328            0 :     } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV) {
    2329            0 :         CHK_RET(GetAlltoAllVTotalCount(param, sendCount, recvCount));
    2330            0 :     } else if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC) {
    2331            0 :         CHK_RET(GetAlltoAllVCTotalCount(param, sendCount, recvCount));
    2332              :     }
    2333            0 :     u64 inputSize = sendCount * sendTypeSize;
    2334            0 :     u64 outputSize = recvCount * recvTypeSize;
    2335            0 :     algResource.paramInputMem = inputSize == 0 ? tinySendRecvMem_ : DeviceMem::create(param.inputPtr, inputSize);
    2336            0 :     algResource.paramOutputMem = outputSize == 0 ? tinySendRecvMem_ : DeviceMem::create(param.outputPtr, outputSize);
    2337            0 :     HCCL_DEBUG(
    2338              :         "[HcclCommAicpu][SetAlltoAllInputAndOutPutMem] Set memory for AllToAll, inputSize[%llu], inputPtr[%p],"
    2339              :         "outputPtr[%p]!",
    2340              :         inputSize, param.inputPtr, param.outputPtr);
    2341            0 :     return HCCL_SUCCESS;
    2342              : }
    2343              : 
    2344            0 : HcclResult HcclCommAicpu::CombineReportOpInfo(OpParam& param, bool isRetry, bool isRelay)
    2345              : {
    2346            0 :     MsprofAicpuHCCLOPInfo hcclOpInfo{};
    2347            0 :     hcclOpInfo.relay = (isRelay) ? 1 : 0;
    2348            0 :     hcclOpInfo.retry = (isRetry) ? 1 : 0;
    2349            0 :     hcclOpInfo.dataType = param.DataDes.dataType;
    2350            0 :     hcclOpInfo.count = param.DataDes.count;
    2351            0 :     hcclOpInfo.groupName = groupHashId_;
    2352            0 :     hcclOpInfo.ranksize = topoInfo_.userRankSize;
    2353            0 :     std::string algTypeStr = TransferAlgType(algType_);
    2354            0 :     CHK_RET(dfx::ProfilingManager::ReportHcclOpInfo(hcclOpInfo, algTypeStr));
    2355            0 :     return HCCL_SUCCESS;
    2356            0 : }
    2357              : 
    2358            0 : HcclResult HcclCommAicpu::UpdateProfReportStartSqeIdx()
    2359              : {
    2360            0 :     if (dfx::ProfilingManager::IsL1fromOffToOn()) {
    2361            0 :         std::vector<Stream> streams;
    2362            0 :         CHK_RET(GetStreamAll(streams));
    2363            0 :         for (auto& tmpStream : streams) {
    2364            0 :             HcclSqeContext* sqeContext = tmpStream.GetSqeContextPtr();
    2365            0 :             SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    2366            0 :             CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(tmpStream.id(), sqeContextBuffer->tailSqeIdx));
    2367              :         }
    2368            0 :     }
    2369            0 :     return HCCL_SUCCESS;
    2370              : }
    2371              : 
    2372            0 : HcclResult HcclCommAicpu::Orchestrate(
    2373              :     const std::string& newTag, const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    2374              :     AlgResourceResponse& algResource, const HcclOpResParam* commParam)
    2375              : {
    2376            0 :     CHK_PTR_NULL(commParam);
    2377              :     // 算子下发信息记录在共享内存区
    2378            0 :     UpdateOpRingBufferIdx();
    2379            0 :     CHK_RET(aicpuShareData_.RecordOpInfo(
    2380              :         newTag, param, (isDeviceMode_ ? mc2OpIndex_ : hcclOpExecIndex_), localUserRank_, isCustom_));
    2381            0 :     CHK_RET(UpdateProfReportStartSqeIdx());
    2382              : 
    2383              :     // 每个算子都刷新一下profiling开关, 支持profiling从中间迭代采集
    2384            0 :     bool profL0Open = dfx::ProfilingManager::IsProfL0On();
    2385            0 :     bool profL1Open = dfx::ProfilingManager::IsProfL1On();
    2386            0 :     HCCL_DEBUG("profL0Open:%d, profL1Open:%d", profL0Open, profL1Open);
    2387              : 
    2388            0 :     LogControl logControl(false, false); // 重执行ERROR日志保底控制,析构时重置日志设置
    2389            0 :     HCCL_ENTRY_INFO(
    2390              :         commParam->opEntry, "[HcclCommAicpu][Orchestrate]start tag[%s] newTag[%s] algName[%s] identifier[%s]",
    2391              :         param.tag.c_str(), newTag.c_str(), algName.c_str(), identifier_.c_str());
    2392            0 :     HCCL_INFO(
    2393              :         "opRetryHandler.isInplacePreSync[%d] opRetryHandler.isPostSync[%d]",
    2394              :         algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
    2395            0 :     if (executor.get() == nullptr) {
    2396            0 :         executor = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
    2397            0 :         CHK_PRT_RET(
    2398              :             executor.get() == nullptr,
    2399              :             HCCL_ERROR(
    2400              :                 "[HcclCommAicpu][Orchestrate]Fail to find executor "
    2401              :                 "for algName[%s]",
    2402              :                 algName.c_str()),
    2403              :             HCCL_E_PARA);
    2404            0 :         executor->SetAlgType(algType_);
    2405            0 :         executor->SetCCLInBuffer(cclbufferSize_);
    2406              : 
    2407            0 :         if (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
    2408            0 :             bool isSupportSDMAReduce = IsSupportSDMAReduce(
    2409            0 :                 cclInputBuffer_.ptr(), cclOutputBuffer_.ptr(), param.DataDes.dataType, param.reduceType);
    2410            0 :             executor->SetIsSupportSDMAReduce(isSupportSDMAReduce);
    2411              :         }
    2412              :     }
    2413            0 :     if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV
    2414            0 :         || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC) {
    2415            0 :         CHK_RET(CalSendRecvInfoFor910B(algName, param, executor));
    2416            0 :         CHK_RET(SetAlltoAllInputAndOutPutMem(param, algResource));
    2417            0 :         if (algName == "RunAlltoAllVTwoLevelPipeline") {
    2418            0 :             CHK_RET(CalSendRecvInfoForAlltoall(param));
    2419            0 :             HCCL_DEBUG("[HcclCommAicpu][Orchestrate] running RunAlltoAllVTwoLevelPipeline, prepare SendRecvInfo.");
    2420            0 :             CollAlltoAllExecutor* alltoAllExecutor = dynamic_cast<CollAlltoAllExecutor*>(executor.get());
    2421            0 :             CHK_PTR_NULL(alltoAllExecutor);
    2422            0 :             CHK_RET(alltoAllExecutor->SetExcutorExtraInfo(allMeshAggregationSendRecvInfo_, cclbufferSize_));
    2423              :         }
    2424              :     }
    2425            0 :     auto waitStopExecCmdTimeoutMs = HcclGetWaitStopExecCmdTimeout();
    2426            0 :     auto waitStopExecCmdTimeout = std::chrono::milliseconds(waitStopExecCmdTimeoutMs);
    2427              : 
    2428            0 :     auto opStartTime = std::chrono::steady_clock::now(); // 记录重执行算子耗时
    2429            0 :     auto startTime = std::chrono::steady_clock::now();
    2430              : 
    2431            0 :     KfcError errorCode = KfcError::kNone;
    2432            0 :     uint32_t retryCnt = 0;
    2433            0 :     bool retryProcessing = false;
    2434            0 :     KfcCommand lastCmd = KfcCommand::kNone;
    2435            0 :     uint32_t beginSqePos = INVALID_UINT;
    2436            0 :     uint32_t endSqePos = INVALID_UINT;
    2437            0 :     HcclOpExecFSM state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT;
    2438            0 :     HcclResult ret = HCCL_SUCCESS;
    2439            0 :     dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneStart;
    2440            0 :     AicpuComContext* ctx = AicpuGetComContext();
    2441            0 :     AicpuHcclProcess::CallMC2MaintenanceThread(ctx);
    2442            0 :     u32 loopCnt = 0;
    2443            0 :     u32 loopNum = 1;
    2444            0 :     commParam_ = commParam;
    2445            0 :     CHK_RET(InitExecLoop(param, executor, loopNum));
    2446              : 
    2447              :     while (true) {
    2448            0 :         switch (state) {
    2449            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT:
    2450            0 :                 HCCL_INFO("hccl aicpu execute loop %u", loopCnt);
    2451            0 :                 ret = HcclOpExecFsmInitProcess(newTag, param, algResource, state, errorCode);
    2452            0 :                 break;
    2453            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_LAUNCH:
    2454            0 :                 ret = HcclOpExecFsmLaunchProcess(
    2455              :                     algName, param, executor, algResource, state, errorCode, beginSqePos, endSqePos, retryCnt);
    2456            0 :                 if (ret == HCCL_E_SUSPENDING && isDeviceMode_ && retryEnable_) {
    2457            0 :                     return HCCL_E_SUSPENDING;
    2458              :                 }
    2459            0 :                 break;
    2460            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END:
    2461            0 :                 ret = HcclOpExecFsmWaitEndProcess(
    2462            0 :                     param, algResource, state, errorCode, retryCnt, param.tag, beginSqePos);
    2463            0 :                 if (state == HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING) {
    2464            0 :                     startTime = std::chrono::steady_clock::now();
    2465              :                 }
    2466            0 :                 break;
    2467            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING:
    2468            0 :                 retryProcessing = true;
    2469            0 :                 if ((std::chrono::steady_clock::now() - startTime) >= waitStopExecCmdTimeout) {
    2470            0 :                     HCCL_ERROR("[OpRetry][AICPU]hccl aicpu wait stop exec timeout[%u ms].", waitStopExecCmdTimeoutMs);
    2471            0 :                     errorCode = KfcError::kTimeout;
    2472            0 :                     state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2473              :                 } else {
    2474            0 :                     ret = HcclOpExecFsmStoppingProcess(param, state, errorCode, retryCnt);
    2475              :                 }
    2476            0 :                 break;
    2477            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPED:
    2478            0 :                 ret = HcclOpExecFsmStoppedProcess(state, errorCode, retryCnt, algName, param, beginSqePos, endSqePos);
    2479            0 :                 if (state == HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY) {
    2480            0 :                     startTime = std::chrono::steady_clock::now();
    2481              :                 }
    2482            0 :                 break;
    2483            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_CHANGE_LINK:
    2484            0 :                 ret = HcclOpExecChangeLinkProcess(newTag, state, errorCode, retryCnt, algResource, commParam, param);
    2485            0 :                 HCCL_DEBUG(
    2486              :                     "[OpRetry][AICPU]retry change link finish, retryCnt:%u, tag:%s, state:%d", retryCnt,
    2487              :                     param.tag.c_str(), state);
    2488            0 :                 break;
    2489            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY: {
    2490            0 :                 auto waitRetryCmdTimeoutMs = HcclGetWaitRetryCmdTimeout(retryCnt);
    2491            0 :                 auto waitRetryCmdTimeout = std::chrono::milliseconds(waitRetryCmdTimeoutMs);
    2492            0 :                 if ((std::chrono::steady_clock::now() - startTime) >= waitRetryCmdTimeout) {
    2493            0 :                     HCCL_ERROR("[OpRetry][AICPU]hccl aicpu wait retry timeout[%u ms].", waitRetryCmdTimeoutMs);
    2494            0 :                     errorCode = KfcError::kTimeout;
    2495            0 :                     state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2496              :                 } else {
    2497            0 :                     ret = HcclOpExecFsmWaitRetryProcess(param, state, errorCode, lastCmd);
    2498              :                 }
    2499            0 :             } break;
    2500            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_RETRY:
    2501              :                 // 重执行前清理当前算子展开的SQE缓存 (if any), 防止命中非完整的cache
    2502            0 :                 CHK_RET(aicpuCacheManager_.ClearOpUnfoldCacheEntry(
    2503              :                     algName, param, algResource, isDeviceMode_, topoInfo_, topoMatcher_, algOpContext_,
    2504              :                     GetWorkflowMode()));
    2505            0 :                 ret = HcclOpExecFsmRetryProcess(
    2506              :                     algName, param, executor, algResource, state, errorCode, retryCnt, beginSqePos, endSqePos);
    2507            0 :                 break;
    2508            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_END:
    2509            0 :                 loopCnt++;
    2510            0 :                 if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2511            0 :                     param.BatchSendRecvDataDes.curIterNum = loopCnt;
    2512            0 :                     ResetBSRRetryCnt();
    2513              :                 }
    2514            0 :                 if (loopCnt < loopNum) {
    2515            0 :                     state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_INIT;
    2516            0 :                     break;
    2517              :                 }
    2518            0 :                 if (retryCnt > 0) {
    2519            0 :                     RecordReportStatus(dfx::ReportStatus::kRetrySuccess);
    2520            0 :                     retryProcessing = false;
    2521            0 :                     auto opEndTime = std::chrono::steady_clock::now();
    2522            0 :                     auto duration = std::chrono::duration_cast<std::chrono::seconds>(opEndTime - opStartTime).count();
    2523            0 :                     HCCL_RUN_INFO(
    2524              :                         "[OpRetry][AICPU]retry exec success, retryCnt [%u], tag [%s], take time [%ld]s", retryCnt,
    2525              :                         param.tag.c_str(), duration);
    2526              :                 }
    2527            0 :                 CHK_RET(CombineReportOpInfo(param, (retryCnt > 0), false));
    2528            0 :                 return HcclOpExecFsmEndProcess(retryCnt);
    2529            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH:
    2530            0 :                 HCCL_DEBUG("[NsRecovery][AICPU] stop the kernel");
    2531              :                 // 停止前清理当前算子展开的SQE缓存 (if any), 防止host侧重新展开该算子并命中非完整的cache (例如step快恢)
    2532            0 :                 CHK_RET(aicpuCacheManager_.ClearOpUnfoldCacheEntry(
    2533              :                     algName, param, algResource, isDeviceMode_, topoInfo_, topoMatcher_, algOpContext_,
    2534              :                     GetWorkflowMode()));
    2535            0 :                 if (!needsResponseStopLaunch_) {
    2536            0 :                     return HCCL_E_SUSPENDING;
    2537              :                 } else {
    2538            0 :                     HCCL_RUN_INFO("[NsRecovery][AICPU] stop the kernel for stop cmd");
    2539            0 :                     needsResponseStopLaunch_ = false;
    2540            0 :                     SetCommRecoveryFlag(true);
    2541            0 :                     if (UpdateOpExecStatus(state, KfcStatus::kStoplaunch, errorCode, 0) == HCCL_SUCCESS) {
    2542            0 :                         return HCCL_E_SUSPENDING;
    2543              :                     } else {
    2544            0 :                         break;
    2545              :                     }
    2546              :                 }
    2547            0 :             case HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR:
    2548              :             default: {
    2549            0 :                 if (retryProcessing) {
    2550            0 :                     RecordReportStatus(dfx::ReportStatus::kRetryFail);
    2551            0 :                     retryProcessing = false;
    2552              :                 }
    2553            0 :                 UpdateOpExecStatus(state, excuteOpId_, KfcStatus::kRetryError, errorCode, retryCnt);
    2554            0 :                 dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneFinished;
    2555            0 :                 if (!isDeviceMode_) {
    2556            0 :                     isOpLaunch = false;
    2557              :                 }
    2558            0 :                 HCCL_INFO("hccl aicpu set kfcStatus[%d]", dfxExtendInfo_.kfcStatus);
    2559            0 :                 if (errorCode == KfcError::kExecConstraint) {
    2560            0 :                     return HCCL_E_OPRETRY_FAIL;
    2561              :                 }
    2562            0 :                 return (ret == HCCL_SUCCESS) ? HCCL_E_INTERNAL : ret;
    2563              :             }
    2564              :         }
    2565            0 :     }
    2566              :     return ret;
    2567            0 : }
    2568              : 
    2569            1 : HcclResult HcclCommAicpu::InitBsrSendRecvOpIdAndExcuteOpId(
    2570              :     OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode)
    2571              : {
    2572            1 :     auto hcclRet = InitBatchSendRecvOpId(param, algResource);
    2573            1 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2574              :         hcclRet, HCCL_ERROR("InitBatchSendRecvOpId failed, ret:%u", hcclRet), KfcError::kInner,
    2575              :         HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2576            1 :     param.BatchSendRecvDataDes.curMode = BatchSendRecvCurMode::SEND_RECV;
    2577            1 :     if (param.BatchSendRecvDataDes.curIterNum == 0) {
    2578            1 :         bsrSendStream_ = algResource.slaveStreams[BSR_RETRY_SEND_STREAM_INDEX];
    2579            1 :         bsrRecvStream_ = algResource.slaveStreams[BSR_RETRY_RECV_STREAM_INDEX];
    2580              :     }
    2581            1 :     HCCL_INFO(
    2582              :         "BSR: iter %u, tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, excuteOpId_.tag, excuteOpId_.index);
    2583            1 :     HCCL_INFO(
    2584              :         "BSR: iter %u, send op Tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrSendOpId_.tag,
    2585              :         bsrSendOpId_.index);
    2586            1 :     HCCL_INFO(
    2587              :         "BSR: iter %u, recv op Tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrRecvOpId_.tag,
    2588              :         bsrRecvOpId_.index);
    2589            1 :     excuteOpId_.bsrInfo[HCCL_SEND].index = bsrSendOpId_.index;
    2590            1 :     excuteOpId_.bsrInfo[HCCL_RECV].index = bsrRecvOpId_.index;
    2591            1 :     excuteOpId_.bsrInfo[HCCL_SEND].tpQpn = bsrSendOpId_.bsrInfo[HCCL_SEND].tpQpn;
    2592            1 :     excuteOpId_.bsrInfo[HCCL_RECV].tpQpn = bsrRecvOpId_.bsrInfo[HCCL_RECV].tpQpn;
    2593            1 :     excuteOpId_.bsrInfo[HCCL_SEND].streamId = bsrSendOpId_.streamId;
    2594            1 :     excuteOpId_.bsrInfo[HCCL_RECV].streamId = bsrRecvOpId_.streamId;
    2595            1 :     excuteOpId_.bsrInfo[HCCL_SEND].srcRank = bsrSendOpId_.srcRank;
    2596            1 :     excuteOpId_.bsrInfo[HCCL_SEND].detRank = bsrSendOpId_.detRank;
    2597            1 :     excuteOpId_.bsrInfo[HCCL_RECV].srcRank = bsrRecvOpId_.srcRank;
    2598            1 :     excuteOpId_.bsrInfo[HCCL_RECV].detRank = bsrRecvOpId_.detRank;
    2599            1 :     CHK_SAFETY_FUNC_RET(memcpy_s(
    2600              :         excuteOpId_.bsrInfo[HCCL_SEND].bsrTag, sizeof(excuteOpId_.bsrInfo[HCCL_SEND].bsrTag), bsrSendOpId_.tag,
    2601              :         sizeof(bsrSendOpId_.tag)));
    2602            1 :     CHK_SAFETY_FUNC_RET(memcpy_s(
    2603              :         excuteOpId_.bsrInfo[HCCL_RECV].bsrTag, sizeof(excuteOpId_.bsrInfo[HCCL_RECV].bsrTag), bsrRecvOpId_.tag,
    2604              :         sizeof(bsrRecvOpId_.tag)));
    2605            1 :     return HCCL_SUCCESS;
    2606              : }
    2607              : 
    2608            1 : HcclResult HcclCommAicpu::HcclOpExecFsmInitProcess(
    2609              :     const std::string& newTag, OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState,
    2610              :     KfcError& errorCode)
    2611              : {
    2612            1 :     excuteOpId_.index = isDeviceMode_ ? (++mc2OpIndex_) : hcclOpExecIndex_;
    2613            1 :     CHK_SAFETY_FUNC_RET(memset_s(excuteOpId_.tag, sizeof(excuteOpId_.tag), 0, sizeof(excuteOpId_.tag)));
    2614            1 :     CHK_SAFETY_FUNC_RET(memcpy_s(excuteOpId_.tag, sizeof(excuteOpId_.tag), param.tag.c_str(), param.tag.size()));
    2615            1 :     CHK_SAFETY_FUNC_RET(memset_s(excuteOpId_.newTag, sizeof(excuteOpId_.newTag), 0, sizeof(excuteOpId_.newTag)));
    2616            1 :     CHK_SAFETY_FUNC_RET(memcpy_s(excuteOpId_.newTag, sizeof(excuteOpId_.newTag), newTag.c_str(), newTag.size()));
    2617            1 :     excuteOpId_.isSendRecv = false;
    2618            1 :     excuteOpId_.streamId = ~0u;
    2619            1 :     excuteOpId_.opType = param.opType;
    2620            1 :     excuteOpId_.isBsrTaskStart = false;
    2621            1 :     if (param.opType == HcclCMDType::HCCL_CMD_SEND || param.opType == HcclCMDType::HCCL_CMD_RECEIVE) {
    2622            0 :         InitSendRecvOpId(param, excuteOpId_);
    2623            1 :     } else if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2624            1 :         CHK_RET(InitBsrSendRecvOpIdAndExcuteOpId(param, algResource, fsmState, errorCode));
    2625              :     }
    2626            1 :     if (GetNsStopLaunchStatus()) {
    2627            0 :         HCCL_WARNING("the op should not be launched in the suspending status");
    2628            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
    2629            0 :         return HCCL_SUCCESS;
    2630              :     }
    2631            1 :     auto ret = aicpuHdc_.InitOpExecStatus(kfcStatusTransferD2H_, excuteOpId_);
    2632            1 :     isOpLaunch = true;
    2633            1 :     HCCL_INFO("%s tag:%s, isDeviceMode:%d, index:%u", __func__, excuteOpId_.tag, isDeviceMode_, excuteOpId_.index);
    2634            1 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2635              :         ret, HCCL_ERROR("InitOpExecStatus failed, ret:%u", ret), KfcError::kInner,
    2636              :         HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2637            1 :     fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_LAUNCH;
    2638            1 :     return ret;
    2639              : }
    2640              : 
    2641            0 : bool HcclCommAicpu::HcclOpCheckSupportRetry(HcclCMDType opType)
    2642              : {
    2643              :     const std::set<HcclCMDType> HcclSupportRetryOpSet
    2644              :         = {HcclCMDType::HCCL_CMD_BROADCAST,      HcclCMDType::HCCL_CMD_ALLREDUCE,      HcclCMDType::HCCL_CMD_REDUCE,
    2645              :            HcclCMDType::HCCL_CMD_ALLGATHER,      HcclCMDType::HCCL_CMD_REDUCE_SCATTER, HcclCMDType::HCCL_CMD_ALLTOALLV,
    2646              :            HcclCMDType::HCCL_CMD_ALLTOALLVC,     HcclCMDType::HCCL_CMD_ALLTOALL,       HcclCMDType::HCCL_CMD_GATHER,
    2647              :            HcclCMDType::HCCL_CMD_SCATTER,        HcclCMDType::HCCL_CMD_SEND,           HcclCMDType::HCCL_CMD_RECEIVE,
    2648            0 :            HcclCMDType::HCCL_CMD_BATCH_SEND_RECV};
    2649            0 :     return (HcclSupportRetryOpSet.find(opType) != HcclSupportRetryOpSet.end());
    2650            0 : }
    2651              : 
    2652            1 : HcclResult HcclCommAicpu::HcclOpExecFsmLaunchProcess(
    2653              :     const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    2654              :     AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t& beginSqePos,
    2655              :     uint32_t& endSqePos, uint32_t retryCnt)
    2656              : {
    2657            1 :     HCCL_DEBUG("hccl aicpu start launch task.");
    2658              : 
    2659            1 :     HcclResult ret = OrchestrateHcclOp(algName, param, executor, algResource, beginSqePos, endSqePos);
    2660            1 :     if (ret == HCCL_SUCCESS) { // 下发成功, 并且没有检测到异常cq或中断命令
    2661            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
    2662            1 :     } else if (ret == HCCL_E_SUSPENDING) { // 检测到异常cq或中断命令
    2663            1 :         if (isDeviceMode_ && retryEnable_) {
    2664            1 :             HCCL_RUN_INFO("Orchestrate hccl op suspending, restart handle by mc2 process.");
    2665            1 :             return ret;
    2666              :         }
    2667            0 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2668              :             // batchsendrecv算子下发过程中出现异常,task下发未完成,send 和 recv 均需要重执行;
    2669              :             // 第一个g故障op重执行下发task完成后,需要主动上报故障,触发第二个op进行重执行
    2670            0 :             SetBSRSendOpExecException();
    2671            0 :             SetBSRRecvOpExecException();
    2672            0 :             HCCL_RUN_INFO("hccl aicpu abort launch batchsendrecv op, need retry");
    2673              :         }
    2674            0 :         CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
    2675              :     } else {
    2676            0 :         HCCL_ERROR("OrchestrateHcclOp failed, ret:%u", ret);
    2677            0 :         errorCode = KfcError::kInner;
    2678            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2679              :     }
    2680            0 :     return ret;
    2681              : }
    2682              : 
    2683            4 : HcclResult HcclCommAicpu::HcclOpExecFsmWaitEndProcess(
    2684              :     OpParam& param, AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt,
    2685              :     std::string& tag, const uint32_t& beginSqePos)
    2686              : {
    2687            4 :     HCCL_DEBUG("hccl aicpu wait task finish.");
    2688            4 :     auto ret = WaitFinishWhileLoop(mainStream_, algResource.slaveStreams, tag, beginSqePos, param);
    2689            4 :     if (ret == HCCL_SUCCESS) {
    2690            0 :         HCCL_DEBUG("hccl aicpu exec complete.");
    2691            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_END;
    2692            4 :     } else if (ret == HCCL_E_SUSPENDING) {
    2693            4 :         HCCL_RUN_INFO("hccl aicpu force stop in wait end, retryCnt[%u]", retryCnt);
    2694            4 :         CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
    2695              :     } else {
    2696            0 :         HCCL_ERROR("WaitTaskFinish failed, ret:%u, identifier[%s]", ret, identifier_.c_str());
    2697            0 :         errorCode = KfcError::kExec;
    2698            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2699              :     }
    2700            4 :     return ret;
    2701              : }
    2702              : 
    2703            0 : HcclResult HcclCommAicpu::HcclOpExecFsmStoppingProcess(
    2704              :     const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt)
    2705              : {
    2706            0 :     HCCL_DEBUG("hccl aicpu stopping.");
    2707            0 :     KfcCommand cmd = KfcCommand::kNone;
    2708            0 :     auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
    2709            0 :     if (ret != HCCL_SUCCESS) {
    2710            0 :         HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, ret:%u", ret);
    2711            0 :         errorCode = KfcError::kExec;
    2712            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2713            0 :         return ret;
    2714              :     }
    2715            0 :     if (cmd == KfcCommand::kExit) {
    2716            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu exec fsm stop by exit cmd.");
    2717            0 :         errorCode = KfcError::kExit;
    2718            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2719            0 :     } else if (cmd == KfcCommand::kStopExec) {
    2720            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu get stop exec cmd.");
    2721            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPED;
    2722            0 :     } else if (cmd == KfcCommand::kStopLaunch) {
    2723            0 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2724            0 :             HcclOpIdentifier targetOp;
    2725            0 :             CHK_RET(aicpuHdc_.GetOpExecCtrlTargetOp(kfcControlTransferH2D_, targetOp));
    2726            0 :             std::string targetOpTag = std::string(reinterpret_cast<char*>(&targetOp.tag[0]));
    2727            0 :             if (targetOpTag != std::string(reinterpret_cast<char*>(&bsrTargetOpId_.tag[0]))) {
    2728            0 :                 CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
    2729              :             }
    2730            0 :         }
    2731            0 :     } else if ((cmd == KfcCommand::kNone) || (cmd == KfcCommand::kRetry)) {
    2732            0 :         HCCL_DEBUG("hccl aicpu wait for stop exec cmd.");
    2733              :         // do nothing
    2734            0 :     } else if (cmd == KfcCommand::kReportRetryErr) {
    2735            0 :         HCCL_ERROR("[OpRetry][AICPU][HcclOpExecFsmStoppingProcess]hccl aicpu can not retry err cmd[%d]", cmd);
    2736            0 :         uint16_t rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2737            0 :         CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2738            0 :         errorCode = KfcError::kExit;
    2739            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2740            0 :         return HCCL_E_OPRETRY_FAIL;
    2741              :     } else {
    2742            0 :         HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, invalid cmd[%u]", cmd);
    2743            0 :         errorCode = KfcError::kExec;
    2744            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2745              :     }
    2746            0 :     return HCCL_SUCCESS;
    2747              : }
    2748              : 
    2749            0 : HcclResult HcclCommAicpu::LoadChangeLinkInfo(ChangeLinkInfo& changeLinkInfo)
    2750              : {
    2751            0 :     HcclResult ret = aicpuHdc_.GetOpExecChangeLink(kfcControlTransferH2D_, changeLinkInfo);
    2752              : 
    2753              :     // DEBUG_INFO aicpu接收的changelinkinfo
    2754            0 :     std::string changeLinkInfoStr = "";
    2755            0 :     for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
    2756              :         changeLinkInfoStr
    2757            0 :             += (std::to_string(changeLinkInfo.remoteRankList[i]) + ":"
    2758            0 :                 + std::to_string(changeLinkInfo.isUseDefaultPort[i]) + "; ");
    2759              :     }
    2760            0 :     HCCL_RUN_INFO(
    2761              :         "[%s]rank[%u], isChangeLinkFlag[%d], changeLinkInfoStr:%s", __func__, localUserRank_,
    2762              :         changeLinkInfo.isChangeLinkFlag, changeLinkInfoStr.c_str());
    2763              : 
    2764            0 :     return ret;
    2765            0 : }
    2766              : 
    2767            0 : HcclResult HcclCommAicpu::HcclOpExecChangeLinkProcess(
    2768              :     const std::string& newTag, HcclOpExecFSM& state, KfcError& errorCode, uint32_t& retryCnt,
    2769              :     AlgResourceResponse& algResource, const HcclOpResParam* commParam, const OpParam& param)
    2770              : {
    2771            0 :     ChangeLinkInfo changeLinkInfo;
    2772            0 :     HcclResult ret = LoadChangeLinkInfo(changeLinkInfo);
    2773            0 :     if (ret != HCCL_SUCCESS) {
    2774            0 :         errorCode = KfcError::kExec;
    2775            0 :         state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2776            0 :         return ret;
    2777              :     }
    2778            0 :     bool useBackupLink = false;
    2779            0 :     std::map<u32, bool> remoteRankPortMap;
    2780            0 :     for (u32 i = 0; i < changeLinkInfo.remoteRankNum; i++) {
    2781            0 :         remoteRankPortMap.insert({changeLinkInfo.remoteRankList[i], changeLinkInfo.isUseDefaultPort[i]});
    2782            0 :         useBackupLink |= (!changeLinkInfo.isUseDefaultPort[i]);
    2783              :     }
    2784            0 :     ret = RefreshAlgResponseTransportRes(
    2785            0 :         newTag, algResource, remoteRankPortMap, changeLinkInfo.isChangeLinkFlag, commParam, param);
    2786            0 :     if (ret != HCCL_SUCCESS) {
    2787            0 :         errorCode = KfcError::kExec;
    2788            0 :         state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2789            0 :         return ret;
    2790              :     }
    2791            0 :     if (useBackupLink) {
    2792            0 :         RecordReportStatus(dfx::ReportStatus::kRetryWithBackupLink);
    2793              :     }
    2794            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2795            0 :         retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
    2796              :     }
    2797            0 :     errorCode = KfcError::kNone;
    2798            0 :     CHK_RET(UpdateOpExecStatus(state, KfcStatus::kChanged, errorCode, retryCnt));
    2799            0 :     state = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
    2800            0 :     return HCCL_SUCCESS;
    2801            0 : }
    2802              : 
    2803            0 : HcclResult HcclCommAicpu::BSRStopedProcess(HcclOpExecFSM& fsmState, KfcError& errorCode)
    2804              : {
    2805              :     // 判断batchsendrecv算子的send 和recv 操作停止的位置是否满足重执行条件
    2806              :     // send / recv 的stream停止位置不能位于该算子的首个sqe 和末尾sqe
    2807              :     u32 bsrSendSqHead;
    2808              :     u32 bsrRecvSqHead;
    2809            0 :     auto ret = QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, bsrSendSqHead);
    2810            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2811              :         ret, HCCL_ERROR("[OpRetry][AICPU]query send stream sq head failed, ret:%u", ret), KfcError::kExec,
    2812              :         HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2813              : 
    2814            0 :     ret = QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, bsrRecvSqHead);
    2815            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2816              :         ret, HCCL_ERROR("[OpRetry][AICPU]query recv stream sq head failed, ret:%u", ret), KfcError::kExec,
    2817              :         HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2818              : 
    2819            0 :     ret = ((bsrSendOpBeginSqePos_ == bsrSendSqHead) || (bsrRecvOpBeginSqePos_ == bsrRecvSqHead)) ? HCCL_E_OPRETRY_FAIL :
    2820              :                                                                                                    HCCL_SUCCESS;
    2821            0 :     if (ret != HCCL_SUCCESS) {
    2822            0 :         uint16_t rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2823            0 :         CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2824              :     }
    2825            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2826              :         ret,
    2827              :         HCCL_ERROR(
    2828              :             "[OpRetry][AICPU]hccl aicpu wait start task is not complete, can not retry. params: send sq head "
    2829              :             "%u, recv sq head %u, send sq begin %u, recv sq begin %u",
    2830              :             bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrRecvOpBeginSqePos_),
    2831              :         KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2832              : 
    2833            0 :     ret = ((bsrRetryOp_ == HCCL_SEND) && (bsrSendSqHead == bsrSendOpEndSqePos_)) ? HCCL_E_OPRETRY_FAIL : HCCL_SUCCESS;
    2834            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2835              :         ret,
    2836              :         HCCL_ERROR(
    2837              :             "[OpRetry][AICPU]hccl aicpu send record complete task is complete, can not retry. params: send sq "
    2838              :             "head %u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
    2839              :             bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
    2840              :             bsrRecvOpEndSqePos_),
    2841              :         KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2842              : 
    2843            0 :     ret = ((bsrRetryOp_ == HCCL_RECV) && (bsrRecvSqHead == bsrRecvOpEndSqePos_)) ? HCCL_E_OPRETRY_FAIL : HCCL_SUCCESS;
    2844            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2845              :         ret,
    2846              :         HCCL_ERROR(
    2847              :             "[OpRetry][AICPU]hccl aicpu recv record complete task is complete, can not retry. params: send sq "
    2848              :             "head %u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
    2849              :             bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
    2850              :             bsrRecvOpEndSqePos_),
    2851              :         KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2852              : 
    2853            0 :     HCCL_RUN_INFO(
    2854              :         "[OpRetry][AICPU]hccl aicpu op is running, can retry. params: send sq head "
    2855              :         "%u, recv sq head %u, send sq begin %u, send sq end %u, recv sq begin %u, recv sq end %u",
    2856              :         bsrSendSqHead, bsrRecvSqHead, bsrSendOpBeginSqePos_, bsrSendOpEndSqePos_, bsrRecvOpBeginSqePos_,
    2857              :         bsrRecvOpEndSqePos_);
    2858            0 :     if (IsTaskExceptionForHccs()) {
    2859            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu stop by sdma/write task exception, can retry.");
    2860              :     }
    2861            0 :     errorCode = KfcError::kNone;
    2862            0 :     uint32_t retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
    2863            0 :     CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStopExec, errorCode, retryCnt));
    2864            0 :     fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
    2865            0 :     return HCCL_SUCCESS;
    2866              : }
    2867              : 
    2868            0 : HcclResult HcclCommAicpu::HcclOpExecFsmStoppedProcess(
    2869              :     HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt, const std::string& algName, OpParam& param,
    2870              :     uint32_t beginSqePos, uint32_t endSqePos)
    2871              : {
    2872            0 :     HCCL_DEBUG("hccl aicpu stop exec.");
    2873            0 :     KfcCommand cmd = KfcCommand::kNone;
    2874            0 :     auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
    2875            0 :     uint16_t rsErrorCode = 0;
    2876            0 :     if (ret != HCCL_SUCCESS) {
    2877            0 :         HCCL_ERROR("[OpRetry][AICPU]GetOpExecCtrlCmd failed, ret:%u", ret);
    2878            0 :         errorCode = KfcError::kExec;
    2879            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2880            0 :         return ret;
    2881              :     }
    2882              : 
    2883            0 :     if (cmd == KfcCommand::kExit) {
    2884            0 :         HCCL_ERROR("[OpRetry][AICPU]hccl aicpu exec fsm stop by exit cmd.");
    2885            0 :         errorCode = KfcError::kExit;
    2886            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2887            0 :         return HCCL_SUCCESS;
    2888              :     }
    2889              : 
    2890            0 :     if (cmd == KfcCommand::kReportRetryErr) {
    2891            0 :         HCCL_ERROR("[OpRetry][AICPU][HcclOpExecFsmStoppedProcess]hccl aicpu can not retry err cmd[%d]", cmd);
    2892            0 :         rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2893            0 :         CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2894            0 :         errorCode = KfcError::kExit;
    2895            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2896            0 :         return HCCL_E_OPRETRY_FAIL;
    2897              :     }
    2898              : 
    2899            0 :     if (!HcclOpSupportRetry(algName, retryEnable_, param)) {
    2900            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    2901            0 :         if (param.isInplaceError) {
    2902            0 :             errorCode = KfcError::kExecConstraint;
    2903            0 :             rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2904            0 :             CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2905            0 :             HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2906              :                 HCCL_E_OPRETRY_FAIL,
    2907              :                 HCCL_ERROR("[Opretry][AICPU][HcclOpExecFsmStoppedProcess]can not retry for inplace error."),
    2908              :                 KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2909            0 :         } else if (isPollutedZeroCopyOp(param)) {
    2910            0 :             errorCode = KfcError::kExecConstraint;
    2911            0 :             rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2912            0 :             CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2913            0 :             HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2914              :                 HCCL_E_OPRETRY_FAIL,
    2915              :                 HCCL_ERROR("[Opretry][AICPU][HcclOpExecFsmStoppedProcess]can not retry for zero copy op."),
    2916              :                 KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2917              :             return HCCL_E_OPRETRY_FAIL;
    2918              :         } else {
    2919            0 :             errorCode = KfcError::kExec;
    2920              :         }
    2921            0 :         return HCCL_SUCCESS;
    2922              :     }
    2923              : 
    2924            0 :     uint32_t sqHead = 0xFFFFFFFF;
    2925            0 :     CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_HEAD, sqHead));
    2926            0 :     if (sqHead == endSqePos) {
    2927            0 :         rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2928            0 :         CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2929            0 :         HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2930              :             HCCL_E_OPRETRY_FAIL,
    2931              :             HCCL_ERROR(
    2932              :                 "[OpRetry][AICPU]hccl aicpu record complete task is complete, can not retry. params: "
    2933              :                 "sqHead %u, beginSqePos %u endSqePos %u",
    2934              :                 sqHead, beginSqePos, endSqePos),
    2935              :             KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2936            0 :     } else if (sqHead == beginSqePos) {
    2937            0 :         rsErrorCode = TS_ERROR_RETRY_CONSTRAINT;
    2938            0 :         CHK_PRT(SendTaskExceptionByMBox(rsErrorCode));
    2939            0 :         HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    2940              :             HCCL_E_OPRETRY_FAIL,
    2941              :             HCCL_ERROR(
    2942              :                 "[OpRetry][AICPU]hccl aicpu wait start task is not complete, can not retry. "
    2943              :                 "params: sqHead %u, beginSqePos %u endSqePos %u",
    2944              :                 sqHead, beginSqePos, endSqePos),
    2945              :             KfcError::kExecConstraint, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    2946            0 :     } else if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    2947            0 :         CHK_RET(BSRStopedProcess(fsmState, errorCode));
    2948            0 :     } else {
    2949            0 :         HCCL_RUN_INFO(
    2950              :             "[OpRetry][AICPU]hccl aicpu op is running, can retry. params: sqHead %u, beginSqePos %u "
    2951              :             "endSqePos %u",
    2952              :             sqHead, beginSqePos, endSqePos);
    2953            0 :         if (IsTaskExceptionForHccs()) {
    2954            0 :             HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu stop by sdma/write task exception, can retry.");
    2955              :         }
    2956            0 :         errorCode = KfcError::kNone;
    2957            0 :         CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStopExec, errorCode, retryCnt));
    2958            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_RETRY;
    2959              :     }
    2960            0 :     return HCCL_SUCCESS;
    2961              : }
    2962              : 
    2963            0 : void HcclCommAicpu::NsCommStop()
    2964              : {
    2965            0 :     if ((StreamsKill(devId_) != HCCL_SUCCESS) || (DeviceQuery(devId_, ts::APP_ABORT_KILL_FINISH, 0U) != HCCL_SUCCESS)) {
    2966            0 :         (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kError, KfcError::kExec, 0);
    2967            0 :         HCCL_ERROR("[NsRecovery][AICPU]Stop failed");
    2968            0 :         return;
    2969              :     }
    2970              :     // 停止条件算子
    2971            0 :     if (isDeviceMode_) {
    2972            0 :         (void)InvokeKfcHandler(AicpuKfcHandlerType::kClearCommitTurn, {rpc_});
    2973              :     }
    2974            0 :     (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kStopExec, KfcError::kNone, 0);
    2975            0 :     (void)HcclOneSideServiceAicpu::DisableAllStreamFunc();
    2976            0 :     HCCL_RUN_INFO("[NsRecovery][AICPU]stopFunc Finished");
    2977              : }
    2978              : 
    2979            0 : void HcclCommAicpu::NsCommClean()
    2980              : {
    2981              :     // 等待drv任务停止
    2982            0 :     if ((DeviceQuery(devId_, ts::APP_ABORT_TERMINATE_FINISH, 0U) != HCCL_SUCCESS) || (CleanStreamFunc() != HCCL_SUCCESS)
    2983            0 :         || (HcclOneSideServiceAicpu::CleanAllStreamFunc() != HCCL_SUCCESS) || (ResetSqBuff() != HCCL_SUCCESS)) {
    2984            0 :         (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kError, KfcError::kExec, 0);
    2985            0 :         HCCL_ERROR("[NsRecovery][AICPU]stream terminate failed");
    2986            0 :         return;
    2987              :     } else {
    2988            0 :         if (isDeviceMode_) {
    2989            0 :             (void)InvokeKfcHandler(AicpuKfcHandlerType::kClearMsgArea, {rpc_});
    2990              :         }
    2991            0 :         HCCL_INFO("ClearFunc, after APP_ABORT_TERMINATE_FINISH");
    2992            0 :         dfxExtendInfo_.pollStatus = PollStatus::kDefault;
    2993            0 :         dfxExtendInfo_.cqeStatus = dfx::CqeStatus::kDefault;
    2994            0 :         (void)aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, KfcStatus::kClear, KfcError::kNone, 0);
    2995            0 :         endStopLaunch = false;
    2996            0 :         isOpLaunch = false;
    2997            0 :         needsResponseStopLaunch_ = false;
    2998            0 :         errMessageReport_ = true;
    2999            0 :         HCCL_RUN_INFO("[NsRecovery][AICPU] clean Finish");
    3000              :     }
    3001              : }
    3002              : 
    3003            0 : HcclResult HcclCommAicpu::GetBackGroundCommand(BackgroundCommand& bgCmd)
    3004              : {
    3005            0 :     return AicpuHdcUtils::GetBackGroundCommand(kfcControlTransferH2D_, bgCmd);
    3006              : }
    3007              : 
    3008            0 : HcclResult HcclCommAicpu::ResponseBackGroundStatus(KfcExecStatus& status)
    3009              : {
    3010            0 :     return AicpuHdcUtils::ResponseBackGroundStatus(kfcStatusTransferD2H_, status);
    3011              : }
    3012              : 
    3013            0 : HcclResult HcclCommAicpu::GetKfcCommand(KfcCommand& cmd)
    3014              : {
    3015            0 :     return AicpuHdcUtils::GetKfcCommand(kfcControlTransferH2D_, cmd);
    3016              : }
    3017              : 
    3018            0 : HcclResult HcclCommAicpu::SetStreamEnable(Stream& stream)
    3019              : {
    3020            0 :     const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
    3021            0 :     HCCL_INFO("[SetStreamEnable] streamid[%d]", streamInfo.actualStreamId);
    3022            0 :     CHK_RET(ConfigSqStatusByType(GetDevId(), streamInfo.sqId, DRV_SQCQ_PROP_SQ_DISABLE_TO_ENABLE, 1));
    3023            0 :     HandleCqeException(stream, true);
    3024            0 :     return HCCL_SUCCESS;
    3025              : }
    3026              : 
    3027            0 : HcclResult HcclCommAicpu::CleanStreamFunc()
    3028              : {
    3029            0 :     CHK_RET(SetStreamEnable(mainStream_));
    3030            0 :     for (auto& stream : slaveStreams_) {
    3031            0 :         CHK_RET(SetStreamEnable(stream));
    3032              :     }
    3033            0 :     CHK_RET(SetStreamEnable(orderStream_));
    3034            0 :     return HCCL_SUCCESS;
    3035              : }
    3036              : 
    3037            0 : std::string HcclCommAicpu::PrintInplaceStatus(u8 isInplaceStatus)
    3038              : {
    3039            0 :     const u8 kNoOverlap = 0;
    3040            0 :     const u8 kAllToAllOverlap = 1;
    3041            0 :     const u8 kInplaceOverlap = 2;
    3042            0 :     switch (isInplaceStatus) {
    3043            0 :         case kNoOverlap:
    3044              :             // input和output不重叠
    3045            0 :             return "There is no overlap.";
    3046            0 :         case kAllToAllOverlap:
    3047              :             // alltoall类算子的input和output重叠
    3048            0 :             return "The param.inputPtr is equal to param.outputPtr, hence they overlap.";
    3049            0 :         case kInplaceOverlap:
    3050              :             // input和output重叠
    3051            0 :             return "It's inplace case. hence they overlap.";
    3052            0 :         default:
    3053            0 :             return "It's an unknown overlap case.";
    3054              :     }
    3055              :     return "";
    3056              : }
    3057              : 
    3058            0 : std::string HcclCommAicpu::PrintInplaceSupportRetryStatus(InplaceSupportRetryStatus inPlaceSupportRetryStatus)
    3059              : {
    3060            0 :     switch (inPlaceSupportRetryStatus) {
    3061            0 :         case InplaceSupportRetryStatus::AG_BD_CASE: // 不需要去变成非DMA削减
    3062              :             // allgather or broadcast 算子
    3063            0 :             return "The Allgather or broadcast op supports inplace retry.";
    3064            0 :         case InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE1: // 需要去变成非DMA削减
    3065              :             // 使用AllReduceMeshSmallCountExecutor, ReduceScatterDeterExecutor
    3066              :             // 且环境变量配置RetryEnable:1
    3067            0 :             return "Since retryEnable:1, the executor without DMAReduce will be applied.";
    3068            0 :         case InplaceSupportRetryStatus::RETRY_0_NOT_ALLOW_NO_DMA_REDUCE_CASE1: // 不需要去变成非DMA削减
    3069              :             // 使用AllReduceMeshSmallCountExecutor, ReduceScatterDeterExecutor
    3070              :             // 且环境变量配置RetryEnable:0
    3071            0 :             return "Since retryEnable:0, ExecutorOnlySupportDMAReduce is not allowed for inplace case.";
    3072            0 :         case InplaceSupportRetryStatus::ALWAYS_NO_DMA_REDUCE: // 不需要去变成非DMA削减,本身就是
    3073              :             // 使用AllReduceComm/ReduceScatterComm
    3074            0 :             return "AllReduceComm or ReduceScatterComm is used for inplace case.";
    3075            0 :         case InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE2: // 需要去变成非DMA削减
    3076              :             // 使用其余在91093场景下使用的reduce scatter, allreduce executor
    3077              :             // 且环境变量配置RetryEnable:1
    3078            0 :             return "Since retryEnable:1, the executor will be applied without DMAReduce operation.";
    3079            0 :         case InplaceSupportRetryStatus::RETRY_0_NOT_ALLOW_NO_DMA_REDUCE_CASE2: // 不需要去变成非DMA削减
    3080              :             // 使用其余在91093场景下使用的reduce scatter, allreduce executor
    3081              :             // 且环境变量配置RetryEnable:0
    3082            0 :             return "Since retryEnable:0, the executor without DMAReduce operation can not be applied.";
    3083            0 :         case InplaceSupportRetryStatus::UNKONWN_EXECUTOR: // 不需要去变成非DMA削减
    3084              :             // 使用未知的executor
    3085            0 :             return "The unknown executor does not support for an inplace case yet.";
    3086            0 :         case InplaceSupportRetryStatus::USER_LARGER_THAN_CCL: // 不需要去变成非DMA削减
    3087              :             // UserInMem > CCLInMem 场景
    3088            0 :             return "UserInMem > CCLInMem case";
    3089            0 :         case InplaceSupportRetryStatus::NOT_BASIC_OP_CASE: // 不需要去变成非DMA削减
    3090              :             // 非 RS AR AG BD算子场景
    3091            0 :             return "Is not ReduceScatter, AllReduce, AllGather or Broadcast case";
    3092            0 :         default:
    3093            0 :             return "It's unknown case. They overlap.";
    3094              :     }
    3095              :     return "";
    3096              : }
    3097              : 
    3098            0 : bool HcclCommAicpu::IsNoNeedMonitor(void)
    3099              : {
    3100            0 :     if (taskMonitorInterval_ == 0)
    3101            0 :         return true;
    3102              : 
    3103            0 :     KfcCommand kfcCmd = KfcCommand::kNone;
    3104            0 :     (void)GetKfcCommand(kfcCmd);
    3105            0 :     if (kfcCmd != KfcCommand::kNone)
    3106            0 :         return true;
    3107              : 
    3108            0 :     BackgroundCommand bgCmd = BackgroundCommand::kNone;
    3109            0 :     (void)GetBackGroundCommand(bgCmd);
    3110            0 :     if (bgCmd != BackgroundCommand::kNone)
    3111            0 :         return true;
    3112              : 
    3113            0 :     HcclComSuspendingFlag suspendingFlag = HcclComSuspendingFlag::isNull;
    3114            0 :     (void)GetSuspendingFlag(suspendingFlag);
    3115            0 :     if (suspendingFlag != HcclComSuspendingFlag::isNull)
    3116            0 :         return true;
    3117            0 :     return false;
    3118              : }
    3119              : 
    3120            0 : void HcclCommAicpu::InsertMonitorData(Stream& stream, HcclUs& curTime, u32 sqHead, uint16_t taskId, uint8_t type)
    3121              : {
    3122            0 :     AicpuStreamMontior tmpTaskMonitor;
    3123            0 :     tmpTaskMonitor.historyTime = curTime;
    3124            0 :     tmpTaskMonitor.historyHead = sqHead;
    3125            0 :     tmpTaskMonitor.historyTaskId = taskId;
    3126            0 :     tmpTaskMonitor.historyType = type;
    3127            0 :     streamTaskMonitor_.insert(std::make_pair(stream.sqId(), tmpTaskMonitor));
    3128            0 :     return;
    3129              : }
    3130              : 
    3131            0 : bool HcclCommAicpu::IsNeedRefreshMonitorData(
    3132              :     AicpuStreamMontior& streamMontior, HcclUs& curTime, uint32_t remoteRank, uint16_t taskId, u32 sqHead, u32 sqTail,
    3133              :     uint8_t type)
    3134              : {
    3135            0 :     auto& historyTime = streamMontior.historyTime;
    3136            0 :     auto& historyHead = streamMontior.historyHead;
    3137            0 :     auto& historyTaskId = streamMontior.historyTaskId;
    3138            0 :     auto& historyType = streamMontior.historyType;
    3139            0 :     if ((historyTaskId != taskId) || (sqHead != historyHead) || (sqHead == sqTail) || (historyType != type)
    3140            0 :         || ((type == RT_STARS_SQE_TYPE_NOTIFY_WAIT) && (remoteRank == INVALID_VALUE_RANKID))) {
    3141            0 :         historyTime = curTime;
    3142            0 :         historyHead = sqHead;
    3143            0 :         historyTaskId = taskId;
    3144            0 :         historyType = type;
    3145            0 :         return true;
    3146              :     }
    3147            0 :     return false;
    3148              : }
    3149              : 
    3150            0 : HcclResult HcclCommAicpu::StreamTaskMonitor(void)
    3151              : {
    3152              :     // 通信域资源已经释放
    3153            0 :     CHK_PRT_RET(
    3154              :         !commOpenStatus, HCCL_DEBUG("[StreamTaskMonitor]group[%s] has been destroyed", identifier_.c_str()),
    3155              :         HCCL_SUCCESS);
    3156            0 :     if (IsNoNeedMonitor())
    3157            0 :         return HCCL_SUCCESS;
    3158            0 :     HCCL_DEBUG("StreamTaskMonitor print");
    3159            0 :     std::vector<Stream> totalStream = {mainStream_};
    3160            0 :     totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
    3161            0 :     HcclUs curTime = TIME_NOW();
    3162            0 :     for (auto& stream : totalStream) {
    3163            0 :         u32 sqHead = 0U, sqTail = 0U;
    3164            0 :         (void)QuerySqStatus(devId_, stream.sqId(), sqHead, sqTail);
    3165            0 :         HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
    3166            0 :         CHK_PTR_NULL(sqeContext);
    3167            0 :         SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    3168            0 :         CHK_PTR_NULL(sqeContextBuffer);
    3169              : 
    3170            0 :         uint8_t type = 0;
    3171            0 :         uint16_t taskId = 0;
    3172            0 :         uint32_t remoteRank = 0;
    3173            0 :         std::string tmp = GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskId, remoteRank);
    3174            0 :         HCCL_DEBUG("GetTaskExceptionTaskInfo type %u taskId %u", type, taskId);
    3175            0 :         auto mapIt = streamTaskMonitor_.find(stream.sqId());
    3176            0 :         if (mapIt == streamTaskMonitor_.end()) {
    3177            0 :             InsertMonitorData(stream, curTime, sqHead, taskId, type);
    3178            0 :             continue;
    3179              :         }
    3180              : 
    3181            0 :         auto& streamMontior = mapIt->second;
    3182            0 :         if (IsNeedRefreshMonitorData(streamMontior, curTime, remoteRank, taskId, sqHead, sqTail, type)) {
    3183            0 :             continue;
    3184              :         }
    3185              : 
    3186            0 :         auto timeVal = DURATION_US(curTime - streamMontior.historyTime).count();
    3187            0 :         const int TIME_CONVERSION = 1000;
    3188            0 :         if (timeVal >= taskMonitorInterval_ * TIME_CONVERSION) {
    3189            0 :             HCCL_RUN_INFO(
    3190              :                 "[StreamTaskMonitor]prof monitor streamId:%d, sqid:%d, head:%u, tail:%u, time %s us, %s", stream.id(),
    3191              :                 stream.sqId(), sqHead, sqTail, std::to_string(timeVal).c_str(), tmp.c_str());
    3192            0 :             HCCL_RUN_INFO(
    3193              :                 "[StreamTaskMonitor]prof monitor %s", GetTaskExceptionOpInfo(sqHead, sqeContextBuffer).c_str());
    3194            0 :             PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer, true);
    3195            0 :             streamMontior.historyTime = curTime;
    3196            0 :             streamMontior.historyHead = sqHead;
    3197            0 :             streamMontior.historyTaskId = taskId;
    3198            0 :             streamMontior.historyType = type;
    3199              :         }
    3200            0 :     }
    3201            0 :     return HCCL_SUCCESS;
    3202            0 : }
    3203              : 
    3204            0 : HcclResult HcclCommAicpu::SupportRetryWithInplaceCheck(const std::string& algName, OpParam& param)
    3205              : {
    3206              :     // 不支持inplace的通信算子重执行
    3207            0 :     u8 isInplaceStatus = 0;
    3208            0 :     InplaceSupportRetryStatus inPlaceSupportRetryStatus = InplaceSupportRetryStatus::INPLACE_STATUS_END;
    3209            0 :     if (IsHcclOpInplace(param.opType, param, topoInfo_.userRank, topoInfo_.userRankSize, isInplaceStatus)) {
    3210            0 :         if (!FitRetryConditionforInPlaceOp(
    3211            0 :                 param.opType, param, algName, cclbufferSize_, topoInfo_.userRankSize,
    3212            0 :                 algOpContext_.opRetryHandler.retryEnable, inPlaceSupportRetryStatus)) {
    3213            0 :             HCCL_RUN_INFO(
    3214              :                 "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
    3215              :                 "opRetryHandler.inplaceSupportRetry[%d], opRetryHandler.inPlaceSupportRetryStatus[%s], "
    3216              :                 "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
    3217              :                 PrintInplaceStatus(isInplaceStatus).c_str(), 0,
    3218              :                 PrintInplaceSupportRetryStatus(inPlaceSupportRetryStatus).c_str(),
    3219              :                 algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
    3220              :         } else {
    3221            0 :             HCCL_RUN_INFO(
    3222              :                 "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
    3223              :                 "opRetryHandler.inplaceSupportRetry[%d], opRetryHandler.inPlaceSupportRetryStatus[%s], "
    3224              :                 "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
    3225              :                 PrintInplaceStatus(isInplaceStatus).c_str(), 1,
    3226              :                 PrintInplaceSupportRetryStatus(inPlaceSupportRetryStatus).c_str(),
    3227              :                 algOpContext_.opRetryHandler.isInplacePreSync, algOpContext_.opRetryHandler.isPostSync);
    3228              :         }
    3229              :     } else {
    3230            0 :         HCCL_RUN_INFO(
    3231              :             "[OpRetry][AICPU]hccl supports inplace status: isInplaceStatus[%s], "
    3232              :             "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d].",
    3233              :             PrintInplaceStatus(isInplaceStatus).c_str(), algOpContext_.opRetryHandler.isInplacePreSync,
    3234              :             algOpContext_.opRetryHandler.isPostSync);
    3235              :     }
    3236            0 :     return HCCL_SUCCESS;
    3237              : }
    3238              : 
    3239            0 : bool HcclCommAicpu::HcclOpSupportRetry(const std::string& algName, bool retryEnable, OpParam& param)
    3240              : {
    3241            0 :     HCCL_RUN_INFO(
    3242              :         "[OpRetry][AICPU]hccl supports retry status: enable[%u], param.tag[%s].", retryEnable, param.tag.c_str());
    3243            0 :     if (!retryEnable) {
    3244            0 :         HCCL_ERROR("[OpRetry][AICPU]hccl aicpu can not retry, enable[%u].", retryEnable);
    3245            0 :         return false;
    3246              :     }
    3247            0 :     if (isPollutedZeroCopyOp(param)) {
    3248            0 :         HCCL_ERROR(
    3249              :             "[OpRetry][AICPU]hccl aicpu can not retry, isZeroCopy[%d], opType[%s].", param.isZeroCopy,
    3250              :             GetCMDTypeEnumStr(param.opType).c_str());
    3251            0 :         return false;
    3252              :     }
    3253              : 
    3254            0 :     CHK_RET(SupportRetryWithInplaceCheck(algName, param));
    3255              :     // 不支持inplace的通信算子重执行
    3256            0 :     if ((!algOpContext_.opRetryHandler.inplaceSupportRetry) && (!algOpContext_.opRetryHandler.isInplacePreSync)
    3257            0 :         && (!algOpContext_.opRetryHandler.isPostSync)) {
    3258            0 :         HCCL_ERROR(
    3259              :             "[OpRetry][AICPU]hccl aicpu can not retry, not support inplace case, opType[%s], "
    3260              :             "inputPtr[0x%016lx], outputPtr[0x%016lx], opRetryHandler.inplaceSupportRetry[%d], "
    3261              :             "opRetryHandler.isInplacePreSync[%d], opRetryHandler.isPostSync[%d]",
    3262              :             GetCMDTypeEnumStr(param.opType).c_str(), param.inputPtr, param.outputPtr,
    3263              :             algOpContext_.opRetryHandler.inplaceSupportRetry, algOpContext_.opRetryHandler.isInplacePreSync,
    3264              :             algOpContext_.opRetryHandler.isPostSync);
    3265            0 :         param.isInplaceError = true;
    3266            0 :         return false;
    3267              :     }
    3268              : 
    3269              :     // 不支持的通信算子重执行
    3270            0 :     if (HcclOpCheckSupportRetry(param.opType) == false) {
    3271            0 :         HCCL_ERROR(
    3272              :             "[OpRetry][AICPU]hccl aicpu can not retry, not support opType[%s].",
    3273              :             GetCMDTypeEnumStr(param.opType).c_str());
    3274            0 :         return false;
    3275              :     }
    3276            0 :     return true;
    3277              : }
    3278              : 
    3279            0 : bool HcclCommAicpu::isPollutedZeroCopyOp(OpParam& param)
    3280              : {
    3281              :     // allreduce\reduce\reducescatter\reducescatterv with zerocopy can not support retry.
    3282            0 :     bool isPollutedOp
    3283            0 :         = ((param.opType == HcclCMDType::HCCL_CMD_ALLREDUCE) || (param.opType == HcclCMDType::HCCL_CMD_REDUCE)
    3284            0 :            || (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER)
    3285            0 :            || (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER_V));
    3286            0 :     return param.isZeroCopy && isPollutedOp;
    3287              : }
    3288              : 
    3289            0 : HcclResult HcclCommAicpu::UpdateOpExecStatus(
    3290              :     HcclOpExecFSM& fsmState, HcclOpIdentifier& opId, KfcStatus state, KfcError& errorCode, uint32_t retryCnt)
    3291              : {
    3292            0 :     HCCL_INFO(
    3293              :         "UpdateOpExecStatus fsmState %d, tag %s, index %u, state %d, errorCode %d, retryCnt %u.", fsmState, opId.tag,
    3294              :         opId.index, state, errorCode, retryCnt);
    3295            0 :     auto ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, opId, state, errorCode, retryCnt);
    3296              : 
    3297            0 :     HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    3298              :         ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec, HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    3299              : 
    3300            0 :     return ret;
    3301              : }
    3302              : 
    3303              : HcclResult
    3304            7 : HcclCommAicpu::UpdateOpExecStatus(HcclOpExecFSM& fsmState, KfcStatus state, KfcError& errorCode, uint32_t retryCnt)
    3305              : {
    3306            7 :     HCCL_INFO(
    3307              :         "UpdateOpExecStatus fsmState %d, state %d, errorCode %d, retryCnt %u.", fsmState, state, errorCode, retryCnt);
    3308            7 :     auto ret = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, state, errorCode, retryCnt);
    3309            7 :     if (ret != HCCL_SUCCESS) {
    3310            0 :         HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret);
    3311            0 :         errorCode = KfcError::kExec;
    3312            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    3313              :     }
    3314            7 :     return ret;
    3315              : }
    3316              : 
    3317              : static constexpr u32 HCCL_AICPU_WAIT_HOST_BASE_TIME_MS = 200 * 1000;
    3318              : static constexpr u32 TIME_S_TO_MS = 1000;
    3319           14 : u32 HcclCommAicpu::HcclGetWaitStopExecCmdTimeout()
    3320              : {
    3321           14 :     return std::max(static_cast<u32>(linkTimeOut_.count()), HCCL_AICPU_WAIT_HOST_BASE_TIME_MS);
    3322              : }
    3323              : 
    3324            7 : u32 HcclCommAicpu::HcclGetWaitRetryCmdTimeout(uint32_t retryCnt)
    3325              : {
    3326            7 :     if (retryCnt == 0) {
    3327            7 :         return HcclGetWaitStopExecCmdTimeout() + retryHoldTime_;
    3328              :     } else {
    3329            0 :         return HcclGetWaitStopExecCmdTimeout() + retryIntervalTime_;
    3330              :     }
    3331              : }
    3332              : 
    3333            0 : HcclResult HcclCommAicpu::HcclOpExecFsmWaitRetryProcess(
    3334              :     const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, KfcCommand& lastCmd)
    3335              : {
    3336            0 :     HCCL_DEBUG("hccl aicpu wait for retry cmd.");
    3337            0 :     KfcCommand cmd = KfcCommand::kNone;
    3338            0 :     auto ret = aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd);
    3339            0 :     if (ret != HCCL_SUCCESS) {
    3340            0 :         HCCL_ERROR("GetOpExecCtrlCmd failed, ret:%u", ret);
    3341            0 :         errorCode = KfcError::kExec;
    3342            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    3343            0 :         return ret;
    3344              :     }
    3345            0 :     if (cmd == KfcCommand::kRetry) {
    3346            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv retry cmd from host.");
    3347            0 :         dfxExtendInfo_.pollStatus = PollStatus::kDefault;
    3348            0 :         dfxExtendInfo_.cqeStatus = dfx::CqeStatus::kDefault;
    3349            0 :         ret = ResetOpRetryException(param.opType);
    3350            0 :         HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    3351              :             ret, HCCL_ERROR("reset stream buff failed, ret:%u", ret), KfcError::kInner,
    3352              :             HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    3353            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_RETRY;
    3354            0 :     } else if (cmd == KfcCommand::kChangeLink && lastCmd != KfcCommand::kChangeLink) { // 防止重复执行
    3355            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv change link cmd, identify[%s]", identifier_.c_str());
    3356            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_CHANGE_LINK;
    3357            0 :     } else if (cmd == KfcCommand::kExit) {
    3358            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu recv exit cmd from host.");
    3359            0 :         errorCode = KfcError::kExit;
    3360            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    3361            0 :     } else if (cmd == KfcCommand::kReportRetryErr) {
    3362            0 :         HCCL_RUN_INFO("[OpRetry][AICPU]hccl aicpu get report retry err cmd.");
    3363            0 :         CHK_PRT(SendTaskExceptionByMBox(TS_ERROR_RETRY_CONSTRAINT));
    3364            0 :         errorCode = KfcError::kExit;
    3365            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    3366            0 :         return HCCL_E_OPRETRY_FAIL;
    3367            0 :     } else if (cmd == KfcCommand::NsStopLaunch && endStopLaunch == false) {
    3368            0 :         HCCL_RUN_INFO("[NsRecovery][AICPU]hccl aicpu force stop in launch loop.");
    3369            0 :         endStopLaunch = true;
    3370            0 :         needsResponseStopLaunch_ = true;
    3371            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
    3372              :     } else {
    3373              :         // do nothing
    3374              :     }
    3375            0 :     lastCmd = cmd;
    3376            0 :     return HCCL_SUCCESS;
    3377              : }
    3378              : 
    3379            2 : HcclResult HcclCommAicpu::ResetOpRetryException(HcclCMDType opType)
    3380              : {
    3381            2 :     if (opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) {
    3382            0 :         CHK_RET(ResetBSRException());
    3383              :     } else {
    3384            6 :         std::vector<Stream> totalStream = {mainStream_};
    3385            2 :         totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
    3386            4 :         for (auto& stream : totalStream) {
    3387            2 :             CHK_RET(CleanStream(stream));
    3388            2 :             CHK_RET(ClearStreamCqeException(stream));
    3389              :         }
    3390            2 :     }
    3391            2 :     return HCCL_SUCCESS;
    3392            2 : }
    3393              : 
    3394            0 : HcclResult HcclCommAicpu::ResetSqBuff()
    3395              : {
    3396            0 :     CHK_RET(CleanStream(mainStream_));
    3397            0 :     for (auto& stream : slaveStreams_) {
    3398            0 :         CHK_RET(CleanStream(stream));
    3399              :     }
    3400            0 :     CHK_RET(CleanStream(orderStream_));
    3401            0 :     HCCL_INFO("reset stream sq buffer success.");
    3402            0 :     return HCCL_SUCCESS;
    3403              : }
    3404              : 
    3405            0 : HcclResult HcclCommAicpu::UpdateSqStatus(Stream& stream)
    3406              : {
    3407            0 :     HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
    3408            0 :     CHK_PTR_NULL(sqeContext);
    3409            0 :     SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    3410            0 :     CHK_PTR_NULL(sqeContextBuffer);
    3411            0 :     auto& head = sqeContextBuffer->sqHead;
    3412            0 :     auto& tail = sqeContextBuffer->sqTail;
    3413              : 
    3414            0 :     CHK_RET(QuerySqStatusByType(devId_, stream.sqId(), DRV_SQCQ_PROP_SQ_TAIL, head));
    3415            0 :     CHK_RET(QuerySqStatusByType(devId_, stream.sqId(), DRV_SQCQ_PROP_SQ_HEAD, tail));
    3416            0 :     HCCL_INFO("UpdateSqStatus, sqid:%u head:%u tail:%u.", stream.sqId(), head, tail);
    3417            0 :     return HCCL_SUCCESS;
    3418              : }
    3419              : 
    3420            0 : HcclResult HcclCommAicpu::HcclOpExecFsmRetryProcess(
    3421              :     const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    3422              :     AlgResourceResponse& algResource, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t& retryCnt,
    3423              :     uint32_t& beginSqePos, uint32_t& endSqePos)
    3424              : {
    3425            0 :     retryCnt++;
    3426            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3427            0 :         UpdateBSRRetryCnt();
    3428              :     }
    3429            0 :     HCCL_RUN_INFO("[OpRetry][AICPU]retry launch start, retryCnt:%u, tag[%s].", retryCnt, param.tag.c_str());
    3430              : 
    3431            0 :     auto ret = RetryOrchestrateHcclOp(algName, param, executor, algResource, beginSqePos, endSqePos);
    3432            0 :     if (ret == HCCL_SUCCESS) {
    3433            0 :         errorCode = KfcError::kNone;
    3434            0 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3435              :             // 是否有前一个重执行阶段积累的故障未上报,需要再次触发重执行
    3436            0 :             CHK_RET(CommitBSRStoredException(fsmState, errorCode));
    3437            0 :         } else {
    3438            0 :             CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kRuning, errorCode, retryCnt));
    3439            0 :             fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
    3440              :         }
    3441            0 :     } else if (ret == HCCL_E_SUSPENDING) {
    3442            0 :         HCCL_RUN_INFO("hccl aicpu force stop in retry launch process");
    3443            0 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3444              :             // batchsendrecv算子下发过程中出现异常,task下发未完成,send 和 recv 均需要重执行
    3445            0 :             if (bsrRetryOp_ == HCCL_SEND) {
    3446            0 :                 SetBSRSendOpExecException();
    3447              :             } else {
    3448            0 :                 SetBSRRecvOpExecException();
    3449              :             }
    3450            0 :             HCCL_RUN_INFO("hccl aicpu abort launch batchsendrecv op, need retry.");
    3451              :         }
    3452            0 :         CHK_RET(UpdateSuspendStatus(param, fsmState, errorCode, retryCnt));
    3453              :     } else {
    3454            0 :         HCCL_ERROR("RetryLaunchHcclOp failed, ret:%u", ret);
    3455            0 :         errorCode = KfcError::kInner;
    3456            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR;
    3457              :     }
    3458            0 :     return ret;
    3459              : }
    3460              : 
    3461            0 : HcclResult HcclCommAicpu::HcclOpExecFsmEndProcess(uint32_t retryCnt)
    3462              : {
    3463              :     auto ret
    3464            0 :         = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, excuteOpId_, KfcStatus::kEnd, KfcError::kNone, retryCnt);
    3465            0 :     if (!isDeviceMode_) {
    3466            0 :         isOpLaunch = false;
    3467              :     }
    3468            0 :     dfxExtendInfo_.kfcStatus = DfxKfcStatus::kOneFinished;
    3469            0 :     HCCL_DEBUG("---------- end AICPU_HcclOpExecFsmEndProcess ----------");
    3470            0 :     return ret;
    3471              : }
    3472              : 
    3473            0 : HcclResult HcclCommAicpu::PrintTaskExceptionAllThreads()
    3474              : {
    3475              :     // 非独立算子场景,跳过
    3476            0 :     CHK_PRT_RET(
    3477              :         !GetIsInitIndOp(), HCCL_RUN_INFO("[%s] IndOp group[%s] not init, skip", __func__, identifier_.c_str()),
    3478              :         HCCL_SUCCESS);
    3479              : 
    3480            0 :     for (auto& thread : threads_) {
    3481            0 :         CHK_RET(taskExecption_.PrintTaskException(*(thread->GetStream())));
    3482              :     }
    3483            0 :     return HCCL_SUCCESS;
    3484              : }
    3485              : 
    3486            0 : void HcclCommAicpu::PrintTaskExceptionAllComm()
    3487              : {
    3488            0 :     std::shared_lock<std::shared_mutex> rwlock(AicpuHcclProcess::AicpuGetCommMutex());
    3489              : 
    3490              :     // 先打印本通信域的taskException
    3491            0 :     (void)PrintTaskExceptionAllStreams();
    3492            0 :     (void)PrintTaskExceptionAllThreads();
    3493              : 
    3494              :     // 再打印其他通信域的taskException
    3495            0 :     std::vector<std::pair<std::string, hccl::HcclCommAicpu*>> aicpuCommInfo;
    3496            0 :     (void)AicpuHcclProcess::AicpuGetCommAll(aicpuCommInfo);
    3497            0 :     for (auto& commInfo : aicpuCommInfo) {
    3498            0 :         hccl::HcclCommAicpu* hcclAicpu = commInfo.second;
    3499            0 :         if (hcclAicpu == nullptr || hcclAicpu->identifier_ == identifier_) {
    3500            0 :             continue;
    3501              :         }
    3502            0 :         (void)hcclAicpu->PrintTaskExceptionAllThreads();
    3503            0 :         (void)hcclAicpu->PrintTaskExceptionAllStreams();
    3504              :     }
    3505            0 : }
    3506              : 
    3507            0 : void HcclCommAicpu::PrintAicpuCommExecStatus()
    3508              : {
    3509            0 :     std::shared_lock<std::shared_mutex> rwlock(AicpuHcclProcess::AicpuGetCommMutex());
    3510              : 
    3511              :     // 记录通信域占核情况
    3512            0 :     int64_t inExecGroupNum = 0;
    3513            0 :     int64_t aicpuCoreNum = 0;
    3514            0 :     (void)hrtHalGetDeviceInfo(devId_, MODULE_TYPE_AICPU, INFO_TYPE_CORE_NUM, &aicpuCoreNum);
    3515              : 
    3516            0 :     std::vector<std::pair<std::string, hccl::HcclCommAicpu*>> aicpuCommInfo;
    3517            0 :     (void)AicpuHcclProcess::AicpuGetCommAll(aicpuCommInfo);
    3518            0 :     for (auto& commInfo : aicpuCommInfo) {
    3519            0 :         hccl::HcclCommAicpu* hcclAicpu = commInfo.second;
    3520            0 :         if (hcclAicpu == nullptr || !hcclAicpu->GetCommInfoStatus()) {
    3521            0 :             continue;
    3522              :         }
    3523              : 
    3524              :         // 获取并打印通信域是否在执行中,以及最后一次下发的算子
    3525            0 :         bool isInExec = AicpuHcclProcess::GetCommExecStatus(hcclAicpu->identifier_);
    3526            0 :         inExecGroupNum += isInExec ? 1 : 0;
    3527            0 :         std::string execStatus = isInExec ? "inExec" : "unExec";
    3528            0 :         HCCL_RUN_INFO(
    3529              :             "AicpuComm: group[%s], status[%s], op[%s], aicpuCoreNum[%lld]", hcclAicpu->identifier_.c_str(),
    3530              :             execStatus.c_str(), hcclAicpu->GetExcuteOp().c_str(), aicpuCoreNum);
    3531            0 :     }
    3532              : 
    3533              :     // AICPU核被占满,部分通信域得不到调度,可能导致通信阻塞,打印维测信息
    3534            0 :     if (inExecGroupNum >= aicpuCoreNum && static_cast<int64_t>(aicpuCommInfo.size()) > aicpuCoreNum) {
    3535            0 :         HCCL_RUN_WARNING(
    3536              :             "In Execution group num[%lld], total group num[%u], bigger than Aicpu cores num[%lld]. "
    3537              :             "Aicpu core being fully utilized may cause tasks to get stuck, and it is necessary to reduce the num of "
    3538              :             "comm.",
    3539              :             inExecGroupNum, aicpuCommInfo.size(), aicpuCoreNum);
    3540              :     }
    3541            0 : }
    3542              : 
    3543            0 : HcclResult HcclCommAicpu::PrintTaskExceptionAllStreams()
    3544              : {
    3545              :     // 通信域资源已经释放
    3546            0 :     CHK_PRT_RET(
    3547              :         !commOpenStatus,
    3548              :         HCCL_RUN_INFO("[PrintTaskExceptionAllStreams]group[%s] has been destroyed", identifier_.c_str()), HCCL_SUCCESS);
    3549            0 :     CHK_RET(UtraceInfo_->Flush());
    3550            0 :     std::vector<Stream> totalStream = {mainStream_};
    3551              :     HcclResult ret;
    3552            0 :     totalStream.insert(totalStream.end(), slaveStreams_.begin(), slaveStreams_.end());
    3553            0 :     for (auto& stream : totalStream) {
    3554            0 :         HCCL_RUN_INFO("[PrintTaskExceptionAllStreams]group[%s] streamid[%d] print", identifier_.c_str(), stream.id());
    3555            0 :         u32 sqHead = 0U;
    3556            0 :         u32 sqTail = 0U;
    3557            0 :         ret = QuerySqStatus(devId_, stream.sqId(), sqHead, sqTail);
    3558            0 :         if (ret != HCCL_SUCCESS || sqHead == sqTail) { // 此流为空时,不打印
    3559            0 :             HCCL_RUN_INFO(
    3560              :                 "[PrintTaskExceptionAllStreams] group[%s] streamid[%d] is empty"
    3561              :                 "or QuerySqStatus failed, ret[%d]",
    3562              :                 identifier_.c_str(), stream.id(), ret);
    3563            0 :             continue;
    3564              :         }
    3565            0 :         HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
    3566            0 :         SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    3567            0 :         CHK_PTR_NULL(sqeContextBuffer);
    3568            0 :         if (stream.id() == mainStream_.id()) {
    3569            0 :             SqeInfo sqeInfo;
    3570            0 :             ret = SqeContextUtils::QuerySqeInfo(
    3571            0 :                 sqeContextBuffer->rtsMirrorBuffer + sqHead * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[sqHead],
    3572              :                 sqeContextBuffer->addInfo[sqHead], &sqeInfo);
    3573            0 :             if (ret != HCCL_SUCCESS) {
    3574            0 :                 HCCL_ERROR("[%s]QuerySqeInfo failed, ret[%d]", __func__, ret);
    3575              :             } else {
    3576              :                 // 根据主流卡在host notify上,则说明未被执行到不打印
    3577            0 :                 if (sqeInfo.type == RT_STARS_SQE_TYPE_NOTIFY_WAIT && sqeInfo.notifyId == opNotifies_[0]->notifyId_) {
    3578            0 :                     HCCL_RUN_INFO(
    3579              :                         "[PrintTaskExceptionAllStreams] group[%s] op is not activated, do nothing",
    3580              :                         identifier_.c_str());
    3581            0 :                     return HCCL_SUCCESS;
    3582              :                 }
    3583              :                 // 根据主流当前位置,判断该算子是否已经打印过taskException
    3584            0 :                 if (IsRepeatedOpTaskException(sqHead, sqeContextBuffer)) {
    3585            0 :                     HCCL_INFO(
    3586              :                         "[PrintTaskExceptionAllStreams] group[%s] op has been printed, do nothing",
    3587              :                         identifier_.c_str());
    3588            0 :                     return HCCL_SUCCESS;
    3589              :                 }
    3590              :             }
    3591              :         }
    3592              : 
    3593            0 :         uint8_t type = 0;
    3594            0 :         uint16_t taskId = 0;
    3595            0 :         uint32_t remoteRank = 0;
    3596            0 :         HCCL_ERROR(
    3597              :             "[TaskException]base information is streamId:%d, sqid:%d, head:%u, tail:%u, %s", stream.id(), stream.sqId(),
    3598              :             sqHead, sqTail, GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskId, remoteRank).c_str());
    3599            0 :         PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer);
    3600              :     }
    3601            0 :     return HCCL_SUCCESS;
    3602            0 : }
    3603              : 
    3604            0 : bool HcclCommAicpu::IsRepeatedOpTaskException(u32 idx, SqeRingBuffer* sqeContextBuffer)
    3605              : {
    3606            0 :     const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[idx].opRingBufferIdx);
    3607            0 :     CHK_PRT_RET(opInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), false);
    3608            0 :     std::string opTag = opInfo->tagBuff;
    3609            0 :     u32 opIndex = opInfo->opIndex;
    3610            0 :     bool opHasPrinted = opTaskException_.find(opTag) != opTaskException_.end() && opTaskException_[opTag] == opIndex;
    3611            0 :     opTaskException_[opTag] = opIndex;
    3612            0 :     CHK_PRT_CONT(
    3613              :         opHasPrinted, HCCL_RUN_INFO(
    3614              :                           "[IsRepeatedOpTaskException]group[%s], op[%s], opIndex[%u] "
    3615              :                           "has been printed",
    3616              :                           identifier_.c_str(), opInfo->tagBuff, opInfo->opIndex));
    3617            0 :     return opHasPrinted;
    3618            0 : }
    3619              : 
    3620            0 : void HcclCommAicpu::PrepareMc2Handler()
    3621              : {
    3622            0 :     auto& handler = algOpContext_.mc2Handler;
    3623            0 :     handler.stepSize = 0U;
    3624            0 :     if (!isDeviceMode_) {
    3625            0 :         HCCL_INFO("Unset step size for non-MC2.");
    3626            0 :         return;
    3627              :     }
    3628            0 :     (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetStepSize, {rpc_, reinterpret_cast<u64>(&handler), GetRankSize()});
    3629              : }
    3630              : 
    3631            0 : HcclResult HcclCommAicpu::OrchestrateHcclOp(
    3632              :     const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    3633              :     AlgResourceResponse& algResource, uint32_t& beginSqePos, uint32_t& endSqePos)
    3634              : {
    3635            0 :     LogControl logControl(false, false); // 重执行ERROR日志控制,析构时重置日志设置
    3636            0 :     PrepareMc2Handler();
    3637            0 :     HcclResult ret = HCCL_SUCCESS;
    3638              :     // task的尾指针,已便重执行stop时判断是否已执行该task,如果该task已执行完成则可支持通信重执行
    3639            0 :     CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, beginSqePos));
    3640              : 
    3641            0 :     const bool retryForBatchSndRcv = (param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV && retryEnable_);
    3642            0 :     if (retryForBatchSndRcv) {
    3643            0 :         CHK_RET(QueryBatchSendRecvPairBeginPos());
    3644            0 :         if (param.BatchSendRecvDataDes.curIterNum == 0) {
    3645              :             // batchsendrecv算子拆分为多轮执行,只有第一个step和最后一个step需要和主stream交互
    3646            0 :             CHK_RET(NotifyWait());
    3647              :         }
    3648            0 :         HCCL_INFO(
    3649              :             "batch send recv op: step %u, mode:%u", param.BatchSendRecvDataDes.curIterNum,
    3650              :             param.BatchSendRecvDataDes.curMode);
    3651              :     } else {
    3652            0 :         CHK_RET(NotifyWait());
    3653              :         // 重执行场景, 算子计数在host侧; MC2场景也不开启卡住检测能力
    3654            0 :         if (opCounterInfo_.isEnableCounter && !retryEnable_ && !isDeviceMode_) {
    3655            0 :             CHK_RET(HcclReduceAsync(
    3656              :                 dispatcher_, reinterpret_cast<void*>(opCounterInfo_.addOneMem),
    3657              :                 opCounterInfo_.memSize / sizeof(int32_t), HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM, mainStream_,
    3658              :                 reinterpret_cast<void*>(opCounterInfo_.headCountMem), INVALID_VALUE_RANKID, LinkType::LINK_ONCHIP,
    3659              :                 INLINE_REDUCE_BIT));
    3660              :         }
    3661              :     }
    3662              : 
    3663              :     // 打印当前展开的算子信息
    3664            0 :     HCCL_INFO(
    3665              :         "[HcclCommAicpu][OrchestrateHcclOp] opUnfoldIdx_[%u] opType[%d] curRank[%u] rankSize[%u] algName[%s]",
    3666              :         opUnfoldIdx_, param.opType, topoInfo_.userRank, GetRankSize(), algName.c_str());
    3667            0 :     HCCL_INFO(
    3668              :         "[HcclCommAicpu][OrchestrateHcclOp] inputPtr[0x%016llx] inputSize[%llu] outputPtr[0x%016llx] outputSize[%llu]",
    3669              :         param.inputPtr, param.inputSize, param.outputPtr, param.outputSize);
    3670            0 :     opUnfoldIdx_ += 1;
    3671              : 
    3672              :     // 检查算子展开的动态缓存, 确认是否可以跳过算子展开
    3673            0 :     bool needExecute = true;
    3674            0 :     bool isCacheMiss = false;
    3675            0 :     auto setProfStartCallback = [this]() {
    3676            0 :         return this->InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeStart, {});
    3677            0 :     };
    3678            0 :     CHK_RET(aicpuCacheManager_.LookupOpUnfoldCache(
    3679              :         algName, param, algResource, needExecute, isCacheMiss, mainStream_, slaveStreams_, dispatcher_, isDeviceMode_,
    3680              :         topoInfo_, topoMatcher_, algOpContext_, ZeroCopyExchanger_, GetWorkflowMode(), tinySendRecvMem_,
    3681              :         setProfStartCallback));
    3682              : 
    3683              :     // 根据needExecute有条件的执行算子展开
    3684              :     // 需要算子执行的场景: (i) expansion mode为AI_CPU_NO_CACHE; (ii) uncacheable算子/场景; (iii) cache miss
    3685            0 :     if (needExecute) {
    3686              :         // Cache miss前执行cache相关的预处理
    3687            0 :         if (isCacheMiss) {
    3688            0 :             CHK_RET(aicpuCacheManager_.PreProcessForCacheMiss(param, executor));
    3689              :         }
    3690              : 
    3691              :         // executor设置AlgOpContext
    3692            0 :         CHK_RET(executor->SetAlgOpContext(algOpContext_));
    3693            0 :         (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeStart, {});
    3694            0 :         ret = executor->Orchestrate(param, algResource);
    3695            0 :         if (ret != HCCL_SUCCESS) {
    3696            0 :             HCCL_ERROR(
    3697              :                 "[HcclCommAicpu][Orchestrate]executor process failed algName[%s], ret = %u", algName.c_str(), ret);
    3698            0 :             printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
    3699            0 :             return ret;
    3700              :         }
    3701              : 
    3702              :         // Cache miss后执行cache相关的后处理
    3703            0 :         if (isCacheMiss) {
    3704            0 :             CHK_RET(aicpuCacheManager_.PostProcessForCacheMiss(
    3705              :                 param, executor, mainStream_, slaveStreams_, dispatcher_, topoInfo_, algOpContext_, GetWorkflowMode()));
    3706              :         }
    3707              :     } // 正常算子展开
    3708              : 
    3709              :     // batchsendrecv算子拆分为多轮执行,只有第一个step和最后一个step需要和主stream交互
    3710            0 :     if (!retryForBatchSndRcv || param.BatchSendRecvDataDes.curIterNum + 1 >= bsrSendRecvPairs_.size()) {
    3711              :         // 重执行场景, 算子计数在host侧 MC2场景也不开
    3712            0 :         if (opCounterInfo_.isEnableCounter && !retryEnable_ && !isDeviceMode_) {
    3713            0 :             CHK_RET(HcclReduceAsync(
    3714              :                 dispatcher_, reinterpret_cast<void*>(opCounterInfo_.addOneMem),
    3715              :                 opCounterInfo_.memSize / sizeof(int32_t), HCCL_DATA_TYPE_INT32, HCCL_REDUCE_SUM, mainStream_,
    3716              :                 reinterpret_cast<void*>(opCounterInfo_.tailCountMem), INVALID_VALUE_RANKID, LinkType::LINK_ONCHIP,
    3717              :                 INLINE_REDUCE_BIT));
    3718              :         }
    3719            0 :         CHK_RET(NotifyPost());
    3720              :     }
    3721            0 :     (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeOrch, {});
    3722            0 :     ret = LaunchTask(dispatcher_, const_cast<Stream&>(mainStream_));
    3723            0 :     if (ret != HCCL_SUCCESS) {
    3724            0 :         HCCL_ERROR("[HcclCommAicpu][LaunchTask]algName[%s] ret = %u", algName.c_str(), ret);
    3725            0 :         printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
    3726            0 :         return ret;
    3727              :     }
    3728            0 :     ret = LaunchSlaveStreamTask(algResource);
    3729            0 :     if (ret != HCCL_SUCCESS) {
    3730            0 :         HCCL_ERROR("[HcclCommAicpu][LaunchSlaveStreamTask]algName[%s] ret = %u", algName.c_str(), ret);
    3731            0 :         printTaskExceptionForErr_ |= (ret == HCCL_E_AGAIN);
    3732            0 :         return ret;
    3733              :     }
    3734            0 :     (void)InvokeKfcHandler(AicpuKfcHandlerType::kSetProfTimeEnd, {});
    3735            0 :     if (retryForBatchSndRcv) {
    3736            0 :         CHK_RET(QueryBatchSendRecvPairEndPos());
    3737              :     }
    3738              : 
    3739            0 :     CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, endSqePos));
    3740              : 
    3741            0 :     HCCL_INFO(
    3742              :         "hccl aicpu launch hccl op task success. stream sqid:%u begin:%u end:%u", mainStream_.sqId(), beginSqePos,
    3743              :         endSqePos);
    3744            0 :     return HCCL_SUCCESS;
    3745            0 : }
    3746              : 
    3747            0 : HcclResult HcclCommAicpu::RetryOrchestrateHcclOp(
    3748              :     const std::string& algName, OpParam& param, std::unique_ptr<CollExecutorBase>& executor,
    3749              :     AlgResourceResponse& algResource, uint32_t& beginSqePos, uint32_t& endSqePos)
    3750              : {
    3751            0 :     LogControl logControl(false, false); // 重执行ERROR日志控制,析构时重置日志设置
    3752            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3753              :         param.BatchSendRecvDataDes.curMode
    3754            0 :             = (bsrRetryOp_ == HCCL_SEND) ? BatchSendRecvCurMode::SEND : BatchSendRecvCurMode::RECV;
    3755            0 :         if (param.BatchSendRecvDataDes.curMode == BatchSendRecvCurMode::SEND) {
    3756            0 :             HCCL_INFO(
    3757              :                 "BSR: iter %u, retry send op tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrSendOpId_.tag,
    3758              :                 bsrSendOpId_.index);
    3759              :         } else {
    3760            0 :             HCCL_INFO(
    3761              :                 "BSR: iter %u, retry recv op tag:%s index:%u", param.BatchSendRecvDataDes.curIterNum, bsrRecvOpId_.tag,
    3762              :                 bsrRecvOpId_.index);
    3763              :         }
    3764              :     }
    3765              : 
    3766            0 :     CHK_RET(AddRetryExecFlipTask(algResource));
    3767            0 :     HcclResult ret = executor->Orchestrate(param, algResource);
    3768            0 :     if (ret != HCCL_SUCCESS) {
    3769            0 :         HCCL_ERROR("[HcclCommAicpu][Orchestrate]executor process failed algName[%s]", algName.c_str());
    3770            0 :         return ret;
    3771              :     }
    3772              : 
    3773            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3774              :         // batchsendrecv算子重执行时,aicpu 主stream没有clean,不需要重新下发notify record
    3775              :         // do nothing
    3776              :     } else {
    3777            0 :         CHK_RET(NotifyPost());
    3778              :     }
    3779            0 :     CHK_RET(LaunchTask(dispatcher_, const_cast<Stream&>(mainStream_)));
    3780            0 :     CHK_RET(LaunchSlaveStreamTask(algResource));
    3781              : 
    3782            0 :     CHK_RET(QuerySqStatusByType(devId_, mainStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, endSqePos));
    3783            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    3784            0 :         CHK_RET(QueryBatchSendRecvPairEndPos());
    3785              :     }
    3786              : 
    3787            0 :     HCCL_RUN_INFO(
    3788              :         "[OpRetry][AICPU]hccl aicpu retry launch hccl op task success. stream sqid:%u begin:%u end:%u",
    3789              :         mainStream_.sqId(), beginSqePos, endSqePos);
    3790            0 :     return HCCL_SUCCESS;
    3791            0 : }
    3792              : 
    3793            4 : bool HcclCommAicpu::IsTaskExceptionForHccs()
    3794              : {
    3795            4 :     if (dfxExtendInfo_.cqeStatus != dfx::CqeStatus::kCqeException) {
    3796            4 :         return false;
    3797              :     }
    3798              : 
    3799              :     // NOTE: 需要task exception补全dfx能力,定位故障task的remote rank;
    3800              :     // 目前暂不具备识别是否跨片的能力,默认失败的task均为跨片操作。
    3801            0 :     if (dfxExtendInfo_.cqeException.sqeType == RT_STARS_SQE_TYPE_SDMA
    3802            0 :         && (dfxExtendInfo_.cqeException.errorCode == RT_SDMA_COMPDATAERR
    3803            0 :             || dfxExtendInfo_.cqeException.errorCode == RT_SDMA_COMPERR)) {
    3804            0 :         return true;
    3805              :     }
    3806            0 :     return false;
    3807              : }
    3808              : 
    3809            5 : void HcclCommAicpu::SetAlgType(u64 algType)
    3810              : {
    3811            5 :     algType_.algoLevel0 = static_cast<AlgTypeLevel0>(static_cast<u32>(algType) & ((1 << HCCL_LEVEL_ALGO_WIDTH) - 1));
    3812            5 :     algType_.algoLevel1 = static_cast<AlgTypeLevel1>(
    3813            5 :         (static_cast<u32>(algType) >> HCCL_LEVEL_ALGO_WIDTH) & ((1 << HCCL_LEVEL_ALGO_WIDTH) - 1));
    3814              :     algType_.algoLevel2
    3815            5 :         = static_cast<AlgTypeLevel2>(static_cast<u32>(algType) >> (HCCL_LEVEL_ALGO_WIDTH + HCCL_LEVEL_ALGO_WIDTH));
    3816            5 :     HCCL_INFO("[HcclCommAicpu][SetAlgType]algType:%u", algType);
    3817            5 : }
    3818              : 
    3819            2 : void HcclCommAicpu::SetDebugMode(u8 debugMode) { debugMode_ = debugMode; }
    3820              : 
    3821            0 : void HcclCommAicpu::SetSendRecvInfoPtr(void* sendRecvInfoPtr) { sendRecvInfoPtr_ = sendRecvInfoPtr; }
    3822              : 
    3823            4 : bool HcclCommAicpu::IsNoNeedWait(void)
    3824              : {
    3825            4 :     return isDeviceMode_ || (debugMode_ != MC2_DEBUG_WAIT_COMM && retryEnable_ == false);
    3826              : }
    3827              : 
    3828           45 : bool HcclCommAicpu::GetOpRetryEnable() { return retryEnable_; }
    3829              : 
    3830            4 : HcclResult HcclCommAicpu::ReportHcclTaskInfo(Stream& mainStream, std::vector<Stream>& subStreams)
    3831              : {
    3832            4 :     if (dfx::ProfilingManager::GetProfL1State()) {
    3833            0 :         CHK_RET(dfx::ProfilingManager::ReportTaskInfo(mainStream.id(), mainStream.GetSqeContextPtr()));
    3834            0 :         for (auto& subStream : subStreams) {
    3835            0 :             CHK_RET(dfx::ProfilingManager::ReportTaskInfo(subStream.id(), subStream.GetSqeContextPtr()));
    3836              :         }
    3837              :     }
    3838            4 :     return HCCL_SUCCESS;
    3839              : }
    3840              : 
    3841            4 : HcclResult HcclCommAicpu::ClearLocalBuff(Stream& mainStream, std::vector<Stream>& subStreams)
    3842              : {
    3843            4 :     CHK_RET(mainStream.ClearLocalBuff());
    3844            4 :     CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(mainStream.id(), 0));
    3845            4 :     for (auto& subStream : subStreams) {
    3846            0 :         CHK_RET(subStream.ClearLocalBuff());
    3847            0 :         CHK_RET(dfx::ProfilingManager::UpdateStartReportSqeIdx(subStream.id(), 0));
    3848              :     }
    3849            4 :     return HCCL_SUCCESS;
    3850              : }
    3851              : 
    3852            4 : HcclResult HcclCommAicpu::WaitFinishWhileLoop(
    3853              :     Stream& mainStream, std::vector<Stream>& subStreams, std::string& tag, const uint32_t& beginSqePos, OpParam& param)
    3854              : {
    3855              :     // 上报Profiling HCCL INFO信息
    3856            4 :     CHK_RET(ReportHcclTaskInfo(mainStream, subStreams));
    3857            4 :     CHK_RET(ClearLocalBuff(mainStream, subStreams));
    3858            4 :     if (IsNoNeedWait()) {
    3859            0 :         return HCCL_SUCCESS;
    3860              :     }
    3861            4 :     const uint64_t startUsec = GetCurCpuTimestamp();
    3862            4 :     uint64_t lastUsec = startUsec;
    3863            4 :     int32_t sqId = mainStream.sqId();
    3864            4 :     uint32_t sqHead = 0;
    3865            4 :     uint32_t sqTail = 0;
    3866            4 :     CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_TAIL, sqTail));
    3867            4 :     CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_HEAD, sqHead));
    3868            4 :     while (sqHead != sqTail) {
    3869            4 :         HcclResult ret = CheckOpExecStatus(); // 检查执行状态,判断是否有异常cq或中断命令
    3870            4 :         CHK_PRT_RET(
    3871              :             ret != HCCL_SUCCESS,
    3872              :             HCCL_RUN_INFO("[HcclCommAicpu][WaitFinishWhileLoop]CheckOpExecStatus exception, ret[%u]", ret), ret);
    3873              : 
    3874            0 :         CHK_RET(QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_HEAD, sqHead));
    3875            0 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && (retryEnable_) && (sqHead != beginSqePos)
    3876            0 :             && (!excuteOpId_.isBsrTaskStart)) {
    3877              :             // 更新D2H通道里的信息opid中isBsrTaskStart = true
    3878            0 :             excuteOpId_.isBsrTaskStart = true;
    3879              :             HcclResult ret1
    3880            0 :                 = aicpuHdc_.SetOpExecStatus(kfcStatusTransferD2H_, excuteOpId_, KfcStatus::kRuning, KfcError::kNone, 0);
    3881            0 :             CHK_PRT_RET(ret1 != HCCL_SUCCESS, HCCL_ERROR("update OpExecStatus failed, ret:%u", ret1), ret1);
    3882            0 :             HCCL_INFO(
    3883              :                 "[HcclCommAicpu][WaitFinishWhileLoop]bsr start task is completed. devId:%d sqid:%d, head:%u,"
    3884              :                 "beginSqePos[%u] group[%s] tag[%s]",
    3885              :                 devId_, sqId, sqHead, beginSqePos, identifier_.c_str(), tag.c_str());
    3886              :         }
    3887            0 :         uint64_t curUsec = GetCurCpuTimestamp();
    3888            0 :         if (curUsec - lastUsec > static_cast<uint64_t>(NSEC_PER_SEC) * dfx::kPrintSqInterval) {
    3889            0 :             lastUsec = curUsec;
    3890            0 :             HCCL_RUN_INFO(
    3891              :                 "[HcclCommAicpu][WaitFinishWhileLoop]Current state. devId:%d sqid:%d, head:%u, tail:%u, "
    3892              :                 "group[%s] tag[%s]",
    3893              :                 devId_, sqId, sqHead, sqTail, identifier_.c_str(), tag.c_str());
    3894              :         }
    3895            0 :         CHK_RET(CheckTaskTimeout(mainStream, startUsec));
    3896              :     }
    3897            0 :     return HCCL_SUCCESS;
    3898              : }
    3899              : 
    3900            0 : HcclResult HcclCommAicpu::CheckTaskTimeout(const Stream& mainStream, const uint64_t startUsec)
    3901              : {
    3902            0 :     if (sqeWaitTimeOut_ != 0
    3903            0 :         && (GetCurCpuTimestamp() - startUsec > static_cast<uint64_t>(NSEC_PER_SEC) * sqeWaitTimeOut_)) {
    3904            0 :         uint32_t status = 0U;
    3905            0 :         int32_t sqId = mainStream.sqId();
    3906            0 :         auto ret = QuerySqStatusByType(devId_, sqId, DRV_SQCQ_PROP_SQ_CQE_STATUS, status);
    3907            0 :         if (ret != 0) {
    3908            0 :             HCCL_ERROR("[HcclCommAicpu]QuerySqStatusByType status failed. ret = %u sqid:%d", ret, sqId);
    3909              :         }
    3910              : 
    3911            0 :         HCCL_ERROR("[HcclCommAicpu]KFC timeout.. group[%s].", identifier_.c_str());
    3912            0 :         printTaskExceptionForErr_ = true;
    3913            0 :         return HCCL_E_TIMEOUT;
    3914              :     }
    3915            0 :     return HCCL_SUCCESS;
    3916              : }
    3917              : 
    3918            0 : HcclResult HcclCommAicpu::AddRetryExecFlipTask(AlgResourceResponse& algResource)
    3919              : {
    3920            0 :     CHK_RET(AddRetryPreamble(dispatcher_, mainStream_));
    3921            0 :     for (u32 i = 0; i < algResource.slaveStreams.size(); ++i) {
    3922            0 :         HcclResult ret = AddRetryPreamble(dispatcher_, algResource.slaveStreams[i]);
    3923            0 :         if (ret != HCCL_SUCCESS) {
    3924            0 :             HCCL_ERROR(
    3925              :                 "[HcclCommAicpu][RetryOrchestrateHcclOp] launch place holder failed, sqid:%u, ret:%u",
    3926              :                 algResource.slaveStreams[i].sqId(), ret);
    3927            0 :             return ret;
    3928              :         }
    3929              :     }
    3930            0 :     return HCCL_SUCCESS;
    3931              : }
    3932              : 
    3933            2 : HcclResult HcclCommAicpu::LaunchSlaveStreamTask(AlgResourceResponse& algResource)
    3934              : {
    3935              :     // 单算子模式中在算法编排中已经执行过LaunchTask,所以这里不需要再执行
    3936              :     // 只有图模式需要再额外执行一次对从流中的task下发
    3937            2 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
    3938            1 :         HCCL_INFO("[HcclCommAicpu][LaunchSlaveStreamTask] op base mode don't need launch slave stream task");
    3939            1 :         return HCCL_SUCCESS;
    3940              :     }
    3941              : 
    3942            1 :     for (u32 i = 0; i < algResource.slaveStreams.size(); ++i) {
    3943            0 :         HcclResult ret = LaunchTask(dispatcher_, algResource.slaveStreams[i]);
    3944            0 :         if (ret != HCCL_SUCCESS) {
    3945            0 :             HCCL_ERROR(
    3946              :                 "[HcclCommAicpu][LaunchSlaveStreamTask] launch task failed, sqid:%u, ret:%u",
    3947              :                 algResource.slaveStreams[i].sqId(), ret);
    3948            0 :             return ret;
    3949              :         }
    3950              :     }
    3951              : 
    3952            1 :     return HCCL_SUCCESS;
    3953              : }
    3954              : 
    3955              : HcclResult
    3956            0 : HcclCommAicpu::GetAlltoAllvSendRecvInfo(const void* sendRecvInfoPtr, HcclDataType sendType, HcclDataType recvType)
    3957              : {
    3958            0 :     allMeshAggregationSendRecvInfo_.clear();
    3959            0 :     u64 stepSize = sizeof(u64) * topoInfo_.userRankSize;
    3960            0 :     const u32 addrItemNum = 4;
    3961            0 :     const u32 recvLengthStep = 2;
    3962            0 :     const u32 recvOffsetStep = 3;
    3963            0 :     for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
    3964            0 :         SendRecvInfo sendRecvInfo;
    3965            0 :         sendRecvInfo.sendLength.resize(topoInfo_.userRankSize);
    3966            0 :         sendRecvInfo.sendOffset.resize(topoInfo_.userRankSize);
    3967            0 :         sendRecvInfo.recvLength.resize(topoInfo_.userRankSize);
    3968            0 :         sendRecvInfo.recvOffset.resize(topoInfo_.userRankSize);
    3969            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(
    3970              :             sendRecvInfo.sendLength.data(), stepSize,
    3971              :             static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + 0 * stepSize, stepSize));
    3972            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(
    3973              :             sendRecvInfo.sendOffset.data(), stepSize,
    3974              :             static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + stepSize, stepSize));
    3975            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(
    3976              :             sendRecvInfo.recvLength.data(), stepSize,
    3977              :             static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + recvLengthStep * stepSize,
    3978              :             stepSize));
    3979            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(
    3980              :             sendRecvInfo.recvOffset.data(), stepSize,
    3981              :             static_cast<const u8*>(sendRecvInfoPtr) + i * stepSize * addrItemNum + recvOffsetStep * stepSize,
    3982              :             stepSize));
    3983            0 :         allMeshAggregationSendRecvInfo_.push_back(std::move(sendRecvInfo));
    3984            0 :     }
    3985              : 
    3986            0 :     for (auto& sendRecvInfo : allMeshAggregationSendRecvInfo_) {
    3987            0 :         for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
    3988            0 :             sendRecvInfo.sendCounts.push_back(sendRecvInfo.sendLength[i] / SIZE_TABLE[sendType]);
    3989            0 :             sendRecvInfo.sendDispls.push_back(sendRecvInfo.sendOffset[i] / SIZE_TABLE[sendType]);
    3990            0 :             sendRecvInfo.recvCounts.push_back(sendRecvInfo.recvLength[i] / SIZE_TABLE[recvType]);
    3991            0 :             sendRecvInfo.recvDispls.push_back(sendRecvInfo.recvOffset[i] / SIZE_TABLE[recvType]);
    3992            0 :             HCCL_INFO(
    3993              :                 "[GetAlltoAllvSendRecvInfo] rank[%u], sendCounts[%llu], sendDispls[%llu], "
    3994              :                 "recvCounts[%llu], recvDispls[%llu]",
    3995              :                 i, sendRecvInfo.sendCounts[i], sendRecvInfo.sendDispls[i], sendRecvInfo.recvCounts[i],
    3996              :                 sendRecvInfo.recvDispls[i]);
    3997            0 :             HCCL_INFO(
    3998              :                 "[GetAlltoAllvSendRecvInfo] rank[%u], sendLength[%llu], sendOffset[%llu], "
    3999              :                 "recvLength[%llu], recvOffset[%llu]",
    4000              :                 i, sendRecvInfo.sendLength[i], sendRecvInfo.sendOffset[i], sendRecvInfo.recvLength[i],
    4001              :                 sendRecvInfo.recvOffset[i]);
    4002              :         }
    4003              :     }
    4004            0 :     CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
    4005            0 :     return HCCL_SUCCESS;
    4006              : }
    4007              : 
    4008              : HcclResult
    4009            0 : HcclCommAicpu::GetAlltoAllvcSendRecvInfo(const void* sendCountMatrix, HcclDataType sendType, HcclDataType recvType)
    4010              : {
    4011            0 :     allMeshAggregationSendRecvInfo_.clear();
    4012            0 :     for (u32 i = 0; i < topoInfo_.userRankSize; i++) {
    4013            0 :         SendRecvInfo sendRecvInfo;
    4014            0 :         sendRecvInfo.sendCounts.resize(topoInfo_.userRankSize);
    4015            0 :         sendRecvInfo.sendDispls.resize(topoInfo_.userRankSize);
    4016            0 :         sendRecvInfo.sendLength.resize(topoInfo_.userRankSize);
    4017            0 :         sendRecvInfo.sendOffset.resize(topoInfo_.userRankSize);
    4018            0 :         u64 curSendDispls = 0;
    4019            0 :         u64 curSendOffset = 0;
    4020            0 :         sendRecvInfo.recvCounts.resize(topoInfo_.userRankSize);
    4021            0 :         sendRecvInfo.recvDispls.resize(topoInfo_.userRankSize);
    4022            0 :         sendRecvInfo.recvLength.resize(topoInfo_.userRankSize);
    4023            0 :         sendRecvInfo.recvOffset.resize(topoInfo_.userRankSize);
    4024            0 :         u64 curRecvDispls = 0;
    4025            0 :         u64 curRecvOffset = 0;
    4026            0 :         for (u32 j = 0; j < topoInfo_.userRankSize; j++) {
    4027            0 :             u64 curSendCounts = *(static_cast<const u64*>(sendCountMatrix) + i * topoInfo_.userRankSize + j);
    4028            0 :             u64 curSendLength = curSendCounts * SIZE_TABLE[sendType];
    4029            0 :             sendRecvInfo.sendCounts[j] = curSendCounts;
    4030            0 :             sendRecvInfo.sendDispls[j] = curSendDispls;
    4031            0 :             sendRecvInfo.sendLength[j] = curSendLength;
    4032            0 :             sendRecvInfo.sendOffset[j] = curSendOffset;
    4033            0 :             curSendDispls += curSendCounts;
    4034            0 :             curSendOffset += curSendLength;
    4035            0 :             u64 curRecvCounts = *(static_cast<const u64*>(sendCountMatrix) + i + topoInfo_.userRankSize * j);
    4036            0 :             u64 curRecvLength = curRecvCounts * SIZE_TABLE[recvType];
    4037            0 :             sendRecvInfo.recvCounts[j] = curRecvCounts;
    4038            0 :             sendRecvInfo.recvDispls[j] = curRecvDispls;
    4039            0 :             sendRecvInfo.recvLength[j] = curRecvLength;
    4040            0 :             sendRecvInfo.recvOffset[j] = curRecvOffset;
    4041            0 :             curRecvDispls += curRecvCounts;
    4042            0 :             curRecvOffset += curRecvLength;
    4043            0 :             HCCL_DEBUG(
    4044              :                 "GetAlltoAllvcSendRecvInfo rank[%u], sendCounts[%llu], sendDispls[%llu] "
    4045              :                 "recvCounts[%llu], recvDispls[%llu]",
    4046              :                 i, sendRecvInfo.sendCounts[j], sendRecvInfo.sendDispls[j], sendRecvInfo.recvCounts[j],
    4047              :                 sendRecvInfo.recvDispls[j]);
    4048              :         }
    4049            0 :         allMeshAggregationSendRecvInfo_.push_back(sendRecvInfo);
    4050            0 :     }
    4051            0 :     CHK_RET(CheckSendRecvParams(allMeshAggregationSendRecvInfo_));
    4052            0 :     return HCCL_SUCCESS;
    4053              : }
    4054              : 
    4055            0 : HcclResult HcclCommAicpu::CheckSendRecvParams(const std::vector<SendRecvInfo>& allMeshAggregationSendRecvInfo)
    4056              : {
    4057            0 :     u32 rankSize = allMeshAggregationSendRecvInfo.size();
    4058            0 :     for (u32 i = 0; i < rankSize; i++) {
    4059            0 :         u32 sendsSize = allMeshAggregationSendRecvInfo[i].sendLength.size();
    4060            0 :         u32 recvsSize = allMeshAggregationSendRecvInfo[i].recvLength.size();
    4061            0 :         if (rankSize != sendsSize || rankSize != recvsSize) {
    4062            0 :             HCCL_ERROR(
    4063              :                 "[AlltoAllV][CheckSendRecvParam] rankSize[%u], sendsSize[%u], recvsSize[%u] are not match Index[%u]",
    4064              :                 rankSize, sendsSize, recvsSize, i);
    4065            0 :             return HCCL_E_PARA;
    4066              :         }
    4067            0 :         for (u32 j = 0; j < sendsSize; j++) {
    4068            0 :             if (allMeshAggregationSendRecvInfo[i].sendLength[j] != allMeshAggregationSendRecvInfo[j].recvLength[i]) {
    4069            0 :                 HCCL_ERROR(
    4070              :                     "SendLength[%u][%u]: %llu and recvLength[%u][%u]: %llu are not match", i, j,
    4071              :                     allMeshAggregationSendRecvInfo[i].sendLength[j], j, i,
    4072              :                     allMeshAggregationSendRecvInfo[j].recvLength[i]);
    4073            0 :                 return HCCL_E_PARA;
    4074              :             }
    4075              :         }
    4076              :     }
    4077            0 :     return HCCL_SUCCESS;
    4078              : }
    4079            0 : HcclResult HcclCommAicpu::GetStreamAll(std::vector<Stream>& streams)
    4080              : {
    4081            0 :     streams.assign(slaveStreams_.begin(), slaveStreams_.end());
    4082            0 :     streams.push_back(mainStream_);
    4083            0 :     return HCCL_SUCCESS;
    4084              : }
    4085              : 
    4086              : // 校验是否有ERROR CQE和停止/退出命令,注册到dispatcher层调用
    4087            0 : HcclResult HcclCommAicpu::CheckOpExecStatusCallback()
    4088              : {
    4089            0 :     HcclResult ret = CheckOpExecStatus();
    4090            0 :     bool logLevel = (ret == HCCL_E_SUSPENDING);
    4091              :     // 返回HCCL_E_SUSPENDING时,需要跨作用域修改ERROR日志->RUN_WARNING
    4092            0 :     LogControl(logLevel, logLevel);
    4093            0 :     return ret;
    4094              : }
    4095              : 
    4096            4 : HcclResult HcclCommAicpu::CheckOpExecStatus()
    4097              : {
    4098              :     // 检测是否有ERROR CQE
    4099            4 :     if (dfxExtendInfo_.pollStatus == PollStatus::kStopAsException) {
    4100            0 :         if (IsTaskExceptionForHccs() && retryEnable_) {
    4101            0 :             HCCL_RUN_INFO(
    4102              :                 "[OpRetry][AICPU]hccl aicpu stop wait task exec finish, for task exception, identify[%s]",
    4103              :                 identifier_.c_str());
    4104            0 :             return HCCL_E_SUSPENDING;
    4105              :         } else {
    4106            0 :             if (!printTaskExceptionForErr_) {
    4107            0 :                 printTaskExceptionForErr_ = true;
    4108            0 :                 HCCL_ERROR(
    4109              :                     "hccl aicpu exec failed, for task exception, identify[%s], cqeStatus[%d], sqeType[%u], "
    4110              :                     "errorCode[%u]",
    4111              :                     identifier_.c_str(), dfxExtendInfo_.cqeStatus, dfxExtendInfo_.cqeException.sqeType,
    4112              :                     dfxExtendInfo_.cqeException.errorCode);
    4113              :             }
    4114            0 :             return HCCL_E_INTERNAL;
    4115              :         }
    4116              :     }
    4117              : 
    4118              :     // 检测是否有停止/退出命令
    4119            4 :     KfcCommand cmd = KfcCommand::kNone;
    4120            4 :     CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd));
    4121            4 :     if (cmd == KfcCommand::kStopLaunch && retryEnable_) {
    4122            4 :         HCCL_RUN_INFO(
    4123              :             "[OpRetry][AICPU]hccl aicpu stop wait finish, for recv stop launch cmd, identify[%s]", identifier_.c_str());
    4124            4 :         return HCCL_E_SUSPENDING;
    4125            0 :     } else if ((cmd == KfcCommand::NsStopLaunch) && (endStopLaunch == false)) {
    4126            0 :         needsResponseStopLaunch_ = true;
    4127            0 :         endStopLaunch = true;
    4128            0 :         HCCL_RUN_INFO("hccl aicpu stop wait finish, for recv stop launch cmd");
    4129            0 :         return HCCL_E_SUSPENDING;
    4130            0 :     } else if (cmd == KfcCommand::kDestroyComm) {
    4131            0 :         HCCL_ERROR("hccl aicpu stop wait finish, for recv destroy comm cmd");
    4132            0 :         return HCCL_E_INTERNAL;
    4133            0 :     } else if (cmd == KfcCommand::kExit) {
    4134            0 :         HCCL_ERROR("hccl aicpu stop wait finish, for recv exit cmd, identify[%s]", identifier_.c_str());
    4135            0 :         return HCCL_E_INTERNAL;
    4136              :     }
    4137            0 :     return HCCL_SUCCESS;
    4138              : }
    4139              : 
    4140            4 : HcclResult HcclCommAicpu::UpdateSuspendStatus(
    4141              :     const OpParam& param, HcclOpExecFSM& fsmState, KfcError& errorCode, uint32_t retryCnt)
    4142              : {
    4143            4 :     if (needsResponseStopLaunch_ == true) {
    4144            0 :         HCCL_RUN_INFO("[NsRecovery][AICPU]hccl aicpu force stop in launch loop");
    4145            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
    4146            4 :     } else if (retryEnable_) {
    4147            4 :         HCCL_RUN_INFO(
    4148              :             "[OpRetry][AICPU]hccl aicpu force stop for stop cmd or recoverable task exception, identify[%s]",
    4149              :             identifier_.c_str());
    4150            4 :         errorCode = IsTaskExceptionForHccs() ? KfcError::kSdma : errorCode;
    4151              : 
    4152            4 :         if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV)) {
    4153            0 :             HcclResult ret = GetBSRRetryOpId(param, bsrTargetOpId_);
    4154            0 :             HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    4155              :                 ret, HCCL_ERROR("get batchsendrecv target op failed, ret:%u", ret), KfcError::kExec,
    4156              :                 HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    4157            0 :             uint32_t bsrRetryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
    4158            0 :             bsrTargetOpId_.isBsrTaskStart = true;
    4159            0 :             ret = aicpuHdc_.SetOpExecStatus(
    4160            0 :                 kfcStatusTransferD2H_, bsrTargetOpId_, KfcStatus::kStoplaunch, errorCode, bsrRetryCnt);
    4161            0 :             HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    4162              :                 ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec,
    4163              :                 HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    4164              :         } else {
    4165            4 :             CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kStoplaunch, errorCode, retryCnt));
    4166              :         }
    4167            4 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING;
    4168              :     } else {
    4169            0 :         HCCL_RUN_INFO(
    4170              :             "[HcclCommAicpu][UpdateSuspendStatus] aicpu force stop in launch loop; needsResponseStopLaunch_[%u] "
    4171              :             "retryEnable_[%u]",
    4172              :             needsResponseStopLaunch_, retryEnable_);
    4173            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_STOP_LAUNCH;
    4174              :     }
    4175            4 :     return HCCL_SUCCESS;
    4176              : }
    4177              : 
    4178            0 : HcclResult HcclCommAicpu::TasktypeTransferD2H(const uint8_t sqeType, TaskType& taskType)
    4179              : {
    4180            0 :     switch (sqeType) {
    4181            0 :         case RT_STARS_SQE_TYPE_PLACE_HOLDER:
    4182              :         case RT_STARS_SQE_TYPE_NOTIFY_WAIT:
    4183            0 :             taskType = TaskType::TASK_NOTIFY_WAIT;
    4184            0 :             break;
    4185            0 :         case RT_STARS_SQE_TYPE_SDMA:
    4186            0 :             taskType = TaskType::TASK_SDMA;
    4187            0 :             break;
    4188            0 :         case RT_STARS_SQE_TYPE_NOTIFY_RECORD:
    4189            0 :             taskType = TaskType::TASK_NOTIFY_RECORD;
    4190            0 :             break;
    4191            0 :         case RT_STARS_SQE_TYPE_WRITE_VALUE:
    4192            0 :             taskType = TaskType::TASK_NOTIFY_WAIT;
    4193            0 :             break;
    4194            0 :         default:
    4195            0 :             HCCL_ERROR("TasktypeTransferD2H sqeType[%d] error.", sqeType);
    4196            0 :             return HCCL_E_PARA;
    4197              :     }
    4198            0 :     return HCCL_SUCCESS;
    4199              : }
    4200              : 
    4201            0 : HcclResult HcclCommAicpu::GenTaskExceptionInfo(u8 sqeType, hccl::Stream& stream, u32 head)
    4202              : {
    4203            0 :     HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
    4204            0 :     SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    4205            0 :     CHK_PTR_NULL(sqeContextBuffer);
    4206              : 
    4207            0 :     const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[head].opRingBufferIdx);
    4208            0 :     std::string opTag = opInfo == nullptr ? "unKnown" : opInfo->tagBuff;
    4209              : 
    4210              :     // 获取需要上报的关键信息
    4211            0 :     ErrorMessageReport emrInfo{};
    4212            0 :     SqeInfo sqeInfo;
    4213            0 :     SqeContextUtils::QuerySqeInfo(
    4214            0 :         sqeContextBuffer->rtsMirrorBuffer + head * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[head],
    4215              :         sqeContextBuffer->addInfo[head], &sqeInfo);
    4216            0 :     emrInfo.remoteUserRank = sqeContextBuffer->rtsDfxInfo[head].remoteRank;
    4217            0 :     emrInfo.streamId = stream.id();
    4218            0 :     emrInfo.taskId = sqeInfo.taskId;
    4219            0 :     emrInfo.notifyId = sqeInfo.notifyId;
    4220            0 :     emrInfo.rankId = localUserRank_;
    4221            0 :     emrInfo.rankSize = topoInfo_.userRankSize;
    4222            0 :     emrInfo.algType = algType_;
    4223            0 :     emrInfo.opIndex = opInfo == nullptr ? 0 : opInfo->opIndex;
    4224            0 :     emrInfo.count = opInfo == nullptr ? 0 : opInfo->count;
    4225            0 :     emrInfo.dataType = opInfo == nullptr ? 0 : opInfo->dataType;
    4226            0 :     emrInfo.dstAddr = opInfo == nullptr ? 0 : opInfo->dstAddr;
    4227            0 :     emrInfo.srcAddr = opInfo == nullptr ? 0 : opInfo->srcAddr;
    4228            0 :     emrInfo.reduceType = opInfo == nullptr ? 255 : opInfo->reduceType; // 255 为 HcclReduceOp::HCCL_REDUCE_RESERVED
    4229            0 :     CHK_RET(TasktypeTransferD2H(sqeType, emrInfo.taskType));
    4230              : 
    4231            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(emrInfo.tag, sizeof(emrInfo.tag), opTag.c_str(), opTag.size()));
    4232            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(emrInfo.group, sizeof(emrInfo.group), identifier_.c_str(), identifier_.size()));
    4233            0 :     CHK_RET(aicpuHdc_.SetErrorMessage(kfcStatusTransferD2H_, emrInfo));
    4234            0 :     return HCCL_SUCCESS;
    4235            0 : }
    4236              : 
    4237            0 : HcclResult HcclCommAicpu::PrintTaskExceptionByTaskId(u8 sqeType, u16 taskId, hccl::Stream& stream, u32 tail)
    4238              : {
    4239            0 :     HcclSqeContext* sqeContext = stream.GetSqeContextPtr();
    4240            0 :     CHK_PTR_NULL(sqeContext);
    4241            0 :     HCCL_ERROR("[HcclCommAicpu][PrintTaskExceptionByTaskId]streamId:%d tail:%u cqeType:%u", stream.id(), tail, sqeType);
    4242            0 :     SqeRingBuffer* sqeContextBuffer = &(sqeContext->buffer);
    4243            0 :     CHK_PTR_NULL(sqeContextBuffer);
    4244            0 :     uint8_t* sqeMirrorBufferAddr = sqeContextBuffer->rtsMirrorBuffer + (tail - 1) * HCCL_SQE_SIZE;
    4245            0 :     rtStarsSqeHeader_t* const sqeHeader = (rtStarsSqeHeader_t* const)sqeMirrorBufferAddr;
    4246              : 
    4247            0 :     s32 taskNum = sqeHeader->taskId - taskId;
    4248            0 :     HCCL_DEBUG("[HcclCommAicpu]tail sqe taskId[%u] cqe taskId[%u] cqe type[%u]", sqeHeader->taskId, taskId, sqeType);
    4249            0 :     s32 sqeIdx = tail - taskNum - 1;
    4250            0 :     u32 sqHead = (sqeIdx + HCCL_SQE_MAX_CNT) % HCCL_SQE_MAX_CNT;
    4251            0 :     uint8_t type = 0;
    4252            0 :     uint16_t taskIdTmp = 0;
    4253            0 :     uint32_t remoteRank = 0;
    4254            0 :     HCCL_ERROR(
    4255              :         "[TaskException][AICPU]base information is streamId:%d, sqid:%d, head:%u, tail:%u, %s", stream.id(),
    4256              :         stream.sqId(), sqHead, tail,
    4257              :         GetTaskExceptionTaskInfo(sqHead, sqeContextBuffer, type, taskIdTmp, remoteRank).c_str());
    4258            0 :     PrintTaskExceptionTaskQue(sqHead, sqeContextBuffer);
    4259            0 :     return HCCL_SUCCESS;
    4260              : }
    4261              : 
    4262            0 : std::string HcclCommAicpu::GetTaskExceptionOpInfo(u32 idx, SqeRingBuffer* sqeContextBuffer)
    4263              : {
    4264            0 :     const AicpuOpInfo* opInfo = aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[idx].opRingBufferIdx);
    4265            0 :     CHK_PRT_RET(opInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), "unKnown");
    4266              : 
    4267            0 :     std::stringstream ss;
    4268            0 :     ss << "tag:" << opInfo->tagBuff << ", ";
    4269            0 :     ss << "group:" << identifier_ << ", ";
    4270            0 :     ss << "isCustom:" << opInfo->isCustom << ", ";
    4271            0 :     ss << "opLaunchIdx:" << opInfo->opIndex << ", ";
    4272            0 :     ss << "opExecIdx:" << opInfo->opExecIndex << ", ";
    4273            0 :     ss << "count:" << opInfo->count << ", ";
    4274            0 :     ss << "dataType:" << static_cast<u16>(opInfo->dataType) << ", ";
    4275            0 :     ss << "opType:" << static_cast<u16>(opInfo->opType) << ", ";
    4276            0 :     ss << "rootId:" << opInfo->rootId << ", ";
    4277            0 :     ss << "dstAddr:0x" << std::hex << opInfo->dstAddr << ", ";
    4278            0 :     ss << "srcAddr:0x" << std::hex << opInfo->srcAddr << ".";
    4279            0 :     return ss.str();
    4280            0 : }
    4281              : 
    4282            0 : std::string HcclCommAicpu::GetTaskExceptionTaskInfo(
    4283              :     u32 sqHead, SqeRingBuffer* sqeContextBuffer, uint8_t& type, uint16_t& taskId, uint32_t& remoteRank)
    4284              : {
    4285            0 :     SqeInfo sqeInfo;
    4286            0 :     SqeContextUtils::QuerySqeInfo(
    4287            0 :         sqeContextBuffer->rtsMirrorBuffer + sqHead * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[sqHead],
    4288              :         sqeContextBuffer->addInfo[sqHead], &sqeInfo);
    4289            0 :     type = sqeInfo.type;
    4290            0 :     taskId = sqeInfo.taskId;
    4291            0 :     remoteRank = sqeContextBuffer->rtsDfxInfo[sqHead].remoteRank;
    4292            0 :     std::stringstream ss;
    4293            0 :     ss << "type:" << SqeContextUtils::RtsqTaskTypeToStr(sqeInfo.type) << ", ";
    4294            0 :     ss << "localRank:" << localUserRank_ << ", ";
    4295            0 :     ss << "remoteRank:" << remoteRank << ", ";
    4296            0 :     ss << "taskId:" << sqeInfo.taskId << ", ";
    4297            0 :     ss << "notifyId:" << sqeInfo.notifyId << ", ";
    4298            0 :     ss << "length:" << sqeInfo.length << ", ";
    4299            0 :     ss << "addr1High:0x" << std::hex << sqeInfo.addr1High << ", ";
    4300            0 :     ss << "addr1Low:0x" << std::hex << sqeInfo.addr1Low << ", ";
    4301            0 :     ss << "addr2High:0x" << std::hex << sqeInfo.addr2High << ", ";
    4302            0 :     ss << "addr2Low:0x" << std::hex << sqeInfo.addr2Low << ".";
    4303            0 :     return ss.str();
    4304            0 : }
    4305              : 
    4306              : // 获取指定索引的算子信息
    4307            0 : const AicpuOpInfo* HcclCommAicpu::GetOpInfoFromSqIdx(u32 sqIdx, SqeRingBuffer* sqeContextBuffer)
    4308              : {
    4309            0 :     return aicpuShareData_.GetAicpuOpInfo(sqeContextBuffer->rtsDfxInfo[sqIdx].opRingBufferIdx);
    4310              : }
    4311              : 
    4312              : // 打印算子数据信息
    4313            0 : void HcclCommAicpu::PrintOpDataInfo(u32 sqIdx, SqeRingBuffer* sqeContextBuffer, bool isMonitor)
    4314              : {
    4315            0 :     std::string opInfo = GetTaskExceptionOpInfo(sqIdx, sqeContextBuffer);
    4316            0 :     if (isMonitor) {
    4317            0 :         HCCL_RUN_INFO("[StreamTaskMonitor]opData information is %s", opInfo.c_str());
    4318              :     } else {
    4319            0 :         HCCL_ERROR("[TaskException]opData information is %s", opInfo.c_str());
    4320              :     }
    4321            0 : }
    4322              : 
    4323              : // 打印task序列行
    4324            0 : void HcclCommAicpu::PrintTaskLine(bool isMonitor, u32 lineNum, u32 totalPrinted, const std::string& taskLine) const
    4325              : {
    4326            0 :     if (isMonitor) {
    4327            0 :         HCCL_RUN_INFO("[StreamTaskMonitor]task sequence[%u/%u] is %s", lineNum, totalPrinted, taskLine.c_str());
    4328              :     } else {
    4329            0 :         HCCL_ERROR("[TaskException]task sequence[%u/%u] is %s", lineNum, totalPrinted, taskLine.c_str());
    4330              :     }
    4331            0 : }
    4332              : 
    4333              : // 更新算子上下文
    4334            0 : void HcclCommAicpu::UpdateOpContext(
    4335              :     u32& opIndex, std::string& opTag, u32& lineCount, std::vector<std::string>& currentOpTasks, u32 newOpIndex,
    4336              :     const std::string& newOpTag) const
    4337              : {
    4338            0 :     opIndex = newOpIndex;
    4339            0 :     opTag = newOpTag;
    4340            0 :     lineCount = 0;
    4341            0 :     currentOpTasks.clear();
    4342            0 :     currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ")");
    4343            0 : }
    4344              : 
    4345              : // 准备下一行数据
    4346            0 : void HcclCommAicpu::PrepareNextLine(u32 opIndex, u32& lineCount, std::vector<std::string>& currentOpTasks) const
    4347              : {
    4348            0 :     lineCount++;
    4349            0 :     currentOpTasks.clear();
    4350            0 :     currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ") continued");
    4351            0 : }
    4352              : 
    4353              : // 拼接task列表为字符串
    4354            0 : std::string HcclCommAicpu::ConcatTaskLine(const std::vector<std::string>& tasks) const
    4355              : {
    4356            0 :     std::string taskLine;
    4357            0 :     for (const auto& task : tasks) {
    4358            0 :         taskLine += task;
    4359              :     }
    4360            0 :     return taskLine;
    4361            0 : }
    4362              : 
    4363              : // 打印剩余未满行的tasks
    4364            0 : void HcclCommAicpu::PrintRemainingTasks(
    4365              :     bool isMonitor, u32 lineCount, u32 printedCount, const std::vector<std::string>& currentOpTasks) const
    4366              : {
    4367              :     // size > 1 表示除了OP头还有task
    4368            0 :     if (currentOpTasks.size() > 1) {
    4369            0 :         std::string taskLine = ConcatTaskLine(currentOpTasks);
    4370            0 :         PrintTaskLine(isMonitor, lineCount + 1, printedCount, taskLine);
    4371            0 :     }
    4372            0 : }
    4373              : 
    4374            0 : void HcclCommAicpu::PrintTaskExceptionTaskQue(u32 sqIdx, SqeRingBuffer* sqeContextBuffer, bool isMonitor)
    4375              : {
    4376            0 :     const u32 sqeNum = 200;
    4377            0 :     const u32 maxTasksPerLine = 50;
    4378              : 
    4379              :     // 获取初始算子信息
    4380            0 :     const AicpuOpInfo* lastOpInfo = GetOpInfoFromSqIdx(sqIdx, sqeContextBuffer);
    4381            0 :     CHK_PRT_RET(lastOpInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), );
    4382              : 
    4383              :     // 初始化状态
    4384            0 :     u32 opIndex = lastOpInfo->opIndex;
    4385            0 :     std::string opTag = lastOpInfo->tagBuff;
    4386            0 :     u32 lineCount = 0;
    4387            0 :     u32 printedCount = 0;
    4388            0 :     u32 extraSlotPerLine = 2;
    4389            0 :     std::vector<std::string> currentOpTasks;
    4390            0 :     currentOpTasks.push_back("OP(" + std::to_string(opIndex) + ")");
    4391              : 
    4392              :     // 主循环:遍历并打印
    4393            0 :     for (u32 i = 0; i < sqeNum; i++) {
    4394              :         // 计算新索引并获取算子信息
    4395            0 :         u32 newSqIdx = (sqIdx - i + HCCL_SQE_MAX_CNT) % HCCL_SQE_MAX_CNT;
    4396            0 :         const AicpuOpInfo* newOpInfo = GetOpInfoFromSqIdx(newSqIdx, sqeContextBuffer);
    4397            0 :         CHK_PRT_RET(newOpInfo == nullptr, HCCL_ERROR("%s fail, opInfo is nullptr", __func__), );
    4398              : 
    4399            0 :         u32 sizeAfterAdd = currentOpTasks.size() + 1;
    4400            0 :         if (sizeAfterAdd >= (maxTasksPerLine + extraSlotPerLine)
    4401            0 :             || (i > 0 && (newOpInfo->opIndex != opIndex || newOpInfo->tagBuff != opTag))) {
    4402              :             // 打印算子信息(仅第一次)
    4403            0 :             if (lineCount == 0) {
    4404            0 :                 PrintOpDataInfo(sqIdx, sqeContextBuffer, isMonitor);
    4405              :             }
    4406              : 
    4407              :             // 拼接并打印task行
    4408            0 :             std::string taskLine = ConcatTaskLine(currentOpTasks);
    4409            0 :             PrintTaskLine(isMonitor, lineCount + 1, printedCount, taskLine);
    4410              : 
    4411              :             // 更新状态
    4412            0 :             if (newOpInfo->opIndex != opIndex || newOpInfo->tagBuff != opTag) {
    4413            0 :                 UpdateOpContext(opIndex, opTag, lineCount, currentOpTasks, newOpInfo->opIndex, newOpInfo->tagBuff);
    4414              :             } else {
    4415            0 :                 PrepareNextLine(opIndex, lineCount, currentOpTasks);
    4416              :             }
    4417            0 :         }
    4418              :         // 添加task到序列
    4419            0 :         currentOpTasks.push_back("," + GetTaskBriefsInfo(newSqIdx, sqeContextBuffer));
    4420            0 :         printedCount++;
    4421              :     }
    4422              :     // 打印剩余tasks
    4423            0 :     PrintRemainingTasks(isMonitor, lineCount, printedCount, currentOpTasks);
    4424            0 : }
    4425              : 
    4426            0 : std::string HcclCommAicpu::GetTaskBriefsInfo(u32 idx, SqeRingBuffer* sqeContextBuffer)
    4427              : {
    4428            0 :     uint8_t* sqeMirrorBufferAddr = sqeContextBuffer->rtsMirrorBuffer + idx * HCCL_SQE_SIZE;
    4429            0 :     rtStarsSqeHeader_t* const sqeHeader = (rtStarsSqeHeader_t* const)sqeMirrorBufferAddr;
    4430            0 :     uint8_t sqeType = sqeHeader->type;
    4431              : 
    4432            0 :     SqeInfo sqeInfo;
    4433            0 :     SqeContextUtils::QuerySqeInfo(
    4434            0 :         sqeContextBuffer->rtsMirrorBuffer + idx * HCCL_SQE_SIZE, sqeContextBuffer->rtsqSqeType[idx],
    4435              :         sqeContextBuffer->addInfo[idx], &sqeInfo);
    4436            0 :     uint8_t subType = sqeInfo.subType;
    4437              : 
    4438            0 :     std::stringstream ss;
    4439            0 :     std::string taskName = "UN";
    4440            0 :     switch (sqeType) {
    4441            0 :         case RT_STARS_SQE_TYPE_NOTIFY_RECORD:
    4442            0 :             taskName = "NR"; // Notify Record
    4443            0 :             break;
    4444            0 :         case RT_STARS_SQE_TYPE_WRITE_VALUE:
    4445            0 :             if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_NOTIFY_RECORD_IPC_NO_PCIE) {
    4446            0 :                 taskName = "NR";
    4447            0 :             } else if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_EVENT_RESET) {
    4448            0 :                 taskName = "NW"; // Notify Wait
    4449            0 :             } else if (subType == RT_STARS_WRITE_VALUE_SUB_TYPE_RDMA_DB_SEND) {
    4450            0 :                 taskName = "RS"; // Rdma Send
    4451              :             }
    4452            0 :             break;
    4453            0 :         case RT_STARS_SQE_TYPE_NOTIFY_WAIT:
    4454            0 :             taskName = "NW";
    4455            0 :             break;
    4456            0 :         case RT_STARS_SQE_TYPE_EVENT_WAIT:
    4457            0 :             taskName = "NW";
    4458            0 :             break;
    4459            0 :         case RT_STARS_SQE_TYPE_SDMA:
    4460            0 :             taskName = "SD"; // SDMA
    4461            0 :             break;
    4462            0 :         case RT_STARS_SQE_TYPE_COND:
    4463            0 :             taskName = "CO";
    4464            0 :             break;
    4465            0 :         case RT_STARS_SQE_TYPE_PLACE_HOLDER:
    4466            0 :             taskName = "PH";
    4467            0 :             break;
    4468            0 :         default:
    4469            0 :             taskName = std::to_string(sqeType);
    4470            0 :             break;
    4471              :     }
    4472              : 
    4473            0 :     ss << taskName << "(";
    4474            0 :     if (sqeContextBuffer->rtsDfxInfo[idx].remoteRank != INVALID_VALUE_RANKID) {
    4475            0 :         ss << sqeContextBuffer->rtsDfxInfo[idx].remoteRank;
    4476              :     } else {
    4477            0 :         ss << "/";
    4478              :     }
    4479            0 :     ss << ",";
    4480            0 :     if (sqeContextBuffer->rtsDfxInfo[idx].notifyId != INVALID_VALUE_RANKID) {
    4481            0 :         ss << sqeContextBuffer->rtsDfxInfo[idx].notifyId;
    4482              :     } else {
    4483            0 :         ss << "/";
    4484              :     }
    4485            0 :     ss << ")";
    4486            0 :     return ss.str();
    4487            0 : }
    4488              : 
    4489            1 : void HcclCommAicpu::RecordReportStatus(dfx::ReportStatus status)
    4490              : {
    4491            1 :     std::unique_lock<std::mutex> lock(reportQueueMutex_);
    4492            1 :     while (reportStatusQueue_.size() >= MAX_REPORT_STATUS) {
    4493            0 :         HCCL_WARNING(
    4494              :             "[HcclCommAicpu][RecordReportStatus] retry status queue reach the limit[%u], "
    4495              :             "the front status[%u] is dropped.",
    4496              :             MAX_REPORT_STATUS, reportStatusQueue_.front());
    4497            0 :         reportStatusQueue_.pop();
    4498              :     }
    4499            1 :     reportStatusQueue_.push(status);
    4500            1 :     HCCL_INFO("[HcclCommAicpu][RecordReportStatus]push[%u], retry queue size()[%u]", status, reportStatusQueue_.size());
    4501            1 : }
    4502              : 
    4503            0 : void HcclCommAicpu::GetReportStatusQueue(std::queue<dfx::ReportStatus>& reportStatusQue)
    4504              : {
    4505            0 :     std::unique_lock<std::mutex> lock(reportQueueMutex_);
    4506            0 :     std::swap(reportStatusQueue_, reportStatusQue);
    4507            0 : }
    4508              : 
    4509            0 : void HcclCommAicpu::SetStreamCqeExceptionStatus(const Stream& stream, CqeExceptionStatus cqeStatus)
    4510              : {
    4511            0 :     HCCL_RUN_INFO("SetStreamCqeExceptionStatus: stream sq id %u, cqe exception %u", stream.sqId(), cqeStatus);
    4512            0 :     auto iter = streamCqeExceptionStatus_.find(stream.sqId());
    4513            0 :     if (iter != streamCqeExceptionStatus_.end()) {
    4514            0 :         iter->second = cqeStatus;
    4515              :     } else {
    4516            0 :         streamCqeExceptionStatus_.insert({stream.sqId(), cqeStatus});
    4517              :     }
    4518            0 :     return;
    4519              : }
    4520              : 
    4521            0 : CqeExceptionStatus HcclCommAicpu::GetStreamCqeExceptionStatus(const Stream& stream)
    4522              : {
    4523            0 :     auto iter = streamCqeExceptionStatus_.find(stream.sqId());
    4524            0 :     if (iter != streamCqeExceptionStatus_.end()) {
    4525            0 :         return iter->second;
    4526              :     } else {
    4527            0 :         return CqeExceptionStatus::kNone;
    4528              :     }
    4529              : }
    4530              : 
    4531            0 : void HcclCommAicpu::ResetStreamCqeExceptionStatus(const Stream& stream)
    4532              : {
    4533            0 :     auto iter = streamCqeExceptionStatus_.find(stream.sqId());
    4534            0 :     if (iter != streamCqeExceptionStatus_.end()) {
    4535            0 :         iter->second = CqeExceptionStatus::kNone;
    4536              :     }
    4537            0 :     HCCL_INFO("ResetStreamCqeExceptionStatus: stream sq id %u", stream.sqId());
    4538            0 :     return;
    4539              : }
    4540              : 
    4541            0 : void HcclCommAicpu::SetBSRSendOpExecException()
    4542              : {
    4543            0 :     HCCL_INFO("set send stream exec exception");
    4544            0 :     bsrSendOpExecException_ = true;
    4545            0 :     return;
    4546              : }
    4547              : 
    4548            0 : void HcclCommAicpu::SetBSRRecvOpExecException()
    4549              : {
    4550            0 :     HCCL_INFO("set recv stream exec exception");
    4551            0 :     bsrRecvOpExecException_ = true;
    4552            0 :     return;
    4553              : }
    4554              : 
    4555            0 : bool HcclCommAicpu::GetBSRSendOpExecException()
    4556              : {
    4557            0 :     bool ret = (GetStreamCqeExceptionStatus(bsrSendStream_) == CqeExceptionStatus::kSdmaErr) || bsrSendOpExecException_;
    4558            0 :     HCCL_INFO(
    4559              :         "GetBSRSendOpExecException: stream %u cqe status %u, send exec status %u", bsrSendStream_.sqId(),
    4560              :         GetStreamCqeExceptionStatus(bsrSendStream_), bsrSendOpExecException_);
    4561            0 :     return ret;
    4562              : }
    4563              : 
    4564            0 : bool HcclCommAicpu::GetBSRRecvOpExecException()
    4565              : {
    4566            0 :     HCCL_INFO(
    4567              :         "GetBSRRecvOpExecException: stream %u cqe status %u, recv exec status %u", bsrRecvStream_.sqId(),
    4568              :         GetStreamCqeExceptionStatus(bsrRecvStream_), bsrRecvOpExecException_);
    4569            0 :     return (GetStreamCqeExceptionStatus(bsrRecvStream_) == CqeExceptionStatus::kSdmaErr) || bsrRecvOpExecException_;
    4570              : }
    4571              : 
    4572            0 : HcclResult HcclCommAicpu::CleanStream(Stream& stream)
    4573              : {
    4574            0 :     CHK_RET(stream.ClearLocalBuff());
    4575            0 :     CHK_RET(UpdateSqStatus(stream));
    4576            0 :     ResetStreamCqeExceptionStatus(stream);
    4577            0 :     HCCL_INFO("CleanStream %u success.", stream.sqId());
    4578            0 :     return HCCL_SUCCESS;
    4579              : }
    4580              : 
    4581            0 : HcclResult HcclCommAicpu::ClearStreamCqeException(Stream& stream)
    4582              : {
    4583            0 :     HandleCqeException(stream, true);
    4584            0 :     return HCCL_SUCCESS;
    4585              : }
    4586              : 
    4587            0 : HcclResult HcclCommAicpu::ResetBSRSendOpExecException()
    4588              : {
    4589            0 :     bsrSendOpExecException_ = false;
    4590            0 :     CHK_RET(CleanStream(bsrSendStream_));
    4591            0 :     CHK_RET(ClearStreamCqeException(bsrSendStream_));
    4592            0 :     HCCL_INFO("ResetBSRSendOpExecException success.");
    4593            0 :     return HCCL_SUCCESS;
    4594              : }
    4595              : 
    4596            0 : HcclResult HcclCommAicpu::ResetBSRRecvOpExecException()
    4597              : {
    4598            0 :     bsrRecvOpExecException_ = false;
    4599            0 :     CHK_RET(CleanStream(bsrRecvStream_));
    4600            0 :     CHK_RET(ClearStreamCqeException(bsrRecvStream_));
    4601            0 :     HCCL_INFO("ResetBSRRecvOpExecException success.");
    4602            0 :     return HCCL_SUCCESS;
    4603              : }
    4604              : 
    4605            0 : HcclResult HcclCommAicpu::ResetBSRException()
    4606              : {
    4607            0 :     if (bsrRetryOp_ == HCCL_SEND) {
    4608            0 :         CHK_RET(ResetBSRSendOpExecException());
    4609            0 :         HCCL_INFO("reset batchsendrecv exception success, tag:%s, index:%u", bsrSendOpId_.tag, bsrSendOpId_.index);
    4610            0 :     } else if (bsrRetryOp_ == HCCL_RECV) {
    4611            0 :         CHK_RET(ResetBSRRecvOpExecException());
    4612            0 :         HCCL_INFO("reset batchsendrecv exception success, tag:%s, index:%u", bsrRecvOpId_.tag, bsrRecvOpId_.index);
    4613              :     } else {
    4614            0 :         HCCL_INFO("reset batchsendrecv exception success, tag:%s", bsrTargetOpId_.tag);
    4615              :     }
    4616            0 :     return HCCL_SUCCESS;
    4617              : }
    4618              : 
    4619            0 : void HcclCommAicpu::UpdateBSRRetryCnt()
    4620              : {
    4621            0 :     if (bsrRetryOp_ == HCCL_SEND) {
    4622            0 :         bsrSendRetryCnt_++;
    4623              :     } else {
    4624            0 :         bsrRecvRetryCnt_++;
    4625              :     }
    4626            0 :     HCCL_INFO("UpdateBSRRetryCnt, SendCnt[%u], RecvCnt[%u]", bsrSendRetryCnt_, bsrRecvRetryCnt_);
    4627            0 :     return;
    4628              : }
    4629              : 
    4630            0 : void HcclCommAicpu::ResetBSRRetryCnt()
    4631              : {
    4632            0 :     bsrSendRetryCnt_ = 0;
    4633            0 :     bsrRecvRetryCnt_ = 0;
    4634            0 :     return;
    4635              : }
    4636              : 
    4637            0 : void HcclCommAicpu::InitSendRecvOpId(const OpParam& param, HcclOpIdentifier& opId)
    4638              : {
    4639              :     // send算子入参中只有dst对端rank号,而recv算子入参中只有src源端rank号
    4640            0 :     if (param.opType == HcclCMDType::HCCL_CMD_SEND) {
    4641            0 :         opId.detRank = param.dstRank;
    4642            0 :         opId.srcRank = topoInfo_.userRank;
    4643              :     } else {
    4644            0 :         opId.srcRank = param.srcRank;
    4645            0 :         opId.detRank = topoInfo_.userRank;
    4646              :     }
    4647            0 :     opId.isSendRecv = true;
    4648            0 :     HCCL_DEBUG(
    4649              :         "[HcclCommAicpu][InitSendRecvOpId]src=[%u] dst=[%u] isSendRecv=[%u]", opId.srcRank, opId.detRank,
    4650              :         opId.isSendRecv);
    4651            0 :     return;
    4652              : }
    4653              : 
    4654            0 : u32 HcclCommAicpu::HcclUpdateBatchSendRecvOpIndex(std::map<u32, u32>& bsrIndexMap, u32 peerRank)
    4655              : {
    4656            0 :     u32 ret = 0;
    4657            0 :     auto opIndexMapIter = bsrIndexMap.find(peerRank);
    4658            0 :     if (opIndexMapIter != bsrIndexMap.end()) {
    4659            0 :         (opIndexMapIter->second)++;
    4660            0 :         ret = opIndexMapIter->second;
    4661              :     } else {
    4662            0 :         bsrIndexMap.insert({peerRank, 1});
    4663            0 :         ret = 1;
    4664              :     }
    4665            0 :     return ret;
    4666              : }
    4667              : 
    4668            0 : u32 HcclCommAicpu::HcclUpdateBatchSendRecvOpIndex(HcclSendRecvType opType, u32 srcRank, u32 dstRank)
    4669              : {
    4670            0 :     u32 peerRank = (opType == HcclSendRecvType::HCCL_SEND) ? dstRank : srcRank;
    4671            0 :     auto& opIndexMap = (opType == HcclSendRecvType::HCCL_SEND) ? bsrSendIndexMap_ : bsrRecvIndexMap_;
    4672              : 
    4673            0 :     return HcclUpdateBatchSendRecvOpIndex(opIndexMap, peerRank);
    4674              : }
    4675              : HcclResult
    4676            0 : HcclCommAicpu::GetBsrTransportQpn(const HcclSendRecvItem* sendrecvPair, AlgResourceResponse& algResource, u32& qpn)
    4677              : {
    4678            0 :     CHK_PTR_NULL(sendrecvPair);
    4679            0 :     LINK targetLink;
    4680            0 :     u32 commIndex = 0;
    4681            0 :     u32 remoteRank = sendrecvPair->remoteRank;
    4682            0 :     u32 localRank = topoInfo_.userRank;
    4683            0 :     HcclSendRecvType sendRecvType = sendrecvPair->sendRecvType;
    4684            0 :     HCCL_DEBUG(
    4685              :         "[GetBsrTransportQpn] bsrOptype =[%d], localRank=[%u] remoteRank=[%u]", sendRecvType, localRank, remoteRank);
    4686              : 
    4687            0 :     if ((sendRecvType == HcclSendRecvType::HCCL_SEND && remoteRank < localRank)
    4688            0 :         || (sendRecvType == HcclSendRecvType::HCCL_RECV && remoteRank > localRank)) {
    4689            0 :         commIndex = COMM_INDEX_0;
    4690              :     } else {
    4691            0 :         commIndex = COMM_INDEX_1;
    4692              :     }
    4693            0 :     CHK_PRT_RET(
    4694              :         commIndex >= algResource.opTransportResponse[COMM_COMBINE_ORDER].size(),
    4695              :         HCCL_ERROR(
    4696              :             "[GetBsrTransportQpn] batchsendrecv op commIndex[%u] is larger than "
    4697              :             "opTransportResponse size[%zu]",
    4698              :             commIndex, algResource.opTransportResponse[COMM_COMBINE_ORDER].size()),
    4699              :         HCCL_E_PARA);
    4700              :     SingleSubCommTransport& commCombined
    4701            0 :         = static_cast<SingleSubCommTransport&>(algResource.opTransportResponse[COMM_COMBINE_ORDER][commIndex]);
    4702              : 
    4703            0 :     CHK_PRT_RET(
    4704              :         sendrecvPair->remoteRank >= commCombined.userRank2subCommRank.size(),
    4705              :         HCCL_ERROR(
    4706              :             "[GetBsrTransportQpn]batchsendrecv op remoteUserRank[%u] is larger than "
    4707              :             "userRank2subCommRank map size[%zu]",
    4708              :             sendrecvPair->remoteRank, commCombined.userRank2subCommRank.size()),
    4709              :         HCCL_E_PARA);
    4710              : 
    4711            0 :     u32 rank = commCombined.userRank2subCommRank[sendrecvPair->remoteRank];
    4712            0 :     CHK_PRT_RET(
    4713              :         rank >= commCombined.links.size(),
    4714              :         HCCL_ERROR(
    4715              :             "[GetBsrTransportQpn] batchsendrecv op remoteUserRank[%u], get rank[%u],"
    4716              :             "the size of combinedComm links is [%zu]",
    4717              :             sendrecvPair->remoteRank, rank, commCombined.links.size()),
    4718              :         HCCL_E_PARA);
    4719            0 :     targetLink = commCombined.links[rank];
    4720              : 
    4721            0 :     CHK_SMART_PTR_NULL(targetLink);
    4722            0 :     if (targetLink->GetLinkType() == LinkType::LINK_ROCE) {
    4723            0 :         CHK_RET(targetLink->GetTransportId(qpn));
    4724              :     }
    4725            0 :     HCCL_DEBUG(
    4726              :         "[HcclCommAicpu][GetBsrTransportQpn] localrank=[%u] remoteuserRank=[%u] remoteRank=[%u],sendrecvType=[%d] qpn "
    4727              :         "=[%u], comindex [%u]",
    4728              :         topoInfo_.userRank, sendrecvPair->remoteRank, remoteRank, sendrecvPair->sendRecvType, qpn, commIndex);
    4729            0 :     return HCCL_SUCCESS;
    4730            0 : }
    4731            0 : HcclResult HcclCommAicpu::InitBatchSendRecvOpId(
    4732              :     const OpParam& param, const HcclSendRecvItem* sendrecvPair, HcclOpIdentifier& opId, u32 streamId,
    4733              :     AlgResourceResponse& algResource)
    4734              : {
    4735            0 :     CHK_PTR_NULL(sendrecvPair);
    4736            0 :     if (sendrecvPair->sendRecvType == HcclSendRecvType::HCCL_RECV) {
    4737            0 :         opId.srcRank = sendrecvPair->remoteRank;
    4738            0 :         opId.detRank = topoInfo_.userRank;
    4739              :     } else {
    4740            0 :         opId.srcRank = topoInfo_.userRank;
    4741            0 :         opId.detRank = sendrecvPair->remoteRank;
    4742              :     }
    4743            0 :     opId.index = HcclUpdateBatchSendRecvOpIndex(sendrecvPair->sendRecvType, opId.srcRank, opId.detRank);
    4744            0 :     opId.isSendRecv = true;
    4745            0 :     opId.opType = HcclCMDType::HCCL_CMD_BATCH_SEND_RECV;
    4746            0 :     std::string sendrecvTag = param.tag + "_BSR_" + std::to_string(opId.srcRank) + "_" + std::to_string(opId.detRank);
    4747            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(opId.tag, sizeof(opId.tag), sendrecvTag.c_str(), sendrecvTag.size()));
    4748            0 :     std::string sendrecvNewTag = param.tag + "_device";
    4749            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(opId.newTag, sizeof(opId.newTag), sendrecvNewTag.c_str(), sendrecvNewTag.size()));
    4750              : 
    4751            0 :     u32 qpn = 0;
    4752            0 :     if ((opId.srcRank != opId.detRank) && (!param.BatchSendRecvDataDes.isDirectRemoteRank[sendrecvPair->remoteRank])) {
    4753            0 :         CHK_RET(GetBsrTransportQpn(sendrecvPair, algResource, qpn));
    4754              :     }
    4755              : 
    4756            0 :     auto& bsrinfo = opId.bsrInfo[sendrecvPair->sendRecvType];
    4757            0 :     bsrinfo.detRank = opId.detRank;
    4758            0 :     bsrinfo.srcRank = opId.srcRank;
    4759            0 :     bsrinfo.index = opId.index;
    4760            0 :     bsrinfo.streamId = streamId;
    4761            0 :     bsrinfo.tpQpn = qpn;
    4762            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(bsrinfo.bsrTag, sizeof(bsrinfo.bsrTag), sendrecvTag.c_str(), sendrecvTag.size()));
    4763              : 
    4764            0 :     HCCL_INFO(
    4765              :         "[HcclCommAicpu][InitBatchSendRecvOpId] tag=[%s] index=[%u] src=[%u] det=[%u] qpn =[%u]", opId.tag, opId.index,
    4766              :         opId.srcRank, opId.detRank, qpn);
    4767            0 :     return HCCL_SUCCESS;
    4768            0 : }
    4769              : 
    4770            0 : HcclResult HcclCommAicpu::InitBatchSendRecvOpId(const OpParam& param, AlgResourceResponse& algResource)
    4771              : {
    4772            0 :     CHK_SAFETY_FUNC_RET(
    4773              :         memset_s(reinterpret_cast<void*>(&bsrSendOpId_), sizeof(bsrSendOpId_), 0, sizeof(bsrSendOpId_)));
    4774            0 :     CHK_SAFETY_FUNC_RET(
    4775              :         memset_s(reinterpret_cast<void*>(&bsrRecvOpId_), sizeof(bsrRecvOpId_), 0, sizeof(bsrRecvOpId_)));
    4776              : 
    4777            0 :     CHK_PRT_RET(
    4778              :         (algResource.slaveStreams.size() < BSR_RETRY_STREAM_NUM),
    4779              :         HCCL_ERROR("in batchsendrecv op, slave stream is not enough."), HCCL_E_INTERNAL);
    4780            0 :     bsrSendOpId_.streamId = algResource.slaveStreams[BSR_RETRY_SEND_STREAM_INDEX].id();
    4781            0 :     bsrRecvOpId_.streamId = algResource.slaveStreams[BSR_RETRY_RECV_STREAM_INDEX].id();
    4782              : 
    4783            0 :     u32 iter = param.BatchSendRecvDataDes.curIterNum;
    4784            0 :     std::vector<std::vector<HcclSendRecvItem*>>& pairs = bsrSendRecvPairs_;
    4785            0 :     CHK_PRT_RET(
    4786              :         (pairs.size() <= iter),
    4787              :         HCCL_ERROR("batchsendrecv sendrecv pairs size[%u] less than or equal to curiter[%u]", pairs.size(), iter),
    4788              :         HCCL_E_INTERNAL);
    4789              : 
    4790            0 :     for (auto& pair : pairs[iter]) {
    4791            0 :         HcclOpIdentifier& opId = (pair->sendRecvType == HcclSendRecvType::HCCL_SEND) ? bsrSendOpId_ : bsrRecvOpId_;
    4792            0 :         auto streamId
    4793            0 :             = (pair->sendRecvType == HcclSendRecvType::HCCL_SEND) ? bsrSendOpId_.streamId : bsrRecvOpId_.streamId;
    4794            0 :         CHK_RET(InitBatchSendRecvOpId(param, pair, opId, streamId, algResource));
    4795              :     }
    4796              : 
    4797              :     // 补全batchsendrecv中sendrecv的bsrInfo, 两边都发生故障的时候要用
    4798            0 :     bsrSendOpId_.bsrInfo[HCCL_RECV].index = bsrRecvOpId_.index;
    4799            0 :     bsrSendOpId_.bsrInfo[HCCL_RECV].streamId = bsrRecvOpId_.streamId;
    4800            0 :     bsrSendOpId_.bsrInfo[HCCL_RECV].srcRank = bsrRecvOpId_.srcRank;
    4801            0 :     bsrSendOpId_.bsrInfo[HCCL_RECV].detRank = bsrRecvOpId_.detRank;
    4802            0 :     bsrSendOpId_.bsrInfo[HCCL_RECV].tpQpn = bsrRecvOpId_.bsrInfo[HCCL_RECV].tpQpn;
    4803            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(
    4804              :         bsrSendOpId_.bsrInfo[HCCL_RECV].bsrTag, sizeof(bsrSendOpId_.bsrInfo[HCCL_RECV].bsrTag), bsrRecvOpId_.tag,
    4805              :         sizeof(bsrRecvOpId_.tag)));
    4806              : 
    4807            0 :     bsrRecvOpId_.bsrInfo[HCCL_SEND].index = bsrSendOpId_.index;
    4808            0 :     bsrRecvOpId_.bsrInfo[HCCL_SEND].streamId = bsrSendOpId_.streamId;
    4809            0 :     bsrRecvOpId_.bsrInfo[HCCL_SEND].srcRank = bsrSendOpId_.srcRank;
    4810            0 :     bsrRecvOpId_.bsrInfo[HCCL_SEND].detRank = bsrSendOpId_.detRank;
    4811            0 :     bsrRecvOpId_.bsrInfo[HCCL_SEND].tpQpn = bsrSendOpId_.bsrInfo[HCCL_SEND].tpQpn;
    4812            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(
    4813              :         bsrRecvOpId_.bsrInfo[HCCL_SEND].bsrTag, sizeof(bsrRecvOpId_.bsrInfo[HCCL_SEND].bsrTag), bsrSendOpId_.tag,
    4814              :         sizeof(bsrSendOpId_.tag)));
    4815            0 :     return HCCL_SUCCESS;
    4816              : }
    4817              : 
    4818            0 : HcclResult HcclCommAicpu::QueryBatchSendRecvPairBeginPos()
    4819              : {
    4820              :     // 前面已经生成 batchsendrecv 的 send & recv opid 时已经校验过slave stream num数,此处不再重复校验
    4821            0 :     CHK_RET(QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrSendOpBeginSqePos_));
    4822            0 :     CHK_RET(QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrRecvOpBeginSqePos_));
    4823              : 
    4824            0 :     HCCL_INFO(
    4825              :         "QueryBatchSendRecvPairBeginPos send sqePos[%u] recv sqePos[%u]", bsrSendOpBeginSqePos_, bsrRecvOpBeginSqePos_);
    4826            0 :     return HCCL_SUCCESS;
    4827              : }
    4828              : 
    4829            0 : HcclResult HcclCommAicpu::QueryBatchSendRecvPairEndPos()
    4830              : {
    4831              :     // 前面已经生成 batchsendrecv 的 send & recv opid 时已经校验过slave stream num数,此处不再重复校验
    4832            0 :     CHK_RET(QuerySqStatusByType(devId_, bsrSendStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrSendOpEndSqePos_));
    4833            0 :     CHK_RET(QuerySqStatusByType(devId_, bsrRecvStream_.sqId(), DRV_SQCQ_PROP_SQ_TAIL, bsrRecvOpEndSqePos_));
    4834              : 
    4835            0 :     HCCL_INFO("QueryBatchSendRecvPairEndPos send sqePos[%u] recv sqePos[%u]", bsrSendOpEndSqePos_, bsrRecvOpEndSqePos_);
    4836            0 :     return HCCL_SUCCESS;
    4837              : }
    4838              : 
    4839            0 : HcclResult HcclCommAicpu::CommitBSRStoredException(HcclOpExecFSM& fsmState, KfcError& errorCode)
    4840              : {
    4841            0 :     if (GetBSRSendOpExecException()) {
    4842            0 :         bsrRetryOp_ = HCCL_SEND;
    4843            0 :         errorCode = KfcError::kSdma;
    4844            0 :         HCCL_INFO("CommitBSRStoredException: send stream remain retry error.");
    4845            0 :     } else if (GetBSRRecvOpExecException()) {
    4846            0 :         bsrRetryOp_ = HCCL_RECV;
    4847            0 :         errorCode = KfcError::kSdma;
    4848            0 :         HCCL_INFO("CommitBSRStoredException: recv stream remain retry error.");
    4849              :     }
    4850              : 
    4851            0 :     u32 retryCnt = (bsrRetryOp_ == HCCL_SEND) ? bsrSendRetryCnt_ : bsrRecvRetryCnt_;
    4852            0 :     if (errorCode != KfcError::kNone) {
    4853            0 :         bsrTargetOpId_ = (bsrRetryOp_ == HCCL_SEND) ? bsrSendOpId_ : bsrRecvOpId_;
    4854            0 :         HCCL_RUN_INFO(
    4855              :             "CommitBSRStoredException: stored op tag %s index %u , report retry error. curSendRetryCnt[%u],"
    4856              :             "curRecvRetryCnt[%u]",
    4857              :             bsrTargetOpId_.tag, bsrTargetOpId_.index, bsrSendRetryCnt_, bsrRecvRetryCnt_);
    4858            0 :         auto ret = aicpuHdc_.SetOpExecStatus(
    4859            0 :             kfcStatusTransferD2H_, bsrTargetOpId_, KfcStatus::kStoplaunch, errorCode, retryCnt);
    4860            0 :         HCCL_RETRY_CHK_RET_AND_TRANS_FSM(
    4861              :             ret, HCCL_ERROR("SetOpExecStatus failed, ret:%u", ret), KfcError::kExec,
    4862              :             HcclOpExecFSM::HCCL_OP_EXEC_FSM_ERROR);
    4863            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_STOPPING;
    4864              :     } else {
    4865            0 :         CHK_RET(UpdateOpExecStatus(fsmState, KfcStatus::kRuning, errorCode, retryCnt));
    4866            0 :         fsmState = HcclOpExecFSM::HCCL_OP_EXEC_FSM_WAIT_END;
    4867              :     }
    4868            0 :     return HCCL_SUCCESS;
    4869              : }
    4870              : 
    4871            0 : HcclResult HcclCommAicpu::GetBSRRetryOpId(const OpParam& param, HcclOpIdentifier& targetOpId)
    4872              : {
    4873            0 :     KfcCommand cmd = KfcCommand::kNone;
    4874            0 :     CHK_RET(aicpuHdc_.GetOpExecCtrlCmd(kfcControlTransferH2D_, cmd));
    4875            0 :     if (cmd == KfcCommand::kStopLaunch) {
    4876            0 :         HcclOpIdentifier targetOp;
    4877            0 :         CHK_RET(aicpuHdc_.GetOpExecCtrlTargetOp(kfcControlTransferH2D_, targetOp));
    4878            0 :         std::string targetOpTag = std::string(reinterpret_cast<char*>(&targetOp.tag[0]));
    4879            0 :         if (targetOpTag == std::string(reinterpret_cast<char*>(&bsrSendOpId_.tag[0]))) {
    4880            0 :             bsrRetryOp_ = HCCL_SEND;
    4881            0 :         } else if (targetOpTag == std::string(reinterpret_cast<char*>(&bsrRecvOpId_.tag[0]))) {
    4882            0 :             bsrRetryOp_ = HCCL_RECV;
    4883            0 :         } else if (targetOpTag == param.tag) {
    4884            0 :             if (targetOp.detRank == bsrSendOpId_.detRank) {
    4885            0 :                 bsrRetryOp_ = HCCL_SEND;
    4886            0 :             } else if (targetOp.srcRank == bsrRecvOpId_.srcRank) {
    4887            0 :                 bsrRetryOp_ = HCCL_RECV;
    4888              :             } else {
    4889            0 :                 HCCL_ERROR(
    4890              :                     "hccl aicpu can not retry, got stop launch command, but target op srcRank[%u] and"
    4891              :                     "dstRank[%u] is not match with send (dst:%u) or recv (src:%u) op",
    4892              :                     targetOp.srcRank, targetOp.detRank, bsrSendOpId_.detRank, bsrRecvOpId_.srcRank);
    4893            0 :                 return HCCL_E_INTERNAL;
    4894              :             }
    4895              :         } else {
    4896              :             // tag 不匹配,报错退出
    4897            0 :             HCCL_ERROR(
    4898              :                 "hccl aicpu can not retry, got stop launch command, but target op tag[%s] is not match with"
    4899              :                 "send (tag:%s) or recv (tag:%s) or batchsendrecv (tag:%s)",
    4900              :                 targetOpTag.c_str(), bsrSendOpId_.tag, bsrRecvOpId_.tag, param.tag.c_str());
    4901            0 :             return HCCL_E_INTERNAL;
    4902              :         }
    4903            0 :         HCCL_RUN_INFO("hccl aicpu got command %u at op[tag: %s, index: %u].", cmd, targetOpTag.c_str(), targetOp.index);
    4904            0 :     } else {
    4905            0 :         if (GetBSRSendOpExecException()) {
    4906            0 :             bsrRetryOp_ = HCCL_SEND;
    4907            0 :         } else if (GetBSRRecvOpExecException()) {
    4908            0 :             bsrRetryOp_ = HCCL_RECV;
    4909              :         } else {
    4910              :             // 其他场景,报错退出
    4911            0 :             HCCL_ERROR("hccl aicpu find task exception, but send and recv op has no exception");
    4912            0 :             return HCCL_E_INTERNAL;
    4913              :         }
    4914              :     }
    4915            0 :     if (bsrRetryOp_ == HCCL_SEND) {
    4916            0 :         targetOpId = bsrSendOpId_;
    4917              :     } else {
    4918            0 :         targetOpId = bsrRecvOpId_;
    4919              :     }
    4920            0 :     HCCL_RUN_INFO(
    4921              :         "GetBSRRetryOpId: bsrRetryOpType %u, targetOpId: tag %s, index %u", bsrRetryOp_, targetOpId.tag,
    4922              :         targetOpId.index);
    4923            0 :     return HCCL_SUCCESS;
    4924              : }
    4925              : 
    4926            0 : HcclResult HcclCommAicpu::InitExecLoop(OpParam& param, std::unique_ptr<CollExecutorBase>& executor, u32& loopNum)
    4927              : {
    4928            0 :     if ((param.opType == HcclCMDType::HCCL_CMD_BATCH_SEND_RECV) && retryEnable_) {
    4929            0 :         CHK_RET(executor->CreatePairWiseList(
    4930              :             param.BatchSendRecvDataDes.sendRecvItemsPtr, param.BatchSendRecvDataDes.itemNum));
    4931            0 :         CHK_RET(executor->GetPairWiseList(bsrSendRecvPairs_));
    4932            0 :         CHK_PRT_RET(
    4933              :             bsrSendRecvPairs_.empty(), HCCL_ERROR("[HcclCommAicpu][InitExecLoop]batchsendrecv pairs is empty"),
    4934              :             HCCL_E_INTERNAL);
    4935              : 
    4936            0 :         for (size_t i = 0; i < bsrSendRecvPairs_.size(); i++) {
    4937            0 :             CHK_PRT_RET(
    4938              :                 (bsrSendRecvPairs_[i].size() > BSR_RETRY_SENDRECV_PAIR_NUM_MAX) || bsrSendRecvPairs_[i].empty(),
    4939              :                 HCCL_ERROR("batchsendrecv pairs[%u] size[%u] is out of range [1,2]", i, bsrSendRecvPairs_[i].size()),
    4940              :                 HCCL_E_INTERNAL);
    4941              : 
    4942            0 :             for (size_t j = 0; j < bsrSendRecvPairs_[i].size(); j++) {
    4943            0 :                 CHK_PTR_NULL(bsrSendRecvPairs_[i][j]);
    4944              :             }
    4945              : 
    4946            0 :             CHK_PRT_RET(
    4947              :                 ((bsrSendRecvPairs_[i].size() == BSR_RETRY_SENDRECV_PAIR_NUM_MAX)
    4948              :                  && (bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_0]->sendRecvType
    4949              :                      == bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_1]->sendRecvType)),
    4950              :                 HCCL_ERROR(
    4951              :                     "batchsendrecv pairs[%u] sendRecvType[%u] is same", i,
    4952              :                     bsrSendRecvPairs_[i][BSR_RETRY_SENDRECV_PAIR_INDEX_0]->sendRecvType),
    4953              :                 HCCL_E_INTERNAL);
    4954              :         }
    4955              : 
    4956            0 :         param.BatchSendRecvDataDes.curIterNum = 0;
    4957            0 :         loopNum = bsrSendRecvPairs_.size();
    4958            0 :     } else {
    4959            0 :         loopNum = 1;
    4960              :     }
    4961            0 :     HCCL_INFO("InitExecLoop: execute loop num %u", loopNum);
    4962            0 :     return HCCL_SUCCESS;
    4963              : }
    4964              : 
    4965            1 : HcclResult HcclCommAicpu::ParseHierarchicalAlgOption(u32* ahcConfInfo)
    4966              : {
    4967            1 :     u32 algOptionSize = ahcConfInfo[TOP_HIERARCHICAL_CONF_lENGTH_INDEX];
    4968            1 :     if (algOptionSize >= (TOP_HIERARCHICAL_CONF_SIZE - 1)) {
    4969            1 :         HCCL_ERROR(
    4970              :             "[HcclCommAicpu][ParseHierarchicalAlgOption] hierarchicalAlgOption size[%lu] exceed maxsize[%lu]",
    4971              :             algOptionSize, (TOP_HIERARCHICAL_CONF_SIZE - 1));
    4972            1 :         return HCCL_E_INTERNAL;
    4973              :     }
    4974              : 
    4975            0 :     std::map<AHCConcOpType, TemplateType> hierarchicalAlgOption;
    4976            0 :     for (u32 i = TOP_HIERARCHICAL_CONF_INFO_INDEX; i < (TOP_HIERARCHICAL_CONF_INFO_INDEX + algOptionSize); i++) {
    4977            0 :         AHCConcOpType ahcConcOpType;
    4978            0 :         ahcConcOpType.ahcLevel = static_cast<AHCLevel>(
    4979            0 :             (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_LEVEL_LOCATION) >> TOP_HIERARCHICAL_CONF_LEVEL_SHIFT);
    4980            0 :         ahcConcOpType.concType = static_cast<ConcType>(
    4981            0 :             (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_CONC_TYPE_LOCATION) >> TOP_HIERARCHICAL_CONF_CONC_TYPE_SHIFT);
    4982            0 :         ahcConcOpType.ahcOpType = static_cast<AHCOpType>(
    4983            0 :             (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_OP_TYPE_LOCATION) >> TOP_HIERARCHICAL_CONF_OP_TYPE_SHIFT);
    4984            0 :         TemplateType templateType = static_cast<TemplateType>(
    4985            0 :             (ahcConfInfo[i] & TOP_HIERARCHICAL_CONF_TEMPLATE_TYPE_LOCATION)
    4986              :             >> TOP_HIERARCHICAL_CONF_TEMPLATE_TYPE_SHIFT);
    4987              : 
    4988            0 :         hierarchicalAlgOption[ahcConcOpType] = templateType;
    4989            0 :         HCCL_DEBUG(
    4990              :             "[HcclCommAicpu][ParseHierarchicalAlgOption]: index[%u] ahcLevel[%u] concType[%u] ahcOpType[%u], "
    4991              :             "templateType[%u]",
    4992              :             i, ahcConcOpType.ahcLevel, ahcConcOpType.concType, ahcConcOpType.ahcOpType, templateType);
    4993              :     }
    4994            0 :     topoMatcher_->SetAHCAlgOption(hierarchicalAlgOption);
    4995            0 :     return HCCL_SUCCESS;
    4996            0 : }
    4997              : 
    4998            0 : void HcclCommAicpu::PollCqeException(
    4999              :     hccl::Stream& stream, bool isReadClear, rtLogicCqReport_t& cqeException, CqeStatus& cqeStatus)
    5000              : {
    5001            0 :     const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
    5002              :     // 以下条件满足其中之一,进行Poll CQE:1、AICPU/Custom读清CQ   2、AICPU进程读取CQ信息
    5003            0 :     bool isPollCqe = true;
    5004            0 :     while (isPollCqe) {
    5005            0 :         LogControl logControl(false, retryEnable_); // 使能重执行场景,修改ERROR->RUN_WARNING,析构时自动恢复
    5006              :         CqeQueryInput cqeQueryInput;
    5007            0 :         dfx_tracer::ExecutorTracer::SetCqeQueryInput(GetDevId(), streamInfo, cqeQueryInput);
    5008            0 :         constexpr u32 reportSize = 256;
    5009              :         rtLogicCqReport_t streamReport[reportSize];
    5010            0 :         cqeQueryInput.cqeAddr = reinterpret_cast<uint8_t*>(streamReport); // 用于存放接收到的cq
    5011            0 :         cqeStatus = CqReportRecv(cqeQueryInput, cqeException);
    5012            0 :         isPollCqe = (cqeStatus == dfx::CqeStatus::kCqeException && isReadClear); // 读清CQ场景,继续查询
    5013            0 :     }
    5014            0 : }
    5015              : 
    5016            0 : void HcclCommAicpu::ExchangeCqeContext(
    5017              :     hccl::Stream& stream, rtLogicCqReport_t& cqeException, CqeStatus& cqeStatus, ErrCqeContext& cqeCtx)
    5018              : {
    5019            0 :     HcclResult ret = HCCL_SUCCESS;
    5020              :     // aicpu进程把读取到的异常cq,写入共享内存
    5021            0 :     if (cqeStatus == dfx::CqeStatus::kCqeException) {
    5022            0 :         ret = stream.SetCqeContext(ErrCqeContext(
    5023            0 :             static_cast<u32>(cqeStatus), cqeException.taskId, cqeException.errorCode, cqeException.sqeType));
    5024              :     }
    5025              : 
    5026              :     // aicpu进程和custom进程,都从共享内存中读取cqe信息
    5027            0 :     if (ret != HCCL_SUCCESS || stream.GetCqeContext(cqeCtx) != HCCL_SUCCESS) {
    5028              :         // 写入/读取共享内存失败,标记流状态,避免背景线程继续轮询这条流,导致刷屏
    5029            0 :         SetStreamCqeExceptionStatus(stream, CqeExceptionStatus::kOther);
    5030            0 :         HCCL_ERROR(
    5031              :             "%s fail, set streamCqeExceptionStatus streamId[%u] exception status[%d]", __func__, stream.id(),
    5032              :             CqeExceptionStatus::kOther);
    5033            0 :         return;
    5034              :     }
    5035              : }
    5036              : 
    5037            0 : void HcclCommAicpu::HandleCqeException(hccl::Stream& stream, bool isReadClear)
    5038              : {
    5039            0 :     std::unique_lock<std::mutex> lock(queryCqeMutex_);
    5040              : 
    5041              :     // poll cqe信息
    5042              :     rtLogicCqReport_t cqeException;
    5043            0 :     CqeStatus cqeStatus = CqeStatus::kDefault;
    5044            0 :     PollCqeException(stream, isReadClear, cqeException, cqeStatus);
    5045              : 
    5046              :     // 以下两种情况直接返回,不处理cq信息:1、读清CQ场景只读取不处理 2、本地记录流上已经有异常信息(避免刷屏)
    5047            0 :     if (isReadClear || GetStreamCqeExceptionStatus(stream) != CqeExceptionStatus::kNone) {
    5048            0 :         return;
    5049              :     }
    5050              : 
    5051              :     // aicpu和custom同步异常cqe信息,并记录在本地
    5052            0 :     ErrCqeContext cqeCtx;
    5053            0 :     ExchangeCqeContext(stream, cqeException, cqeStatus, cqeCtx);
    5054            0 :     cqeStatus = static_cast<dfx::CqeStatus>(cqeCtx.cqeStatus);
    5055              : 
    5056              :     // 处理流上的异常cq
    5057            0 :     if (cqeStatus != dfx::CqeStatus::kDefault) {
    5058            0 :         bool isSdmaTypeErr = cqeStatus == dfx::CqeStatus::kCqeException && cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA;
    5059            0 :         bool isCompDataErr = cqeCtx.errorCode == RT_SDMA_COMPDATAERR || cqeCtx.errorCode == RT_SDMA_COMPERR
    5060            0 :                              || cqeCtx.errorCode == RT_SDMA_DATAERR;
    5061            0 :         bool isSdmaCompDataErr = isSdmaTypeErr && isCompDataErr;
    5062              : 
    5063            0 :         ReportErrCqe(stream, cqeCtx);
    5064              : 
    5065              :         // 标记发生ErrCqe的流
    5066            0 :         hccl::CqeExceptionStatus cqeExceptionStatus
    5067            0 :             = isSdmaCompDataErr ? hccl::CqeExceptionStatus::kSdmaErr : hccl::CqeExceptionStatus::kOther;
    5068            0 :         SetStreamCqeExceptionStatus(stream, cqeExceptionStatus);
    5069              : 
    5070              :         // 通知kfc线程
    5071            0 :         dfxExtendInfo_.cqeException.sqeType = cqeCtx.sqeType;
    5072            0 :         dfxExtendInfo_.cqeException.errorCode = cqeCtx.errorCode;
    5073            0 :         dfxExtendInfo_.cqeStatus = cqeStatus;
    5074            0 :         dfxExtendInfo_.pollStatus = PollStatus::kStopAsException;
    5075            0 :         HCCL_INFO(
    5076              :             "update dfxExtendInfo, group %s, streamId %u, cqeStatus %d, sqetype %u, errorCode %u", identifier_.c_str(),
    5077              :             stream.id(), cqeStatus, cqeCtx.sqeType, cqeCtx.errorCode);
    5078              :     }
    5079            0 : }
    5080              : 
    5081            0 : void HcclCommAicpu::ReportErrCqe(hccl::Stream& stream, ErrCqeContext& cqeCtx)
    5082              : {
    5083            0 :     dfx::CqeStatus cqeStatus = static_cast<dfx::CqeStatus>(cqeCtx.cqeStatus);
    5084            0 :     const HcclComStreamInfo& streamInfo = stream.GetHcclStreamInfo();
    5085            0 :     u32 head = 0;
    5086            0 :     u32 tail = 0;
    5087            0 :     QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_HEAD, head);
    5088            0 :     QuerySqStatusByType(devId_, streamInfo.sqId, DRV_SQCQ_PROP_SQ_TAIL, tail);
    5089              : 
    5090            0 :     bool isSdmaTypeErr = cqeStatus == dfx::CqeStatus::kCqeException && cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA;
    5091            0 :     bool isCompDataErr = cqeCtx.errorCode == RT_SDMA_COMPDATAERR || cqeCtx.errorCode == RT_SDMA_COMPERR
    5092            0 :                          || cqeCtx.errorCode == RT_SDMA_DATAERR;
    5093            0 :     bool isSdmaCompDataErr = isSdmaTypeErr && isCompDataErr;
    5094              : 
    5095              :     // 发生sdma、notify_wait、place_holder、write_value错误,上报error message
    5096            0 :     bool isComReportErrMesg
    5097              :         = cqeStatus == dfx::CqeStatus::kCqeException
    5098            0 :           && (cqeCtx.sqeType == RT_STARS_SQE_TYPE_SDMA || cqeCtx.sqeType == RT_STARS_SQE_TYPE_NOTIFY_WAIT
    5099            0 :               || cqeCtx.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER || cqeCtx.sqeType == RT_STARS_SQE_TYPE_WRITE_VALUE);
    5100              : 
    5101              :     // 使能重执行且触发SDMA ERROR的场景,修改ERROR->RUN_WARNING
    5102            0 :     LogControl retryLog(false, retryEnable_ && isSdmaCompDataErr);
    5103              : 
    5104              :     // 只在AICPU进程上报taskException,Custom进程不上报
    5105            0 :     if (isComReportErrMesg && errMessageReport_) {
    5106              :         // 记录关键信息,并通过D2H通信通道交给host内存
    5107            0 :         GenTaskExceptionInfo(cqeCtx.sqeType, stream, head);
    5108              :         // 通知ts错误信息,触发非SDMA错误、不使能重执行触发SDMA错误、使能重执行触发无法重执行的错误时,进行故障上报
    5109            0 :         if (!isSdmaTypeErr || (isSdmaTypeErr && (!retryEnable_ || !isCompDataErr))) {
    5110            0 :             HcclResult ret = SendTaskExceptionByMBox(cqeCtx.errorCode);
    5111            0 :             HCCL_RUN_INFO(
    5112              :                 "[HcclCommAicpu][SendTaskExceptionByMBox]group[%s]:"
    5113              :                 "Try to send task exception by mailbox, errType[%u], errCode[%u], streamId[%d]",
    5114              :                 identifier_.c_str(), cqeCtx.sqeType, cqeCtx.errorCode, stream.id());
    5115            0 :             CHK_PRT_CONT(
    5116              :                 ret != HCCL_SUCCESS,
    5117              :                 HCCL_ERROR(
    5118              :                     "[OpRetry][AICPU]group[%s]:Send task exception by mailBox failed, streamId[%d]",
    5119              :                     identifier_.c_str(), stream.id()));
    5120              :         }
    5121              :         // 当前阶段, 每个通信域在plog打印一次,error message作为host上报,只打印首次
    5122            0 :         errMessageReport_ = false;
    5123              :     }
    5124              : 
    5125              :     // 发生ErrCqe之后,统一在AICPU进程上报taskException
    5126            0 :     if (cqeStatus == dfx::CqeStatus::kCqeException) {
    5127            0 :         if (IsNoNeedWait() && cqeCtx.sqeType == RT_STARS_SQE_TYPE_PLACE_HOLDER) {
    5128            0 :             PrintTaskExceptionAllComm(); // 超时场景打印所有通信域的taskException
    5129            0 :             PrintAicpuCommExecStatus();
    5130            0 :         } else if (IsNoNeedWait()) {
    5131            0 :             ErrCqeContext cqeCtx;
    5132            0 :             stream.GetCqeContext(cqeCtx);
    5133            0 :             PrintTaskExceptionByTaskId(cqeCtx.sqeType, cqeCtx.taskId, stream, tail); // 仅打印本条流的taskException
    5134              :         }
    5135              :     }
    5136              : 
    5137            0 :     CHK_PRT_CONT(
    5138              :         !retryEnable_ && isSdmaCompDataErr,
    5139              :         HCCL_RUN_INFO(
    5140              :             "[OpRetry][AICPU]group[%s] hccl aicpu can not retry, retryEnable is false.", identifier_.c_str()));
    5141              : 
    5142            0 :     CHK_PRT_CONT(
    5143              :         retryEnable_ && isSdmaTypeErr && !isCompDataErr,
    5144              :         HCCL_RUN_INFO(
    5145              :             "[OpRetry][AICPU]group[%s] hccl aicpu can not retry, errCode is [%u].", identifier_.c_str(),
    5146              :             cqeCtx.errorCode));
    5147              : 
    5148            0 :     HCCL_ERROR(
    5149              :         "Exception happened, group %s, sqid %d, cqeStatus %d, sqetype %u, errorCode %u, head %u, tail %u",
    5150              :         identifier_.c_str(), streamInfo.sqId, cqeStatus, cqeCtx.sqeType, cqeCtx.errorCode, head, tail);
    5151            0 : }
    5152              : 
    5153            0 : HcclResult HcclCommAicpu::SendTaskExceptionByMBox(const uint16_t& rsErrorCode)
    5154              : {
    5155              :     HcclSignalInfo notifyInfo;
    5156            0 :     opNotifies_[1]->GetNotifyData(notifyInfo);
    5157              : 
    5158            0 :     HCCL_INFO("[HcclCommAicpu][SendTaskExceptionByMBox] HostToDeviceLogicId[%u]", devId_);
    5159            0 :     CHK_RET(hccl_plf::SendTaskExceptionByMBox(
    5160              :         devId_, 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 remote 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
        

Generated by: LCOV version 2.0-1