LCOV - code coverage report
Current view: top level - base_comm/resources/endpoint_pairs/channels/aiv - aiv_ub_mem_transport.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.7 % 217 186
Test Date: 2026-08-18 17:47:01 Functions: 100.0 % 17 17

            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 "aiv_ub_mem_transport.h"
      12              : #include "exception_handler.h"
      13              : #include "../../../../../../legacy/ascend950/unified_platform/resource/socket/socket.h"
      14              : #include "../../../../../../legacy/ascend950/unified_platform/resource/buffer/exchange_ipc_buffer_dto.h"
      15              : #include "../../../../../../legacy/ascend950/unified_platform/resource/mem/user_remote_mem_getter.h"
      16              : #include "env_config/env_config_v2.h"
      17              : 
      18              : namespace hcomm {
      19              : 
      20           10 : AivUbMemTransport::AivUbMemTransport(Hccl::Socket* socket, HcommChannelDesc& channelDesc)
      21           10 :     : socket_(socket),
      22           10 :       channelDesc_(channelDesc)
      23           10 : {}
      24              : 
      25            2 : HcclResult AivUbMemTransport::FillBufferVec(
      26              :     HcommMemHandle* memHandles, uint32_t bufferNum, std::vector<Hccl::LocalIpcRmaBuffer*>& bufferVec)
      27              : {
      28            2 :     uint32_t totalBufferNum = localRmaBufferVec_.size() + bufferNum;
      29            2 :     if (UNLIKELY(totalBufferNum > MAX_BUFFER_NUM)) {
      30            0 :         HCCL_ERROR(
      31              :             "[AivUbMemTransport][FillBufferVec] totalBufferNum[%u] exceeds limit[%u]", totalBufferNum, MAX_BUFFER_NUM);
      32            0 :         return HCCL_E_PARA;
      33              :     }
      34            5 :     for (uint32_t i = 0; i < bufferNum; ++i) {
      35            3 :         auto localIpcRmaBuffer = reinterpret_cast<Hccl::LocalIpcRmaBuffer*>(memHandles[i]);
      36            3 :         CHK_PTR_NULL(localIpcRmaBuffer);
      37            3 :         auto buf = localIpcRmaBuffer->GetBuf();
      38            3 :         CHK_PTR_NULL(buf);
      39            3 :         bufferVec.push_back(localIpcRmaBuffer);
      40            3 :         HCCL_INFO(
      41              :             "[AivUbMemTransport][FillBufferVec] memHandleNum[%u] buffer[%s]", i, localIpcRmaBuffer->Describe().data());
      42              :     }
      43            2 :     return HCCL_SUCCESS;
      44              : }
      45              : 
      46            1 : HcclResult AivUbMemTransport::Init()
      47              : {
      48            1 :     uint32_t bufferNum = channelDesc_.memHandleNum;
      49            1 :     if (bufferNum == 0) {
      50            1 :         HCCL_ERROR("[AivUbMemTransport][Init] bufferNum is 0.");
      51            1 :         return HCCL_E_PARA;
      52              :     }
      53            0 :     HCCL_INFO("[AivUbMemTransport][Init] channelDesc_.memHandleNum: %u", bufferNum);
      54            0 :     CHK_RET(FillBufferVec(channelDesc_.memHandles, bufferNum, localRmaBufferVec_));
      55              : 
      56            0 :     baseStatus_ = Hccl::TransportStatus::INIT;
      57            0 :     return HCCL_SUCCESS;
      58              : }
      59              : 
      60            8 : HcclResult AivUbMemTransport::IsSocketReady(bool& isReady)
      61              : {
      62            8 :     CHK_PTR_NULL(socket_);
      63              :     EXCEPTION_HANDLE_BEGIN
      64            8 :     Hccl::SocketStatus socketStatus = socket_->GetAsyncStatus();
      65            7 :     if (socketStatus == Hccl::SocketStatus::OK) {
      66            7 :         baseStatus_ = Hccl::TransportStatus::SOCKET_OK;
      67            7 :         isReady = true;
      68            0 :     } else if (socketStatus == Hccl::SocketStatus::TIMEOUT) {
      69            0 :         baseStatus_ = Hccl::TransportStatus::SOCKET_TIMEOUT;
      70            0 :         isReady = false;
      71              :     }
      72            1 :     EXCEPTION_HANDLE_END
      73            7 :     return HCCL_SUCCESS;
      74              : }
      75              : 
      76            6 : void AivUbMemTransport::CheckStatusFuncResult(std::string funcName, HcclResult ret)
      77              : {
      78            6 :     if (UNLIKELY(ret != HCCL_SUCCESS)) {
      79            1 :         HCCL_ERROR(
      80              :             "[%s] fail ret[%d], aivUbStatus_[%d], baseStatus_[%d]", funcName.c_str(), ret, aivUbStatus_, baseStatus_);
      81            1 :         baseStatus_ = Hccl::TransportStatus::INVALID;
      82              :     }
      83            6 : }
      84              : 
      85            8 : Hccl::TransportStatus AivUbMemTransport::GetStatus()
      86              : {
      87            8 :     if (baseStatus_ == Hccl::TransportStatus::READY || baseStatus_ == Hccl::TransportStatus::INVALID) {
      88            0 :         return baseStatus_;
      89            8 :     } else if (baseStatus_ == Hccl::TransportStatus::INIT) {
      90            0 :         aivUbStatus_ = AivUbMemTransportStatus::INIT;
      91              :     }
      92              : 
      93            8 :     bool isReady = false;
      94            8 :     if (UNLIKELY(IsSocketReady(isReady) != HCCL_SUCCESS)) {
      95            1 :         HCCL_ERROR("[%s] IsSocketReady fail, aivUbStatus_[%d], baseStatus_[%d]", __func__, aivUbStatus_, baseStatus_);
      96            1 :         baseStatus_ = Hccl::TransportStatus::INVALID;
      97            1 :         return baseStatus_;
      98              :     }
      99            7 :     if (!isReady) {
     100            0 :         return baseStatus_;
     101              :     }
     102            7 :     return UpdateStatus();
     103              : }
     104              : 
     105            7 : Hccl::TransportStatus AivUbMemTransport::UpdateStatus()
     106              : {
     107            7 :     HCCL_INFO(
     108              :         "%s aivUbStatus_[%d], baseStatus_[%d] start, aivUbStatus_::SOCKET_OK[%d]", __func__, aivUbStatus_, baseStatus_,
     109              :         AivUbMemTransportStatus::SOCKET_OK);
     110              :     HcclResult ret;
     111            7 :     switch (aivUbStatus_) {
     112            0 :         case AivUbMemTransportStatus::INIT:
     113            0 :             aivUbStatus_ = AivUbMemTransportStatus::SOCKET_OK;
     114            0 :             baseStatus_ = Hccl::TransportStatus::SOCKET_OK;
     115            0 :             break;
     116            1 :         case AivUbMemTransportStatus::SOCKET_OK:
     117            1 :             ret = SendDataSize();
     118            1 :             CheckStatusFuncResult("SendDataSize", ret);
     119            1 :             aivUbStatus_ = AivUbMemTransportStatus::SEND_DATA_SIZE;
     120            1 :             break;
     121            1 :         case AivUbMemTransportStatus::SEND_DATA_SIZE:
     122            1 :             ret = RecvDataSize();
     123            1 :             CheckStatusFuncResult("RecvDataSize", ret);
     124            1 :             aivUbStatus_ = AivUbMemTransportStatus::RECV_DATA_SIZE;
     125            1 :             break;
     126            1 :         case AivUbMemTransportStatus::RECV_DATA_SIZE:
     127            1 :             ret = SendMemInfo();
     128            1 :             CheckStatusFuncResult("SendMemInfo", ret);
     129            1 :             aivUbStatus_ = AivUbMemTransportStatus::SEND_MEM_INFO;
     130            1 :             break;
     131            1 :         case AivUbMemTransportStatus::SEND_MEM_INFO:
     132            1 :             ret = RecvMemInfo();
     133            1 :             CheckStatusFuncResult("RecvMemInfo", ret);
     134            1 :             aivUbStatus_ = AivUbMemTransportStatus::RECV_MEM_INFO;
     135            1 :             break;
     136            2 :         case AivUbMemTransportStatus::RECV_MEM_INFO:
     137            2 :             ret = RecvDataProcess();
     138            2 :             CheckStatusFuncResult("RecvDataProcess", ret);
     139            2 :             aivUbStatus_ = AivUbMemTransportStatus::RECV_MEM_FIN;
     140            2 :             break;
     141            1 :         case AivUbMemTransportStatus::RECV_MEM_FIN:
     142            1 :             aivUbStatus_ = AivUbMemTransportStatus::READY;
     143            1 :             baseStatus_ = Hccl::TransportStatus::READY;
     144            1 :             break;
     145            0 :         default:
     146            0 :             break;
     147              :     }
     148            7 :     HCCL_INFO("%s aivUbStatus_[%d], baseStatus_[%d]", __func__, aivUbStatus_, baseStatus_);
     149            7 :     return baseStatus_;
     150              : }
     151              : 
     152            1 : HcclResult AivUbMemTransport::SendDataSize()
     153              : {
     154            1 :     HCCL_INFO("[%s] start", __func__);
     155              : 
     156            1 :     Hccl::BinaryStream binaryStream;
     157            1 :     CHK_RET(BufferPack(binaryStream, localRmaBufferVec_));
     158              : 
     159            1 :     binaryStream.Dump(sendData_);
     160            1 :     u32 sendSize = sendData_.size();
     161              :     EXCEPTION_HANDLE_BEGIN
     162            1 :     socket_->SendAsync(&sendSize, sizeof(sendSize));
     163            0 :     EXCEPTION_HANDLE_END
     164            1 :     HCCL_INFO("[%s] finished", __func__);
     165            1 :     return HCCL_SUCCESS;
     166            1 : }
     167              : 
     168            2 : HcclResult AivUbMemTransport::RecvDataSize()
     169              : {
     170            2 :     HCCL_INFO("[%s] start", __func__);
     171              : 
     172              :     EXCEPTION_HANDLE_BEGIN
     173            2 :     socket_->RecvAsync(reinterpret_cast<u8*>(&exchangeDataSize_), sizeof(exchangeDataSize_));
     174            0 :     EXCEPTION_HANDLE_END
     175            2 :     HCCL_INFO("[%s] finished", __func__);
     176            2 :     return HCCL_SUCCESS;
     177              : }
     178              : 
     179            2 : HcclResult AivUbMemTransport::SendMemInfo()
     180              : {
     181            2 :     HCCL_INFO("[%s] start", __func__);
     182              : 
     183              :     EXCEPTION_HANDLE_BEGIN
     184            2 :     socket_->SendAsync(&sendData_[0], sendData_.size());
     185            0 :     EXCEPTION_HANDLE_END
     186            2 :     HCCL_INFO("[%s] finished", __func__);
     187            2 :     return HCCL_SUCCESS;
     188              : }
     189              : 
     190              : HcclResult
     191            3 : AivUbMemTransport::BufferPack(Hccl::BinaryStream& binaryStream, std::vector<Hccl::LocalIpcRmaBuffer*>& bufferVec)
     192              : {
     193            3 :     u32 vecSize = bufferVec.size();
     194            3 :     binaryStream << vecSize;
     195            3 :     HCCL_INFO("BufferPack vecSize=%u", vecSize);
     196              : 
     197            6 :     for (uint32_t i = 0; i < vecSize; ++i) {
     198            3 :         std::unique_ptr<Hccl::Serializable> dto = bufferVec[i]->GetExchangeDto();
     199            3 :         CHK_PTR_NULL(dto);
     200            3 :         dto->Serialize(binaryStream);
     201            3 :         HCCL_INFO("[%s] dto[%s]", __func__, dto->Describe().c_str());
     202            3 :     }
     203            3 :     return HCCL_SUCCESS;
     204              : }
     205              : 
     206            2 : HcclResult AivUbMemTransport::RecvMemInfo()
     207              : {
     208            2 :     recvData_.resize(exchangeDataSize_);
     209              :     EXCEPTION_HANDLE_BEGIN
     210            2 :     socket_->RecvAsync(reinterpret_cast<u8*>(&recvData_[0]), recvData_.size());
     211            0 :     EXCEPTION_HANDLE_END
     212              :     // HCCL_INFO("recv data, size=%llu, data=%s", data.size(), Hccl::Bytes2hex(data.data(), data.size()).c_str());
     213            2 :     return HCCL_SUCCESS;
     214              : }
     215              : 
     216            2 : HcclResult AivUbMemTransport::RecvDataProcess()
     217              : {
     218            2 :     Hccl::BinaryStream binaryStream(recvData_);
     219            2 :     rmtBufferVec_.clear();
     220            2 :     rmtRmaBufferVec_.clear();
     221              :     EXCEPTION_HANDLE_BEGIN
     222            2 :     RmtBufferUnpackProc(binaryStream);
     223            1 :     EXCEPTION_HANDLE_END
     224            1 :     return HCCL_SUCCESS;
     225            2 : }
     226              : 
     227            2 : void AivUbMemTransport::RmtBufferUnpackProc(Hccl::BinaryStream& binaryStream)
     228              : {
     229            2 :     u32 vecSize{0};
     230            2 :     binaryStream >> vecSize;
     231            2 :     HCCL_INFO("vecSize=%u", vecSize);
     232            2 :     uint32_t totalBufferNum = rmtBufferVec_.size() + vecSize;
     233            2 :     if (UNLIKELY(totalBufferNum > MAX_BUFFER_NUM)) {
     234            0 :         EXCEPTION_THROW_IF_ERR(HCCL_E_PARA, "[AivUbMemTransport][RmtBufferUnpackProc] vecSize exceeds limit.");
     235              :     }
     236              : 
     237            3 :     for (u32 pos = 0; pos < vecSize; ++pos) {
     238            1 :         Hccl::ExchangeIpcBufferDto dto;
     239            1 :         dto.Deserialize(binaryStream);
     240            1 :         HCCL_INFO("[%s] dto[%s]", __func__, dto.Describe().c_str());
     241            1 :         if (dto.size == 0) { // size为0,则为 remote 空buffer
     242            0 :             HCCL_INFO("unpack nullptr, pos=%u", pos);
     243            0 :             rmtBufferVec_.push_back(nullptr);
     244            0 :             rmtRmaBufferVec_.push_back(nullptr);
     245              :         } else { // size非0,则构造一个remote buffer
     246            1 :             HCCL_INFO("[AivUbMemTransport][RmtBufferUnpackProc] unpack buffer memInfo[%s]", dto.memInfo.c_str());
     247            1 :             rmtBufferVec_.push_back(std::make_unique<Hccl::RemoteIpcRmaBuffer>(dto));
     248            1 :             rmtBufferVec_.back()->SetPathMode(channelDesc_.ubMemAttr.pathMode);
     249            1 :             rmtRmaBufferVec_.push_back(rmtBufferVec_.back().get());
     250              :         }
     251            1 :     }
     252            2 : }
     253              : 
     254            2 : HcclResult AivUbMemTransport::GetRemoteMems(uint32_t* memNum, CommMem** remoteMem, char*** memInfos)
     255              : {
     256            2 :     std::lock_guard<std::mutex> lock(remoteMemsMutex_);
     257              :     Hccl::RemoteMemCtx<std::unique_ptr<Hccl::RemoteIpcRmaBuffer>> remoteMemCtx{
     258            2 :         cacheValid_, rmtBufferVec_, remoteUserMems_, memInfoCopies_, memInfoPointers_, remoteMem, memInfos, memNum};
     259            2 :     CHK_RET(GetRemoteUserMems(remoteMemCtx));
     260            2 :     return HCCL_SUCCESS;
     261            2 : }
     262              : 
     263            5 : HcclResult AivUbMemTransport::CheckSocketStatus(std::string socketOperator)
     264              : {
     265            5 :     CHK_PTR_NULL(socket_);
     266            5 :     auto timeout = std::chrono::seconds(Hccl::EnvConfig::GetInstance().GetSocketConfig().GetLinkTimeOut());
     267            5 :     auto startTime = std::chrono::steady_clock::now();
     268            5 :     uint32_t retryCount = 0;
     269              :     while (true) {
     270              :         EXCEPTION_HANDLE_BEGIN
     271            5 :         Hccl::SocketStatus socketStatus = socket_->GetAsyncStatus();
     272            5 :         if (socketStatus == Hccl::SocketStatus::OK) {
     273              :             auto elapsed
     274            4 :                 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTime)
     275            4 :                       .count();
     276            4 :             HCCL_INFO(
     277              :                 "[AivUbMemTransport][%s] socket transport operation[%s] success, elapsed[%lld]ms, retryCount[%u]",
     278              :                 __func__, socketOperator.c_str(), elapsed, retryCount);
     279            4 :             break;
     280              :         }
     281            1 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout || socketStatus == Hccl::SocketStatus::TIMEOUT) {
     282              :             auto elapsed
     283            1 :                 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTime)
     284            1 :                       .count();
     285            1 :             HCCL_ERROR(
     286              :                 "[AivUbMemTransport][%s] socket transport operation[%s] timeout after %lld sec, elapsed[%lld]ms, "
     287              :                 "retryCount[%u]",
     288              :                 __func__, socketOperator.c_str(), timeout, elapsed, retryCount);
     289            1 :             return HCCL_E_TIMEOUT;
     290              :         }
     291            0 :         EXCEPTION_HANDLE_END
     292            0 :         retryCount++;
     293            0 :     }
     294            4 :     return HCCL_SUCCESS;
     295              : }
     296              : 
     297            3 : HcclResult AivUbMemTransport::UpdateMemInfo(HcommMemHandle* memHandles, uint32_t memHandleNum)
     298              : {
     299            3 :     if (memHandleNum == 0) {
     300            1 :         HCCL_WARNING("[AivUbMemTransport][UpdateMemInfo] bufferNum is 0.");
     301            1 :         return HCCL_SUCCESS;
     302              :     }
     303            2 :     locMemTemp_.clear();
     304            2 :     CHK_RET(FillBufferVec(memHandles, memHandleNum, locMemTemp_));
     305            2 :     HCCL_INFO("[AivUbMemTransport][UpdateMemInfo] bufferNum[%zu]", locMemTemp_.size());
     306            2 :     sendData_.clear();
     307            2 :     Hccl::BinaryStream sendStream;
     308            2 :     CHK_RET(BufferPack(sendStream, locMemTemp_));
     309            2 :     sendStream.Dump(sendData_);
     310            2 :     u32 sendSize = sendData_.size();
     311              :     EXCEPTION_HANDLE_BEGIN
     312            2 :     socket_->SendAsync(&sendSize, sizeof(sendSize));
     313            0 :     EXCEPTION_HANDLE_END
     314            4 :     CHK_RET(CheckSocketStatus("SendDataSize"));
     315            1 :     CHK_RET(RecvDataSize());
     316            2 :     CHK_RET(CheckSocketStatus("RecvDataSize"));
     317            1 :     CHK_RET(SendMemInfo());
     318            2 :     CHK_RET(CheckSocketStatus("SendMemInfo"));
     319            1 :     CHK_RET(RecvMemInfo());
     320            2 :     CHK_RET(CheckSocketStatus("RecvMemInfo"));
     321            1 :     Hccl::BinaryStream recvStream(recvData_);
     322              :     EXCEPTION_HANDLE_BEGIN
     323            1 :     RmtBufferUnpackProc(recvStream);
     324            0 :     EXCEPTION_HANDLE_END
     325            1 :     localRmaBufferVec_.insert(localRmaBufferVec_.end(), locMemTemp_.begin(), locMemTemp_.end());
     326              :     // 流程中已有新增内存数量判断,故执行到此位置一定存在新增内存,需要将标识置位false,使得再次调用GetRemoteMems时重新构造缓存
     327            1 :     cacheValid_ = false;
     328            1 :     return HCCL_SUCCESS;
     329            2 : }
     330              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1