LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/resource/transport/host - transport_direct_npu.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 595 0
Test Date: 2026-08-04 10:52:23 Functions: 0.0 % 65 0

            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 <arpa/inet.h>
      12              : #include <securec.h>
      13              : #include <string>
      14              : #include "network/hccp_common.h"
      15              : #include "network_manager_pub.h"
      16              : #include "externalinput_pub.h"
      17              : #include "hccl_network.h"
      18              : #include "transport_direct_npu.h"
      19              : #include "launch_aicpu.h"
      20              : #include "acl/acl_rt.h"
      21              : 
      22              : using namespace std;
      23              : 
      24              : namespace hccl {
      25              : UniversalConcurrentMap<u64, TransportDirectNpu*> TransportDirectNpu::g_qpn2IbversLinkMap_;
      26              : bool TransportDirectNpu::g_flag = false;
      27              : bool TransportDirectNpu::g_isSupCqeErrInfoListConfig = false;
      28              : u32 TransportDirectNpu::cqeErrQpn_ = 0;
      29              : 
      30              : constexpr u32 DEV_PHY_ID_BIT = 32;
      31              : constexpr u32 CQE_ARRAY_SIZE = 128;
      32              : 
      33            0 : TransportDirectNpu::TransportDirectNpu(DispatcherPub *dispatcher,
      34              :                                    const std::unique_ptr<NotifyPool> &notifyPool,
      35              :                                    MachinePara &machinePara,
      36            0 :                                    std::chrono::milliseconds timeout)
      37              :     : TransportNet(dispatcher, notifyPool, machinePara, timeout),
      38            0 :       qpsPerConnection_(1), access_(RA_ACCESS_LOCAL_WRITE | RA_ACCESS_REMOTE_WRITE | RA_ACCESS_REMOTE_READ),
      39            0 :       workFlowMode_(HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB),
      40            0 :       currentQP_(0), qpMode_(machinePara.qpMode)
      41              : {
      42            0 : }
      43              : 
      44            0 : TransportDirectNpu::~TransportDirectNpu()
      45              : {
      46            0 :     HCCL_DEBUG("~TransportDirectNpu Enter!");
      47              : 
      48            0 :     (void)DeInit();
      49            0 :     UnloadAICPUKernel();
      50              : 
      51            0 :     HCCL_DEBUG("~TransportDirectNpu Success!");
      52            0 : }
      53              : 
      54            0 : HcclResult TransportDirectNpu::DeInit()
      55              : {
      56            0 :     (void)DeRegMR();
      57              : 
      58            0 :     (void)DestroyQP();
      59              : 
      60            0 :     (void)DestroyAicpuMem();
      61              : 
      62            0 :     return HCCL_SUCCESS;
      63              : }
      64              : 
      65            0 : HcclResult TransportDirectNpu::GetRemoteMem(UserMemType memType, void **remotePtr)
      66              : {
      67            0 :     HCCL_INFO("[TransportDirectNpu][GetRemoteMem] direct npu getRemoteMem");
      68            0 :     switch (memType) {
      69            0 :         case UserMemType::INPUT_MEM:
      70              :         case UserMemType::OUTPUT_MEM:
      71            0 :             *remotePtr = remoteMemMsg_[static_cast<u32>(memType)].addr;
      72            0 :             break;
      73              : 
      74            0 :         default:
      75            0 :             HCCL_ERROR("[Get][RemoteMem]not support dst_mem_type=%d", memType);
      76            0 :             return HCCL_E_NOT_SUPPORT;
      77              :     }
      78            0 :     return HCCL_SUCCESS;
      79              : }
      80              : 
      81            0 : HcclResult TransportDirectNpu::GetLocalNotifyValueAddrKey(std::vector<AddrKey> &notifyValue)
      82              : {
      83              :     // 目前这里时随意填充了一些数据上去,不然会调用到基类接口,导致报错
      84            0 :     AddrKey notifyDetails;
      85            0 :     notifyDetails.addr = reinterpret_cast<u64>(memMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].addr);
      86            0 :     notifyDetails.key = reinterpret_cast<u32>(memMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].lkey);
      87            0 :     notifyValue.push_back(notifyDetails);
      88            0 :     notifyValue.push_back(notifyDetails);
      89            0 :     notifyValue.push_back(notifyDetails);
      90            0 :     return HCCL_SUCCESS;
      91              : }
      92              : 
      93            0 : HcclResult TransportDirectNpu::GetLocalRdmaNotify(std::vector<HcclSignalInfo> &rdmaNotify)
      94              : {
      95            0 :     HcclSignalInfo signalInfo = {};
      96            0 :     rdmaNotify.push_back(signalInfo);
      97            0 :     rdmaNotify.push_back(signalInfo);
      98            0 :     rdmaNotify.push_back(signalInfo);
      99            0 :     return HCCL_SUCCESS;
     100              : }
     101              : 
     102            0 : HcclResult TransportDirectNpu::GetRemoteRdmaNotifyAddrKey(std::vector<AddrKey> &rdmaNotifyAddr)
     103              : {
     104            0 :     AddrKey notifyDetails;
     105            0 :     notifyDetails.addr = reinterpret_cast<u64>(memMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].addr);
     106            0 :     notifyDetails.key = reinterpret_cast<u32>(memMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].lkey);
     107            0 :     rdmaNotifyAddr.push_back(notifyDetails);
     108            0 :     rdmaNotifyAddr.push_back(notifyDetails);
     109            0 :     rdmaNotifyAddr.push_back(notifyDetails);
     110            0 :     return HCCL_SUCCESS;
     111              : }
     112              : 
     113            0 : HcclResult TransportDirectNpu::GetRemoteMemSize(UserMemType memType, u64 &size)
     114              : {
     115            0 :     HCCL_INFO("[TransportDirectNpu][GetRemoteMem] direct npu GetRemoteMemSize");
     116            0 :     switch (memType) {
     117            0 :         case UserMemType::INPUT_MEM:
     118              :         case UserMemType::OUTPUT_MEM:
     119            0 :             size = remoteMemMsg_[static_cast<u32>(memType)].len;
     120            0 :             break;
     121              : 
     122            0 :         default:
     123            0 :             HCCL_ERROR("[Get][RemoteMem]not support dst_mem_type=%d", memType);
     124            0 :             return HCCL_E_NOT_SUPPORT;
     125              :     }
     126            0 :     return HCCL_SUCCESS;
     127              : }
     128              : 
     129            0 : HcclResult TransportDirectNpu::LoadBinaryFromFile(const char *binPath, aclrtBinaryLoadOptionType optionType, uint32_t cpuKernelMode,
     130              :                                                 aclrtBinHandle &binHandle)
     131              : {
     132              : #ifndef CCL_KERNEL
     133              :     CHK_PRT_RET(binPath == nullptr,
     134              :         HCCL_ERROR("[LoadBinaryFromFile] binary path is nullptr"),
     135              :         HCCL_E_PTR);
     136              : 
     137              :     char realPath[PATH_MAX] = {0};
     138              :     CHK_PRT_RET(realpath(binPath, realPath) == nullptr,
     139              :         HCCL_ERROR("LoadBinaryFromFile: %s is not a valid real path, err[%d]", binPath, errno),
     140              :         HCCL_E_INTERNAL);
     141              :     HCCL_INFO("[LoadBinaryFromFile]realPath: %s", realPath);
     142              : 
     143              :     aclrtBinaryLoadOptions loadOptions = {0};
     144              :     aclrtBinaryLoadOption option;
     145              :     loadOptions.numOpt = 1;
     146              :     loadOptions.options = &option;
     147              :     option.type = optionType;
     148              :     option.value.cpuKernelMode = cpuKernelMode;
     149              :     aclError aclRet = aclrtBinaryLoadFromFile(realPath, &loadOptions, &binHandle); // ACL_RT_BINARY_LOAD_OPT_CPU_KERNEL_MODE
     150              :     CHK_PRT_RET(aclRet != ACL_SUCCESS,
     151              :         HCCL_ERROR("[LoadBinaryFromFile]errNo[0x%016llx] load binary from file error.", aclRet),
     152              :         HCCL_E_OPEN_FILE_FAILURE);
     153              : #else
     154            0 :     HCCL_ERROR("[AicpuAclKernelLaunch]Does not support this interface.");
     155            0 :     return HCCL_E_NOT_SUPPORT;
     156              : #endif
     157              :     return HCCL_SUCCESS;
     158              : }
     159              : 
     160            0 : HcclResult TransportDirectNpu::LoadAICPUKernel(void)
     161              : {
     162              : #ifndef CCL_KERNEL
     163              :     std::string jsonPath;
     164              :     CHK_RET(GetKernelFilePath(jsonPath));
     165              :     jsonPath += "ccl_kernel.json";
     166              :     HcclResult ret = LoadBinaryFromFile(jsonPath.c_str(), ACL_RT_BINARY_LOAD_OPT_CPU_KERNEL_MODE, 0, binHandle_);
     167              :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     168              :         HCCL_ERROR("[LoadAICPUKernel]errNo[0x%016llx]load aicpu file fail, path[%s] optionType[%u]"
     169              :         "cpuKernelMode[%u].", ret, jsonPath.c_str(), ACL_RT_BINARY_LOAD_OPT_CPU_KERNEL_MODE, 0), ret);
     170              : #endif
     171            0 :     return HCCL_SUCCESS;
     172              : }
     173              : 
     174            0 : void TransportDirectNpu::UnloadAICPUKernel(void)
     175              : {
     176              : #ifndef CCL_KERNEL
     177              :     if (binHandle_ != nullptr) {
     178              :         aclError aclRet = aclrtBinaryUnLoad(binHandle_);
     179              :         if (aclRet != ACL_SUCCESS) {
     180              :             HCCL_ERROR("[UnloadAICPUKernel]errNo[0x%016llx] unload binary from binHandel[%p] error.",
     181              :                 aclRet, binHandle_);
     182              :         }
     183              :         binHandle_ = nullptr;
     184              :     }
     185              : #endif
     186            0 :     return;
     187              : }
     188              : 
     189            0 : HcclResult TransportDirectNpu::DeRegOneMR(QpHandle& qpHandle, MemMsg& memMsg)
     190              : {
     191            0 :     struct MrInfoT mrInfo = {nullptr};
     192            0 :     mrInfo.addr = memMsg.addr;
     193            0 :     HcclResult ret = HrtRaMrDereg(qpHandle, &mrInfo);
     194            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     195              :         HCCL_ERROR("errNo[0x%016llx] in link lbv, In lbv exp deconstruct, mr dereg failed.",
     196              :             HCCL_ERROR_CODE(ret)), ret);
     197            0 :     return HCCL_SUCCESS;
     198              : }
     199              : 
     200            0 : void TransportDirectNpu::DeRegMRForQPhandles(MemMsg& memMsg)
     201              : {
     202            0 :     for (u32 j = 0; j < qpHandles_.size(); j++) {
     203            0 :         if (qpHandles_[j] == nullptr) {
     204            0 :             continue;
     205              :         }
     206            0 :         (void)DeRegOneMR(qpHandles_[j], memMsg);
     207              :     }
     208            0 : }
     209              : 
     210            0 : HcclResult TransportDirectNpu::DeRegMR()
     211              : {
     212              :     /* 销毁mr */
     213            0 :     std::map<uintptr_t, s32> addrMap;
     214            0 :     for (s32 i = 0; i < static_cast<s32>(MemType::MEM_TYPE_RESERVED); i++) {
     215            0 :         if (memMsg_[i].mrRegFlag == REG_VALID) {
     216              :             std::pair<std::map<uintptr_t, s32>::iterator, bool> res =
     217            0 :                 addrMap.insert(std::pair<uintptr_t, s32>(reinterpret_cast<uintptr_t>(memMsg_[i].addr), 0));
     218            0 :             if (res.second) {
     219            0 :                 DeRegMRForQPhandles(memMsg_[i]);
     220              :             }
     221              :         }
     222              :     }
     223            0 :     return HCCL_SUCCESS;
     224            0 : }
     225              : 
     226            0 : HcclResult TransportDirectNpu::DestroyQpVct(std::vector<QpHandle>& qpHandles)
     227              : {
     228              :     HcclResult ret;
     229            0 :     for (u32 i = 0; i < qpHandles.size(); i++) {
     230            0 :         if (qpHandles[i] != nullptr) {
     231            0 :             struct QpAttr attr{};
     232            0 :             CHK_RET(hrtRaGetQpAttr(qpHandles[i], &attr));
     233              : 
     234            0 :             g_qpn2IbversLinkMap_.Erase(((static_cast<u64>(machinePara_.localDeviceId) << DEV_PHY_ID_BIT) | attr.qpn));
     235              : 
     236            0 :             ret = HrtRaQpDestroy(qpHandles[i]);
     237            0 :             if (ret != HCCL_SUCCESS) {
     238            0 :                 HCCL_ERROR("errNo[0x%016llx] in link lbv, lbv exp deconstruct, qp destroy failed.",
     239              :                     HCCL_ERROR_CODE(ret));
     240              :             }
     241            0 :             qpHandles[i] = nullptr;
     242              :         }
     243              :     }
     244            0 :     return HCCL_SUCCESS;
     245              : }
     246              : 
     247            0 : HcclResult TransportDirectNpu::DestroyQP()
     248              : {
     249            0 :     CHK_RET(DestroyQpVct(qpHandles_));
     250            0 :     return HCCL_SUCCESS;
     251              : }
     252              : 
     253            0 : HcclResult TransportDirectNpu::DestroyAicpuMem()
     254              : {
     255            0 :     if (aicpuMem_.ptr() != nullptr) {
     256            0 :         aicpuMem_.free();
     257              :     }
     258            0 :     return HCCL_SUCCESS;
     259              : }
     260              : 
     261            0 : HcclResult TransportDirectNpu::CreateAicpuMem()
     262              : {
     263            0 :     CHK_RET(DeviceMem::alloc(aicpuMem_, AICPU_FLAG_AREA));
     264              : 
     265            0 :     CHK_RET(hrtMemSet(aicpuMem_.ptr(), aicpuMem_.size(), aicpuMem_.size()));
     266              : 
     267            0 :     HCCL_INFO("[TransportDirectNpu][CreateAicpuMem] buffer ptr[%p]", aicpuMem_.ptr());
     268            0 :     return HCCL_SUCCESS;
     269              : }
     270              : 
     271            0 : HcclResult TransportDirectNpu::Init()
     272              : {
     273            0 :     HCCL_INFO(
     274              :         "machineType=[%d], serverId=[%s], localDeviceId=[%d], remoteDeviceId=[%d], "\
     275              :         "localRank=[%u], localUserRank=[%u], remoteRank=[%u], remoteUserrank=[%u], "\
     276              :         "deviceType=[%d], inputMem=[%p], outputMem=[%p], isAicpuModeEn[%d], notifyNum[%u], "\
     277              :         "custom exchange data size [%llu].",
     278              :         machinePara_.machineType, machinePara_.serverId.c_str(), machinePara_.localDeviceId,
     279              :         machinePara_.remoteDeviceId, machinePara_.localUserrank, machinePara_.localWorldRank,
     280              :         machinePara_.remoteUserrank, machinePara_.remoteWorldRank,
     281              :         machinePara_.deviceType, machinePara_.inputMem.ptr(), machinePara_.outputMem.ptr(),
     282              :         machinePara_.isAicpuModeEn, machinePara_.notifyNum, machinePara_.exchangeInfo.size());
     283            0 :     HcclUs startut = TIME_NOW();
     284              : 
     285            0 :     CHK_SMART_PTR_NULL(machinePara_.inputMem);
     286            0 :     CHK_SMART_PTR_NULL(machinePara_.outputMem);
     287            0 :     CHK_RET(CheckDeviceId());
     288            0 :     CHK_RET(CheckExchangeData());
     289            0 :     CHK_RET(CreateAicpuMem());
     290            0 :     CHK_RET(LoadAICPUKernel());
     291              : 
     292              :     // 上层初始化时保证 machinePara_.sockets 非空
     293            0 :     if (machinePara_.sockets.size() == 0) {
     294            0 :         HCCL_ERROR("machinePara sockets is empty.");
     295            0 :         return HCCL_E_INTERNAL;
     296              :     }
     297            0 :     defaultSocket_ = machinePara_.sockets[0];
     298            0 :     CHK_PTR_NULL(defaultSocket_);
     299              : 
     300            0 :     CHK_RET(hrtGetDeviceType(localDeviceType));
     301            0 :     HCCL_INFO("localDeviceType=[%d], remoteDeviceType=[%d]", localDeviceType, machinePara_.deviceType);
     302            0 :     CHK_RET(GetNicHandle());
     303              : 
     304              :     // 设置linkType
     305            0 :     transportAttr_.linkType = hccl::LinkType::LINK_ROCE;
     306              : 
     307              :     /* 获取当前的连接模式,offline模式或者op base模式 */
     308            0 :     workFlowMode_ = GetWorkflowMode();
     309            0 :     HCCL_INFO("current work mode is [%d]", workFlowMode_);
     310              : 
     311              :     /* 创建QP连接 */
     312            0 :     CHK_RET(InitQpConnect());
     313              : 
     314            0 :     HCCL_INFO("linkexp initialization success,Time:%lld us", DURATION_US(TIME_NOW() - startut));
     315              : 
     316            0 :     CHK_RET(GetQpAttr());
     317            0 :     return HCCL_SUCCESS;
     318              : }
     319              : 
     320            0 : HcclResult TransportDirectNpu::GetQpAttr()
     321              : {
     322              :     char stackLogBuffer[LOG_TMPBUF_SIZE];
     323            0 :     s32 ret = snprintf_s(stackLogBuffer, LOG_TMPBUF_SIZE, LOG_TMPBUF_SIZE - 1U,
     324              :         "communicator[%s], local rank[%u], ip[%s], remote rank[%u], ip[%s], transporttype[%s]",
     325              :         machinePara_.tag.c_str(), machinePara_.localUserrank, machinePara_.localIpAddr.GetReadableAddress(), 
     326            0 :         machinePara_.remoteUserrank, machinePara_.remoteIpAddr.GetReadableAddress(), GetLinkTypeEnumStr(GetLinkType()).c_str());
     327            0 :     CHK_PRT_RET(ret == -1, HCCL_ERROR("[GetQpAttr]errNo[0x%016llx] sal snprintf_s error", 
     328              :         HCCL_ERROR_CODE(HCCL_E_INTERNAL)), HCCL_E_INTERNAL);
     329            0 :     std::string logInfo = "create hccl transport:" + std::string(stackLogBuffer);
     330            0 :     for (u32 i = 0; i < qpHandles_.size(); i++){
     331            0 :         struct QpAttr attr{};
     332            0 :         hrtRaGetQpAttr(qpHandles_[i], &attr);
     333            0 :         HCCL_USER_CRITICAL_LOG("%s, rdma qpn[%u], rdma qp sport[%u], rdma TC[%u], rdma SL[%u]",
     334              :             logInfo.c_str(), attr.qpn, attr.udpSport, machinePara_.tc, machinePara_.sl);
     335              :     }
     336              : 
     337            0 :     return HCCL_SUCCESS;
     338            0 : }
     339              : 
     340            0 : HcclResult TransportDirectNpu::IsUseQpCreateWithAttrs(bool &isUseQpCreateWithAttrs, s32 qpMode)
     341              : {
     342            0 :     isUseQpCreateWithAttrs = false;
     343            0 :     if (machinePara_.nicDeploy == NICDeployment::NIC_DEPLOYMENT_DEVICE) {
     344            0 :         bool is910Bor91093 =
     345            0 :             machinePara_.deviceType == DevType::DEV_TYPE_910B || machinePara_.deviceType == DevType::DEV_TYPE_910_93;
     346            0 :         if (is910Bor91093 && (qpMode == OFFLINE_QP_MODE_EXT || qpMode == OPBASE_QP_MODE_EXT)) {
     347            0 :             isUseQpCreateWithAttrs = true;
     348              :         }
     349              :     }
     350            0 :     return HCCL_SUCCESS;
     351              : }
     352              : 
     353            0 : HcclResult TransportDirectNpu::FillExchangeDataTotalSize()
     354              : {
     355            0 :     const uint8_t memMsgCount = 3;
     356            0 :     exchangeDataTotalSize_ = 0;
     357            0 :     exchangeDataTotalSize_ += sizeof(u32);  // 首个内容放qp数量
     358            0 :     exchangeDataTotalSize_ += sizeof(MemMsg) * memMsgCount; // output and input mem and aicpu
     359            0 :     exchangeDataTotalSize_ += machinePara_.exchangeInfo.size();
     360              : 
     361            0 :     HCCL_DEBUG("[TransportDirectNpu][FillExchangeDataTotalSize] exchangeDataTotalSize[%llu]", exchangeDataTotalSize_);
     362            0 :     return HCCL_SUCCESS;
     363              : }
     364              : 
     365            0 : HcclResult TransportDirectNpu::ConstructExchangeForSend()
     366              : {
     367            0 :     exchangeDataForSend_.resize(exchangeDataTotalSize_);
     368            0 :     u8 *exchangeDataPtr = exchangeDataForSend_.data();
     369            0 :     u64 exchangeDataBlankSize = exchangeDataTotalSize_;
     370              :     // 把qp对数量放在最前头,第一个做检验
     371            0 :     u32 qpNum = 1;
     372            0 :     s32 sRet = memcpy_s(exchangeDataPtr, sizeof(u32), reinterpret_cast<void*>(&qpNum), sizeof(u32));
     373            0 :     CHK_PRT_RET(sRet != EOK,
     374              :         HCCL_ERROR("[Set][LocalMem]errNo[0x%016llx] memory copy failed. errorno[%d], params:dstMaxSize[%zu],cnt[%zu]",
     375              :         HCCL_ERROR_CODE(HCCL_E_MEMORY), sRet, sizeof(u32), sizeof(u32)), HCCL_E_MEMORY);
     376            0 :     exchangeDataPtr += sizeof(u32);
     377            0 :     exchangeDataBlankSize -= sizeof(u32);
     378              : 
     379            0 :     CHK_RET(RegUserMem(MemType::AICPU_SYNC_MEM, exchangeDataPtr, exchangeDataBlankSize));
     380            0 :     CHK_RET(RegUserMem(MemType::USER_OUTPUT_MEM, exchangeDataPtr, exchangeDataBlankSize));
     381            0 :     CHK_RET(RegUserMem(MemType::USER_INPUT_MEM, exchangeDataPtr, exchangeDataBlankSize));
     382            0 :     CHK_RET(ConstructExchangeDataForSend(exchangeDataPtr, exchangeDataBlankSize));
     383              : 
     384            0 :     if (exchangeDataBlankSize != 0) {
     385            0 :         HCCL_ERROR("[TransportDirectNpu][ConstructExchangeForSend] failed to construct exchange Data \
     386              :             exchangeDataBlankSize[%llu]",
     387              :             exchangeDataBlankSize);
     388            0 :         return HCCL_E_INTERNAL;
     389              :     }
     390              : 
     391            0 :     HCCL_DEBUG("[TransportDirectNpu] ConstructExchangeForSend finished.");
     392            0 :     return HCCL_SUCCESS;
     393              : }
     394              : 
     395            0 : HcclResult TransportDirectNpu::ParseReceivedExchangeData()
     396              : {
     397            0 :     u8* exchangeDataPtr = exchangeDataForRecv_.data();
     398            0 :     u64 exchangeDataBlankSize = exchangeDataTotalSize_;
     399              : 
     400              :     // 首先解析qp对数量,并作一致性校验
     401            0 :     u32 localQpNum = 1;
     402            0 :     u32 remoteQpNum = 0;
     403            0 :     s32 sRet = memcpy_s(reinterpret_cast<void*>(&remoteQpNum), sizeof(u32), exchangeDataPtr, sizeof(u32));
     404            0 :     CHK_PRT_RET(sRet != EOK,
     405              :         HCCL_ERROR("[Get][RemoteMem]errNo[0x%016llx] memory copy failed. errorno[%d], params:dstMaxSize[%zu],cnt[%zu]",
     406              :         HCCL_ERROR_CODE(HCCL_E_MEMORY), sRet, sizeof(u32), sizeof(u32)), HCCL_E_MEMORY);
     407            0 :     CHK_PRT_RET(localQpNum != remoteQpNum, HCCL_ERROR("[TransportDirectNpu][ParseReceivedExchangeData]"
     408              :         "local qps[%u] not equal to remote qps[%u], rank:local[%u],remote[%u]", localQpNum, remoteQpNum,
     409              :         machinePara_.localUserrank, machinePara_.remoteUserrank), HCCL_E_INTERNAL);
     410            0 :     exchangeDataPtr += sizeof(u32);
     411            0 :     exchangeDataBlankSize -= sizeof(u32);
     412              : 
     413            0 :     CHK_RET(GetRemoteAddr(MemType::AICPU_SYNC_MEM, exchangeDataPtr, exchangeDataBlankSize));
     414              : 
     415            0 :     CHK_RET(GetRemoteAddr(MemType::USER_OUTPUT_MEM, exchangeDataPtr, exchangeDataBlankSize));
     416              : 
     417            0 :     CHK_RET(GetRemoteAddr(MemType::USER_INPUT_MEM, exchangeDataPtr, exchangeDataBlankSize));
     418              : 
     419            0 :     CHK_RET(ParseExchangeData(exchangeDataPtr, exchangeDataBlankSize));
     420              : 
     421            0 :     if (exchangeDataBlankSize != 0) {
     422            0 :         HCCL_ERROR("[TransportDirectNpu][ParseReceivedExchangeData] failed to Parse exchange Data \
     423              :             exchangeDataBlankSize[%llu]", exchangeDataBlankSize);
     424            0 :         return HCCL_E_INTERNAL;
     425              :     }
     426            0 :     HCCL_DEBUG("Parse Received ExchangeData success!");
     427            0 :     return HCCL_SUCCESS;
     428              : }
     429              : 
     430            0 : u32 TransportDirectNpu::GetQpsPerConnection()
     431              : {
     432            0 :     u32 externalQps = std::max(static_cast<u32>(machinePara_.srcPorts.size()), 1U);
     433            0 :     s32 qpMode = GetQpMode();
     434            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     435              :         externalQps != HCCL_QPS_PER_CONNECTION_DEFAULT) {
     436            0 :         HCCL_RUN_INFO("HCCL_RDMA_QPS_PER_CONNECTION is set to [%u] but it is not effective in offline mode.",
     437              :             externalQps);
     438            0 :     } else if (qpMode != OPBASE_QP_MODE_EXT && externalQps > 1) {
     439            0 :         HCCL_RUN_INFO("HCCL_RDMA_QPS_PER_CONNECTION is set to [%u] but current devType[%d] does not support multi-QP.",
     440              :             externalQps, machinePara_.deviceType);
     441            0 :         return 1;  // 非单算子模式仅支持单QP, QPS = 1
     442              :     }
     443            0 :     if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     444            0 :         return externalQps;  // only work for opbase mode
     445              :     }
     446            0 :     return 1;  // 非单算子模式仅支持单QP, QPS = 1
     447              : }
     448              : 
     449            0 : HcclResult TransportDirectNpu::GetNicHandle()
     450              : {
     451            0 :     RaResourceInfo raResourceInfo;
     452            0 :     CHK_RET(NetworkManager::GetInstance(machinePara_.deviceLogicId).GetRaResourceInfo(raResourceInfo));
     453            0 :     std::map<HcclIpAddress, IpSocket> &tmpSocketMap = machinePara_.nicDeploy == NICDeployment::NIC_DEPLOYMENT_DEVICE ?
     454              :         raResourceInfo.nicSocketMap : raResourceInfo.hostNetSocketMap;
     455              : 
     456            0 :     HcclIpAddress localIpAddr = machinePara_.localIpAddr;
     457              : 
     458              :     // 获取 nicRdmaHandle
     459            0 :     auto itSocket = tmpSocketMap.find(localIpAddr);
     460            0 :     if (itSocket == tmpSocketMap.end()) {
     461            0 :         HCCL_ERROR("[Get][NicHandle]In get nic handle, can not find socket handle, handle size[%u], "\
     462              :             "local ip[%s]", tmpSocketMap.size(), localIpAddr.GetReadableAddress());
     463            0 :         return HCCL_E_PARA;
     464              :     }
     465              : 
     466            0 :     nicRdmaHandle_ = itSocket->second.nicRdmaHandle;
     467            0 :     CHK_PTR_NULL(nicRdmaHandle_);
     468              : 
     469            0 :     return HCCL_SUCCESS;
     470            0 : }
     471              : 
     472              : // 创建一个QP
     473            0 : HcclResult TransportDirectNpu::CreateOneQp(
     474              :     s32 qpMode, u32 qpsPerConnection, QpHandle &qpHandle, AiQpInfo &aiQpInfo, bool useAicpu, u32 udpSport)
     475              : {
     476            0 :     bool isUseQpCreateWithAttrs = false;
     477            0 :     CHK_RET(IsUseQpCreateWithAttrs(isUseQpCreateWithAttrs, qpMode));
     478              :     HcclResult ret;
     479            0 :     std::string useAicpuTitle = useAicpu ? std::string("aicpu ") : std::string("");
     480            0 :     std::string qpInfo = useAicpuTitle + std::string("rank:") + std::to_string(machinePara_.localWorldRank) +
     481            0 :         std::string(",localUserrank:") + std::to_string(machinePara_.localUserrank) +
     482            0 :         std::string(",localIpAddr: ") + std::string(machinePara_.localIpAddr.GetReadableAddress()) +
     483            0 :         std::string(",deviceLogicId:") + std::to_string(machinePara_.deviceLogicId);
     484            0 :     struct QpExtAttrs attrs{};
     485              :     // 判断是否为NORMALQP需要使用qpMode_; hostnic场景的qpmode也是NORMALQP
     486            0 :     if (useAicpu || qpMode_ == QPMode::NORMAL) {
     487            0 :         bool isWorkFlowLib = (workFlowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB);
     488            0 :         CHK_RET(ConstructQpAttrs(qpMode, attrs, machinePara_.queueDepthAttr, isWorkFlowLib));
     489              : 
     490              :         // A3 aicpu图模式使用单个qp, qp深度为socket数量*128
     491            0 :         bool isAicpuLib = machinePara_.isAicpuModeEn &&
     492            0 :                             (machinePara_.deviceType == DevType::DEV_TYPE_910_93) &&
     493            0 :                             (workFlowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB);
     494            0 :         if (isAicpuLib) {
     495            0 :             attrs.qpAttr.cap.max_send_wr = machinePara_.sockets.size() * DEFAULT_OFFLINE_MAX_SEND_WR;
     496              :         }
     497            0 :         HCCL_DEBUG("qp set max_send_wr %u, socket size %u, isWorkFlowLib %d",
     498              :             attrs.qpAttr.cap.max_send_wr, machinePara_.sockets.size(), isWorkFlowLib);
     499              : 
     500            0 :         attrs.udpSport = udpSport;
     501            0 :         ret = hrtRaAiQpCreate(machinePara_.localDeviceId, nicRdmaHandle_, &attrs, &aiQpInfo, qpHandle);
     502            0 :         HCCL_DEBUG(
     503              :             "aiQpAddr:%llu db_index:%u, sq_index=%u", aiQpInfo.aiQpAddr, aiQpInfo.dbIndex, aiQpInfo.sqIndex);
     504            0 :         qpInfo = qpInfo + std::string(",sendCqDepth:") + std::to_string(attrs.cqAttr.sendCqDepth);
     505            0 :     } else if (!isUseQpCreateWithAttrs && qpsPerConnection == HCCL_QPS_PER_CONNECTION_DEFAULT) {
     506            0 :         ret = HrtRaQpCreate(nicRdmaHandle_, QP_FLAG_RC, qpMode, qpHandle);
     507            0 :     } else if (!isUseQpCreateWithAttrs && qpsPerConnection != HCCL_QPS_PER_CONNECTION_DEFAULT) {
     508            0 :         HCCL_ERROR("qpsPerConnection[%u] is set but qpMode[%d] is not supported", qpsPerConnection, qpMode);
     509            0 :         return HCCL_E_PARA;
     510              :     } else {
     511            0 :         CHK_RET(ConstructQpAttrs(qpMode, attrs, machinePara_.queueDepthAttr));
     512            0 :         attrs.udpSport = udpSport;
     513            0 :         ret = hrtRaQpCreateWithAttrs(nicRdmaHandle_, &attrs, qpHandle);
     514            0 :         qpInfo = qpInfo + std::string(",sendCqDepth:") + std::to_string(attrs.cqAttr.sendCqDepth);
     515              :     }
     516              : 
     517            0 :     RPT_ENV_ERR(ret != 0 || (qpHandle == nullptr), "EI0007", vector<string>({ "resource_type", "resource_info" }),
     518              :         vector<string>({ "qp", "CreateOneQp" }));
     519              : 
     520            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s][%s]create qp failed, localDeviceId[%d], qpMode[%d]",
     521              :         LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RESOURCE.c_str(), machinePara_.localDeviceId, qpMode),
     522              :         HCCL_E_ROCE_CONNECT);
     523              : 
     524              :     // 表示没有通过config配置,则使用环境变量配置
     525            0 :     CHK_RET(SetQpAttrQos(qpHandle, machinePara_.tc, machinePara_.sl));
     526              :     // 配置RDMA Timeout时间
     527            0 :     CHK_RET(SetQpAttrTimeOut(qpHandle));
     528              :     // 配置RDMA Retry Cnt重传次数
     529            0 :     CHK_RET(SetQpAttrRetryCnt(qpHandle));
     530              :     // qpn map 插入
     531            0 :     struct QpAttr attr{} ;
     532            0 :     CHK_RET(hrtRaGetQpAttr(qpHandle, &attr));
     533              : 
     534            0 :     g_qpn2IbversLinkMap_.Emplace(((static_cast<u64>(machinePara_.localDeviceId) << DEV_PHY_ID_BIT) | attr.qpn), this);
     535              : 
     536            0 :     HCCL_DEBUG("ra qp create success.");
     537            0 :     return HCCL_SUCCESS;
     538            0 : }
     539              : 
     540            0 : HcclResult TransportDirectNpu::CreateSingleQp(s32 qpMode) // 根据socket个数创建QP(下沉模板不够用多QP)
     541              : {
     542            0 :     u32 socketNum = 1;
     543              :     // A3 aicpu图模式只使用1个qp,qp深度为socketNum*128,最大不超过32K
     544            0 :     bool isAicpuLib = machinePara_.isAicpuModeEn &&
     545            0 :                         (machinePara_.deviceType == DevType::DEV_TYPE_910_93) &&
     546            0 :                         (workFlowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB);
     547            0 :     if (!isAicpuLib) {
     548            0 :         socketNum = std::max(static_cast<u32>(machinePara_.sockets.size()), socketNum);
     549              :     }
     550              :     // 原来是 machinePara_.socketFdHandles 换成 machinePara_.sockets
     551            0 :     for (u32 i = 0; i < socketNum; i++) {
     552            0 :         QpHandle qpHandle = nullptr;
     553            0 :         u32 udpSport = machinePara_.srcPorts.empty() ? 0 : machinePara_.srcPorts[0];
     554            0 :         CHK_RET(CreateOneQp(
     555              :             qpMode, HCCL_QPS_PER_CONNECTION_DEFAULT, qpHandle, aiQpInfo_, machinePara_.isAicpuModeEn, udpSport));
     556            0 :         qpHandles_.push_back(qpHandle);
     557              :     }
     558            0 :     return HCCL_SUCCESS;
     559              : }
     560              : 
     561            0 : s32 TransportDirectNpu::GetQpMode()
     562              : {
     563            0 :     s32 qpMode = NORMAL_QP_MODE;
     564              : 
     565            0 :     if (qpMode_ == QPMode::NORMAL) {
     566            0 :         return qpMode;
     567              :     }
     568              : 
     569            0 :     if (machinePara_.nicDeploy == NICDeployment::NIC_DEPLOYMENT_DEVICE) {
     570            0 :         if (workFlowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     571            0 :             qpMode = (machinePara_.deviceType == DevType::DEV_TYPE_910B ||
     572            0 :                 machinePara_.deviceType == DevType::DEV_TYPE_910_93) ? OPBASE_QP_MODE_EXT : OPBASE_QP_MODE;
     573              :             // isCapture需要创建下沉QP
     574            0 :             qpMode = (qpMode == OPBASE_QP_MODE_EXT && qpMode_ == QPMode::OFFLOAD) ? OFFLINE_QP_MODE_EXT : qpMode;
     575              :         } else {
     576            0 :             qpMode = (machinePara_.deviceType == DevType::DEV_TYPE_910B ||
     577            0 :                 machinePara_.deviceType == DevType::DEV_TYPE_910_93) ? OFFLINE_QP_MODE_EXT : OFFLINE_QP_MODE;
     578              :         }
     579              :     }
     580            0 :     if (machinePara_.isAicpuModeEn) {
     581            0 :         qpMode = (machinePara_.deviceType == DevType::DEV_TYPE_910B ||
     582            0 :             machinePara_.deviceType == DevType::DEV_TYPE_910_93) ? OPBASE_QP_MODE_EXT : OPBASE_QP_MODE;
     583              :     }
     584            0 :     return qpMode;
     585              : }
     586              : 
     587            0 : HcclResult TransportDirectNpu::CreateQp()
     588              : {
     589            0 :     s32 qpMode = GetQpMode();
     590            0 :     HCCL_DEBUG("[TransportDirectNpu][CreateQp] QpMode[%u]", qpMode);
     591            0 :     CHK_RET(CreateSingleQp(qpMode));
     592            0 :     HCCL_DEBUG("ra qp create %u qp success.", qpHandles_.size());
     593            0 :     return HCCL_SUCCESS;
     594              : }
     595              : 
     596            0 : HcclResult TransportDirectNpu::InitQpConnect()
     597              : {
     598              :     /* 创建QP操作句柄 */
     599            0 :     qpsPerConnection_ = GetQpsPerConnection();
     600              : 
     601            0 :     CHK_RET(CreateQp());
     602              : 
     603            0 :     CHK_RET(FillExchangeDataTotalSize());
     604              : 
     605            0 :     CHK_RET(ConstructExchangeForSend());
     606              : 
     607            0 :     HCCL_DEBUG("[TransportDirectNpu] resource create done exchangeDataTotalSize_[%llu]", exchangeDataTotalSize_);
     608              : 
     609            0 :     HcclResult ret = defaultSocket_->Send(exchangeDataForSend_.data(), exchangeDataTotalSize_);
     610            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     611              :         HCCL_ERROR("[TransportDirectNpu][InitQpConnect] failed to send exchangeData exchangeDataTotalSize[%llu], "
     612              :             "custom exchange data size [%llu].", exchangeDataTotalSize_, machinePara_.exchangeInfo.size()), ret);
     613            0 :     HCCL_DEBUG("[TransportDirectNpu]Seocket Send finished, exchangeDataTotalSize[%llu]", exchangeDataTotalSize_);
     614              : 
     615            0 :     exchangeDataForRecv_.resize(exchangeDataTotalSize_);
     616            0 :     ret = defaultSocket_->Recv(exchangeDataForRecv_.data(), exchangeDataTotalSize_);
     617            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     618              :         HCCL_ERROR("[TransportDirectNpu][InitQpConnect] failed to recv exchangeData exchangeDataTotalSize[%llu], "
     619              :             "custom exchange data size [%llu].", exchangeDataTotalSize_, machinePara_.exchangeInfo.size()), ret);
     620              : 
     621            0 :     HCCL_DEBUG("[TransportDirectNpu][Init] Socket Data Recved");
     622              : 
     623            0 :     CHK_RET(ParseReceivedExchangeData());
     624              : 
     625              :     // 连接Qp
     626            0 :     CHK_RET(ConnectQp());
     627            0 :     HCCL_INFO("In link ibv, qp status has ready");
     628            0 :     return HCCL_SUCCESS;
     629              : }
     630              : 
     631            0 : HcclResult TransportDirectNpu::ConnectSingleQp(std::function<bool()> needStop)
     632              : {
     633              :     // QP建链
     634            0 :     for (u32 i = 0; i < qpHandles_.size(); i++) {
     635            0 :         CHK_RET(HrtRaQpConnectAsync(qpHandles_[i], machinePara_.sockets[i]->GetFdHandle(), needStop));
     636              :     }
     637              :     // 查询QP建链是否成功
     638            0 :     s32 qpStatus = 0;
     639            0 :     s32 raRet = 0;
     640            0 :     auto startTime = std::chrono::steady_clock::now();
     641            0 :     HCCL_INFO("In link ibv, waiting for qp status ready...");
     642            0 :     for (u32 i = 0; i < qpHandles_.size(); i++) {
     643              :         while (true) {
     644            0 :             CHK_PRT_RET(needStop(), HCCL_ERROR("Terminating operation due to external request"), HCCL_E_INTERNAL);
     645              : 
     646            0 :             if ((std::chrono::steady_clock::now() - startTime) >= timeout_) {
     647            0 :                 HCCL_ERROR("[Connect][Qp]get qp status timeout_=%lld, qp_status=%d", timeout_, qpStatus);
     648            0 :                 return HCCL_E_TIMEOUT;
     649              :             }
     650            0 :             raRet = hrtGetRaQpStatus(qpHandles_[i], &qpStatus);
     651            0 :             if ((!raRet) && (qpStatus == 1)) { // 为1时,qp 建链成功
     652            0 :                 HCCL_INFO("In link ibv, %u of %u QP get status success.", (i + 1), qpHandles_.size());
     653            0 :                 break;
     654              :             } else {
     655              :                 // qp建链需要时间,获取qp状态直至超时
     656            0 :                 SaluSleep(WAIT_US_COUNT);
     657              :             }
     658              :         }
     659              :     }
     660            0 :     return HCCL_SUCCESS;
     661              : }
     662              : 
     663            0 : HcclResult TransportDirectNpu::ConnectQp()
     664              : {
     665            0 :     CHK_RET(ConnectSingleQp([this]() -> bool { return this->GetStopFlag(); }));
     666            0 :     return HCCL_SUCCESS;
     667              : }
     668              : 
     669            0 : HcclResult TransportDirectNpu::TxAsync(UserMemType dstMemType, u64 dstOffset,
     670              :                                      const void *src, u64 len, Stream &stream)
     671              : {
     672            0 :     CHK_RET(TxData(dstMemType, dstOffset, src, len, stream));
     673            0 :     return HCCL_SUCCESS;
     674              : }
     675              : 
     676            0 : HcclResult TransportDirectNpu::TxAsync(std::vector<TxMemoryInfo>& txMems, Stream &stream)
     677              : {
     678            0 :     for(auto& mem : txMems) {
     679            0 :         CHK_RET(TxAsync(mem.dstMemType, mem.dstOffset, mem.src, mem.len, stream));
     680              :     }
     681            0 :     return HCCL_SUCCESS;
     682              : }
     683              : 
     684            0 : HcclResult TransportDirectNpu::RxAsync(UserMemType srcMemType, u64 srcOffset, void *dst, u64 len, Stream &stream)
     685              : {
     686            0 :     CHK_PRT(RxData(srcMemType, srcOffset, dst, len, stream));
     687            0 :     return HCCL_SUCCESS;
     688              : }
     689              : 
     690            0 : HcclResult TransportDirectNpu::RxAsync(std::vector<RxMemoryInfo>& rxMems, Stream &stream)
     691              : {
     692            0 :     for(auto &mem: rxMems) {
     693            0 :         CHK_RET(RxAsync(mem.srcMemType,mem.srcOffset,mem.dst,mem.len,stream));
     694              :     }
     695            0 :     return HCCL_SUCCESS;
     696              : }
     697              : 
     698            0 : HcclResult TransportDirectNpu::DataReceivedAck(Stream &stream)
     699              : {
     700            0 :     CHK_RET(PostFinAck(stream));
     701            0 :     CHK_RET(WaitFinAck(stream));
     702              : 
     703            0 :     return HCCL_SUCCESS;
     704              : }
     705              : 
     706            0 : HcclResult TransportDirectNpu::TxWaitDone(Stream &stream)
     707              : {
     708            0 :     return HCCL_SUCCESS;
     709              : }
     710              : 
     711              : /* 发送ack消息(同步模式) */
     712            0 : HcclResult TransportDirectNpu::TxAck(Stream &stream)
     713              : {
     714            0 :     return HCCL_SUCCESS;
     715              : }
     716              : 
     717              : /* 接收ack消息(同步模式) */
     718            0 : HcclResult TransportDirectNpu::RxAck(Stream &stream)
     719              : {
     720            0 :     return HCCL_SUCCESS;
     721              : }
     722              : 
     723            0 : HcclResult TransportDirectNpu::TxDataSignal(Stream &stream)
     724              : {
     725            0 :     return HCCL_SUCCESS;
     726              : }
     727              : 
     728            0 : HcclResult TransportDirectNpu::RxDataSignal(Stream &stream)
     729              : {
     730            0 :     return HCCL_SUCCESS;
     731              : }
     732              : 
     733            0 : HcclResult TransportDirectNpu::RegUserMem(MemType memType, u8*& exchangeDataPtr, u64& exchangeDataBlankSize)
     734              : {
     735            0 :     void *memPtr = nullptr;
     736              :     u64 memSize;
     737            0 :     switch (memType) {
     738            0 :         case MemType::USER_INPUT_MEM: {
     739            0 :             memPtr = machinePara_.inputMem.ptr();
     740            0 :             memSize = machinePara_.inputMem.size();
     741            0 :             break;
     742              :         }
     743              : 
     744            0 :         case MemType::USER_OUTPUT_MEM: {
     745            0 :             memPtr = machinePara_.outputMem.ptr();
     746            0 :             memSize = machinePara_.outputMem.size();
     747            0 :             break;
     748              :         }
     749              : 
     750            0 :         case MemType::AICPU_SYNC_MEM: {
     751            0 :             memPtr = aicpuMem_.ptr();
     752            0 :             memSize = aicpuMem_.size();
     753            0 :             break;
     754              :         }
     755              : 
     756            0 :         default: {
     757            0 :             HCCL_ERROR("[Reg][UserMem]not support dst_mem_type=%d", memType);
     758            0 :             return HCCL_E_NOT_SUPPORT;
     759              :         }
     760              :     }
     761            0 :     struct MrInfoT mrInfo = {nullptr};
     762            0 :     mrInfo.addr = memPtr;
     763            0 :     mrInfo.size = memSize;
     764            0 :     mrInfo.access = access_;
     765            0 :     for (u32 i = 0; i < qpHandles_.size(); i++) {
     766            0 :         CHK_RET(HrtRaMrReg(qpHandles_[i], &mrInfo));
     767              :     }
     768              : 
     769            0 :     memMsg_[static_cast<u32>(memType)].mrRegFlag = REG_VALID;
     770            0 :     memMsg_[static_cast<u32>(memType)].addr = memPtr;
     771            0 :     memMsg_[static_cast<u32>(memType)].len = memSize;
     772            0 :     memMsg_[static_cast<u32>(memType)].memType = memType;
     773            0 :     memMsg_[static_cast<u32>(memType)].lkey = mrInfo.lkey;
     774              : 
     775            0 :     CHK_SAFETY_FUNC_RET(memcpy_s(exchangeDataPtr, exchangeDataBlankSize,
     776              :         reinterpret_cast<void*>(&memMsg_[static_cast<u32>(memType)]), sizeof(MemMsg)));
     777              : 
     778            0 :     exchangeDataPtr += sizeof(MemMsg);
     779            0 :     exchangeDataBlankSize -= sizeof(MemMsg);
     780              : 
     781            0 :     HCCL_DEBUG("memType=%d mem_ptr=%p mem_size=%llu Byte, key = %u", memType, memPtr, memSize, mrInfo.lkey);
     782              : 
     783            0 :     return HCCL_SUCCESS;
     784              : }
     785              : 
     786            0 : HcclResult TransportDirectNpu::GetMemInfo(UserMemType memType, void **dstMemPtr, u64 *dstMemSize)
     787              : {
     788            0 :     switch (memType) {
     789            0 :         case UserMemType::INPUT_MEM: {
     790            0 :             *dstMemPtr = remoteMemMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].addr;
     791            0 :             *dstMemSize = remoteMemMsg_[static_cast<u32>(MemType::USER_INPUT_MEM)].len;
     792            0 :             break;
     793              :         }
     794              : 
     795            0 :         case UserMemType::OUTPUT_MEM: {
     796            0 :             *dstMemPtr = remoteMemMsg_[static_cast<u32>(MemType::USER_OUTPUT_MEM)].addr;
     797            0 :             *dstMemSize = remoteMemMsg_[static_cast<u32>(MemType::USER_OUTPUT_MEM)].len;
     798            0 :             break;
     799              :         }
     800              : 
     801            0 :         default: {
     802            0 :             HCCL_ERROR("[Get][MemInfo]not support dst_mem_type=%d", memType);
     803            0 :             return HCCL_E_NOT_SUPPORT;
     804              :         }
     805              :     }
     806            0 :     return HCCL_SUCCESS;
     807              : }
     808              : 
     809            0 : HcclResult TransportDirectNpu::GetRemoteAddr(MemType memType, u8*& exchangeDataPtr, u64& exchangeDataBlankSize)
     810              : {
     811            0 :     s32 sRet = memcpy_s(&remoteMemMsg_[static_cast<u32>(memType)],
     812              :         sizeof(MemMsg), exchangeDataPtr, sizeof(MemMsg));
     813            0 :     CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Get][RemoteAddr]errNo[0x%016llx] In lbv exp get remote addr, "\
     814              :         "memcpy failed. errorno[%d], params:destMaxSize[%zu],count[%zu]",
     815              :         HCCL_ERROR_CODE(HCCL_E_MEMORY), sRet, sizeof(MemMsg), sizeof(MemMsg)), HCCL_E_MEMORY);
     816            0 :     CHK_PTR_NULL(remoteMemMsg_[static_cast<u32>(memType)].addr);
     817              : 
     818            0 :     exchangeDataPtr += sizeof(MemMsg);
     819            0 :     exchangeDataBlankSize -= sizeof(MemMsg);
     820            0 :     HCCL_INFO("GetRemoteAddr success: memType=%d, addr=%p len=%llu, notifyId=%u",
     821              :         static_cast<int32_t>(memType), remoteMemMsg_[static_cast<u32>(memType)].addr,
     822              :         remoteMemMsg_[static_cast<u32>(memType)].len, remoteMemMsg_[static_cast<u32>(memType)].notifyId);
     823            0 :     return HCCL_SUCCESS;
     824              : }
     825              : 
     826              : /* 发送ack消息(同步模式) */
     827            0 : HcclResult TransportDirectNpu::TxPrepare(Stream &stream)
     828              : {
     829            0 :     return HCCL_SUCCESS;
     830              : }
     831              : 
     832              : /* 接收ack消息(同步模式) */
     833            0 : HcclResult TransportDirectNpu::RxPrepare(Stream &stream)
     834              : {
     835            0 :     return HCCL_SUCCESS;
     836              : }
     837              : 
     838            0 : HcclResult TransportDirectNpu::TxData(UserMemType dstMemType, u64 dstOffset, const void *src, u64 len, Stream &stream)
     839              : {
     840            0 :     CHK_PTR_NULL(src);
     841              :     struct ApiParamDef
     842              :     {
     843              :         u32 lKey;
     844              :         u32 rKey;
     845              :         HcclQpInfoV2 qpInfo;
     846              :         u64 remoteAddr;
     847              :         u64 localAddr;
     848              :         u64 dataSize;
     849              :         u64 timeout;
     850              :         u64 localFlagAddr;
     851              :         u64 remoteFlagAddr;
     852              :         u32 lfKey;
     853              :         u32 rfKey;
     854              :     };
     855            0 :     const std::string kernelName = "RunTransportRoceTx";
     856            0 :     struct ApiParamDef apiParam = {};
     857            0 :     MemDetails inputMemDetails;
     858            0 :     MemDetails outputMemDetails;
     859            0 :     CHK_PRT(GetLocalMemDetails(UserMemType::INPUT_MEM, inputMemDetails));
     860            0 :     CHK_PRT(GetLocalMemDetails(UserMemType::OUTPUT_MEM, outputMemDetails));
     861              : 
     862            0 :     if (reinterpret_cast<u64>(src) >= inputMemDetails.addr && reinterpret_cast<u64>(src) < inputMemDetails.addr + inputMemDetails.size) {
     863            0 :         apiParam.lKey = inputMemDetails.key;
     864            0 :     } else if (reinterpret_cast<u64>(src) >= outputMemDetails.addr && reinterpret_cast<u64>(src) <= outputMemDetails.addr + outputMemDetails.size) {
     865            0 :         apiParam.lKey = outputMemDetails.key;
     866              :     } else {
     867            0 :         HCCL_ERROR("[TransportDirectNpu][TxData]src_ptr=%p is out of range, inputmem src[%p], size[%llu];"
     868              :                 " outputmem src[%p] size[%llu]",
     869              :                 src, inputMemDetails.addr, inputMemDetails.size, outputMemDetails.addr, outputMemDetails.size);
     870            0 :         return HCCL_E_INTERNAL;
     871              :     }
     872            0 :     CHK_RET(GetRemoteMemKey(dstMemType, &apiParam.rKey));
     873            0 :     void *remoteAddr = nullptr;
     874            0 :     u64 memSize = 0;
     875            0 :     CHK_RET(GetMemInfo(dstMemType, &remoteAddr, &memSize));
     876            0 :     apiParam.remoteFlagAddr = reinterpret_cast<u64>(remoteMemMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].addr);
     877            0 :     apiParam.lfKey = memMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].lkey;
     878            0 :     apiParam.rfKey = remoteMemMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].lkey;
     879            0 :     apiParam.remoteAddr = reinterpret_cast<u64>(remoteAddr) + dstOffset;
     880            0 :     apiParam.dataSize = len;
     881            0 :     apiParam.localAddr = reinterpret_cast<u64>(src);
     882            0 :     apiParam.timeout = NOTIFY_DEFAULT_WAIT_TIME;
     883            0 :     if (GetExternalInputHcclExecTimeoutSet() != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_NOT_SET ||
     884            0 :         dispatcher_->GetExecTimeOutSet()) {
     885            0 :         apiParam.timeout = dispatcher_->GetExecTimeOut();
     886              :     }
     887            0 :     apiParam.localFlagAddr = reinterpret_cast<u64>(aicpuMem_.ptr());
     888            0 :     std::vector<HcclQpInfoV2> aiQpInfos;
     889            0 :     CHK_RET(GetAiQpInfo(aiQpInfos));
     890            0 :     apiParam.qpInfo = aiQpInfos[0];
     891            0 :     HCCL_INFO("[TransportDirectNpu][TxData]localRank %u remoteRank %u lkey %u rkey %u remoteAddr %p localAddr %p dataSize %llu "
     892              :         "timeout %llu localFlagAddr %p remoteFlagAddr %p lfkey %u rfkey %u qpinfo %llu",
     893              :         machinePara_.localUserrank, machinePara_.remoteUserrank, apiParam.lKey, apiParam.rKey, apiParam.remoteAddr, apiParam.localAddr, apiParam.dataSize,
     894              :         apiParam.timeout, apiParam.localFlagAddr, apiParam.remoteFlagAddr, apiParam.lfKey, apiParam.rfKey, apiParam.qpInfo.qpPtr);
     895              : 
     896              : #ifndef CCL_KERNEL
     897              :     u16 timeOut = NOTIFY_DEFAULT_WAIT_TIME > std::numeric_limits<uint16_t>::max() ? 
     898              :                     std::numeric_limits<uint16_t>::max() : NOTIFY_DEFAULT_WAIT_TIME;
     899              :     CHK_PRT(AicpuAclKernelLaunch(stream.ptr(), reinterpret_cast<void *>(&apiParam), sizeof(apiParam),
     900              :             binHandle_, kernelName, true, timeOut));
     901              : #else
     902            0 :     HCCL_ERROR("[AicpuAclKernelLaunch]Does not support this interface.");
     903            0 :     return HCCL_E_NOT_SUPPORT;
     904              : #endif
     905              :     HCCL_INFO("[TransportDirectNpu][TxData] exec succ.");
     906              :     return HCCL_SUCCESS;
     907            0 : }
     908              : 
     909            0 : HcclResult TransportDirectNpu::RxData(UserMemType srcMemType, u64 srcOffset, void *dst, u64 len, Stream &stream)
     910              : {
     911            0 :     CHK_PTR_NULL(dst);
     912              :     struct ApiParamDef
     913              :     {
     914              :         u32 lKey;
     915              :         u32 rKey;
     916              :         HcclQpInfoV2 qpInfo;
     917              :         u64 remoteAddr;
     918              :         u64 localAddr;
     919              :         u64 dataSize;
     920              :         u64 timeout;
     921              :         u64 localFlagAddr;
     922              :         u64 remoteFlagAddr;
     923              :         u32 lfKey;
     924              :         u32 rfKey;
     925              :     };
     926            0 :     const std::string kernelName = "RunTransportRoceRx";
     927            0 :     struct ApiParamDef apiParam = {};
     928            0 :     MemDetails inputMemDetails;
     929            0 :     MemDetails outputMemDetails;
     930            0 :     CHK_PRT(GetLocalMemDetails(UserMemType::INPUT_MEM, inputMemDetails));
     931            0 :     CHK_PRT(GetLocalMemDetails(UserMemType::OUTPUT_MEM, outputMemDetails));
     932              : 
     933            0 :     if (reinterpret_cast<u64>(dst) >= inputMemDetails.addr && reinterpret_cast<u64>(dst) < inputMemDetails.addr + inputMemDetails.size) {
     934            0 :         apiParam.lKey = inputMemDetails.key;
     935            0 :     } else if (reinterpret_cast<u64>(dst) >= outputMemDetails.addr && reinterpret_cast<u64>(dst) <= outputMemDetails.addr + outputMemDetails.size) {
     936            0 :         apiParam.lKey = outputMemDetails.key;
     937              :     } else {
     938            0 :         HCCL_ERROR("[TransportDirectNpu][RxData]src_ptr=%p is out of range, inputmem src[%p], size[%llu];"
     939              :                 " outputmem src[%p] size[%llu]",
     940              :                 dst, inputMemDetails.addr, inputMemDetails.size, outputMemDetails.addr, outputMemDetails.size);
     941            0 :         return HCCL_E_INTERNAL;
     942              :     }
     943            0 :     CHK_RET(GetRemoteMemKey(srcMemType, &apiParam.rKey));
     944            0 :     void *remoteAddr = nullptr;
     945            0 :     u64 memSize = 0;
     946            0 :     CHK_RET(GetMemInfo(srcMemType, &remoteAddr, &memSize));
     947            0 :     apiParam.remoteFlagAddr = reinterpret_cast<u64>(remoteMemMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].addr);
     948            0 :     apiParam.lfKey = memMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].lkey;
     949            0 :     apiParam.rfKey = remoteMemMsg_[static_cast<u32>(MemType::AICPU_SYNC_MEM)].lkey;
     950            0 :     apiParam.remoteAddr = reinterpret_cast<u64>(remoteAddr) + srcOffset;
     951            0 :     apiParam.dataSize = len;
     952            0 :     apiParam.localAddr = reinterpret_cast<u64>(dst);
     953            0 :     apiParam.timeout = NOTIFY_DEFAULT_WAIT_TIME;
     954            0 :     if (GetExternalInputHcclExecTimeoutSet() != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_NOT_SET ||
     955            0 :         dispatcher_->GetExecTimeOutSet()) {
     956            0 :         apiParam.timeout = dispatcher_->GetExecTimeOut();
     957              :     }
     958            0 :     apiParam.localFlagAddr = reinterpret_cast<u64>(aicpuMem_.ptr());
     959            0 :     std::vector<HcclQpInfoV2> aiQpInfos;
     960            0 :     CHK_RET(GetAiQpInfo(aiQpInfos));
     961            0 :     apiParam.qpInfo = aiQpInfos[0];
     962            0 :     HCCL_INFO("[TransportDirectNpu][RxData]localRank %u remoteRank %u lkey %u rkey %u remoteAddr %p localAddr %p dataSize %llu "
     963              :         "timeout %llu localFlagAddr %p remoteFlagAddr %p lfkey %u rfkey %u qpinfo %llu",
     964              :         machinePara_.localUserrank, machinePara_.remoteUserrank, apiParam.lKey, apiParam.rKey, apiParam.remoteAddr, apiParam.localAddr, apiParam.dataSize,
     965              :         apiParam.timeout, apiParam.localFlagAddr, apiParam.remoteFlagAddr, apiParam.lfKey, apiParam.rfKey, apiParam.qpInfo.qpPtr);
     966              : 
     967              : #ifndef CCL_KERNEL
     968              :     u16 timeOut = NOTIFY_DEFAULT_WAIT_TIME > std::numeric_limits<uint16_t>::max() ? 
     969              :                     std::numeric_limits<uint16_t>::max() : NOTIFY_DEFAULT_WAIT_TIME;
     970              :     CHK_PRT(AicpuAclKernelLaunch(stream.ptr(), reinterpret_cast<void *>(&apiParam), sizeof(apiParam),
     971              :             binHandle_, kernelName, true, timeOut));
     972              : #else
     973            0 :     HCCL_ERROR("[AicpuAclKernelLaunch]Does not support this interface.");
     974            0 :     return HCCL_E_NOT_SUPPORT;
     975              : #endif
     976              :     return HCCL_SUCCESS;
     977            0 : }
     978              : 
     979            0 : HcclResult TransportDirectNpu::TxDone(Stream &stream)
     980              : {
     981            0 :     return HCCL_SUCCESS;
     982              : }
     983              : 
     984            0 : HcclResult TransportDirectNpu::RxDone(Stream &stream)
     985              : {
     986            0 :     return HCCL_SUCCESS;
     987              : }
     988              : 
     989            0 : HcclResult TransportDirectNpu::PostFin(Stream &stream)
     990              : {
     991            0 :     return HCCL_SUCCESS;
     992              : }
     993              : 
     994            0 : HcclResult TransportDirectNpu::WaitFin(Stream &stream)
     995              : {
     996            0 :     return HCCL_SUCCESS;
     997              : }
     998              : 
     999            0 : HcclResult TransportDirectNpu::PostFinAck(Stream &stream)
    1000              : {
    1001            0 :     return HCCL_SUCCESS;
    1002              : }
    1003              : 
    1004            0 : HcclResult TransportDirectNpu::WaitFinAck(Stream &stream)
    1005              : {
    1006            0 :     return HCCL_SUCCESS;
    1007              : }
    1008              : 
    1009            0 : HcclResult TransportDirectNpu::GetRemoteMemKey(UserMemType memType, uint32_t *remoteMemKey)
    1010              : {
    1011            0 :     switch (memType) {
    1012            0 :         case UserMemType::INPUT_MEM:
    1013              :         case UserMemType::OUTPUT_MEM:
    1014            0 :             *remoteMemKey = remoteMemMsg_[static_cast<u32>(memType)].lkey;
    1015            0 :             break;
    1016              : 
    1017            0 :         default:
    1018            0 :             HCCL_ERROR("[Get][RemoteMemKey]not support dst_mem_type=%d", memType);
    1019            0 :             return HCCL_E_NOT_SUPPORT;
    1020              :     }
    1021            0 :     return HCCL_SUCCESS;
    1022              : }
    1023              : 
    1024            0 : HcclResult TransportDirectNpu::GetLocalMemDetails(UserMemType memType, MemDetails &memDetails)
    1025              : {
    1026            0 :     switch (memType) {
    1027            0 :         case UserMemType::INPUT_MEM:
    1028              :         case UserMemType::OUTPUT_MEM:
    1029            0 :             memDetails.addr = reinterpret_cast<u64>(memMsg_[static_cast<u32>(memType)].addr);
    1030            0 :             memDetails.size = memMsg_[static_cast<u32>(memType)].len;
    1031            0 :             memDetails.key = memMsg_[static_cast<u32>(memType)].lkey;
    1032            0 :             break;
    1033              : 
    1034            0 :         default:
    1035            0 :             HCCL_ERROR("[Get][LocalMemDetails]not support dst_mem_type=%d", memType);
    1036            0 :             return HCCL_E_NOT_SUPPORT;
    1037              :     }
    1038            0 :     return HCCL_SUCCESS;
    1039              : }
    1040              : 
    1041            0 : HcclResult TransportDirectNpu::GetAiQpInfo(std::vector<HcclQpInfoV2> &aiQpInfo)
    1042              : {
    1043            0 :     aiQpInfo.resize(aiQpInfos_.size() + 1);
    1044              : 
    1045            0 :     aiQpInfo[0].qpPtr   = aiQpInfo_.aiQpAddr;
    1046            0 :     aiQpInfo[0].sqIndex = aiQpInfo_.sqIndex;
    1047            0 :     aiQpInfo[0].dbIndex = aiQpInfo_.dbIndex;
    1048            0 :     HCCL_DEBUG("[TransportDirectNpu][GetAiQpInfo] i[0] qpPtr[%llu] sqIndex[%u] dbIndex[%u]",
    1049              :         aiQpInfo[0].qpPtr, aiQpInfo[0].sqIndex, aiQpInfo[0].dbIndex);
    1050            0 :     for (u32 i = 1, j = 0; i < aiQpInfo.size(); i++, j++) {
    1051            0 :         aiQpInfo[i].qpPtr = aiQpInfos_[j].aiQpAddr;
    1052            0 :         aiQpInfo[i].sqIndex = aiQpInfos_[j].sqIndex;
    1053            0 :         aiQpInfo[i].dbIndex = aiQpInfos_[j].dbIndex;
    1054            0 :         HCCL_DEBUG("[TransportDirectNpu][GetAiQpInfo] i[%u] qpPtr[%llu] sqIndex[%u] dbIndex[%u]",
    1055              :             i, aiQpInfo[i].qpPtr, aiQpInfo[i].sqIndex, aiQpInfo[i].dbIndex);
    1056              :     }
    1057            0 :     return HCCL_SUCCESS;
    1058              : }
    1059              : 
    1060            0 : HcclResult TransportDirectNpu::GetTransportErrorCqe(const HcclNetDevCtx netDevCtx,
    1061              :     std::vector<std::pair<TransportBase*, CqeInfo>> &infos, u32 &num)
    1062              : {
    1063            0 :     if (g_qpn2IbversLinkMap_.Size() == 0) {
    1064            0 :         num = 0;
    1065            0 :         return HCCL_SUCCESS;
    1066              :     }
    1067              : 
    1068            0 :     if (UNLIKELY(!g_flag)) {
    1069            0 :         CHK_RET(IsSuppCqeErrInfoListConfig(g_isSupCqeErrInfoListConfig));
    1070            0 :         g_flag = true;
    1071              :     }
    1072              : 
    1073            0 :     CHK_PTR_NULL(netDevCtx);
    1074            0 :     s32 deviceLogicId       = (static_cast<NetDevContext *>(netDevCtx))->GetLogicId();
    1075            0 :     s32 devicePhyId         = (static_cast<NetDevContext *>(netDevCtx))->GetPhyId();
    1076            0 :     HcclIpAddress localIp   = (static_cast<NetDevContext *>(netDevCtx))->GetLocalIp();
    1077            0 :     NicType nicType         = (static_cast<NetDevContext *>(netDevCtx))->GetNicType();
    1078            0 :     CHK_PRT_RET(nicType == NicType::HOST_NIC_TYPE,
    1079              :         HCCL_WARNING("[TransportDirectNpu][GetTransportErrorCqe] nicType[%d] not support", nicType), HCCL_SUCCESS);
    1080            0 :     RaResourceInfo raResourceInfo;
    1081            0 :     CHK_RET(NetworkManager::GetInstance(deviceLogicId).GetRaResourceInfo(raResourceInfo));
    1082            0 :     RdmaHandle rdmaHandle   = raResourceInfo.nicSocketMap[localIp].nicRdmaHandle;
    1083            0 :     CHK_PTR_NULL(rdmaHandle);
    1084              : 
    1085            0 :     if (g_isSupCqeErrInfoListConfig) {
    1086            0 :         u32 loop = 0;
    1087            0 :         if (num > CQE_ARRAY_SIZE) {
    1088            0 :             loop = (num % CQE_ARRAY_SIZE) ? (num / CQE_ARRAY_SIZE) : ((num / CQE_ARRAY_SIZE) - 1);
    1089              :         }
    1090              : 
    1091            0 :         struct CqeErrInfo infolist[CQE_ARRAY_SIZE] = {};
    1092            0 :         u32 cqeNum = CQE_ARRAY_SIZE;
    1093            0 :         for (u32 index = 0; index <= loop; index++) {
    1094            0 :             cqeNum = (index == loop) ? (num - index * CQE_ARRAY_SIZE) : CQE_ARRAY_SIZE;
    1095            0 :             u32 temNum = cqeNum;
    1096            0 :             CHK_RET(hrtRaGetCqeErrInfoList(rdmaHandle, infolist, &temNum));
    1097            0 :             ProcessCqeInfo(devicePhyId, infolist, temNum, infos);
    1098            0 :             if (temNum < cqeNum) {
    1099            0 :                 break;
    1100              :             }
    1101              :         }
    1102              :     } else {
    1103            0 :         struct CqeErrInfo infolist[1] = {};
    1104            0 :         CHK_RET(hrtRaGetCqeErrInfo(devicePhyId, &infolist[0]));
    1105            0 :         if (infolist[0].status == 0) {
    1106            0 :             num = 0;
    1107            0 :             return HCCL_SUCCESS;
    1108              :         }
    1109            0 :         u32 cqeNum = 1;
    1110            0 :         ProcessCqeInfo(devicePhyId, infolist, cqeNum, infos);
    1111              :     }
    1112              : 
    1113            0 :     num = infos.size();
    1114              : 
    1115            0 :     return HCCL_SUCCESS;
    1116            0 : }
    1117              : 
    1118            0 : void TransportDirectNpu::ProcessCqeInfo(const s32 deviceId, const struct CqeErrInfo *infolist, const u32 cqeNum,
    1119              :     std::vector<std::pair<TransportBase*, CqeInfo>> &infos)
    1120              : {
    1121            0 :     for (u32 i = 0; i < cqeNum; i++) {
    1122              :         // localPhyId + qpn
    1123            0 :         auto it = g_qpn2IbversLinkMap_.Find(((static_cast<u64>(deviceId) << DEV_PHY_ID_BIT) | infolist[i].qpn));
    1124            0 :         if (it.second) {
    1125            0 :             TransportBase *ptr = reinterpret_cast<TransportBase*>(it.first->second);
    1126            0 :             infos.push_back(std::make_pair(
    1127              :                 ptr,
    1128            0 :                 CqeInfo(infolist[i].time, infolist[i].status, it.first->second->GetRemoteIp())));
    1129            0 :                 cqeErrQpn_ = infolist[i].qpn;
    1130              :         } else {
    1131            0 :             HCCL_RUN_WARNING("[GetTransportErrorCqe]get err failed, transport is not find.");
    1132              :         }
    1133              :     }
    1134            0 :     return;
    1135              : }
    1136              : 
    1137            0 : HcclIpAddress& TransportDirectNpu::GetRemoteIp()
    1138              : {
    1139            0 :     return machinePara_.remoteIpAddr;
    1140              : }
    1141              : 
    1142            0 : HcclResult TransportDirectNpu::GetTransportId(u32 &id)
    1143              : {
    1144            0 :     id = cqeErrQpn_;
    1145            0 :     return HCCL_SUCCESS;
    1146              : }
    1147              : }  // namespace hccl
        

Generated by: LCOV version 2.0-1