LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/remote_access - comm_remote_access.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 440 0
Test Date: 2026-07-28 12:11:00 Functions: 0.0 % 23 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 "comm_remote_access.h"
      12              : #include "externalinput_pub.h"
      13              : 
      14              : namespace hccl {
      15              : using namespace std;
      16              : 
      17            0 : CommRemoteAccess::CommRemoteAccess(u32 rank, u32 devicePhyId, const std::map<u32, std::vector<HcclIpAddress>>& rankInfo,
      18            0 :     const std::vector<MemRegisterAddr>& addrInfos)
      19            0 :     : remoteTransportMap_(), rank_(rank), deviceLogicId_(0), devicePhyId_(devicePhyId), rankSize_(0),
      20            0 :       nicDeployment_(NICDeployment::NIC_DEPLOYMENT_DEVICE), rankInfo_(rankInfo), addrInfos_(addrInfos),
      21            0 :       dstInterServerMap_(), dstInterClientMap_(), nicSocketHandle_(), tag_("RemoteAccess"), threadsApplyNum_(0),
      22            0 :       dispatcher_(nullptr), notifyPool_(nullptr)
      23              : {
      24            0 : }
      25              : 
      26            0 : CommRemoteAccess::~CommRemoteAccess()
      27              : {
      28              :     HcclResult ret;
      29            0 :     for (u32 index = 0; index < linkThreads_.size(); index++) {
      30            0 :         if (linkThreads_[index]) {
      31            0 :             if (linkThreads_[index]->joinable()) {
      32            0 :                 HCCL_DEBUG("Joining Link Thread[%u]", index);
      33            0 :                 linkThreads_[index]->join();  // 等待线程执行后释放资源
      34              :             }
      35            0 :             ret = hrtResetDevice(deviceLogicId_);  // 防止线程里面异常退出,在进程中reset
      36            0 :             if (ret != HCCL_SUCCESS) {
      37            0 :                 HCCL_ERROR("[Comm][RemoteAccess]CommRemoteAccess reset device[%d] failed", deviceLogicId_);
      38              :             }
      39              :         }
      40              :     }
      41            0 :     struct SocketCloseInfoT socketCloseInfo = {0};
      42            0 :     for (u32 i = 0; i < raSockets_.size(); i++) {
      43            0 :         socketCloseInfo.socketHandle = raSockets_[i].socketHandle; // 带入设备ID为物理ID
      44            0 :         socketCloseInfo.fdHandle = raSockets_[i].fdHandle;
      45            0 :         if ((raSockets_[i].socketHandle != nullptr) && (raSockets_[i].fdHandle != nullptr)) {
      46            0 :             ret = hrtRaSocketBatchClose(&socketCloseInfo, 1); /* 销毁已经创建的socket */
      47            0 :             if (ret != HCCL_SUCCESS) {
      48            0 :                 HCCL_WARNING("~CommRemoteAccess:socket batch close fail! ret=%d", ret);
      49              :             }
      50              :         }
      51              :     }
      52              : 
      53            0 :     ret = DeleteSocketWhiteList();
      54            0 :     if (ret != HCCL_SUCCESS) {
      55            0 :         HCCL_WARNING("~CommRemoteAccess:delete Socket whiteList fail! ret=%d", ret);
      56              :     }
      57            0 :     remoteTransportMap_.clear();
      58              : 
      59            0 :     ret = CommRemoteDeInitRa();
      60            0 :     if (ret != HCCL_SUCCESS) {
      61            0 :         HCCL_ERROR("[Comm][RemoteAccess]CommRemoteAccess CommRemoteDeInitRa fail! ret[%d]", ret);
      62              :     }
      63            0 :     ret = notifyPool_->UnregisterOp(tag_);
      64            0 :     if (ret != HCCL_SUCCESS) {
      65            0 :         HCCL_WARNING("~CommRemoteAccess:UnregisterOp fail! ret=%d", ret);
      66              :     }
      67              : 
      68            0 :     if (dispatcher_ != nullptr) {
      69            0 :         HcclDispatcherDestroy(dispatcher_);
      70            0 :         dispatcher_ = nullptr;
      71              :     }
      72            0 : }
      73              : 
      74            0 : HcclResult CommRemoteAccess::Init()
      75              : {
      76            0 :     HCCL_INFO("CommRemoteAccess Init start");
      77              :     // 获取当前线程操作的设备ID
      78            0 :     CHK_RET(hrtGetDevice(&deviceLogicId_));
      79              :     // dispatcher 资源初始化
      80            0 :     CHK_RET(RescoucePrepare());
      81              :     // 初始化ra资源,若hcom_init则不会进行再初始化
      82            0 :     CHK_RET(CommRemoteInitRa());
      83            0 :     CHK_RET(NetworkManager::GetInstance(deviceLogicId_).GetRaResourceInfo(raResourceInfo_));
      84              :     // 建链关系计算,只和统一平面和本端rank建单向链
      85            0 :     CHK_RET(CalcRemoteLink());
      86              :     // socket资源准备(白名单、batch connect
      87            0 :     CHK_RET(PrepareSocket());
      88              :     // 创建链接并保存fd_socket_handle
      89            0 :     CHK_RET(CreateLinks());
      90            0 :     HCCL_INFO("CommRemoteAccess Init end");
      91            0 :     return HCCL_SUCCESS;
      92              : }
      93              : 
      94            0 : HcclResult CommRemoteAccess::DeleteSocketWhiteList()
      95              : {
      96            0 :     if (wlistInfosVec_.size() > 0) {
      97            0 :         for (u32 idx = 0; idx < nicSocketHandle_.size(); idx++) {
      98            0 :             CHK_RET(hrtRaSocketWhiteListDel(nicSocketHandle_[idx], wlistInfosVec_.data(), wlistInfosVec_.size()));
      99              :         }
     100              :     }
     101            0 :     return HCCL_SUCCESS;
     102              : }
     103              : 
     104            0 : std::shared_ptr<TransportRemoteAccess> &CommRemoteAccess::GetTransportByRank(const u32 dstRank)
     105              : {
     106            0 :     if (remoteTransportMap_.find(dstRank) == remoteTransportMap_.end()) {
     107            0 :         HCCL_ERROR("[Get][TransportByRank]can not find dstRank[%u] in remoteTransportMap_,"
     108              :             "remoteTransportMap_ size is [%llu]",
     109              :                    dstRank, remoteTransportMap_.size());
     110            0 :         return transportDummy_;
     111              :     }
     112              : 
     113            0 :     return remoteTransportMap_.lower_bound(dstRank)->second;
     114              : }
     115              : 
     116            0 : HcclResult CommRemoteAccess::RescoucePrepare()
     117              : {
     118              :     // 根据设备ID创建dispatcher
     119            0 :     CHK_SMART_PTR_NULL(dispatcher_);
     120              : 
     121            0 :     notifyPool_.reset(new (std::nothrow) NotifyPool());
     122            0 :     CHK_SMART_PTR_NULL(notifyPool_);
     123            0 :     CHK_RET(notifyPool_->Init(devicePhyId_));
     124            0 :     CHK_RET(notifyPool_->RegisterOp(tag_));
     125            0 :     return HCCL_SUCCESS;
     126              : }
     127              : 
     128            0 : HcclResult CommRemoteAccess::CommRemoteInitRa()
     129              : {
     130            0 :     CHK_RET(NetworkManager::GetInstance(deviceLogicId_).Init(nicDeployment_));
     131              : 
     132            0 :     auto iter = rankInfo_.find(rank_);
     133            0 :     bool check = (iter == rankInfo_.end());
     134            0 :     CHK_PRT_RET(check, HCCL_ERROR("[Get][Instance]can not find rank[%u] info in rankInfo_", rank_), HCCL_E_PARA);
     135            0 :     HCCL_INFO("in CommRemoteInitRa, rank_[%u], iter->second.size[%d]", rank_, iter->second.size());
     136            0 :     for (size_t ipIdex = 0; ipIdex < iter->second.size(); ipIdex++) {
     137            0 :         if (iter->second[ipIdex].IsInvalid()) {
     138            0 :             continue;
     139              :         }
     140            0 :         u32 port = HETEROG_CCL_PORT;
     141            0 :         HcclResult ret = NetworkManager::GetInstance(deviceLogicId_).StartNic(iter->second[ipIdex], port, true);
     142            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     143              :             HCCL_ERROR("[InitRa][CommRemote]start nic ipaddr[%s] failed", iter->second[ipIdex].GetReadableAddress()),
     144              :             ret);
     145              :     }
     146            0 :     return HCCL_SUCCESS;
     147              : }
     148              : 
     149            0 : HcclResult CommRemoteAccess::CommRemoteDeInitRa()
     150              : {
     151            0 :     auto iter = rankInfo_.find(rank_);
     152            0 :     bool check = (iter == rankInfo_.end());
     153            0 :     CHK_PRT_RET(check, HCCL_ERROR("[DeInit][Ra]can not find rank[%u] info in rankInfo_", rank_), HCCL_E_PARA);
     154            0 :     HCCL_INFO("in CommRemoteDeInitRa, rank_[%u], iter->second.size[%zu]", rank_, iter->second.size());
     155            0 :     for (size_t ipIdex = 0; ipIdex < iter->second.size(); ipIdex++) {
     156            0 :         if (iter->second[ipIdex].IsInvalid()) {
     157            0 :             continue;
     158              :         }
     159            0 :         CHK_RET(NetworkManager::GetInstance(deviceLogicId_).StopNic(iter->second[ipIdex], 0));
     160              :     }
     161            0 :     CHK_RET(NetworkManager::GetInstance(deviceLogicId_).DeInit(nicDeployment_));
     162            0 :     return HCCL_SUCCESS;
     163              : }
     164              : 
     165            0 : HcclResult CommRemoteAccess::CalcRemoteLink()
     166              : {
     167            0 :     rankSize_ = rankInfo_.size();
     168            0 :     if ((rankSize_ == 0)) {
     169            0 :         HCCL_ERROR("[Calc][RemoteLink]invalid rankSize, rankSize:[%zu].", rankSize_);
     170            0 :         return HCCL_E_PARA;
     171              :     }
     172              : 
     173              :     // 计算同一平面的server端rank信息,小于或等于本rank的为server端(本rank既是server也是client)
     174            0 :     for (u32 serverRank = rank_;; serverRank--) {
     175            0 :         HCCL_INFO("CalcRemoteLink rank[%u] serverRank[%u]", rank_, serverRank);
     176            0 :         auto serverRankInfo = rankInfo_.find(serverRank);
     177            0 :         if (serverRankInfo == rankInfo_.end()) {
     178            0 :             HCCL_ERROR("[Calc][RemoteLink]can not find server rank[%u] in rankInfo_.", serverRank);
     179            0 :             return HCCL_E_PARA;
     180              :         }
     181            0 :         std::vector<HcclIpAddress> ipVec(rankInfo_[serverRank]);
     182            0 :         auto serverIter = dstInterServerMap_.find(serverRank);
     183            0 :         if (serverIter == dstInterServerMap_.end()) {
     184            0 :             dstInterServerMap_.insert({serverRank, ipVec});
     185              :         }
     186            0 :         if (serverRank == 0) {
     187            0 :             break;
     188              :         }
     189            0 :     }
     190              :     // 计算同一平面的client端rank信息,大于等于本rank的为client端(本rank既是server也是client)
     191            0 :     for (u32 clientRank = rank_; clientRank < rankSize_; clientRank++) {
     192            0 :         auto clientRankInfo = rankInfo_.find(clientRank);
     193            0 :         if (clientRankInfo == rankInfo_.end()) {
     194            0 :             HCCL_ERROR("[Calc][RemoteLink]can not find client rank[%u] in rankInfo_.", clientRank);
     195            0 :             return HCCL_E_PARA;
     196              :         }
     197            0 :         std::vector<HcclIpAddress> ipVec(rankInfo_[clientRank]);
     198            0 :         auto clientIter = dstInterClientMap_.find(clientRank);
     199            0 :         if (clientIter == dstInterClientMap_.end()) {
     200            0 :             dstInterClientMap_.insert({clientRank, ipVec});
     201              :         }
     202            0 :     }
     203            0 :     return HCCL_SUCCESS;
     204              : }
     205              : 
     206            0 : HcclResult CommRemoteAccess::PrepareSocket()
     207              : {
     208              :     // socket handle 是一一对应关系
     209            0 :     if (dstInterServerMap_.size() * raResourceInfo_.nicSocketMap.size() +
     210            0 :         dstInterClientMap_.size() * raResourceInfo_.nicSocketMap.size() > 0) {
     211            0 :         for (u32 idx = 0; idx < rankInfo_[rank_].size(); idx++) {
     212            0 :             if (rankInfo_[rank_][idx].IsInvalid()) {
     213            0 :                 HCCL_ERROR("[Prepare][Socket]rank_[%u] nicIp[%u] is 0", rank_, idx);
     214            0 :                 continue;
     215              :             }
     216            0 :             auto it = raResourceInfo_.nicSocketMap.find(rankInfo_[rank_][idx]);
     217            0 :             if (it == raResourceInfo_.nicSocketMap.end()) {
     218            0 :                 HCCL_ERROR("[Prepare][Socket]can not find nicSocketHandle, ip[%s]",
     219              :                     rankInfo_[rank_][idx].GetReadableAddress());
     220            0 :                 return HCCL_E_PARA;
     221              :             } else {
     222            0 :                 if (it->second.nicSocketHandle == nullptr) {
     223            0 :                     HCCL_ERROR("[Prepare][Socket]CommRemoteAccess prepare socket failed! rank[%u] IP addr[%s]", rank_,
     224              :                         rankInfo_[rank_][idx].GetReadableAddress());
     225            0 :                     return HCCL_E_PARA;
     226              :                 }
     227            0 :                 nicSocketHandle_.push_back(it->second.nicSocketHandle);
     228              :             }
     229            0 :             HCCL_INFO("rank[%u], nicSocketMap[%u] nicIp.size[%u]", rank_, raResourceInfo_.nicSocketMap.size(),
     230              :                 rankInfo_[rank_].size());
     231              :         }
     232              :     }
     233              : 
     234            0 :     HCCL_INFO("In PrepareSocket raResourceInfo_Size[%u]", nicSocketHandle_.size());
     235            0 :     CHK_RET(AddSocketWhiteList());
     236              : 
     237              :     // 当前rank作为client端batch connect动作
     238            0 :     u32 dstInterServerNum = dstInterServerMap_.size() * raResourceInfo_.nicSocketMap.size();
     239            0 :     HCCL_INFO("socket batch connect dstInterServerNum[%u]", dstInterServerNum);
     240            0 :     if (dstInterServerNum > 0) {
     241            0 :         std::vector<struct SocketConnectInfoT> conns(dstInterServerNum);
     242            0 :         struct SocketConnectInfoT *conn = conns.data();
     243            0 :         s32 sRet = memset_s(conn, sizeof(struct SocketConnectInfoT) * dstInterServerNum, 0,
     244            0 :                             sizeof(struct SocketConnectInfoT) * dstInterServerNum);
     245            0 :         CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Prepare][Socket]memory set failed, return[%d]. params:"
     246              :             "destMaxSize[%zu], c[%d], count[%zu]", sRet,
     247              :             sizeof(struct SocketConnectInfoT) * dstInterServerNum, 0,
     248              :             sizeof(struct SocketConnectInfoT) * dstInterServerNum), HCCL_E_MEMORY);
     249              : 
     250            0 :         u32 loop = 0;
     251            0 :         for (auto iter = dstInterServerMap_.begin(); iter != dstInterServerMap_.end(); iter++) {
     252            0 :             for (u32 idx = 0; idx < nicSocketHandle_.size() && idx < (iter->second).size(); idx++) {
     253            0 :                 conn[loop].remoteIp.addr = (iter->second)[idx].GetBinaryAddress().addr;
     254            0 :                 conn[loop].remoteIp.addr6 = (iter->second)[idx].GetBinaryAddress().addr6;
     255            0 :                 conn[loop].socketHandle = nicSocketHandle_[idx];
     256            0 :                 conn[loop].port = HETEROG_CCL_PORT;
     257            0 :                 if (nicSocketHandle_[idx] == nullptr) {
     258            0 :                     HCCL_ERROR("[Prepare][Socket]index[%u] nicSocketHandle_ is null", idx);
     259            0 :                     return HCCL_E_INTERNAL;
     260              :                 }
     261            0 :                 sRet = memcpy_s(&conn[loop].tag[0], sizeof(conn[loop].tag) - 1, tag_.c_str(), tag_.size());
     262            0 :                 CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Prepare][Socket]memcpy failed. errorno[%d]:"
     263              :                     "destMaxSize[%zu], count[%zu]", sRet, sizeof(conn[loop].tag),
     264              :                     tag_.size()), HCCL_E_MEMORY);
     265              :             }
     266            0 :             loop++;
     267              :         }
     268            0 :         HcclResult ret = hrtRaSocketBatchConnect(conn, dstInterServerNum);
     269            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     270              :             HCCL_ERROR("[Prepare][Socket]socket batch failed, batch size[%u], loop[%u], "\
     271              :             "dst_inter_server_map_size[%u], handle size[%u]",
     272              :             dstInterServerNum, loop, dstInterServerMap_.size(), nicSocketHandle_.size()), ret);
     273            0 :     }
     274              : 
     275            0 :     return HCCL_SUCCESS;
     276              : }
     277              : 
     278            0 : HcclResult CommRemoteAccess::AddSocketWhiteList()
     279              : {
     280              :     // 当前rank作为server端socket白名单下发动作
     281            0 :     struct SocketWlistInfoT wlistInfo = {0};
     282            0 :     for (auto iter = dstInterClientMap_.begin(); iter != dstInterClientMap_.end(); iter++) {
     283            0 :         wlistInfo.connLimit = NIC_SOCKET_CONN_LIMIT;
     284            0 :         s32 sRet = memcpy_s(&wlistInfo.tag[0], sizeof(wlistInfo.tag) - 1, tag_.c_str(), tag_.size());
     285            0 :         if (sRet != EOK) {
     286            0 :             HCCL_ERROR("[Add][Socket]memory copy failed. errorno[%d]: dest size[%zu], src[%s],"
     287              :                 "count[%zu]", sRet, sizeof(wlistInfo.tag), tag_.c_str(), tag_.size());
     288            0 :             wlistInfosVec_.clear();
     289            0 :             return HCCL_E_MEMORY;
     290              :         }
     291            0 :         for (u32 idx = 0; idx < (iter->second).size(); idx++) {
     292            0 :             wlistInfo.remoteIp.addr = iter->second[idx].GetBinaryAddress().addr;
     293            0 :             wlistInfo.remoteIp.addr6 = iter->second[idx].GetBinaryAddress().addr6;
     294            0 :             wlistInfosVec_.push_back(wlistInfo);
     295              :         }
     296              :     }
     297              : 
     298            0 :     if (wlistInfosVec_.size() > 0) {
     299            0 :         for (u32 idx = 0; idx < nicSocketHandle_.size(); idx++) {
     300            0 :             CHK_RET(hrtRaSocketWhiteListAdd(nicSocketHandle_[idx], wlistInfosVec_.data(), wlistInfosVec_.size()));
     301              :         }
     302              :     }
     303              : 
     304            0 :     return HCCL_SUCCESS;
     305              : }
     306              : 
     307            0 : HcclResult CommRemoteAccess::CreateLinks()
     308              : {
     309              :     // 计算建链所需线程
     310            0 :     u32 nicNum = raResourceInfo_.nicSocketMap.size();
     311            0 :     u32 threadsNum = dstInterClientMap_.size() * nicNum + dstInterServerMap_.size() * nicNum;
     312            0 :     HCCL_INFO("threadsNum[%u]", threadsNum);
     313            0 :     HCCL_INFO("CommRemoteAccess CreateLinks rank_[%u] dstInterClientMapSize[%u], nicNum[%u], dstInterServerMapSize[%u]",
     314              :         rank_, dstInterClientMap_.size(), nicNum, dstInterServerMap_.size());
     315            0 :     CHK_PRT_RET((threadsNum == 0), HCCL_ERROR("[Create][Links]no link to create, please check ranktable to see if"
     316              :         "device_ip is configured. nicNum[%u]", nicNum), HCCL_E_INTERNAL);
     317            0 :     linkThreads_.resize(threadsNum);
     318            0 :     threadsStatus_.resize(threadsNum);
     319            0 :     HCCL_INFO(
     320              :         "comm base threads info:link threads size[%llu], dst inter client map size[%llu], " \
     321              :         "dst inter server map size[%llu]", linkThreads_.size(), dstInterClientMap_.size() * nicNum,
     322              :         dstInterServerMap_.size() * nicNum);
     323            0 :     HcclUs startut = TIME_NOW();
     324              :     // 获取当前rank作为client端时,获取所有server端的socket
     325            0 :     CHK_RET(CreateInterServerLinks());
     326              :     // 获取当前rank作为server端时,获取所有client端的socket
     327            0 :     CHK_RET(CreateInterClientLinks());
     328              : 
     329            0 :     bool check = (threadsApplyNum_ != linkThreads_.size());
     330            0 :     CHK_PRT_RET(check, HCCL_ERROR("[Create][Links]comm apply num[%u] is not equal to link threads[%llu]",
     331              :         threadsApplyNum_, linkThreads_.size()), HCCL_E_INTERNAL);
     332              : 
     333            0 :     HCCL_INFO("CommRemoteAccess CreateLinks threadsApplyNum_[%u]", threadsApplyNum_);
     334              : 
     335            0 :     for (u32 index = 0; index < linkThreads_.size(); index++) {
     336            0 :         linkThreads_[index]->join();  // 等待线程执行完毕
     337            0 :         CHK_RET(hrtResetDevice(deviceLogicId_));  // 防止线程里面异常退出,在进程中reset
     338              :     }
     339            0 :     for (u32 index = 0; index < threadsStatus_.size(); index++) {
     340            0 :         CHK_PRT_RET(threadsStatus_[index] != 0, HCCL_ERROR("[Create][Links]execute the thread[%u] function failed",
     341              :             index), HCCL_E_PARA);
     342              :     }
     343            0 :     linkThreads_.clear();
     344            0 :     HCCL_DEBUG("rdma_rasocket Time:%lld us", DURATION_US(TIME_NOW() - startut));
     345            0 :     return HCCL_SUCCESS;
     346              : }
     347              : 
     348            0 : HcclResult CommRemoteAccess::CreateInterServerLinks()
     349              : {
     350              :     // 获取当前rank作为client端时,获取所有server端的socket
     351            0 :     u32 dstInterServerNum = dstInterServerMap_.size() * nicSocketHandle_.size();
     352            0 :     if (dstInterServerNum > 0) {
     353            0 :         std::vector<struct SocketInfoT> cliConns(dstInterServerNum);
     354            0 :         struct SocketInfoT *cliConn = cliConns.data();
     355            0 :         s32 sRet = memset_s(cliConn, sizeof(struct SocketInfoT) * dstInterServerNum, 0,
     356            0 :                             sizeof(struct SocketInfoT) * dstInterServerNum);
     357            0 :         CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Create][InterServerLinks]memory set failed. return[%d]."
     358              :             "params: destMaxSize[%zu], c[%d], count[%zu]", sRet,
     359              :             sizeof(struct SocketInfoT) * dstInterServerNum, 0, \
     360              :             sizeof(struct SocketInfoT) * dstInterServerNum), HCCL_E_MEMORY);
     361              :         // 构建socket_info_t信息,用于获取fd_socket_handle
     362            0 :         u32 connLoop = 0;
     363            0 :         for (auto iter = dstInterServerMap_.begin(); iter != dstInterServerMap_.end(); iter++) {
     364            0 :             sRet = memcpy_s(&cliConn[connLoop].tag[0], sizeof(cliConn[connLoop].tag) - 1, tag_.c_str(), tag_.size());
     365            0 :             CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Create][InterServerLinks]memcpy failed. errorno[%d],"
     366              :                 "params:destMaxSize[%zu], count[%zu]", sRet, sizeof(cliConn[connLoop].tag), tag_.size()),
     367              :                 HCCL_E_MEMORY);
     368            0 :             for (u32 idx = 0; idx < nicSocketHandle_.size(); idx++) {
     369            0 :                 cliConn[connLoop].socketHandle = nicSocketHandle_[idx];
     370            0 :                 cliConn[connLoop].remoteIp.addr = iter->second[idx].GetBinaryAddress().addr;
     371            0 :                 cliConn[connLoop].remoteIp.addr6 = iter->second[idx].GetBinaryAddress().addr6;
     372              :                 /* 插入建链状态的指示 */
     373            0 :                 LinkStatus_t linkInfo;
     374            0 :                 linkInfo.userRank = iter->first;
     375            0 :                 linkInfo.status = SOCKET_CONNECT_NO_CONNECTION;
     376            0 :                 linkInfo.isLinked = false;
     377            0 :                 linkInfo.remoteIp = (iter->second)[idx];
     378            0 :                 linkInfo.localIp = rankInfo_[rank_][idx];
     379            0 :                 HCCL_DEBUG("CLIENT rank[%u]  LocalIp[%s]  RemoteIp[%s]",
     380              :                     rank_, linkInfo.localIp.GetReadableAddress(), linkInfo.remoteIp.GetReadableAddress());
     381            0 :                 serverLinkStatus_.insert(std::make_pair(iter->second[idx], linkInfo));
     382            0 :                 connLoop++;
     383            0 :             }
     384              :         }
     385            0 :         CHK_RET(GetRaSocket(CLIENT_ROLE_SOCKET, cliConn, dstInterServerNum));
     386            0 :     }
     387            0 :     return HCCL_SUCCESS;
     388              : }
     389              : 
     390            0 : HcclResult CommRemoteAccess::GetRaSocket(const u32 role, const struct SocketInfoT conn[], const u32 num)
     391              : {
     392            0 :     HCCL_INFO("get sockets para: socket role[%u], socket num[%u]", role, num);
     393            0 :     auto startTime = std::chrono::steady_clock::now();
     394            0 :     auto timeout = std::chrono::seconds(GetExternalInputHcclLinkTimeOut());
     395              :     s32 sockRet;
     396            0 :     u32 gotSocketsCnt = 0;
     397            0 :     HCCL_INFO("In GetRaSocket, waiting for all rasockets link up...");
     398            0 :     u32 left = num;
     399              :     while (true) {
     400            0 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
     401            0 :             PrintErrorConnection(role, left);
     402            0 :             HCCL_ERROR("[Get][RaSocket]in GetRaSocket, get rasocket error role[%u], rank[%u]num[%u], timeout[%lld s]",
     403              :                 role, rank_, left, timeout);
     404            0 :             return HCCL_E_TIMEOUT;
     405              :         }
     406            0 :         std::vector<struct SocketInfoT> conns(left);
     407            0 :         struct SocketInfoT *tmpConn = conns.data();
     408            0 :         s32 sret = memcpy_s(tmpConn, sizeof(struct SocketInfoT) * left,
     409            0 :                             conn + (num - left), sizeof(struct SocketInfoT) * left);
     410            0 :         CHK_PRT_RET(sret != EOK, HCCL_ERROR("[Get][RaSocket]memcpy failed. errorno[%d], params:"
     411              :             "destMaxSize[%zu], count[%zu]", sret, sizeof(struct SocketInfoT) * left,
     412              :             sizeof(struct SocketInfoT) * left), HCCL_E_MEMORY);
     413            0 :         u32 connectedNum = 0;
     414            0 :         sockRet = hrtRaGetSockets(role, tmpConn, left, &connectedNum);
     415            0 :         if ((connectedNum == 0 && sockRet == 0) || (sockRet == SOCK_EAGAIN)) {
     416            0 :             SaluSleep(ONE_MILLISECOND_OF_USLEEP);
     417            0 :         } else if (sockRet != 0) {
     418            0 :             PrintErrorConnection(role, num);
     419            0 :             HCCL_ERROR("[Get][RaSocket]in GetRaSocket, get rasocket error. role[%u], rank[%u],num[%u] sockRet[%d] > 0",
     420              :                 role, rank_, num, sockRet);
     421            0 :             return HCCL_E_TCP_CONNECT;
     422            0 :         } else if (connectedNum > 0) {
     423            0 :             u32 sockNum = abs(static_cast<s32>(connectedNum));
     424            0 :             left = left - sockNum;
     425              :             // 保存建链成功的socket
     426            0 :             HcclResult ret = DealSuccRasocket(connectedNum, role, tmpConn, sockNum);
     427            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     428              :                 HCCL_ERROR("[Get][RaSocket]in GetRaSocket, save rasocket failed. role[%u], rank[%u]"\
     429              :                 "num[%u] ret[%d] connectednum[%u]", role, rank_, num, ret, connectedNum), ret);
     430            0 :             gotSocketsCnt += sockNum;
     431              : 
     432            0 :             if (gotSocketsCnt == num) {
     433            0 :                 break;
     434            0 :             } else if (gotSocketsCnt > num) {
     435            0 :                 HCCL_ERROR("[Get][RaSocket]total Sockets[%u], more than needed num[%u]!", gotSocketsCnt, num);
     436            0 :                 return HCCL_E_TCP_CONNECT;
     437              :             } else {
     438            0 :                 SaluSleep(ONE_MILLISECOND_OF_USLEEP);
     439              :             }
     440              :         }
     441            0 :     }
     442            0 :     HCCL_INFO("In CommRemoteAccess, all rasockets linked up ");
     443            0 :     return HCCL_SUCCESS;
     444              : }
     445              : 
     446            0 : HcclResult CommRemoteAccess::CreateInterClientLinks()
     447              : {
     448              :     // 获取当前rank作为server端时,获取所有client端的socket
     449            0 :     u32 dstInterClientNum = dstInterClientMap_.size() * nicSocketHandle_.size();
     450            0 :     HCCL_INFO("dstInterClientNum[%u]", dstInterClientNum);
     451            0 :     if (dstInterClientNum > 0) {
     452            0 :         std::vector<struct SocketInfoT> srvConns(dstInterClientNum);
     453            0 :         struct SocketInfoT *srvConn = srvConns.data();
     454            0 :         s32 sRet = memset_s(srvConn, sizeof(struct SocketInfoT) * dstInterClientNum, 0,
     455            0 :                             sizeof(struct SocketInfoT) * dstInterClientNum);
     456            0 :         CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[Create][InterClientLinks]memory set failed. return[%d]."
     457              :             "params: destMaxSize[%zu], c[%d], count[%zu]", sRet,
     458              :             sizeof(struct SocketInfoT) * dstInterClientNum, 0, \
     459              :             sizeof(struct SocketInfoT) * dstInterClientNum), HCCL_E_MEMORY);
     460            0 :         u32 loop = 0;
     461            0 :         for (u32 interIndex = 0; interIndex < dstInterClientMap_.size(); interIndex++) {
     462            0 :             sRet = memcpy_s(&srvConn[loop].tag[0], sizeof(srvConn[loop].tag) - 1, tag_.c_str(), tag_.size());
     463            0 :             CHK_PRT_RET(sRet != EOK,\
     464              :                 HCCL_ERROR("[Create][InterClientLinks]memcpy failed. errorno[%d], params:"
     465              :                     "destMaxSize[%zu],count[%zu]",\
     466              :                     sRet, sizeof(srvConn[loop].tag),\
     467              :                     tag_.size()), HCCL_E_MEMORY);
     468            0 :             for (u32 idx = 0; idx < nicSocketHandle_.size(); idx++) {
     469            0 :                 srvConn[loop].socketHandle = nicSocketHandle_[idx];
     470            0 :                 loop++;
     471              :             }
     472              :         }
     473              :         /* 插入建链状态的指示 */
     474            0 :         for (auto iter = dstInterClientMap_.begin(); iter != dstInterClientMap_.end(); iter++) {
     475            0 :             LinkStatus_t linkInfo;
     476            0 :             linkInfo.userRank = iter->first;
     477            0 :             linkInfo.status = SOCKET_CONNECT_NO_CONNECTION;
     478            0 :             linkInfo.isLinked = false;
     479            0 :             for (u32 idx = 0; idx < (iter->second).size(); idx++) {
     480            0 :                 linkInfo.remoteIp = (iter->second)[idx];
     481            0 :                 linkInfo.localIp = rankInfo_[rank_][idx];
     482            0 :                 HCCL_DEBUG("CreateInterClientLinks SERVER rank[%u]  LocalIp[%s]  RemoteIp[%s]",
     483              :                     rank_, linkInfo.localIp.GetReadableAddress(), linkInfo.remoteIp.GetReadableAddress());
     484            0 :                 clientLinkStatus_.insert(std::make_pair((iter->second)[idx], linkInfo));
     485              :             }
     486            0 :         }
     487            0 :         CHK_RET(GetRaSocket(SERVER_ROLE_SOCKET, srvConn, dstInterClientNum));
     488            0 :     }
     489            0 :     return HCCL_SUCCESS;
     490              : }
     491              : 
     492            0 : void CommRemoteAccess::PrintErrorConnection(const u32 role, const u32 num)
     493              : {
     494            0 :     RPT_INNER_ERR_PRT("remote op nic connect failed, please ensure that collective communication execution status "\
     495              :         "of each device is consistent(include network TLS configuration)");
     496              : 
     497            0 :     HCCL_ERROR("Some NPUs get socket timeout, the details are as follows:");
     498            0 :     HCCL_ERROR("   _________________________LINK_ERROR_INFO___________________________");
     499            0 :     HCCL_ERROR("   |  comm error, device[%d] num[%u] ", deviceLogicId_, num);
     500            0 :     HCCL_ERROR("   |  dest_ip(user_rank)  |   dest_port   |  src_ip(user_rank)   |   src_port   |   MyRole   "
     501              :         "|   Status   |");
     502            0 :     HCCL_ERROR("   |--------------------|--------------------|----------|------------|-----------------"
     503              :         "|-----------------|");
     504              : 
     505              :     /* 第一行打印deviceIds */
     506            0 :     HcclResult ret = HCCL_SUCCESS;
     507            0 :     if (role == SERVER_ROLE_SOCKET) {
     508            0 :         ret = PrintErrorConnectionInfo(clientLinkStatus_, role);
     509            0 :     } else if (role == CLIENT_ROLE_SOCKET) {
     510            0 :         ret = PrintErrorConnectionInfo(serverLinkStatus_, role);
     511              :     }
     512            0 :     if (ret != HCCL_SUCCESS) {
     513            0 :         HCCL_ERROR("[Print][ErrorConnection]PrintErrorConnectionInfo fail. ret[%d] role[%u]", ret, role);
     514            0 :         return;
     515              :     }
     516            0 :     HCCL_ERROR("   ___________________________________________________________________  ");
     517            0 :     HCCL_ERROR("the connection failure between this device and target device may be due to the following reasons:");
     518            0 :     HCCL_ERROR("1. the connection between this device and the target device is abnormal.");
     519            0 :     HCCL_ERROR("2. an exception occurred at the target devices.");
     520            0 :     HCCL_ERROR("3. the time difference between the execution of hcom on this device and the target device exceeds the "\
     521              :         "timeout threshold, make sure this by keyword [Entry-].");
     522            0 :     HCCL_ERROR("4. the behavior of executing the calculation graph on this device and the target device is " \
     523              :         "inconsistent. ");
     524            0 :     HCCL_ERROR("5. Now you can freely specify a port for listening and connecting. If an invalid port is chosen, "
     525              :         "it may result in failed listening and connection timeouts");
     526            0 :     return;
     527              : }
     528              : 
     529              : #define TRANSFORM_RASOCKET_STATUS(status, stringStatus) do {                   \
     530              :     switch (status) {                                                          \
     531              :         default:                                                               \
     532              :         case SOCKET_CONNECT_NO_CONNECTION:                                     \
     533              :             stringStatus = "no connect";                                       \
     534              :             break;                                                             \
     535              :         case SOCKET_CONNECT_OK:                                                \
     536              :             stringStatus = "connected";                                        \
     537              :             break;                                                             \
     538              :         case SOCKET_CONNECT_TIMEOUT:                                           \
     539              :             stringStatus = "connecting";                                       \
     540              :             break;                                                             \
     541              :     }                                                                          \
     542              : } while (0)
     543              : 
     544            0 : HcclResult CommRemoteAccess::PrintErrorConnectionInfo(const std::map<HcclIpAddress, LinkStatus_t> &linkStatusMap,
     545              :     u32 role)
     546              : {
     547            0 :     std::string sRole;
     548            0 :     switch (role) {
     549            0 :         case SERVER_ROLE_SOCKET:
     550            0 :             sRole = " server ";
     551            0 :             break;
     552            0 :         case CLIENT_ROLE_SOCKET:
     553            0 :             sRole = " client ";
     554            0 :             break;
     555            0 :         default:
     556            0 :             sRole = "   NA   ";
     557            0 :             break;
     558              :     }
     559            0 :     for (auto iter = linkStatusMap.begin(); iter != linkStatusMap.end(); iter++) {
     560            0 :         if (!iter->second.isLinked) {
     561            0 :             std::string connectStatus = "";
     562            0 :             TRANSFORM_RASOCKET_STATUS(iter->second.status, connectStatus);
     563            0 :             HCCL_ERROR("   |  %s(%u)   |  %u  |   %s(%u)   |  %u  | %s | %s |  ",
     564              :                 iter->second.remoteIp.GetReadableAddress(), iter->second.userRank, HETEROG_CCL_PORT,
     565              :                 iter->second.localIp.GetReadableAddress(), rank_, HETEROG_CCL_PORT,
     566              :                 sRole.c_str(), connectStatus.c_str());
     567            0 :         }
     568              :     }
     569            0 :     return HCCL_SUCCESS;
     570            0 : }
     571              : 
     572              : // 根据IP信息,获得RANK信息
     573            0 : HcclResult CommRemoteAccess::GetDstRank(std::map<u32, std::vector<HcclIpAddress>> &dstMap, const HcclIpAddress &dstIp,
     574              :     u32 &dstRank)
     575              : {
     576            0 :     for (auto it = dstMap.begin(); it != dstMap.end(); it++) {
     577            0 :         for (u32 idx = 0; idx < it->second.size(); idx++) {
     578            0 :             if (it->second[idx] == dstIp) {
     579            0 :                 dstRank = it->first;
     580            0 :                 return HCCL_SUCCESS;
     581              :             }
     582              :         }
     583              :     }
     584              : 
     585            0 :     HCCL_ERROR("[Get][DstRank]can't find ip[%s] in dst map", dstIp.GetReadableAddress());
     586            0 :     return HCCL_E_NOT_FOUND;
     587              : }
     588              : 
     589            0 : HcclResult CommRemoteAccess::CreateInterThread(const u32 role, const SocketInfoT &socketInfo)
     590              : {
     591              :     // 线程命名,CommRemoteTerL代表CommRemote Inter Link
     592            0 :     std::string threadStr = "RemoteThrd_" + std::to_string(threadsApplyNum_);
     593            0 :     HcclIpAddress nicIp;
     594            0 :     u32 dstRank = 0;
     595            0 :     threadsStatus_[threadsApplyNum_] = 1;
     596            0 :     CHK_RET(GetNicByHandle(socketInfo.socketHandle, nicIp));
     597              :     HcclInAddr temp;
     598            0 :     temp.addr = socketInfo.remoteIp.addr;
     599            0 :     temp.addr6 = socketInfo.remoteIp.addr6;
     600            0 :     HcclIpAddress remoteIP(rankInfo_[rank_][0].GetFamily(), temp);
     601            0 :     CHK_PRT_RET(remoteIP.IsInvalid(), HCCL_ERROR("ip is invalid."), HCCL_E_PARA);
     602            0 :     workflowMode_ = GetWorkflowMode();
     603            0 :     if (role == SERVER_ROLE_SOCKET) {
     604            0 :         CHK_RET(GetDstRank(dstInterClientMap_, remoteIP, dstRank));
     605            0 :         linkThreads_[threadsApplyNum_].reset(
     606            0 :             new (std::nothrow) std::thread(&CommRemoteAccess::InitDestTransport, this, hrtErrMGetErrorContext(), role,
     607            0 :                                 nicIp, dstRank, threadStr, socketInfo.fdHandle, &threadsStatus_[threadsApplyNum_]));
     608              :     }
     609              : 
     610            0 :     if (role == CLIENT_ROLE_SOCKET) {
     611            0 :         CHK_RET(GetDstRank(dstInterServerMap_, remoteIP, dstRank));
     612            0 :         linkThreads_[threadsApplyNum_].reset(
     613            0 :             new (std::nothrow) std::thread(&CommRemoteAccess::InitDestTransport, this, hrtErrMGetErrorContext(), role,
     614            0 :                                 nicIp, dstRank, threadStr, socketInfo.fdHandle, &threadsStatus_[threadsApplyNum_]));
     615              :     }
     616            0 :     bool check = !linkThreads_[threadsApplyNum_];
     617            0 :     CHK_PRT_RET(check, HCCL_ERROR("[Create][InterThread]link threads[%u] reset failed.", threadsApplyNum_),
     618              :         HCCL_E_INTERNAL);
     619            0 :     threadsApplyNum_++;
     620            0 :     return HCCL_SUCCESS;
     621            0 : }
     622              : 
     623            0 : HcclResult CommRemoteAccess::DealSuccRasocket(s32 sockRet, const u32 role,
     624              :     const struct SocketInfoT tmpConn[], const u32 num)
     625              : {
     626            0 :     HCCL_DEBUG("CommRemoteAccess DealSuccRasocketNum[%u]", num);
     627            0 :     u32 socketsCnt = static_cast<u32>(sockRet);
     628            0 :     u32 loop = 0;
     629            0 :     for (u32 i = 0; i < num; i++) {
     630              :         HcclInAddr temp;
     631            0 :         temp.addr = tmpConn[i].remoteIp.addr;
     632            0 :         temp.addr6 = tmpConn[i].remoteIp.addr6;
     633            0 :         HcclIpAddress remoteIP(rankInfo_[rank_][0].GetFamily(), temp);
     634            0 :         CHK_PRT_RET(remoteIP.IsInvalid(), HCCL_ERROR("ip is invalid."), HCCL_E_PARA);
     635            0 :         if (tmpConn[i].status == SOCKET_CONNECT_OK) {
     636            0 :             raSockets_.push_back(tmpConn[i]);
     637            0 :             CHK_RET(CreateInterThread(role, tmpConn[i]));
     638              :             // 建链成功的在本地标志建链成功
     639            0 :             serverLinkStatus_[remoteIP].isLinked = true;
     640            0 :             loop++;
     641              :         }
     642            0 :         if (tmpConn[i].status != SOCKET_CONNECT_NO_CONNECTION) {
     643            0 :             clientLinkStatus_[remoteIP].status = tmpConn[i].status;
     644              :         }
     645            0 :     }
     646              : 
     647            0 :     if (socketsCnt != loop) {
     648            0 :         HCCL_ERROR("[Deal][SuccRasocket]current socketsCnt[%u], not equal to actual connect number[%u]!",
     649              :             socketsCnt, loop);
     650            0 :         return HCCL_E_TCP_CONNECT;
     651              :     }
     652            0 :     return HCCL_SUCCESS;
     653              : }
     654              : 
     655            0 : HcclResult CommRemoteAccess::InitDestTransport(const ErrContext &error_context, u32 role, const HcclIpAddress &nicIp,
     656              :     const u32 dstRank, const std::string &threadStr, FdHandle socketFdHandle, u32 *getThreadStatus)
     657              : {
     658            0 :     hrtErrMSetErrorContext(error_context);
     659              : 
     660              :     // 给当前线程添加名字
     661            0 :     SetThreadName(threadStr);
     662            0 :     CHK_RET(hrtSetDevice(deviceLogicId_));
     663            0 :     SetWorkflowMode(workflowMode_);
     664              : 
     665            0 :     RemoteAccessPara accessPara;
     666            0 :     CHK_RET(SetAccessPara(role, nicIp, dstRank, socketFdHandle, accessPara));
     667            0 :     HCCL_INFO("[InitDestTransport para]local_rank[%u]-localIpAddr[%s],dst rank[%u]-remote_rank[%u]-remote_ip_addr[%s], "
     668              :               "role[%u]",
     669              :         rank_, rankInfo_[rank_][0].GetReadableAddress(), dstRank, dstRank, rankInfo_[dstRank][0].GetReadableAddress(),
     670              :         role);
     671              : 
     672            0 :     std::shared_ptr<TransportRemoteAccess> transportPtr;
     673            0 :     transportPtr.reset(new (std::nothrow) TransportRemoteAccess(tag_, dispatcher_, notifyPool_, accessPara, addrInfos_,
     674            0 :         deviceLogicId_));
     675            0 :     CHK_PRT_RET(!transportPtr, HCCL_ERROR("[Init][DestTransport]InitDestTransport failed"), HCCL_E_PTR);
     676              : 
     677            0 :     std::unique_lock<std::mutex> remoteTransportMapLock(remoteTransportMapLock_);
     678            0 :     remoteTransportMap_.insert(std::make_pair(dstRank, transportPtr));
     679            0 :     remoteTransportMapLock.unlock();
     680              : 
     681            0 :     CHK_RET(transportPtr->Init());
     682            0 :     *getThreadStatus = 0;
     683            0 :     return HCCL_SUCCESS;
     684            0 : }
     685              : 
     686              : // 根据socket handle,获取本device所使用的网口IP
     687            0 : HcclResult CommRemoteAccess::GetNicByHandle(const SocketHandle socketHandle, HcclIpAddress &nicIp)
     688              : {
     689            0 :     for (auto it = raResourceInfo_.nicSocketMap.begin(); it != raResourceInfo_.nicSocketMap.end(); it++) {
     690            0 :         if (it->second.nicSocketHandle == socketHandle) {
     691            0 :             nicIp = it->first;
     692            0 :             return HCCL_SUCCESS;
     693              :         }
     694              :     }
     695              : 
     696            0 :     HCCL_ERROR("[Get][NicByHandle]current socket handle error");
     697            0 :     return HCCL_E_NOT_FOUND;
     698              : }
     699              : 
     700            0 : HcclResult CommRemoteAccess::SetAccessPara(u32 role, const HcclIpAddress &nicIp, u32 dstRank, FdHandle socketFdhandle,
     701              :     RemoteAccessPara &accessPara)
     702              : {
     703            0 :     accessPara.role = role;
     704            0 :     accessPara.localIp = nicIp;
     705            0 :     accessPara.localRank = rank_;
     706            0 :     accessPara.remoteRank = dstRank;
     707            0 :     accessPara.socketFdhandle = socketFdhandle;
     708            0 :     accessPara.raResourceInfo = raResourceInfo_;
     709              : 
     710              :     // 获取 nicSocketHandle
     711            0 :     auto itSocket = raResourceInfo_.nicSocketMap.find(nicIp);
     712            0 :     if (itSocket == raResourceInfo_.nicSocketMap.end()) {
     713            0 :         HCCL_ERROR("[Set][AccessPara]In get nic handle, can not find socket handle, handle size[%u], local ip[%s]",
     714              :             raResourceInfo_.nicSocketMap.size(), nicIp.GetReadableAddress());
     715            0 :         return HCCL_E_PARA;
     716              :     }
     717            0 :     accessPara.nicSocketHandle = itSocket->second.nicSocketHandle;
     718            0 :     CHK_PTR_NULL(accessPara.nicSocketHandle);
     719              : 
     720            0 :     accessPara.nicRdmaHandle = itSocket->second.nicRdmaHandle;
     721            0 :     CHK_PTR_NULL(accessPara.nicRdmaHandle);
     722            0 :     return HCCL_SUCCESS;
     723              : }
     724              : }
        

Generated by: LCOV version 2.0-1