LCOV - code coverage report
Current view: top level - coll_communicator_mgr/resource_mgr/local/my_rank - my_rank.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.6 % 598 446
Test Date: 2026-08-04 10:52:23 Functions: 87.2 % 39 34

            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              : #include "my_rank.h"
      11              : #include "hcomm_c_adpt.h"
      12              : #include "endpoint_pair.h"
      13              : #include "hccl_res.h"
      14              : #include "../common/loggers/channel_logger.h"  // 日志记录器
      15              : #include "hcclCommDfx.h"
      16              : #include "config/env_config.h"
      17              : #include "env_config/env_config.h"
      18              : #include "channel_process.h"
      19              : #include "ccu_dev_mgr_imp.h"
      20              : #include "ccu_device_res.h"
      21              : #include "ccu_res_desc.h"
      22              : #include "ccu_device_pub.h"
      23              : #include "ccu_res_desc_mgr.h"
      24              : #include "ccu_log.h"
      25              : #include "dlprof_function.h"
      26              : #include "config_log.h"
      27              : #include "comm_engine_utils.h"
      28              : #include "hcom_common.h"
      29              : #include "op_base.h"
      30              : #include "ccu_res.h"
      31              : #include "coll_comm_mgr.h"
      32              : 
      33              : #include <acl/acl.h>
      34              : 
      35              : using namespace hcomm;
      36              : 
      37              : namespace MyRankUtils {
      38              : 
      39            4 : uint32_t ResolveUbCommDomainQos(const hccl::CommConfig &commConfig)
      40              : {
      41            4 :     if (commConfig.GetConfigHcclQos() == HCCL_COMM_QOS_CONFIG_NOT_SET) {
      42            1 :         return EnvConfig::UB_QOS_DEFAULT;
      43              :     }
      44            3 :     return commConfig.GetConfigHcclQos();
      45              : }
      46              : 
      47           13 : HcommChannelDesc ChannelDescHccl2Hcomm(const HcclChannelDesc &hcclDesc, const hccl::CommConfig &commConfig)
      48              : {
      49           13 :     HcommChannelDesc hcommDesc{};
      50           13 :     (void)HcommChannelDescInit(&hcommDesc, 1);
      51           13 :     hcommDesc.remoteEndpoint = hcclDesc.remoteEndpoint;
      52           13 :     hcommDesc.notifyNum = hcclDesc.notifyNum;
      53           13 :     hcommDesc.memHandles = reinterpret_cast<HcommMemHandle *>(hcclDesc.memHandles);
      54           13 :     hcommDesc.memHandleNum = hcclDesc.memHandleNum;
      55           13 :     (void)memcpy_s(hcommDesc.raws, sizeof(hcommDesc.raws), hcclDesc.raws, sizeof(hcommDesc.raws));
      56           13 :     if (hcclDesc.channelProtocol == COMM_PROTOCOL_ROCE) {
      57            5 :         hcommDesc.roceAttr.retryCnt = hcclDesc.roceAttr.retryCnt;
      58            5 :         hcommDesc.roceAttr.retryInterval = hcclDesc.roceAttr.retryInterval;
      59            5 :         hcommDesc.roceAttr.sl = hcclDesc.roceAttr.sl;
      60            5 :         hcommDesc.roceAttr.tc = hcclDesc.roceAttr.tc;
      61            5 :         return hcommDesc;
      62              :     }
      63            8 :     if (hcclDesc.channelProtocol == COMM_PROTOCOL_UBC_CTP ||
      64            7 :         hcclDesc.channelProtocol == COMM_PROTOCOL_UBC_TP ||
      65            5 :         hcclDesc.channelProtocol == COMM_PROTOCOL_UBOE ||
      66            4 :         hcclDesc.channelProtocol == COMM_PROTOCOL_UBG) {
      67            4 :         hcommDesc.qos = ResolveUbCommDomainQos(commConfig);
      68              :     }
      69            8 :     return hcommDesc;
      70              : }
      71              : 
      72              : /* 公共模块函数返回值定义,跟业务层同步 */
      73              : const std::unordered_map<CommProtocol, std::string> HCOM_COMM_PROTOCOL_STR_MAP = {
      74              :     {COMM_PROTOCOL_RESERVED, "RESERVED"},
      75              :     {COMM_PROTOCOL_HCCS, "HCCS"},
      76              :     {COMM_PROTOCOL_ROCE, "ROCE"},
      77              :     {COMM_PROTOCOL_PCIE, "PCIE"},
      78              :     {COMM_PROTOCOL_SIO, "SIO"},
      79              :     {COMM_PROTOCOL_UBC_CTP, "UBC_CTP"},
      80              :     {COMM_PROTOCOL_UBC_TP, "UBC_TP"},
      81              :     {COMM_PROTOCOL_UB_MEM, "UB_MEM"},
      82              :     {COMM_PROTOCOL_UBOE, "UBOE"},
      83              :     {COMM_PROTOCOL_UBG, "UBG"}
      84              : };
      85              : 
      86            0 : inline std::string GetCommProtocolEnumStr(CommProtocol protocol)
      87              : {
      88            0 :     auto iter = HCOM_COMM_PROTOCOL_STR_MAP.find(protocol);
      89            0 :     if (iter == HCOM_COMM_PROTOCOL_STR_MAP.end()) {
      90            0 :         return "CommProtocol(" + std::to_string(protocol) + ")";
      91              :     } else {
      92            0 :         return iter->second;
      93              :     }
      94              : }
      95              : 
      96              : } // namespace MyRankUtils
      97              : 
      98              : namespace hccl {
      99              : 
     100              : constexpr uint32_t UNREUSE_CHANNEL_IDX = 0xFFFFFFFF;
     101              : 
     102          167 : MyRank::MyRank(aclrtBinHandle binHandle, uint32_t rankId, const CommConfig &config, const ManagerCallbacks &callbacks,
     103              :     RankGraph *rankGraph,
     104          167 :     const Hccl::RankIpPortMapPtr& rankIpPortMap)
     105          167 :     : binHandle_(binHandle),
     106          167 :       rankId_(rankId),
     107          167 :       config_(config),
     108          167 :       callbacks_(callbacks),
     109          167 :       rankGraph_(rankGraph),
     110          167 :       rankIpPortMap_(rankIpPortMap)
     111              : {
     112          167 : }
     113              : 
     114          334 : MyRank::~MyRank()
     115              : {
     116          167 :     HCCL_INFO("[MyRank][~MyRank] MyRank deinit, rankId_[%u], devLogicId_[%d]", rankId_, devLogicId_);
     117              :     // 析构有时序要求
     118          167 :     rankPairMgr_ = nullptr; // 内部会销毁channel,可能需要返还endpoint与ccu资源
     119          167 :     endpointMgr_ = nullptr; // 内部会销毁endpoint,可能需要返回ccu资源
     120              : 
     121              :     struct ResourceCleanupGuard {
     122          167 :         explicit ResourceCleanupGuard(MyRank &myRank) : myRank_(myRank) {}
     123          167 :         ~ResourceCleanupGuard() noexcept
     124              :         {
     125          167 :             myRank_.ccuInsHandle_ = 0;
     126              : 
     127          167 :             if (!myRank_.useCcuResStaticAlloc_ && myRank_.ccuDrvHandle_) {
     128            1 :                 myRank_.ccuDrvHandle_ = nullptr; // 先减少引用计数,再尝试关闭
     129            1 :                 (void)CcuDeinitFeature(myRank_.devLogicId_);
     130              :                 // 尝试关闭CCU功能,最后一个调用时会关闭CCU驱动
     131              :             }
     132              : 
     133          167 :             myRank_.ReleaseCcuMsCommReservation();
     134              : 
     135          167 :             myRank_.commMems_ = nullptr;
     136          167 :             myRank_.nsRecoveryProcessor_ = nullptr;
     137          167 :         }
     138              : 
     139              :         MyRank &myRank_;
     140          167 :     } cleanupGuard(*this);
     141              : 
     142          167 :     if (ccuInsHandle_ != 0) {  // 内部清理CCU资源,关闭CCU通道
     143              :         // 刷新并获取当前线程的 DeviceId
     144            6 :         int32_t threadDevId = INVALID_INT;
     145            6 :         CHK_RET_NULL(HcclDeviceRefresh(threadDevId));
     146            6 :         HCCL_INFO("[%s] curDeviceLogicId[%d], threadDevId[%d]", __func__, devLogicId_, threadDevId);
     147              :         // 先切换为目标 curDeviceLogicId
     148            6 :         bool isDiffDevId = false;
     149            6 :         if (devLogicId_ != threadDevId) {
     150            0 :             CHK_RET_NULL(hrtSetDevice(devLogicId_));
     151            0 :             isDiffDevId = true;
     152              :         }
     153              :         // 销毁 CcuInstance
     154            6 :         CcuResult ret = HcommCcuInsDestroy(ccuInsHandle_);
     155            6 :         if (ret != CCU_SUCCESS) {
     156            4 :             HCCL_ERROR("[%s] HcommCcuInsDestroy failed, ret[%d]", __func__, ret);
     157              :         }
     158              :         // 切换回原来的 DeviceId
     159            6 :         if (isDiffDevId) {
     160            0 :             CHK_RET_NULL(hrtSetDevice(threadDevId));
     161            0 :             CHK_PRT(HcclDeviceRefresh(threadDevId));
     162              :         }
     163              :     }
     164          334 : }
     165              : 
     166            5 : HcclResult MyRank::GetLocalTlsStatus(Hccl::TlsStatus &tlsStatus) const
     167              : {
     168            5 :     tlsStatus = Hccl::TlsStatus::UNKNOWN;
     169            5 :     s32 deviceLogicId = -1;
     170            5 :     u32 devicePhyId = INVALID_UINT;
     171            5 :     CHK_RET(hrtGetDevice(&deviceLogicId));
     172            4 :     CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<u32>(deviceLogicId), devicePhyId));
     173              : 
     174            3 :     RaInfo info{};
     175            3 :     info.mode = NetworkMode::NETWORK_OFFLINE;
     176            3 :     info.phyId = devicePhyId;
     177            3 :     return Hccl::HrtRaGetTlsStatus(&info, tlsStatus);
     178              : }
     179              : 
     180              : constexpr uint32_t DEFAULT_MODE = 0;
     181              : constexpr uint32_t AICPU_TS_MODE = 2;
     182              : constexpr uint32_t CCU_MS_MODE = 5;
     183              : constexpr uint32_t CCU_SCHED_MODE = 6;
     184           13 : inline CcuInstanceType OpExpansionModeToCcuInstanceType(uint32_t opExpansionMode)
     185              : {
     186              :     // 仅作数据类型转换,不做逻辑处理
     187           13 :     if (opExpansionMode == CCU_SCHED_MODE) {
     188            4 :         return CcuInstanceType::CCU_SCHED;
     189              :     }
     190              : 
     191            9 :     if (opExpansionMode == CCU_MS_MODE) {
     192            7 :         return CcuInstanceType::CCU_MS;
     193              :     }
     194              :     
     195            2 :     return CcuInstanceType::CCU_UNUSED;
     196              : }
     197              : 
     198           11 : HcclResult MyRank::TryInitCcuInstanceLegacy()
     199              : {
     200           11 :     auto ccuInsType = OpExpansionModeToCcuInstanceType(opExpansionMode_);
     201           11 :     if (ccuInsType == CcuInstanceType::CCU_UNUSED) {
     202            0 :         ccuInsHandle_ = 0;
     203            0 :         return HcclResult::HCCL_SUCCESS;
     204              :     }
     205              : 
     206           11 :     auto ccuInitRet = HcommCcuInsCreateLegacy(ccuInsType, &ccuInsHandle_);
     207              : 
     208              :     // ccu驱动拉起失败,直接回退至aicpu ts
     209           11 :     if (ccuInitRet == CcuResult::CCU_E_DRV_BUSY) {
     210            2 :         opExpansionMode_ = AICPU_TS_MODE;
     211            2 :         ccuInsHandle_ = 0;
     212            2 :         HCCL_RUN_WARNING("[MyRank][%s] failed to init ccu driver, fallback to aicpu, rankId[%u].", __func__, rankId_);
     213            2 :         return HcclResult::HCCL_SUCCESS;
     214              :     }
     215              : 
     216              :     // ccu通信域数量过多,导致资源不足     
     217            9 :     if (CCU_CHK_RES_UNAVAIL(ccuInitRet)) {
     218              :         // 如果是ccu ms模式,回退至ccu调度模式重试
     219              :         // 复用原有的ccuResContainer,回退到ccu sched时不需要重复拉起ccu驱动
     220            4 :         if (opExpansionMode_ == CCU_MS_MODE) {
     221            3 :             opExpansionMode_ = CCU_SCHED_MODE;
     222            3 :             CHK_RET(TryInitCcuInstanceLegacy()); // 至多递归一次
     223            3 :             return HcclResult::HCCL_SUCCESS;
     224              :         }
     225              : 
     226              :         // 其余模式资源不足回退至aicpu ts
     227            1 :         opExpansionMode_ = AICPU_TS_MODE;
     228            1 :         ccuInsHandle_ = 0;
     229            1 :         HCCL_RUN_WARNING("[MyRank][%s] ccu resources are unavailable, fallback to aicpu, rankId[%u].", __func__, rankId_);
     230            1 :         return HcclResult::HCCL_SUCCESS;
     231              :     }
     232              : 
     233              :     // 预期外返回值属于错误
     234            5 :     if (ccuInitRet != CcuResult::CCU_SUCCESS) {
     235            2 :         HCCL_ERROR("[%s] failed, ret[%d] is not expected.", __func__, ccuInitRet);
     236            2 :         ccuInsHandle_ = 0;
     237            2 :         return static_cast<HcclResult>(ccuInitRet);
     238              :     }
     239              : 
     240              :     // ccu资源申请成功
     241            3 :     return HcclResult::HCCL_SUCCESS;
     242              : }
     243              : 
     244           10 : HcclResult MyRank::ReserveCcuMsCommOrFallback()
     245              : {
     246           10 :     if (opExpansionMode_ != CCU_MS_MODE) {
     247            2 :         return HCCL_SUCCESS;
     248              :     }
     249              : 
     250            8 :     bool reserved = false;
     251            8 :     CHK_RET(CollCommMgr::GetInstance()->TryReserveCcuMsComm(
     252              :         devLogicId_, config_.GetConfigCommName(), reserved));
     253            8 :     if (reserved) {
     254            7 :         ccuMsCommReserved_ = true;
     255            7 :         return HCCL_SUCCESS;
     256              :     }
     257              : 
     258            1 :     opExpansionMode_ = CCU_SCHED_MODE;
     259            1 :     HCCL_RUN_WARNING("[MyRank][%s] CCU_MS comm already exists on device[%d], fallback to CCU_SCHED, rankId[%u].",
     260              :         __func__, devLogicId_, rankId_);
     261            1 :     return HCCL_SUCCESS;
     262              : }
     263              : 
     264          177 : void MyRank::ReleaseCcuMsCommReservation()
     265              : {
     266          177 :     if (!ccuMsCommReserved_) {
     267          169 :         return;
     268              :     }
     269            8 :     CollCommMgr::GetInstance()->ReleaseCcuMsComm(devLogicId_, config_.GetConfigCommName());
     270            8 :     ccuMsCommReserved_ = false;
     271              : }
     272              : 
     273           10 : void MyRank::ReconcileCcuMsCommReservation(HcclResult initRet)
     274              : {
     275           10 :     if (initRet != HCCL_SUCCESS || opExpansionMode_ != CCU_MS_MODE) {
     276           10 :         ReleaseCcuMsCommReservation();
     277              :     }
     278           10 : }
     279              : 
     280            2 : HcclResult MyRank::TryInitCcuInstanceOnDemand()
     281              : {
     282              :     // 以下为ccu新接口流程
     283            2 :     auto ccuInsType = OpExpansionModeToCcuInstanceType(opExpansionMode_);
     284            2 :     if (ccuInsType == CcuInstanceType::CCU_UNUSED) {
     285            2 :         ccuInsHandle_ = 0;
     286            2 :         return HcclResult::HCCL_SUCCESS;
     287              :     }
     288              : 
     289            0 :     if (mainBoardType_ == Hccl::HcclMainboardId::MAINBOARD_OTHERS) {
     290            0 :         CHK_RET(CcuGetMainboardType(devLogicId_, mainBoardType_));
     291              :     }
     292              : 
     293            0 :     if (mainBoardType_ == Hccl::HcclMainboardId::MAINBOARD_PCIE_STD &&
     294              :         ccuInsType == CcuInstanceType::CCU_MS) { // 标卡环境下配置CCU_MS拦截报错
     295            0 :         HCCL_ERROR("[%s] ccuInstanceType[%d] not support in %s", __func__,
     296              :             ccuInsType, mainBoardType_.Describe().c_str());
     297            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     298              :     }
     299              : 
     300              :     // 拉起ccu驱动
     301            0 :     if (!ccuDrvHandle_) {
     302            0 :         auto ccuInitRet = CcuInitFeature(devLogicId_, ccuDrvHandle_);
     303              : 
     304              :         // ccu驱动拉起失败,直接回退至aicpu ts
     305            0 :         if (ccuInitRet == CcuResult::CCU_E_DRV_BUSY) {
     306            0 :             opExpansionMode_ = AICPU_TS_MODE;
     307            0 :             ccuInsHandle_ = 0;
     308            0 :             HCCL_RUN_WARNING("[MyRank][%s] failed to init ccu driver, "
     309              :                 "fallback to aicpu, rankId[%u].", __func__, rankId_);
     310            0 :             return HcclResult::HCCL_SUCCESS;
     311              :         }
     312              : 
     313              :         // 预期外返回值属于错误
     314            0 :         if (ccuInitRet != CcuResult::CCU_SUCCESS) {
     315            0 :             HCCL_ERROR("[%s] failed, ret[%d] is not expected.",
     316              :                 __func__, ccuInitRet);
     317            0 :             ccuInsHandle_ = 0;
     318            0 :             return static_cast<HcclResult>(ccuInitRet);
     319              :         }
     320              :     }
     321              : 
     322              :     // ccu驱动拉起成功
     323            0 :     return HcclResult::HCCL_SUCCESS;
     324              : }
     325              : 
     326           10 : HcclResult MyRank::TryInitCcuInstance()
     327              : {
     328           10 :     CHK_RET(ReserveCcuMsCommOrFallback());
     329              : 
     330           10 :     HcclResult ret = HCCL_SUCCESS;
     331           10 :     if (useCcuResStaticAlloc_) {
     332            8 :         HCCL_RUN_INFO(
     333              :             "[MyRank][%s] HCCL version does not support CCU on-demand resource allocation, use legacy allocation.",
     334              :             __func__);
     335            8 :         ret = TryInitCcuInstanceLegacy();
     336              :     } else {
     337            2 :         ret = TryInitCcuInstanceOnDemand();
     338              :     }
     339           10 :     ReconcileCcuMsCommReservation(ret);
     340           10 :     return ret;
     341              : }
     342              : 
     343           33 : HcclResult MyRank::GetDevicePortInternal(uint32_t rank, uint32_t *devPort, EndpointLocType locType)
     344              : {
     345           33 :     CHK_PTR_NULL(devPort);
     346           33 :     CHK_PTR_NULL(rankGraph_);
     347              : 
     348              :     DevType devType;
     349           33 :     CHK_RET(hrtGetDeviceType(devType));
     350              :     // v1 模式 (mode_ == 0): 强制转换为 RankGraphV1 调用 GetDevicePort
     351              :     // v2 模式 (mode_ != 0): 使用 rankGraph_->GetDevicePort()
     352           33 :     if (devType == DevType::DEV_TYPE_910B) {
     353            0 :         RankGraphV1* rankGraphV1 = static_cast<RankGraphV1*>(rankGraph_);
     354            0 :         CHK_RET(rankGraphV1->GetDevicePort(rank, devPort));
     355              :     } else {
     356           33 :         CHK_RET(rankGraph_->GetListenPort(rank, devPort, locType));
     357              :     }
     358           33 :     return HCCL_SUCCESS;
     359              : }
     360              : 
     361          110 : inline HcclResult GetHcclVersion(int &hcclVersion)
     362              : {
     363          110 :     char hcclPkgName[] = "hccl";
     364          110 :     aclError aclRet = aclsysGetVersionNum(hcclPkgName, &hcclVersion);
     365          110 :     CHK_PRT_RET(aclRet != ACL_SUCCESS,
     366              :         HCCL_ERROR("[GetHcclVersion] aclsysGetVersionNum failed, aclRet[%d].", aclRet), HCCL_E_INTERNAL);
     367          110 :     HCCL_RUN_INFO("[GetHcclVersion] hccl version is %d.", hcclVersion);
     368          110 :     return HCCL_SUCCESS;
     369              : }
     370              : 
     371              : constexpr int MAX_HCCL_VERSION_USING_CCU_RES_STATIC_ALLOC = 90100000;
     372          110 : HcclResult MyRank::Init(HcclMem cclBuffer, const uint32_t opExpansionMode, uint32_t rankNum)
     373              : {
     374              :     // EXCEPTION_HANDLE_BEGIN
     375          110 :     CHK_RET(hrtGetDevice(&devLogicId_));
     376              : 
     377              :     // 获取hccl版本
     378          110 :     int hcclVersion = 0;
     379          110 :     CHK_RET(GetHcclVersion(hcclVersion));
     380          110 :     useCcuResStaticAlloc_ = hcclVersion <= MAX_HCCL_VERSION_USING_CCU_RES_STATIC_ALLOC;
     381              : 
     382              :     // ns recovery processor初始化
     383          110 :     EXCEPTION_CATCH(nsRecoveryProcessor_ = std::make_unique<NsRecoveryProcessor>(), return HCCL_E_PTR);
     384              :     
     385              :     // 创建通信内存管理器
     386          110 :     EXCEPTION_CATCH(commMems_ = std::make_unique<CommMems>(config_.GetConfigBufferSize()), return HCCL_E_PTR);
     387              : 
     388              :     // 初始化通信内存
     389          110 :     CHK_RET(commMems_->Init(cclBuffer));
     390              : 
     391          110 :     EXCEPTION_CATCH(engineCtxs_ = std::make_unique<EngineCtxs>(), return HCCL_E_PTR);
     392              : 
     393              :     // 通信域配置config优先级更高,当配置默认展开模式时,读取环境变量配置
     394          110 :     opExpansionMode_ = opExpansionMode;
     395          110 :     if (opExpansionMode_ == DEFAULT_MODE) {
     396              :         // 环境变量模块已处理,当用户未配置时,输出ccu sched模式
     397            1 :         auto accelerator = Hccl::EnvConfig::GetInstance().GetAlgoConfig().GetHcclAccelerator();
     398            1 :         HCCL_RUN_INFO("[MyRank][%s] set op expansion mode by env[%s].",
     399              :             __func__, accelerator.Describe().c_str());
     400            1 :         opExpansionMode_ = static_cast<uint32_t>(accelerator);
     401              :     }
     402              : 
     403              :     // 仅自定义算子ccu流程初始化资源
     404          110 :     if (ccuInsHandle_ == 0 && rankNum != 1 &&
     405          109 :         (opExpansionMode_ == CCU_MS_MODE || opExpansionMode_ == CCU_SCHED_MODE)) {
     406            7 :         const uint32_t originOpExpansionMode = opExpansionMode_; // 记录原始加速模式,避免中间执行修改后丢失
     407            7 :         auto ret = TryInitCcuInstance();
     408            7 :         if (ret != HcclResult::HCCL_SUCCESS) { // 申请成功与回退成功都属于成功,其他均非预期
     409            1 :             HCCL_ERROR("[MyRank][%s] failed to init ccu instance, op expansion mode[%u].",
     410              :                 __func__, originOpExpansionMode);
     411            1 :             return ret;
     412              :         }
     413              :     }
     414              : 
     415              :     // 创建端点管理器
     416          109 :     EXCEPTION_CATCH(endpointMgr_ = std::make_unique<hcomm::EndpointMgr>(), return HCCL_E_PTR);
     417              : 
     418              :     // rankPairMgr_初始化
     419          109 :     EXCEPTION_CATCH(rankPairMgr_ = std::make_unique<RankPairMgr>(rankIpPortMap_), return HCCL_E_PTR);
     420              : 
     421          109 :     DlProfFunction::GetInstance().DlProfFunctionInit();
     422              :     // EXCEPTION_HANDLE_END
     423          109 :     return HCCL_SUCCESS;
     424              : }
     425              : 
     426            9 : HcclResult MyRank::QueryListenPort(uint32_t localRank, uint32_t remoteRank, const EndpointDesc &localEndpointDesc,
     427              :         const EndpointDesc &remoteEndpointDesc, uint32_t &listenPort, HcommChannelDesc &hcommDesc)
     428              : {
     429              :     // 查询rmtRankId对应的devPort
     430            9 :     uint32_t rmtPort = 0;
     431            9 :     CHK_RET(GetDevicePortInternal(remoteRank, &rmtPort, remoteEndpointDesc.loc.locType));
     432            9 :     if (rmtPort > Hccl::MAX_VALUE_TCPPORT) {
     433            1 :         HCCL_ERROR("[%s] Invalid port[%u] of Rank[%u]", __func__, rmtPort, remoteRank);
     434            1 :         return HCCL_E_PARA;
     435              :     }
     436              :     // 查询该socket链接的server端监听的端口(监听方的选择策略需要跟SocketConfig中保持一致)
     437            8 :     Hccl::IpAddress localIpAddr{};
     438            8 :     Hccl::IpAddress remoteIpAddr{};
     439            8 :     CHK_RET(CommAddrToIpAddress(localEndpointDesc.commAddr, localIpAddr));
     440            8 :     CHK_RET(CommAddrToIpAddress(remoteEndpointDesc.commAddr, remoteIpAddr));
     441            8 :     if (localIpAddr < remoteIpAddr) {
     442              :         // 查询localRankId对应的devPort
     443            6 :         CHK_RET(GetDevicePortInternal(localRank, &listenPort, localEndpointDesc.loc.locType));
     444            6 :         hcommDesc.role = HcommSocketRole::HCOMM_SOCKET_ROLE_SERVER;
     445            6 :         if (listenPort > Hccl::MAX_VALUE_TCPPORT) {
     446            0 :             HCCL_ERROR("[%s] Invalid port[%u] of Rank[%u]", __func__, listenPort, localRank);
     447            0 :             return HCCL_E_PARA;
     448              :         }
     449            6 :         hcommDesc.port = static_cast<uint16_t>(listenPort); // HcommChannelDesc.port中填监听端口号
     450              :     } else {
     451            2 :         listenPort = rmtPort;
     452            2 :         hcommDesc.role = HcommSocketRole::HCOMM_SOCKET_ROLE_CLIENT;
     453            2 :         hcommDesc.port = static_cast<uint16_t>(rmtPort); // HcommChannelDesc.port中填对端端口号(此场景下对端端口号也就是监听端口号)
     454              :     }
     455              : 
     456            8 :     return HCCL_SUCCESS;
     457              : }
     458              : 
     459           12 : HcclResult MyRank::GetEndpointPairFromChannel(const HcclChannelDesc &channelDesc, uint32_t channelIndex, uint32_t channelNum,
     460              :     uint32_t &remoteRank, hcomm::EndpointPair* &endpointPair, RankPair* &rankPair)
     461              : {
     462           12 :     remoteRank = channelDesc.remoteRank;
     463           12 :     HCCL_INFO("[%s][%u/%u] remoteRank[%u] localProtocol[%d] remoteProtocol[%d]",
     464              :         __func__, channelIndex + 1, channelNum, remoteRank, channelDesc.localEndpoint.protocol, channelDesc.remoteEndpoint.protocol);
     465              : 
     466           12 :     const RankIdPair rankIdPair = std::make_pair(rankId_, remoteRank);
     467           12 :     const EndpointDescPair endpointDescPair = std::make_pair(channelDesc.localEndpoint, channelDesc.remoteEndpoint);
     468           12 :     CHK_RET(rankPairMgr_->Get(rankIdPair, rankPair));
     469           12 :     CHK_PTR_NULL(rankPair);
     470           12 :     CHK_RET(rankPair->GetEndpointPair(endpointDescPair, endpointPair));
     471           12 :     CHK_PTR_NULL(endpointPair);
     472           12 :     return HCCL_SUCCESS;
     473              : }
     474              : 
     475           12 : inline std::string AddProtocolToSocketTag(const std::string &socketTag, const HcclChannelDesc* channelDescs)
     476              : {
     477           12 :     std::string newSocketTag = socketTag + "_protocol_" + std::to_string(channelDescs->channelProtocol);
     478           12 :     return newSocketTag;
     479              : }
     480              : 
     481            3 : HcclResult MyRank::BatchServerInitForChannels(const HcclChannelDesc* channelDescs, uint32_t channelNum,
     482              :     const std::string &socketTag, ReuseSocketIdxMap &reuseSocketIdxMap)
     483              : {
     484              :     // 批量获取socket,与server监听隔离开
     485            9 :     for (uint32_t i = 0; i < channelNum; ++i) {
     486            6 :         hcomm::EndpointPair* endpointPair = nullptr;
     487            6 :         RankPair* rankPair = nullptr;
     488            6 :         uint32_t remoteRank = 0;
     489              : 
     490            6 :         CHK_RET(GetEndpointPairFromChannel(channelDescs[i], i, channelNum, remoteRank, endpointPair, rankPair));
     491              : 
     492            6 :         if (reuseSocketIdxMap.find(rankPair) == reuseSocketIdxMap.end()) {
     493            4 :             std::unordered_map<hcomm::EndpointPair*, u32> endpointPair2Idx{};
     494            4 :             endpointPair2Idx.emplace(endpointPair, 0);
     495            4 :             reuseSocketIdxMap.emplace(rankPair, endpointPair2Idx);
     496            6 :         } else if (reuseSocketIdxMap[rankPair].find(endpointPair) == reuseSocketIdxMap[rankPair].end()) {
     497            0 :             reuseSocketIdxMap[rankPair].emplace(endpointPair, 0);
     498              :         }
     499            6 :         u32& reuseIdx = reuseSocketIdxMap[rankPair][endpointPair];
     500              : 
     501              :         uint32_t devicePhyId;
     502              :         uint32_t remoteDevicePhyId;
     503            6 :         rankGraph_->GetDeviceId(rankId_, &devicePhyId);
     504            6 :         rankGraph_->GetDeviceId(remoteRank, &remoteDevicePhyId);
     505              : 
     506            6 :         const std::string socketTagAddProto = AddProtocolToSocketTag(socketTag, &channelDescs[i]);
     507            6 :         auto ret = endpointPair->ServerInit(rankId_, remoteRank, socketTagAddProto, reuseIdx, devicePhyId, remoteDevicePhyId);
     508            6 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     509              :             HCCL_ERROR("[%s] ServerInitFailed, channelIndex[%u], remoteRank[%u], protocol[%d] reuseIdx[%u]",
     510              :                 __func__, i, remoteRank, channelDescs[i].localEndpoint.protocol, reuseIdx),
     511              :             ret);
     512              : 
     513            6 :         HCCL_INFO("[%s][%u/%u] server listen successfully, remoteRank[%u], reuseIdx[%u]",
     514              :             __func__, i + 1, channelNum, remoteRank, reuseIdx);
     515            6 :     }
     516            3 :     return HCCL_SUCCESS;
     517              : }
     518              : 
     519            3 : HcclResult MyRank::BatchGetSocketsForChannels(const HcclChannelDesc* channelDescs, uint32_t channelNum,
     520              :     const std::string &socketTag, std::vector<HcommChannelDesc> &hcommDescs,
     521              :     ReuseSocketIdxMap &reuseSocketIdxMap)
     522              : {
     523            9 :     for (uint32_t i = 0; i < channelNum; ++i) {
     524            6 :         hcomm::EndpointPair* endpointPair = nullptr;
     525            6 :         RankPair* rankPair = nullptr;
     526            6 :         uint32_t remoteRank = 0;
     527              : 
     528            6 :         CHK_RET(GetEndpointPairFromChannel(channelDescs[i], i, channelNum, remoteRank, endpointPair, rankPair));
     529              : 
     530            6 :         uint32_t listenPort = 0;
     531            6 :         CHK_RET(QueryListenPort(rankId_, remoteRank, channelDescs[i].localEndpoint, channelDescs[i].remoteEndpoint, listenPort, hcommDescs[i]));
     532              : 
     533            6 :         u32& reuseIdx = reuseSocketIdxMap[rankPair][endpointPair];
     534              :         uint32_t devicePhyId;
     535              :         uint32_t remoteDevicePhyId;
     536            6 :         rankGraph_->GetDeviceId(rankId_, &devicePhyId);
     537            6 :         rankGraph_->GetDeviceId(remoteRank, &remoteDevicePhyId);
     538            6 :         HCCL_INFO("[MyRank][BatchCreateSockets] rankId_[%u] devicePhyId[%u] remoteRank[%u] remoteDevicePhyId[%u]",
     539              :                  rankId_, devicePhyId, remoteRank, remoteDevicePhyId);
     540            6 :         Hccl::Socket* socket = nullptr;
     541            6 :         const std::string socketTagAddProto = AddProtocolToSocketTag(socketTag, &channelDescs[i]);
     542            6 :         auto ret = endpointPair->GetConnectedSocket(rankId_, remoteRank, socketTagAddProto, reuseIdx, listenPort, socket, devicePhyId, remoteDevicePhyId);
     543            6 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     544              :             HCCL_ERROR("[%s] failed to get socket, channelIndex[%u], remoteRank[%u], protocol[%d], reuseIdx[%u], tag[%s]",
     545              :                 __func__, i, remoteRank, channelDescs[i].localEndpoint.protocol, reuseIdx, socketTagAddProto.c_str()),
     546              :             ret);
     547            6 :         CHK_PTR_NULL(socket);
     548              : 
     549            6 :         hcommDescs[i].socket = reinterpret_cast<HcommSocket>(socket);
     550              : 
     551            6 :         HCCL_INFO("[%s][%u/%u] socket created successfully, remoteRank[%u], socket[%p] reuseIdx[%u]",
     552              :             __func__, i + 1, channelNum, remoteRank, socket, reuseIdx);
     553            6 :         reuseIdx++;
     554            6 :     }
     555            3 :     return HCCL_SUCCESS;
     556              : }
     557              : 
     558            3 : HcclResult MyRank::BatchCreateSockets(const HcclChannelDesc* channelDescs, uint32_t channelNum,
     559              :         const std::string &socketTag, std::vector<HcommChannelDesc> &hcommDescs)
     560              : {
     561            3 :     CHK_PTR_NULL(channelDescs);
     562            3 :     CHK_PRT_RET(channelNum == 0,
     563              :         HCCL_ERROR("[%s] invalid param: channelNum is zero", __func__), HCCL_E_PARA);
     564              : 
     565            3 :     ReuseSocketIdxMap reuseSocketIdxMap{};
     566              :     // socket服务器首先监听
     567            3 :     CHK_RET(BatchServerInitForChannels(channelDescs, channelNum, socketTag, reuseSocketIdxMap));
     568              :     // socket添加白名单以及进行连接,获取最后的socket
     569            3 :     CHK_RET(BatchGetSocketsForChannels(channelDescs, channelNum, socketTag, hcommDescs, reuseSocketIdxMap));
     570            3 :     return HCCL_SUCCESS;
     571            3 : }
     572              : 
     573              : constexpr uint32_t MEM_HANDLE_NUM_MAX = 256;  // memHandleNum的默认限制最大为256
     574              : constexpr uint32_t NOTIFY_NUM_MAX = 64; // notifynum 的默认限制最大为64
     575              : 
     576            2 : HcclResult MyRank::CheckChannelParam(CommEngine engine, const HcclChannelDesc* channelDesc,
     577              :     uint32_t channelNum) const
     578              : {
     579            3 :     for (u32 index = 0; index < channelNum; ++index) {
     580            2 :         if (engine == COMM_ENGINE_AIV) {
     581            0 :             CHK_PRT_RET(
     582              :                 (channelDesc->memHandleNum > MEM_HANDLE_NUM_MAX),
     583              :                 HCCL_ERROR("[%s]Channeldesc[%u] invalid memHandleNum, memHandleNum[%u], max channel num[%u]",
     584              :                 __func__, index, channelDesc->memHandleNum, MEM_HANDLE_NUM_MAX), HCCL_E_PARA
     585              :             );
     586            0 :             CHK_PRT_RET(
     587              :                 (channelDesc->memHandleNum != 0 && channelDesc->memHandles == nullptr),
     588              :                 HCCL_ERROR("[%s]Channeldesc[%u] invalid memHandles, memHandles is null",
     589              :                 __func__, index), HCCL_E_PARA
     590              :             );
     591              :         } else {
     592            2 :             if (channelDesc->memHandleNum != 0) {
     593            1 :                 HCCL_WARNING("[%s]Channeldesc[%u] memHandleNum[%u] is non-zero, memHandle exchange is not supported.",
     594              :                     __func__, index, channelDesc->memHandleNum);
     595              :             }
     596              :         }
     597            2 :         CHK_PRT_RET(channelDesc->notifyNum > NOTIFY_NUM_MAX,
     598              :             HCCL_ERROR("[%s]Channeldesc[%u] invalid notifyNum [%u], max notify num[%u]",
     599              :             __func__, index, channelDesc->notifyNum, NOTIFY_NUM_MAX), HCCL_E_PARA);
     600              :     }
     601              : 
     602            1 :     return HCCL_SUCCESS;
     603              : }
     604              : 
     605              : // 批量创建channels,如果CCU资源不足(如Xn, Cke, channel ctx, jetty ctx, wqebb)会失败,返回HCCL_E_UNAVAIL
     606            6 : HcclResult MyRank::BatchCreateChannels(CommEngine engine, const HcclChannelDesc* channelDescs, uint32_t channelNum,
     607              :         std::vector<HcommChannelDesc> &hcommDescs, ChannelHandle *channelHandles)
     608              : {
     609            6 :     CHK_PTR_NULL(channelDescs);
     610            6 :     CHK_PTR_NULL(channelHandles);
     611            6 :     CHK_PRT_RET(channelNum == 0,
     612              :         HCCL_ERROR("[%s] invalid param: channelNum is zero", __func__), HCCL_E_PARA);
     613              : 
     614            6 :     uint32_t localRank = rankId_;
     615            6 :     std::vector<HcclMem> memVec;
     616            6 :     CHK_SMART_PTR_NULL(commMems_);
     617            6 :     CHK_RET(commMems_->GetMemoryHandles(memVec));
     618              :     std::unordered_map<RankPair*, std::unordered_map<CommEngine,
     619            6 :         std::unordered_map<hcomm::EndpointPair*, u32>>> reuseChannelIdxMap{};
     620              :     
     621              :     // 记录本轮新申请的channel
     622            6 :     newChannels_.clear();
     623            6 :     bool isAllSuccess = true;
     624              : 
     625           22 :     for (uint32_t i = 0; i < channelNum; ++i) {
     626           18 :         const EndpointDesc &localEndpointDesc = channelDescs[i].localEndpoint;
     627           18 :         const EndpointDesc &remoteEndpointDesc = channelDescs[i].remoteEndpoint;
     628           18 :         uint32_t remoteRank = channelDescs[i].remoteRank;
     629              : 
     630           18 :         HCCL_INFO("[%s][%u/%u] remoteRank[%u] localProtocol[%d] remoteProtocol[%d] engine[%s]",
     631              :             __func__, i + 1, channelNum, remoteRank, localEndpointDesc.protocol, remoteEndpointDesc.protocol, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str()
     632              :         );
     633              : 
     634           18 :         EndpointHandle epHandle = nullptr;
     635           18 :         CHK_PTR_NULL(endpointMgr_);
     636           18 :         auto ret = endpointMgr_->Get(localEndpointDesc, epHandle);
     637           18 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     638              :             HCCL_ERROR("[%s] failed to get endpoint, channelIndex[%u], remoteRank[%u], protocol[%d]",
     639              :                 __func__, i, remoteRank, localEndpointDesc.protocol),
     640              :             ret);
     641           18 :         CHK_PTR_NULL(epHandle);
     642              : 
     643              :         // 启动监听
     644           18 :         uint32_t listenPort = 0;
     645           18 :         CHK_RET(GetDevicePortInternal(localRank, &listenPort, localEndpointDesc.loc.locType));
     646           18 :         CHK_RET(static_cast<HcclResult>(HcommEndpointStartListen(epHandle, listenPort, nullptr)));
     647              : 
     648           18 :         HCCL_INFO("[%s][%u/%u] remoteRank[%u] epHandle[%p] protocol[%d]",
     649              :             __func__, i + 1, channelNum, remoteRank,
     650              :             epHandle, localEndpointDesc.protocol);
     651              : 
     652              :         // 注册内存
     653           18 :         std::vector<MemHandle> memHandleVec;
     654           18 :         std::vector<std::string> memTag;
     655           18 :         memVec.clear();
     656           18 :         CHK_RET(commMems_->GetTagMemoryHandles(channelDescs[i].memHandles, channelDescs[i].memHandleNum, memVec, memTag));
     657           18 :         HCCL_INFO("[%s][%u/%u] remoteRank[%u] got %zu user memory handles",
     658              :             __func__, i + 1, channelNum, remoteRank, memVec.size());
     659           18 :         ret = endpointMgr_->RegisterMemory(epHandle, memTag, memVec, memHandleVec);
     660           18 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     661              :             HCCL_ERROR("[%s] failed to register memory, channelIndex[%u], remoteRank[%u], memTagNum[%zu]",
     662              :                 __func__, i, remoteRank, memTag.size()),
     663              :             ret);
     664              : 
     665           18 :         hcommDescs[i].exchangeAllMems = false;
     666           18 :         hcommDescs[i].memHandles = memHandleVec.data();
     667           18 :         hcommDescs[i].memHandleNum = memHandleVec.size();
     668              : 
     669           18 :         hcomm::EndpointPair* endpointPair = nullptr;
     670           18 :         RankIdPair rankIdPair = std::make_pair(localRank, remoteRank);
     671           18 :         EndpointDescPair endpointDescPair = std::make_pair(localEndpointDesc, remoteEndpointDesc);
     672           18 :         RankPair* rankPair = nullptr;
     673           18 :         CHK_RET(rankPairMgr_->Get(rankIdPair, rankPair));
     674           18 :         CHK_PTR_NULL(rankPair);
     675           18 :         CHK_RET(rankPair->GetEndpointPair(endpointDescPair, endpointPair));
     676           18 :         CHK_PTR_NULL(endpointPair);
     677              : 
     678           18 :         if (reuseChannelIdxMap.find(rankPair) == reuseChannelIdxMap.end()) {
     679           10 :             std::unordered_map<CommEngine, std::unordered_map<hcomm::EndpointPair*, u32>> engine2EndpointPairMap{};
     680           10 :             std::unordered_map<hcomm::EndpointPair*, u32> endpointPair2Idx{};
     681           10 :             endpointPair2Idx.emplace(endpointPair, 0);
     682           10 :             engine2EndpointPairMap.emplace(engine, endpointPair2Idx);
     683           10 :             reuseChannelIdxMap.emplace(rankPair, engine2EndpointPairMap);
     684           18 :         } else if (reuseChannelIdxMap[rankPair].find(engine) == reuseChannelIdxMap[rankPair].end()) {
     685            0 :             std::unordered_map<hcomm::EndpointPair*, u32> endpointPair2Idx{};
     686            0 :             endpointPair2Idx.emplace(endpointPair, 0);
     687            0 :             reuseChannelIdxMap[rankPair].emplace(engine, endpointPair2Idx);
     688            8 :         } else if (reuseChannelIdxMap[rankPair][engine].find(endpointPair) == reuseChannelIdxMap[rankPair][engine].end()) {
     689            0 :             reuseChannelIdxMap[rankPair][engine].emplace(endpointPair, 0);
     690              :         }
     691              : 
     692           18 :         u32& reuseIdx = reuseChannelIdxMap[rankPair][engine][endpointPair];
     693           18 :         u32 idx = reuseIdx;
     694              :         /* hostNIC -- DeviceNic(transport不复用link/Channel),此流程也是新创建channel,需要计入isNewChannel */
     695           18 :         if (localEndpointDesc.loc.locType != remoteEndpointDesc.loc.locType) {
     696            0 :             idx = UNREUSE_CHANNEL_IDX;
     697              :         }
     698           18 :         bool isNewChannel = (endpointPair->IsChannelNotExist(engine, reuseIdx) || (idx == UNREUSE_CHANNEL_IDX));
     699              : 
     700              :         // CreateChannel 返回 HCCL_E_UNAVAIL 表示资源不足创建失败
     701           18 :         ret = endpointPair->CreateChannel(epHandle, engine, idx, &hcommDescs[i], channelHandles + i);
     702           18 :         if (ret == HCCL_E_TIMEOUT || ret == HCCL_E_INTERNAL) {
     703            0 :             Hccl::TlsStatus tlsStatus = Hccl::TlsStatus::UNKNOWN;
     704            0 :             CHK_PRT_CONT(GetLocalTlsStatus(tlsStatus) != HCCL_SUCCESS,
     705              :                 HCCL_WARNING("[GetLocalTlsStatus] Can not get TlsStatus"));
     706              :         }
     707           18 :         if (ret == HCCL_E_UNAVAIL) {
     708              :             // 申请channel因资源不足失败,清理已申请的channel
     709            2 :             HCCL_RUN_WARNING("[%s] create channel failed, channelIndex[%u], remoteRank[%u], engine[%s], reuseIdx[%u], need clean new channels",
     710              :                 __func__, i + 1, remoteRank, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), reuseIdx);
     711            2 :             isAllSuccess = false;
     712            2 :             break;
     713              :         }
     714              :         // 记录新申请的channel信息,用于清理临时资源
     715           16 :         if (isNewChannel) {
     716           10 :             newChannels_.emplace_back(std::make_pair(i, reuseIdx));
     717              :         }
     718              : 
     719           16 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     720              :             HCCL_ERROR("[%s] failed to create channel, channelIndex[%u], remoteRank[%u], engine[%s], reuseIndex[%u]",
     721              :                 __func__, i + 1, remoteRank, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), reuseIdx),
     722              :             ret);
     723           16 :         if (idx != UNREUSE_CHANNEL_IDX) {
     724           16 :             reuseIdx++;
     725              :         }
     726              : 
     727           16 :         HCCL_INFO("[%s][%u/%u] channel created successfully, remoteRank[%u], channelHandle[%p]",
     728              :             __func__, i + 1, channelNum, remoteRank, channelHandles[i]);
     729           20 :     }
     730              : 
     731              :     // 如果申请失败,清理endpoint pair中记录的channel handle
     732            6 :     if (!isAllSuccess) {
     733            2 :         HCCL_RUN_WARNING("[%s] create channel failed, destroy new channels num[%zu], engine[%s]", __func__, newChannels_.size(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     734            2 :         CHK_RET(DestroyNewChannels(engine, channelDescs));
     735            2 :         return HCCL_E_UNAVAIL;
     736              :     }
     737              : 
     738            4 :     return HCCL_SUCCESS;
     739            6 : }
     740              : 
     741            2 : HcclResult MyRank::DestroyNewChannels(CommEngine engine, const HcclChannelDesc* channelDescs)
     742              : {
     743            2 :     uint32_t localRank = rankId_;
     744           14 :     for (auto idxPairIter = std::rbegin(newChannels_); idxPairIter != std::rend(newChannels_); ++idxPairIter) { // 由于新申请的在申请过的后面,所以要从后往前找reuseIdx销毁
     745            4 :         auto idxPair = *idxPairIter;
     746            4 :         const EndpointDesc &localEndpointDesc = channelDescs[idxPair.first].localEndpoint;
     747            4 :         const EndpointDesc &remoteEndpointDesc = channelDescs[idxPair.first].remoteEndpoint;
     748            4 :         uint32_t remoteRank = channelDescs[idxPair.first].remoteRank;
     749            4 :         hcomm::EndpointPair* endpointPair = nullptr;
     750            4 :         RankIdPair rankIdPair = std::make_pair(localRank, remoteRank);
     751            4 :         EndpointDescPair endpointDescPair = std::make_pair(localEndpointDesc, remoteEndpointDesc);
     752            4 :         RankPair* rankPair = nullptr;
     753            4 :         CHK_RET(rankPairMgr_->Get(rankIdPair, rankPair));
     754            4 :         CHK_PTR_NULL(rankPair);
     755            4 :         CHK_RET(rankPair->GetEndpointPair(endpointDescPair, endpointPair));
     756            4 :         CHK_PTR_NULL(endpointPair);
     757            4 :         CHK_RET(endpointPair->DestroyChannel(engine, idxPair.second));
     758              :     }
     759            2 :     newChannels_.clear();
     760            2 :     return HCCL_SUCCESS;
     761              : }
     762              : 
     763            2 : HcclResult MyRank::BatchConnectChannels(const HcclChannelDesc* channelDescs, ChannelHandle *channelHandles, uint32_t channelNum)
     764              : {
     765            2 :     auto timeout = std::chrono::seconds(Hccl::EnvConfig::GetInstance().GetSocketConfig().GetLinkTimeOut());
     766            2 :     auto startTime = std::chrono::steady_clock::now();
     767              : 
     768            2 :     HCCL_INFO("[%s] start connecting channels, channelNum[%u], timeout[%lld]sec",
     769              :         __func__, channelNum, timeout.count());
     770              : 
     771            2 :     std::vector<int32_t> statusVec(channelNum, 0);
     772            2 :     int32_t* statusList = statusVec.data();
     773            2 :     uint32_t retryCount = 0;
     774              :     while (true) {
     775      1485356 :         HcclResult ret =  hcomm::ChannelProcess::ChannelGetStatus(channelHandles, channelNum, statusList);
     776              : 
     777              :         // 卫语句:先处理异常情况
     778              : 
     779              :         // 1. 检查超时
     780      1485356 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     781            2 :             auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
     782            4 :                 std::chrono::steady_clock::now() - startTime).count();
     783            2 :             HCCL_ERROR("[%s] channel connect timeout after %lld sec, channelNum[%u], elapsed[%lld]ms, retryCount[%u]",
     784              :                 __func__, timeout.count(), channelNum, elapsed, retryCount);
     785           14 :             RPT_INPUT_ERR(true, "EI0006", std::vector<std::string>({"reason"}), \
     786              :                 std::vector<std::string>({GET_SOCKET_TIMEOUT_REASON_CLOSE_DETECT}));
     787            2 :             Hccl::TlsStatus tlsStatus = Hccl::TlsStatus::UNKNOWN;
     788            2 :             CHK_PRT_CONT(GetLocalTlsStatus(tlsStatus) != HCCL_SUCCESS,
     789              :                 HCCL_WARNING("[GetLocalTlsStatus] Can not get TlsStatus"));
     790            2 :             logger::ChannelLogger::PrintChannelErrorDetails(
     791              :                 rankId_, channelNum, channelDescs, channelHandles, statusList, static_cast<uint64_t>(elapsed), tlsStatus);
     792            2 :             return HCCL_E_TIMEOUT;
     793              :         }
     794              : 
     795              :         // 2. 处理重试(去除频繁的重试日志,一秒可能重试上千次)
     796      1485354 :         if (ret == HCCL_E_AGAIN) {
     797      1485354 :             retryCount++;
     798      1485354 :             continue;
     799              :         }
     800              : 
     801              :         // 3. 处理失败
     802            0 :         if (ret != HCCL_SUCCESS) {
     803            0 :             auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
     804            0 :                 std::chrono::steady_clock::now() - startTime).count();
     805            0 :             HCCL_ERROR("[%s] channel connect failed, channelNum[%u], ret[%d], elapsed[%lld]ms, retryCount[%u]",
     806              :                 __func__, channelNum, ret, elapsed, retryCount);
     807            0 :             Hccl::TlsStatus tlsStatus = Hccl::TlsStatus::UNKNOWN;
     808            0 :             CHK_PRT_CONT(GetLocalTlsStatus(tlsStatus) != HCCL_SUCCESS,
     809              :                 HCCL_WARNING("[GetLocalTlsStatus] Can not get TlsStatus"));
     810            0 :             logger::ChannelLogger::PrintChannelErrorDetails(
     811              :                 rankId_, channelNum, channelDescs, channelHandles, statusList, static_cast<uint64_t>(elapsed), tlsStatus);
     812            0 :             return ret;
     813              :         }
     814              : 
     815              :         // 4. 正常情况:所有通道连接成功
     816            0 :         auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
     817            0 :             std::chrono::steady_clock::now() - startTime).count();
     818            0 :         HCCL_INFO("[%s] all channels connected successfully, channelNum[%u], elapsed[%lld]ms, retryCount[%u]",
     819              :             __func__, channelNum, elapsed, retryCount);
     820            0 :         break;
     821      1485354 :     }
     822            0 :     return HCCL_SUCCESS;
     823            4 : }
     824              : 
     825            7 : HcclResult MyRank::ConfigSqDepthByExpansionMode(CommEngine engine, HcommChannelDesc& hcommDesc) const
     826              : {
     827            7 :     constexpr u32 CCU_MS_MODE_DEPTH = 128;
     828            7 :     constexpr u32 CCU_SCHED_MODE_DEPTH = 16;
     829            7 :     if (engine == COMM_ENGINE_CCU) {
     830            5 :         if (opExpansionMode_ == CCU_MS_MODE) {
     831            2 :             hcommDesc.ubAttr.sqDepth = CCU_MS_MODE_DEPTH;
     832            3 :         } else if (opExpansionMode_ == CCU_SCHED_MODE) {
     833            2 :             hcommDesc.ubAttr.sqDepth = CCU_SCHED_MODE_DEPTH;
     834              :         } else {
     835            1 :             HCCL_ERROR("[%s] unexpected op expansion mode[%u] for ccu,", __func__, opExpansionMode_);
     836            1 :             return HCCL_E_INTERNAL;
     837              :         }
     838              :     }
     839            6 :     return HCCL_SUCCESS;
     840              : }
     841              : 
     842            5 : HcclResult MyRank::CreateChannels(CommEngine engine, const std::string &commTag,
     843              :         const HcclChannelDesc* channelDescs, uint32_t channelNum, ChannelHandle *channelHandles)
     844              : {
     845            5 :     CHK_PTR_NULL(channelDescs);
     846            4 :     CHK_PTR_NULL(channelHandles);
     847            3 :     CHK_PRT_RET(channelNum == 0, HCCL_ERROR("[%s] invalid param: channelNum is zero", __func__), HCCL_E_PARA);
     848              : 
     849            2 :     HCCL_INFO("[CreateChannels][Enter] engine[%s] commTag[%s] channelNum[%u] rankId[%u]", GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), commTag.c_str(), channelNum, rankId_);
     850              : 
     851              :     // 参数检查
     852            2 :     CHK_RET(CheckChannelParam(engine, channelDescs, channelNum));
     853              : 
     854            1 :     std::vector<ChannelHandle> hostChannelHandles(channelNum);
     855            1 :     ChannelHandle *hostChannelHandleList = hostChannelHandles.data();
     856              : 
     857            1 :     auto& rdmaConfig = Hccl::EnvConfig::GetInstance().GetRdmaConfig();
     858            1 :     std::vector<HcommChannelDesc> hcommDescs(channelNum);
     859            2 :     for (u32 i = 0; i < channelNum; ++i) {
     860            1 :         hcommDescs[i] = MyRankUtils::ChannelDescHccl2Hcomm(channelDescs[i], config_);
     861            1 :         hcommDescs[i].roceAttr.qpThreshold = rdmaConfig.GetRdmaMultiQpThreshold();
     862            1 :         CHK_RET(ConfigSqDepthByExpansionMode(engine, hcommDescs[i]));
     863              :     }
     864              : 
     865            1 :     auto start = std::chrono::steady_clock::now();
     866            1 :     std::string socketTag = commTag + "_engine_" + std::to_string(engine);
     867            1 :     CHK_RET(BatchCreateSockets(channelDescs, channelNum, socketTag, hcommDescs));
     868            1 :     CHK_RET_UNAVAIL(BatchCreateChannels(engine, channelDescs, channelNum, hcommDescs, hostChannelHandleList));
     869              : 
     870            1 :     if (!newChannels_.empty()) {
     871            0 :         CHK_RET(BatchConnectChannels(channelDescs, hostChannelHandleList, channelNum));
     872            0 :         auto end = std::chrono::steady_clock::now();
     873            0 :         auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
     874            0 :         HCCL_RUN_INFO("[MyRank][CreateChannels] CreateChannels Time Elapsed [%lld]us, channelNum [%u]", duration, channelNum);
     875              :     }
     876              : 
     877              :     // 借用hcommDescs.socket,完成一致性校验必要的数据交换
     878              :     DevType devType;
     879            1 :     CHK_RET(hrtGetDeviceType(devType));
     880            1 :     if (devType == DevType::DEV_TYPE_950) {
     881            1 :         auto startConsistency = std::chrono::steady_clock::now();
     882            1 :         CHK_RET(exchangeInfoMgr_.BatchExchangeAndCheckConsistency(
     883              :             channelDescs, hcommDescs, channelNum, newChannels_, collCommConfigConsistency_, engine));
     884            0 :         auto endConsistency = std::chrono::steady_clock::now();
     885            0 :         auto durationConsistency = std::chrono::duration_cast<std::chrono::microseconds>(endConsistency - startConsistency).count();
     886            0 :         HCCL_INFO("[MyRank][CreateChannels] BatchExchangeAndCheckConsistency Time Elapsed [%lld]us, channelNum [%u]",
     887              :             durationConsistency, channelNum);
     888              :     }
     889              : 
     890              :     // 添加初始化时进行填表
     891            0 :     for (u32 i = 0; i < channelNum; ++i) {
     892            0 :         u32 remoteRank = channelDescs[i].remoteRank;
     893            0 :         HcclCommDfx::AddChannelRemoteRankId(commTag, hostChannelHandleList[i], remoteRank);
     894              :         // 打印UB通道建链信息
     895            0 :         if (channelDescs[i].localEndpoint.loc.locType == ENDPOINT_LOC_TYPE_DEVICE &&
     896            0 :             channelDescs[i].remoteEndpoint.loc.locType == ENDPOINT_LOC_TYPE_DEVICE) {
     897            0 :             HCCL_CONFIG_DEBUG(HCCL_RES, "create channel info:channel handle[%s] comm tag[%s] protocol[%s]"
     898              :                 " local rank[%u] local dev phyid[%u] remote rank[%u] remote dev phyid[%u] engine[%s]",
     899              :                 std::to_string(reinterpret_cast<uint64_t>(hostChannelHandleList[i])).c_str(), commTag.c_str(),
     900              :                 MyRankUtils::GetCommProtocolEnumStr(channelDescs[i].localEndpoint.protocol).c_str(), rankId_,
     901              :                 channelDescs[i].localEndpoint.loc.device.devPhyId, remoteRank,
     902              :                 channelDescs[i].remoteEndpoint.loc.device.devPhyId, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     903            0 :         } else {
     904            0 :             HCCL_CONFIG_DEBUG(HCCL_RES, "create channel info:channel handle[%s] comm tag[%s] protocol[%s]"
     905              :                 " local rank[%u] remote rank[%u] engine[%s]",
     906              :                 std::to_string(reinterpret_cast<uint64_t>(hostChannelHandleList[i])).c_str(), commTag.c_str(),
     907              :                 MyRankUtils::GetCommProtocolEnumStr(channelDescs[i].localEndpoint.protocol).c_str(), rankId_,
     908              :                 remoteRank, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     909              :         }
     910              :     }
     911              : 
     912            0 :     if (engine == COMM_ENGINE_AICPU || engine == COMM_ENGINE_AICPU_TS) {
     913              :         // 新增:添加 kernelLaunchAicpuCommInit 调用
     914            0 :         if (!callbacks_.getAicpuCommState()) {
     915            0 :             HCCL_INFO("MyRank::%s kernelLaunchAicpuCommInit start.", __func__);
     916            0 :             HcclResult ret = callbacks_.kernelLaunchAicpuCommInit();
     917            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[%s] kernelLaunchAicpuCommInit failed, return [%d].", __func__, ret), ret);
     918            0 :             callbacks_.setAicpuCommState(true);
     919              :         }
     920            0 :         HcommChannelDesc *hcommDesc = hcommDescs.data();
     921            0 :         CHK_RET(ChannelProcess::ChannelKernelLaunchForComm(
     922              :             channelHandles, hostChannelHandleList, hcommDesc, channelNum, commTag, binHandle_));
     923              : 
     924              :         // ns recovery
     925            0 :         nsRecoveryProcessor_->AddNsRecoveryData(engine, channelHandles, hostChannelHandleList, channelNum, commTag);
     926              : 
     927            0 :         return HCCL_SUCCESS;
     928              :     }
     929              : 
     930            0 :     if (engine == COMM_ENGINE_CPU || engine == COMM_ENGINE_CCU || engine == COMM_ENGINE_AIV) {
     931              :         // TODO: Host侧 Channel 赋值到 channelHandles
     932            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(channelHandles, channelNum * sizeof(ChannelHandle), hostChannelHandleList,
     933              :             channelNum * sizeof(ChannelHandle)));
     934            0 :         return HCCL_SUCCESS;
     935              :     }
     936              : 
     937            0 :     HCCL_ERROR("[MyRank][%s] unsupported comm engine[%s].", __func__, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     938            0 :     return HCCL_E_NOT_SUPPORT;
     939            1 : }
     940              : 
     941            1 : HcclResult MyRank::ChannelGetHcclBuffer(ChannelHandle channel, void **buffer, uint64_t *size)
     942              : {
     943            1 :     CHK_PTR_NULL(buffer);
     944            1 :     CHK_PTR_NULL(size);
     945              : 
     946            1 :     u32 memNum = 0;
     947            1 :     CommMem* remoteMem = nullptr;
     948            1 :     char** memTags = nullptr;
     949            1 :     CHK_RET(static_cast<HcclResult>(HcommChannelGetRemoteMems(channel, &memNum, &remoteMem, &memTags)));
     950            1 :     if (memNum > 0) {
     951            0 :         CHK_PTR_NULL(remoteMem);
     952              :         // AicpuTsHccsChannel不使用memTag,返回为空,默认索引0为cclBuffer
     953            0 :         if (memTags == nullptr) {
     954            0 :             *buffer = remoteMem[0].addr;
     955            0 :             *size = remoteMem[0].size;
     956            0 :             HCCL_INFO("[%s] Found HcclBuffer : addr=%p, size=%llu", __func__, *buffer, *size);
     957            0 :             return HCCL_SUCCESS;
     958              :         }
     959            0 :         for (u32 i = 0; i < memNum; ++i) {
     960            0 :             std::string tag = memTags[i];
     961            0 :             if (tag == "HcclBuffer") {
     962            0 :                 *buffer = remoteMem[i].addr;
     963            0 :                 *size = remoteMem[i].size;
     964            0 :                 HCCL_INFO("[%s] Found HcclBuffer : addr=%p, size=%llu", __func__, *buffer, *size);
     965            0 :                 return HCCL_SUCCESS;
     966              :             }
     967            0 :             HCCL_INFO("[%s] Found %s : addr=%p, size=%llu", __func__, memTags[i],
     968              :                 remoteMem[i].addr, remoteMem[i].size);
     969            0 :         }
     970              :     }
     971            1 :     HCCL_ERROR("[%s] HcclBuffer not found.", __func__);
     972            1 :     return HCCL_E_INTERNAL;
     973              : }
     974              : 
     975            4 : HcclResult MyRank::ChannelGetRemoteMems(ChannelHandle channel, uint32_t *memNum, CommMem **remoteMem, char ***memTags) const
     976              : {
     977            4 :     CHK_PTR_NULL(remoteMem);
     978            3 :     CHK_PTR_NULL(memTags);
     979            2 :     CHK_PTR_NULL(memNum);
     980            1 :     CHK_RET(static_cast<HcclResult>(HcommChannelGetRemoteMems(channel, memNum, remoteMem, memTags)));
     981              :     // 添加空指针检查,防止返回的指针为空
     982            1 :     if (*memNum > 0) {
     983            0 :         CHK_PTR_NULL(*remoteMem);
     984            0 :         CHK_PTR_NULL(*memTags);
     985              :     }
     986            1 :     HCCL_INFO("[%s] success. memNum[%u]", __func__, *memNum);
     987            1 :     return HCCL_SUCCESS;
     988              : }
     989              : 
     990            4 : HcclResult MyRank::ChannelGetRemoteMems(ChannelHandle channel, uint32_t *memNum, CommMem **remoteMem,
     991              :     std::vector<std::string> &memTags) const
     992              : {
     993            4 :     CHK_PTR_NULL(remoteMem);
     994            3 :     CHK_PTR_NULL(memNum);
     995            2 :     char **rawTags = nullptr;
     996            2 :     CHK_RET(static_cast<HcclResult>(HcommChannelGetRemoteMems(channel, memNum, remoteMem, &rawTags)));
     997              :     // 添加空指针检查,防止返回的指针为空
     998            2 :     if (*memNum > 0) {
     999            1 :         CHK_PTR_NULL(*remoteMem);
    1000            1 :         CHK_PTR_NULL(rawTags);
    1001            1 :         memTags.reserve(*memNum);
    1002            3 :         for (uint32_t i = 0; i < *memNum; ++i) {
    1003            2 :             memTags.emplace_back(rawTags[i] == nullptr ? "" : rawTags[i]);
    1004              :         }
    1005              :     }
    1006            2 :     HCCL_INFO("[%s] success. memNum[%u]", __func__, *memNum);
    1007            2 :     return HCCL_SUCCESS;
    1008              : }
    1009              : 
    1010            0 : std::vector<ChannelHandle> MyRank::GetAllChannelList()
    1011              : {
    1012            0 :     ChannelTable channelTable = rankPairMgr_->GetChannelTable();
    1013            0 :     std::vector<ChannelHandle> channelList;
    1014            0 :     for (const auto& rankPair : channelTable) {
    1015            0 :         for (const auto& endPointPair : rankPair.second) {
    1016            0 :             for (const auto& comEngines : endPointPair.second) {
    1017            0 :                 channelList.insert(channelList.end(), comEngines.second.begin(), comEngines.second.end());
    1018              :             }
    1019              :         }
    1020              :     }
    1021              : 
    1022            0 :     return channelList;
    1023            0 : }
    1024              : 
    1025           98 : void MyRank::SetKfcControlTransfer(std::shared_ptr<HDCommunicate> kfcControlTransferH2D, 
    1026              :         std::shared_ptr<HDCommunicate> kfcStatusTransferD2H)
    1027              : {
    1028           98 :     if (nsRecoveryProcessor_ == nullptr) {
    1029            1 :         HCCL_ERROR("[MyRank][SetKfcControlTransfer] nsRecoveryProcessor_ is null, cannot set KFC control transfer.");
    1030            1 :         return;
    1031              :     }
    1032           97 :     nsRecoveryProcessor_->SetKfcControlTransfer(kfcControlTransferH2D, kfcStatusTransferD2H);
    1033              : }
    1034              : 
    1035            0 : HcclResult MyRank::StopLaunch()
    1036              : {
    1037            0 :     HCCL_INFO("[NsRecovery][StopLaunch] MyRank::StopLaunch start!");
    1038            0 :     auto ret = nsRecoveryProcessor_->StopLaunch();
    1039            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1040            0 :         HCCL_ERROR("[NsRecovery][StopLaunch] MyRank::StopLaunch failed, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
    1041              :     }
    1042            0 :     HCCL_INFO("[NsRecovery][StopLaunch] MyRank::StopLaunch success!");
    1043            0 :     return ret;
    1044              : }
    1045              : 
    1046            0 : HcclResult MyRank::Clean()
    1047              : {
    1048            0 :     HCCL_INFO("[NsRecovery][Clean] MyRank::Clean start!");
    1049            0 :     auto channelList = GetAllChannelList();
    1050            0 :     if (channelList.empty()) {
    1051            0 :         HCCL_INFO("[NsRecovery][Clean] Channel list empty, No need to clean!");
    1052            0 :         return HcclResult::HCCL_SUCCESS;
    1053              :     }
    1054            0 :     auto ret = ChannelProcess::ChannelClean(channelList.data(), channelList.size());
    1055            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1056            0 :         HCCL_ERROR("[NsRecovery][Clean] MyRank::Clean failed, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
    1057            0 :         return ret;
    1058              :     }
    1059              : 
    1060            0 :     ret = nsRecoveryProcessor_->Clean();
    1061            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1062            0 :         HCCL_ERROR("[NsRecovery][Clean] MyRank::Clean failed, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
    1063            0 :         return ret;
    1064              :     }
    1065              : 
    1066            0 :     HCCL_INFO("[NsRecovery][Clean] MyRank::Clean success!");
    1067            0 :     return HcclResult::HCCL_SUCCESS;
    1068            0 : }
    1069              : 
    1070            0 : HcclResult MyRank::Resume()
    1071              : {
    1072            0 :     HCCL_INFO("[NsRecovery][Resume] MyRank::Resume start!");
    1073            0 :     auto channelList = GetAllChannelList();
    1074            0 :     if (channelList.empty()) {
    1075            0 :         HCCL_INFO("[NsRecovery][Resume] Resume list empty, No need to resume!");
    1076            0 :         return HcclResult::HCCL_SUCCESS;
    1077              :     }
    1078              : 
    1079            0 :     auto ret = ChannelProcess::ChannelResume(channelList.data(), channelList.size());
    1080            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1081            0 :         HCCL_ERROR("[NsRecovery][Resume] MyRank::Resume failed, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
    1082            0 :         return ret;
    1083              :     }
    1084              : 
    1085            0 :     ret = nsRecoveryProcessor_->Resume(binHandle_);
    1086            0 :     if (ret != HcclResult::HCCL_SUCCESS) {
    1087            0 :         HCCL_ERROR("[NsRecovery][Resume] MyRank::Resume failed, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
    1088            0 :         return ret;
    1089              :     }
    1090              : 
    1091            0 :     HCCL_INFO("[NsRecovery][Resume] MyRank::Resume success!");
    1092            0 :     return HCCL_SUCCESS;
    1093            0 : }
    1094              : 
    1095            7 : CollCommConfigConsistency &MyRank::GetCollCommConfigConsistency()
    1096              : {
    1097            7 :     return collCommConfigConsistency_;
    1098              : }
    1099              : 
    1100              : } // namespace hccl
        

Generated by: LCOV version 2.0-1