LCOV - code coverage report
Current view: top level - base_comm/resources/endpoint_pairs/channels/aiv - aiv_urma_channel.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.3 % 407 347
Test Date: 2026-08-18 17:47:01 Functions: 93.3 % 45 42

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 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_urma_channel.h"
      12              : #include "endpoint.h"
      13              : #include "orion_adpt_utils.h"
      14              : #include "acl_device_slab_guard.h"
      15              : #include "shared_jetty_channel_helper.h"
      16              : 
      17              : #include "hcomm_c_adpt.h"
      18              : 
      19              : // Orion
      20              : #include "topo_common_types.h"
      21              : #include "virtual_topo.h"
      22              : #include "makebufs_helper.h"
      23              : #include "orion_adapter_hccp.h"
      24              : #include "adapter_rts.h"
      25              : #include "acl/acl_rt.h"
      26              : 
      27              : #include <algorithm>
      28              : #include <cstdint>
      29              : #include <cstdlib>
      30              : #include <cstring>
      31              : 
      32              : namespace hcomm {
      33              : constexpr uint16_t DEFAULT_LISTENING_PORT = 60001;
      34              : 
      35              : namespace {
      36              :     constexpr size_t AIV_URMA_ENTITY_ALIGN_SIZE = 64;
      37              :     constexpr size_t QUEUE_INDEX_MEM_UNIT_SIZE = sizeof(void*);
      38              : 
      39              :     struct DeviceEntitySection {
      40              :         size_t offset{0};
      41              :         size_t size{0};
      42              :     };
      43              : 
      44              :     struct DeviceChannelEntityLayout {
      45              :         DeviceEntitySection entitySection{0, sizeof(ChannelEntity)};
      46              :         DeviceEntitySection localNotifySection;
      47              :         DeviceEntitySection remoteNotifySection;
      48              :         DeviceEntitySection localBufferSection;
      49              :         DeviceEntitySection remoteBufferSection;
      50              :         DeviceEntitySection sqContextSection;
      51              :         DeviceEntitySection cqContextSection;
      52              :         DeviceEntitySection sqPiSection;
      53              :         DeviceEntitySection sqCiSection;
      54              :         DeviceEntitySection cqPiSection;
      55              :         DeviceEntitySection cqCiSection;
      56              :         size_t slabSize{0};
      57              :     };
      58              : 
      59            6 :     HcclResult SecureMemset(void* dest, size_t destMax, int value, size_t count, const char* fieldName)
      60              :     {
      61            6 :         if (dest == nullptr) {
      62            0 :             HCCL_ERROR("[SecureMemset] dest is nullptr, field[%s]", fieldName);
      63            0 :             return HCCL_E_PTR;
      64              :         }
      65            6 :         if (count > destMax) {
      66            0 :             HCCL_ERROR("[SecureMemset] invalid size, field[%s], count[%zu], destMax[%zu]", fieldName, count, destMax);
      67            0 :             return HCCL_E_PARA;
      68              :         }
      69              : 
      70            6 :         errno_t ret = memset_s(dest, destMax, value, count);
      71            6 :         if (ret != EOK) {
      72            0 :             HCCL_ERROR(
      73              :                 "[SecureMemset] memset_s failed, field[%s], ret[%d], count[%zu], destMax[%zu]", fieldName, ret, count,
      74              :                 destMax);
      75            0 :             return HCCL_E_MEMORY;
      76              :         }
      77            6 :         return HCCL_SUCCESS;
      78              :     }
      79              : 
      80            3 :     HcclResult GetAllMemHandles(EndpointHandle endpointHandle, void** memHandles, uint32_t* memHandleNum)
      81              :     {
      82            3 :         return static_cast<HcclResult>(HcommMemGetAllMemHandles(endpointHandle, memHandles, memHandleNum));
      83              :     }
      84              : 
      85           84 :     size_t AlignUp(size_t value, size_t alignment) { return (value + alignment - 1) / alignment * alignment; }
      86              : 
      87           70 :     HcclResult AddDeviceEntitySection(
      88              :         size_t elemSize, uint32_t elemNum, size_t& offset, DeviceEntitySection& section, const char* sectionName)
      89              :     {
      90           70 :         section.offset = AlignUp(offset, AIV_URMA_ENTITY_ALIGN_SIZE);
      91           70 :         if (elemNum == 0) {
      92           28 :             section.size = 0;
      93           28 :             offset = section.offset;
      94           28 :             return HCCL_SUCCESS;
      95              :         }
      96           42 :         CHK_PRT_RET(
      97              :             elemSize != 0 && elemNum > (SIZE_MAX / elemSize),
      98              :             HCCL_ERROR(
      99              :                 "[AivUrmaChannel::AddDeviceEntitySection] %s size overflow, elemSize[%zu], elemNum[%u]", sectionName,
     100              :                 elemSize, elemNum),
     101              :             HCCL_E_PARA);
     102           42 :         section.size = elemSize * static_cast<size_t>(elemNum);
     103           42 :         CHK_PRT_RET(
     104              :             section.offset > (SIZE_MAX - section.size),
     105              :             HCCL_ERROR(
     106              :                 "[AivUrmaChannel::AddDeviceEntitySection] %s offset overflow, offset[%zu], size[%zu]", sectionName,
     107              :                 section.offset, section.size),
     108              :             HCCL_E_PARA);
     109           42 :         offset = section.offset + section.size;
     110           42 :         return HCCL_SUCCESS;
     111              :     }
     112              : 
     113           52 :     void* GetSlabPtr(void* base, const DeviceEntitySection& section)
     114              :     {
     115           52 :         if (section.size == 0) {
     116            0 :             return nullptr;
     117              :         }
     118           52 :         return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(base) + section.offset);
     119              :     }
     120              : 
     121              :     template <typename T>
     122           18 :     HcclResult CopyArrayToSlab(
     123              :         void* slabBase, const T* hostArray, uint32_t arrayNum, const DeviceEntitySection& section, T** deviceArrayPtr,
     124              :         const char* arrayName)
     125              :     {
     126           18 :         CHK_PTR_NULL(deviceArrayPtr);
     127           18 :         if (arrayNum == 0 || hostArray == nullptr) {
     128           12 :             CHK_PRT_RET(
     129              :                 arrayNum != 0,
     130              :                 HCCL_ERROR("[AivUrmaChannel::CopyArrayToSlab] %s hostArray is nullptr, num[%u]", arrayName, arrayNum),
     131              :                 HCCL_E_PTR);
     132           12 :             *deviceArrayPtr = nullptr;
     133           12 :             return HCCL_SUCCESS;
     134              :         }
     135            6 :         CHK_PRT_RET(
     136              :             section.size != static_cast<size_t>(arrayNum) * sizeof(T),
     137              :             HCCL_ERROR(
     138              :                 "[AivUrmaChannel::CopyArrayToSlab] %s size mismatch, sectionSize[%zu], expect[%zu]", arrayName,
     139              :                 section.size, static_cast<size_t>(arrayNum) * sizeof(T)),
     140              :             HCCL_E_PARA);
     141            6 :         void* sectionPtr = GetSlabPtr(slabBase, section);
     142            6 :         CHK_PTR_NULL(sectionPtr);
     143            6 :         Hccl::HrtMemcpy(
     144            6 :             sectionPtr, section.size, hostArray, section.size, Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
     145            6 :         *deviceArrayPtr = reinterpret_cast<T*>(sectionPtr);
     146            6 :         HCCL_INFO(
     147              :             "[AivUrmaChannel::CopyArrayToSlab] %s: host[%p] -> dev[%p], num[%u], size[%zu]", arrayName, hostArray,
     148              :             sectionPtr, arrayNum, section.size);
     149            6 :         return HCCL_SUCCESS;
     150              :     }
     151              : 
     152            7 :     HcclResult BuildDeviceChannelEntityLayout(const ChannelEntity& hostChannel, DeviceChannelEntityLayout& layout)
     153              :     {
     154            7 :         layout.slabSize = AlignUp(sizeof(ChannelEntity), AIV_URMA_ENTITY_ALIGN_SIZE);
     155            7 :         CHK_RET(AddDeviceEntitySection(
     156              :             sizeof(RegedNotifyEntity), hostChannel.localNotifyNum, layout.slabSize, layout.localNotifySection,
     157              :             "localNotifyAddr"));
     158            7 :         CHK_RET(AddDeviceEntitySection(
     159              :             sizeof(RegedNotifyEntity), hostChannel.remoteNotifyNum, layout.slabSize, layout.remoteNotifySection,
     160              :             "remoteNotifyAddr"));
     161            7 :         CHK_RET(AddDeviceEntitySection(
     162              :             sizeof(RegedBufferEntity), hostChannel.localBufferNum, layout.slabSize, layout.localBufferSection,
     163              :             "localBufferAddr"));
     164            7 :         CHK_RET(AddDeviceEntitySection(
     165              :             sizeof(RegedBufferEntity), hostChannel.remoteBufferNum, layout.slabSize, layout.remoteBufferSection,
     166              :             "remoteBufferAddr"));
     167            7 :         CHK_RET(AddDeviceEntitySection(
     168              :             sizeof(SqContext), hostChannel.sqNum, layout.slabSize, layout.sqContextSection, "sqContextAddr"));
     169            7 :         CHK_RET(AddDeviceEntitySection(
     170              :             sizeof(CqContext), hostChannel.cqNum, layout.slabSize, layout.cqContextSection, "cqContextAddr"));
     171            7 :         CHK_RET(AddDeviceEntitySection(
     172              :             QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.sqNum, layout.slabSize, layout.sqPiSection, "sqPiAddr"));
     173            7 :         CHK_RET(AddDeviceEntitySection(
     174              :             QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.sqNum, layout.slabSize, layout.sqCiSection, "sqCiAddr"));
     175            7 :         CHK_RET(AddDeviceEntitySection(
     176              :             QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.cqNum, layout.slabSize, layout.cqPiSection, "cqPiAddr"));
     177            7 :         CHK_RET(AddDeviceEntitySection(
     178              :             QUEUE_INDEX_MEM_UNIT_SIZE, hostChannel.cqNum, layout.slabSize, layout.cqCiSection, "cqCiAddr"));
     179            7 :         layout.slabSize = AlignUp(layout.slabSize, AIV_URMA_ENTITY_ALIGN_SIZE);
     180            7 :         return HCCL_SUCCESS;
     181              :     }
     182              : 
     183            6 :     HcclResult AllocDeviceEntitySlab(size_t slabSize, AclDeviceSlabGuard& slabGuard, void*& slabPtr)
     184              :     {
     185            6 :         HcclResult ret = hrtMalloc(&slabPtr, slabSize);
     186            6 :         CHK_PRT_RET(
     187              :             ret != HCCL_SUCCESS || slabPtr == nullptr,
     188              :             HCCL_ERROR("[AivUrmaChannel::%s] hrtMalloc slab failed, ret[%d], size[%zu]", __func__, ret, slabSize),
     189              :             HCCL_E_MEMORY);
     190            5 :         slabGuard.Reset(slabPtr, slabSize);
     191            5 :         return HCCL_SUCCESS;
     192              :     }
     193              : 
     194           20 :     HcclResult ZeroQueueIndexSection(
     195              :         void* slabPtr, const std::vector<uint8_t>& zeroQueueIndexMem, const DeviceEntitySection& section)
     196              :     {
     197           20 :         if (section.size == 0) {
     198            0 :             return HCCL_SUCCESS;
     199              :         }
     200           20 :         void* sectionPtr = GetSlabPtr(slabPtr, section);
     201           20 :         CHK_PTR_NULL(sectionPtr);
     202           20 :         Hccl::HrtMemcpy(
     203           20 :             sectionPtr, section.size, zeroQueueIndexMem.data(), section.size,
     204              :             Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
     205           20 :         return HCCL_SUCCESS;
     206              :     }
     207              : 
     208            5 :     HcclResult InitQueueIndexSections(void* slabPtr, const DeviceChannelEntityLayout& layout, uint32_t queueNum)
     209              :     {
     210            5 :         std::vector<uint8_t> zeroQueueIndexMem(QUEUE_INDEX_MEM_UNIT_SIZE * queueNum, 0);
     211            5 :         CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.sqPiSection));
     212            5 :         CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.sqCiSection));
     213            5 :         CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.cqPiSection));
     214            5 :         CHK_RET(ZeroQueueIndexSection(slabPtr, zeroQueueIndexMem, layout.cqCiSection));
     215            5 :         return HCCL_SUCCESS;
     216            5 :     }
     217              : 
     218            5 :     void SetQueueIndexDeviceMem(
     219              :         Hccl::AivUrmaTransport& transport, void* slabPtr, const DeviceChannelEntityLayout& layout, uint32_t queueNum)
     220              :     {
     221            5 :         transport.SetQueueIndexDeviceMem(
     222            5 :             GetSlabPtr(slabPtr, layout.sqPiSection), GetSlabPtr(slabPtr, layout.sqCiSection),
     223            5 :             GetSlabPtr(slabPtr, layout.cqPiSection), GetSlabPtr(slabPtr, layout.cqCiSection),
     224            5 :             queueNum * QUEUE_INDEX_MEM_UNIT_SIZE);
     225            5 :     }
     226              : 
     227            3 :     HcclResult CopyChannelEntityToSlab(
     228              :         void* slabPtr, const ChannelEntity& hostChannel, const DeviceChannelEntityLayout& layout,
     229              :         ChannelEntity& devChannel)
     230              :     {
     231            3 :         devChannel = hostChannel;
     232            3 :         CHK_RET(CopyArrayToSlab(
     233              :             slabPtr, hostChannel.localNotifyAddr, hostChannel.localNotifyNum, layout.localNotifySection,
     234              :             &devChannel.localNotifyAddr, "localNotifyAddr"));
     235            3 :         CHK_RET(CopyArrayToSlab(
     236              :             slabPtr, hostChannel.remoteNotifyAddr, hostChannel.remoteNotifyNum, layout.remoteNotifySection,
     237              :             &devChannel.remoteNotifyAddr, "remoteNotifyAddr"));
     238            3 :         CHK_RET(CopyArrayToSlab(
     239              :             slabPtr, hostChannel.localBufferAddr, hostChannel.localBufferNum, layout.localBufferSection,
     240              :             &devChannel.localBufferAddr, "localBufferAddr"));
     241            3 :         CHK_RET(CopyArrayToSlab(
     242              :             slabPtr, hostChannel.remoteBufferAddr, hostChannel.remoteBufferNum, layout.remoteBufferSection,
     243              :             &devChannel.remoteBufferAddr, "remoteBufferAddr"));
     244            3 :         CHK_RET(CopyArrayToSlab(
     245              :             slabPtr, hostChannel.sqContextAddr, hostChannel.sqNum, layout.sqContextSection, &devChannel.sqContextAddr,
     246              :             "sqContextAddr"));
     247            3 :         CHK_RET(CopyArrayToSlab(
     248              :             slabPtr, hostChannel.cqContextAddr, hostChannel.cqNum, layout.cqContextSection, &devChannel.cqContextAddr,
     249              :             "cqContextAddr"));
     250            3 :         return HCCL_SUCCESS;
     251              :     }
     252              : 
     253            3 :     HcclResult CopyChannelEntityHeaderToSlab(
     254              :         void* slabPtr, const DeviceChannelEntityLayout& layout, const ChannelEntity& devChannel, void*& entityDevPtr)
     255              :     {
     256            3 :         entityDevPtr = GetSlabPtr(slabPtr, layout.entitySection);
     257            3 :         CHK_PTR_NULL(entityDevPtr);
     258            3 :         Hccl::HrtMemcpy(
     259              :             entityDevPtr, sizeof(ChannelEntity), &devChannel, sizeof(ChannelEntity),
     260              :             Hccl::tagRtMemcpyKind::RT_MEMCPY_HOST_TO_DEVICE);
     261            3 :         return HCCL_SUCCESS;
     262              :     }
     263              : } // namespace
     264              : 
     265           35 : AivUrmaChannel::AivUrmaChannel(EndpointHandle endpointHandle, const HcommChannelDesc& channelDesc)
     266           35 :     : endpointHandle_(endpointHandle),
     267           35 :       channelDesc_(channelDesc)
     268              : {
     269           35 :     channelKind_ = HcommChannelKind::AIV_URMA;
     270           35 : }
     271              : 
     272           36 : AivUrmaChannel::~AivUrmaChannel()
     273              : {
     274           35 :     PutSocketIfNeeded();
     275           35 :     ReleaseDeviceChannelEntity();
     276           36 : }
     277              : 
     278           37 : void AivUrmaChannel::PutSocketIfNeeded()
     279              : {
     280           37 :     if (socket_ == nullptr) {
     281           35 :         return;
     282              :     }
     283            2 :     if (socketConfig_ == nullptr) {
     284            1 :         socket_ = nullptr;
     285            1 :         return;
     286              :     }
     287            1 :     if (channelDesc_.socket == nullptr && socket_ != nullptr) {
     288            1 :         (void)SocketMgr::GetInstance(devicePhyId_).PutSocket(socketConfig_, socket_);
     289              :     }
     290            1 :     socket_ = nullptr;
     291              : }
     292              : 
     293           40 : void AivUrmaChannel::ReleaseDeviceChannelEntity()
     294              : {
     295           40 :     if (devChannelEntitySlab_ != nullptr) {
     296            5 :         HcclResult ret = hrtFree(devChannelEntitySlab_);
     297            5 :         if (ret != HCCL_SUCCESS) {
     298            0 :             HCCL_WARNING(
     299              :                 "[AivUrmaChannel::%s] hrtFree devChannelEntitySlab failed, ptr[%p], size[%zu], ret[%d]", __func__,
     300              :                 devChannelEntitySlab_, devChannelEntitySlabSize_, ret);
     301              :         }
     302            5 :         devChannelEntitySlab_ = nullptr;
     303            5 :         devChannelEntitySlabSize_ = 0;
     304              :     }
     305           40 :     deviceMemories_.clear();
     306           40 :     devChannelEntity_ = nullptr;
     307           40 : }
     308              : 
     309            6 : HcclResult AivUrmaChannel::ParseInputParam()
     310              : {
     311              :     // 1. 从 endpointHandle_,获得 localEp_ 和 rdmaHandle_
     312            6 :     Endpoint* localEpPtr = reinterpret_cast<Endpoint*>(endpointHandle_);
     313            6 :     CHK_PTR_NULL(localEpPtr);
     314            5 :     localEp_ = localEpPtr->GetEndpointDesc();
     315            5 :     rdmaHandle_ = localEpPtr->GetRdmaHandle();
     316            5 :     devicePhyId_ = localEp_.loc.device.devPhyId;
     317              : 
     318            5 :     socket_ = reinterpret_cast<Hccl::Socket*>(channelDesc_.socket);
     319            5 :     remoteEp_ = channelDesc_.remoteEndpoint;
     320            5 :     notifyNum_ = channelDesc_.notifyNum;
     321            5 :     commonRes_.bufferVec.clear();
     322            5 :     if (channelDesc_.exchangeAllMems) {
     323            3 :         HCCL_INFO("[AivUrmaChannel][%s] exchangeAllMems == true. Get memHandles from endpoint.", __func__);
     324            3 :         std::shared_ptr<Hccl::LocalUbRmaBuffer>* memHandles = nullptr;
     325            3 :         uint32_t memHandleNum = 0;
     326            3 :         CHK_RET(GetAllMemHandles(endpointHandle_, reinterpret_cast<void**>(&memHandles), &memHandleNum));
     327            2 :         HCCL_INFO("[AivUrmaChannel][%s] Got memHandleNum[%u].", __func__, memHandleNum);
     328            3 :         for (uint32_t i = 0; i < memHandleNum; ++i) {
     329            1 :             std::shared_ptr<Hccl::LocalUbRmaBuffer>& localUbRmaBuffer = memHandles[i];
     330            1 :             CHK_SMART_PTR_NULL(localUbRmaBuffer);
     331            1 :             Hccl::Buffer* buf = localUbRmaBuffer->GetBuf();
     332            1 :             CHK_PTR_NULL(buf);
     333            1 :             HCCL_INFO(
     334              :                 "[AivUrmaChannel][%s] Got memHandle No.%u: addr[0x%llx], size[0x%llx], memInfo[%s].", __func__, i,
     335              :                 localUbRmaBuffer->GetAddr(), localUbRmaBuffer->GetSize(), buf->GetMemInfo().c_str());
     336            1 :             commonRes_.bufferVec.push_back(localUbRmaBuffer.get());
     337              :         }
     338              :     } else {
     339            2 :         HCCL_INFO("[AivUrmaChannel][%s] exchangeAllMems == false. Get memHandles from channelDesc.", __func__);
     340            2 :         CHK_RET(MakeRmaBufferVecFromMemHandles(
     341              :             channelDesc_.memHandles, channelDesc_.memHandleNum, commonRes_.bufferVec, "AivUrmaChannel"));
     342              :     }
     343              : 
     344            4 :     return HCCL_SUCCESS;
     345              : }
     346              : 
     347            4 : HcclResult AivUrmaChannel::BuildSocket()
     348              : {
     349            4 :     if (socket_ != nullptr) {
     350            2 :         return HCCL_SUCCESS;
     351              :     }
     352            2 :     HCCL_INFO("[AivUrmaChannel][%s] socket ptr is NULL, rebuildSocket", __func__);
     353              : 
     354            2 :     Hccl::LinkData linkData = BuildDefaultLinkData();
     355            2 :     CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
     356            2 :     HCCL_INFO("[AivUrmaChannel][%s] built linkData: %s", __func__, linkData.Describe().c_str());
     357            2 :     uint16_t port = channelDesc_.port;
     358            2 :     if (port == 0) {
     359            0 :         port = DEFAULT_LISTENING_PORT;
     360            0 :         HCCL_INFO("[AivUrmaChannel::%s] channelDesc port is 0, use default port [%u]", __func__, port);
     361              :     }
     362              :     std::string socketTag
     363            6 :         = (channelDesc_.channelName != nullptr) ? std::string(channelDesc_.channelName) : "AUTOMATIC_SOCKET_TAG";
     364            2 :     if (channelDesc_.role == HCOMM_SOCKET_ROLE_RESERVED) {
     365            1 :         EXCEPTION_CATCH(
     366              :             socketConfigHolder_ = std::make_unique<Hccl::SocketConfig>(linkData, port, socketTag), return HCCL_E_PTR);
     367            1 :         socketConfigHolder_->noRankId = true;
     368              :     } else {
     369            1 :         bool isServer = (channelDesc_.role == HCOMM_SOCKET_ROLE_SERVER);
     370            1 :         EXCEPTION_CATCH(
     371              :             socketConfigHolder_ = std::make_unique<Hccl::SocketConfig>(linkData, port, socketTag, isServer),
     372              :             return HCCL_E_PTR);
     373              :     }
     374            2 :     socketConfig_ = socketConfigHolder_.get();
     375            2 :     CHK_RET(SocketMgr::GetInstance(devicePhyId_).GetSocket(*socketConfigHolder_, socket_));
     376            2 :     HCCL_INFO("[AivUrmaChannel::%s] SUCCESS. port[%u].", __func__, port);
     377            2 :     return HCCL_SUCCESS;
     378            2 : }
     379              : 
     380            5 : HcclResult AivUrmaChannel::StartListen()
     381              : {
     382            5 :     if (channelDesc_.role != HCOMM_SOCKET_ROLE_SERVER) {
     383            3 :         return HCCL_SUCCESS;
     384              :     }
     385              : 
     386            2 :     uint16_t port = channelDesc_.port;
     387            2 :     HCCL_INFO("[AivUrmaChannel::%s] Start. EndpointHandle[%p], port[%u]", __func__, endpointHandle_, port);
     388            2 :     if (port == 0) {
     389            1 :         port = DEFAULT_LISTENING_PORT;
     390            1 :         HCCL_INFO("[AivUrmaChannel::%s] channelDesc port is 0, use default port [%u]", __func__, port);
     391              :     }
     392            2 :     CHK_RET(static_cast<HcclResult>(HcommEndpointStartListen(endpointHandle_, port, nullptr)));
     393            2 :     HCCL_INFO("[AivUrmaChannel::%s] SUCCESS. port[%u].", __func__, port);
     394            2 :     return HCCL_SUCCESS;
     395              : }
     396              : 
     397            2 : HcclResult AivUrmaChannel::BuildAttr()
     398              : {
     399            2 :     attr_.devicePhyId = localEp_.loc.device.devPhyId;
     400            2 :     attr_.opMode = Hccl::OpMode::OPBASE;
     401            2 :     attr_.opAcceState = Hccl::AcceleratorState::AIV;
     402            2 :     return HCCL_SUCCESS;
     403              : }
     404              : 
     405            4 : HcclResult AivUrmaChannel::CreateUbConnectionByProtocol(
     406              :     const UbConnBuildContext& ctx, std::unique_ptr<Hccl::DevUbConnection>& ubConn)
     407              : {
     408            4 :     Hccl::OpMode opMode = Hccl::OpMode::OPBASE;
     409            4 :     bool devUsed = true;
     410            4 :     Hccl::HrtUbJfcMode jfcMode = Hccl::HrtUbJfcMode::USER_CTL;
     411            4 :     switch (ctx.protocol) {
     412            1 :         case Hccl::LinkProtocol::UB_TP:
     413            1 :             EXCEPTION_CATCH(
     414              :                 ubConn = std::make_unique<Hccl::DevUbTpConnection>(
     415              :                     rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode, Hccl::IpAddress(),
     416              :                     Hccl::IpAddress(), ctx.qosPre, COMM_ENGINE_AIV, ctx.sqDepth),
     417              :                 return HCCL_E_PTR);
     418            1 :             break;
     419            1 :         case Hccl::LinkProtocol::UB_CTP:
     420            1 :             EXCEPTION_CATCH(
     421              :                 ubConn = std::make_unique<Hccl::DevUbCtpConnection>(
     422              :                     rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode, Hccl::IpAddress(),
     423              :                     Hccl::IpAddress(), ctx.qosPre, COMM_ENGINE_AIV, ctx.sqDepth),
     424              :                 return HCCL_E_PTR);
     425            1 :             break;
     426            2 :         case Hccl::LinkProtocol::UB_RTP:
     427            2 :             EXCEPTION_CATCH(
     428              :                 ubConn = std::make_unique<Hccl::DevUbRtpConnection>(
     429              :                     rdmaHandle_, ctx.locAddr, ctx.rmtAddr, opMode, devUsed, jfcMode, ctx.locAddr, ctx.rmtAddr,
     430              :                     ctx.qosPre, COMM_ENGINE_AIV, ctx.sqDepth),
     431              :                 return HCCL_E_PTR);
     432            2 :             break;
     433            0 :         default:
     434            0 :             HCCL_ERROR("%s No LinkProtocol to match", __func__);
     435            0 :             break;
     436              :     }
     437            4 :     return HCCL_SUCCESS;
     438              : }
     439              : 
     440              : HcclResult
     441            0 : AivUrmaChannel::AcquireSharedJettyInBuildConnection(const UbConnBuildContext& ctx, Hccl::DevUbConnection* connection)
     442              : {
     443              :     // 共享 jetty 模式:复用同 Endpoint 下已创建的 jetty
     444            0 :     Endpoint* endpoint = reinterpret_cast<Endpoint*>(endpointHandle_);
     445            0 :     auto tempFactory = [rdmaHandle = rdmaHandle_, &ctxLoc = ctx.locAddr, &ctxRmt = ctx.rmtAddr, qosPre = ctx.qosPre,
     446            0 :                         protocol = ctx.protocol, sqDepth = ctx.sqDepth]() -> std::unique_ptr<Hccl::DevUbConnection> {
     447              :         // 与主 switch 保持对称的协议判断,避免 UB_RTP/未知协议误降级为 CTP
     448            0 :         switch (protocol) {
     449            0 :             case Hccl::LinkProtocol::UB_TP:
     450            0 :                 return std::make_unique<Hccl::DevUbTpConnection>(
     451            0 :                     rdmaHandle, ctxLoc, ctxRmt, Hccl::OpMode::OPBASE, true, Hccl::HrtUbJfcMode::USER_CTL,
     452            0 :                     Hccl::IpAddress(), Hccl::IpAddress(), qosPre, COMM_ENGINE_AIV, sqDepth);
     453            0 :             case Hccl::LinkProtocol::UB_CTP:
     454            0 :                 return std::make_unique<Hccl::DevUbCtpConnection>(
     455            0 :                     rdmaHandle, ctxLoc, ctxRmt, Hccl::OpMode::OPBASE, true, Hccl::HrtUbJfcMode::USER_CTL,
     456            0 :                     Hccl::IpAddress(), Hccl::IpAddress(), qosPre, COMM_ENGINE_AIV, sqDepth);
     457            0 :             default:
     458            0 :                 HCCL_ERROR(
     459              :                     "[AivUrmaChannel][tempFactory] unsupported protocol[%s], return nullptr.",
     460              :                     protocol.Describe().c_str());
     461            0 :                 return nullptr;
     462              :         }
     463            0 :     };
     464            0 :     Endpoint::SharedJettyCtx sharedCtx{};
     465            0 :     CHK_RET(hcomm::AcquireSharedJettyForChannel(endpoint, connection, tempFactory, sharedCtx));
     466              :     // 保存共享 PI/CI 指针,供 BuildChannelEntityToDevice 绑给 transport
     467            0 :     sharedSqPiPtr_ = sharedCtx.sqPiPtr;
     468            0 :     sharedSqCiPtr_ = sharedCtx.sqCiPtr;
     469            0 :     sharedCqPiPtr_ = sharedCtx.cqPiPtr;
     470            0 :     sharedCqCiPtr_ = sharedCtx.cqCiPtr;
     471            0 :     return HCCL_SUCCESS;
     472              : }
     473              : 
     474            4 : HcclResult AivUrmaChannel::BuildConnection()
     475              : {
     476            4 :     UbConnBuildContext ctx;
     477            4 :     CHK_RET(PrepareUbConnBuildContext(localEp_, remoteEp_, channelDesc_, ctx));
     478            4 :     CHK_RET(CheckUbSqDepth(ctx, devBaseAttr_));
     479              : 
     480            4 :     std::unique_ptr<Hccl::DevUbConnection> ubConn = nullptr;
     481            4 :     CHK_RET(CreateUbConnectionByProtocol(ctx, ubConn));
     482            4 :     CHK_SMART_PTR_NULL(ubConn);
     483              : 
     484              :     // 共享 jetty 模式:复用同 Endpoint 下已创建的 jetty。
     485              :     // 必须在 push_back(move(ubConn)) 之前调用:AcquireSharedJetty 失败时 ubConn 仍为局部变量,
     486              :     // 函数返回时自动析构,不会在 connections_/connVec 中残留不完整 connection。
     487            4 :     if (IsSharedJetty()) {
     488            0 :         CHK_RET(AcquireSharedJettyInBuildConnection(ctx, ubConn.get()));
     489              :     }
     490              : 
     491            4 :     commonRes_.connVec.clear();
     492            4 :     connections_.clear();
     493            4 :     commonRes_.connVec.emplace_back(ubConn.get());
     494            4 :     connections_.push_back(std::move(ubConn));
     495              : 
     496            4 :     return HCCL_SUCCESS;
     497            4 : }
     498              : 
     499            1 : HcclResult AivUrmaChannel::BuildAivUrmaTransport()
     500              : {
     501            1 :     const Hccl::Socket& socket = *socket_;
     502              : 
     503            1 :     Hccl::LinkData linkData = BuildDefaultLinkData();
     504            1 :     CHK_RET(EndpointDescPairToLinkData(localEp_, remoteEp_, linkData));
     505              : 
     506              :     // make_unique / make_shared / release 包一层抛异常的宏
     507            1 :     EXCEPTION_CATCH(
     508              :         transport_ = std::make_unique<Hccl::AivUrmaTransport>(
     509              :             commonRes_, attr_, linkData, socket, rdmaHandle_), // 这里区分是否是优先recv
     510              :         return HCCL_E_PTR);
     511            1 :     return HCCL_SUCCESS;
     512              : }
     513              : 
     514            5 : HcclResult AivUrmaChannel::BuildChannelEntityToDevice(void** devChannelPtr)
     515              : {
     516            5 :     if (devChannelPtr == nullptr) {
     517            1 :         HCCL_ERROR("[AivUrmaChannel] BuildChannelEntityToDevice devChannelPtr is nullptr");
     518            1 :         return HCCL_E_PTR;
     519              :     }
     520              : 
     521            4 :     CHK_PTR_NULL(transport_.get());
     522              : 
     523              :     ChannelEntity hostChannel;
     524            3 :     CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
     525              : 
     526            3 :     transport_->PrepareHostChannelEntity(&hostChannel);
     527              : 
     528            3 :     DeviceChannelEntityLayout layout;
     529            3 :     CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
     530            3 :     void* slabPtr = nullptr;
     531            3 :     AclDeviceSlabGuard slabGuard;
     532            3 :     CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
     533            2 :     uint32_t queueNum = std::max(hostChannel.sqNum, hostChannel.cqNum);
     534            2 :     if (IsSharedJetty() && sharedSqPiPtr_ != nullptr) {
     535              :         // 共享 jetty:PI/CI 用同 endpoint 下多 channel 共享的 device 内存,slab 内 PI/CI 段闲置不用。
     536              :         // 共享内存在首次 AcquireSharedJettyForChannel 时已分配并清零,此处直接绑给 transport。
     537            0 :         transport_->SetQueueIndexDeviceMem(
     538            0 :             sharedSqPiPtr_, sharedSqCiPtr_, sharedCqPiPtr_, sharedCqCiPtr_, queueNum * QUEUE_INDEX_MEM_UNIT_SIZE);
     539              :     } else {
     540            2 :         CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
     541            2 :         SetQueueIndexDeviceMem(*transport_, slabPtr, layout, queueNum);
     542              :     }
     543              : 
     544            2 :     CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
     545            2 :     transport_->GetHostChannelEntity(&hostChannel);
     546            2 :     hostChannel.abiHeader = channelDesc_.header;
     547            2 :     hostChannel.engine = COMM_ENGINE_AIV;
     548            2 :     hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
     549              : 
     550              :     ChannelEntity devChannel;
     551            2 :     CHK_RET(CopyChannelEntityToSlab(slabPtr, hostChannel, layout, devChannel));
     552            2 :     void* entityDevPtr = nullptr;
     553            2 :     CHK_RET(CopyChannelEntityHeaderToSlab(slabPtr, layout, devChannel, entityDevPtr));
     554            2 :     ReleaseDeviceChannelEntity();
     555            2 :     devChannelEntitySlab_ = slabGuard.Release();
     556            2 :     devChannelEntitySlabSize_ = layout.slabSize;
     557            2 :     devChannelEntity_ = entityDevPtr;
     558            2 :     *devChannelPtr = devChannelEntity_;
     559            2 :     HCCL_INFO(
     560              :         "[AivUrmaChannel] Build channel entity to device success, devPtr[%p], slabPtr[%p], slabSize[%zu]",
     561              :         devChannelEntity_, devChannelEntitySlab_, devChannelEntitySlabSize_);
     562            2 :     return HCCL_SUCCESS;
     563            3 : }
     564              : 
     565            6 : HcclResult AivUrmaChannel::PreAllocChannelEntityToDevice(void** devChannelPtr)
     566              : {
     567            6 :     if (devChannelPtr == nullptr) {
     568            1 :         HCCL_ERROR("[AivUrmaChannel::%s] devChannelPtr is nullptr", __func__);
     569            1 :         return HCCL_E_PTR;
     570              :     }
     571            5 :     CHK_PTR_NULL(transport_.get());
     572              : 
     573            4 :     if (devChannelEntitySlab_ != nullptr) {
     574            1 :         *devChannelPtr = devChannelEntity_;
     575            1 :         HCCL_INFO("[AivUrmaChannel::%s] already built, return cached devPtr[%p]", __func__, devChannelEntity_);
     576            1 :         return HCCL_SUCCESS;
     577              :     }
     578              : 
     579            3 :     uint32_t bufNum = 0;
     580            3 :     uint32_t connNum = 0;
     581            3 :     transport_->GetEntityCountsForLayout(bufNum, connNum);
     582              : 
     583            3 :     ChannelEntity tmp{};
     584            3 :     tmp.localBufferNum = bufNum;
     585            3 :     tmp.remoteBufferNum = bufNum;
     586            3 :     tmp.sqNum = connNum;
     587            3 :     tmp.cqNum = connNum;
     588              : 
     589            3 :     DeviceChannelEntityLayout layout;
     590            3 :     CHK_RET(BuildDeviceChannelEntityLayout(tmp, layout));
     591              : 
     592            3 :     void* slabPtr = nullptr;
     593            3 :     AclDeviceSlabGuard slabGuard;
     594            3 :     CHK_RET(AllocDeviceEntitySlab(layout.slabSize, slabGuard, slabPtr));
     595              : 
     596            3 :     uint32_t queueNum = std::max(tmp.sqNum, tmp.cqNum);
     597            3 :     if (IsSharedJetty() && sharedSqPiPtr_ != nullptr) {
     598              :         // 共享 jetty:PI/CI 用共享 device 内存,slab 内 PI/CI 段闲置不用(已在首次分配时清零)
     599            0 :         transport_->SetQueueIndexDeviceMem(
     600            0 :             sharedSqPiPtr_, sharedSqCiPtr_, sharedCqPiPtr_, sharedCqCiPtr_, queueNum * QUEUE_INDEX_MEM_UNIT_SIZE);
     601              :     } else {
     602            3 :         CHK_RET(InitQueueIndexSections(slabPtr, layout, queueNum));
     603              :     }
     604              : 
     605            3 :     devChannelEntitySlab_ = slabGuard.Release();
     606            3 :     devChannelEntitySlabSize_ = layout.slabSize;
     607            3 :     devChannelEntity_ = GetSlabPtr(devChannelEntitySlab_, layout.entitySection);
     608            3 :     if (!IsSharedJetty() || sharedSqPiPtr_ == nullptr) {
     609            3 :         SetQueueIndexDeviceMem(*transport_, devChannelEntitySlab_, layout, queueNum);
     610              :     }
     611            3 :     *devChannelPtr = devChannelEntity_;
     612              : 
     613            3 :     HCCL_INFO(
     614              :         "[AivUrmaChannel::%s] pre-alloc success, devPtr[%p], slabPtr[%p], slabSize[%zu]", __func__, devChannelEntity_,
     615              :         devChannelEntitySlab_, devChannelEntitySlabSize_);
     616            3 :     return HCCL_SUCCESS;
     617            3 : }
     618              : 
     619            2 : HcclResult AivUrmaChannel::FillChannelEntityToDevice()
     620              : {
     621            2 :     if (devChannelEntitySlab_ == nullptr) {
     622            1 :         HCCL_ERROR("[AivUrmaChannel::%s] devChannelEntitySlab_ is nullptr, not pre-allocated.", __func__);
     623            1 :         return HCCL_E_INTERNAL;
     624              :     }
     625            1 :     CHK_PTR_NULL(transport_.get());
     626              : 
     627              :     ChannelEntity hostChannel;
     628            1 :     CHK_RET(SecureMemset(&hostChannel, sizeof(ChannelEntity), 0, sizeof(ChannelEntity), "hostChannel"));
     629            1 :     transport_->GetHostChannelEntity(&hostChannel);
     630            1 :     hostChannel.abiHeader = channelDesc_.header;
     631            1 :     hostChannel.engine = COMM_ENGINE_AIV;
     632            1 :     hostChannel.protocol = channelDesc_.remoteEndpoint.protocol;
     633              : 
     634            1 :     DeviceChannelEntityLayout layout;
     635            1 :     CHK_RET(BuildDeviceChannelEntityLayout(hostChannel, layout));
     636            1 :     if (layout.slabSize > devChannelEntitySlabSize_) {
     637            0 :         HCCL_ERROR(
     638              :             "[AivUrmaChannel::%s] slabSize[%zu] > preAllocSize[%zu]", __func__, layout.slabSize,
     639              :             devChannelEntitySlabSize_);
     640            0 :         return HCCL_E_INTERNAL;
     641              :     }
     642              : 
     643              :     ChannelEntity devChannel;
     644            1 :     CHK_RET(CopyChannelEntityToSlab(devChannelEntitySlab_, hostChannel, layout, devChannel));
     645            1 :     void* entityDevPtr = nullptr;
     646            1 :     CHK_RET(CopyChannelEntityHeaderToSlab(devChannelEntitySlab_, layout, devChannel, entityDevPtr));
     647              : 
     648            1 :     devChannelEntity_ = entityDevPtr;
     649            1 :     HCCL_INFO("[AivUrmaChannel::%s] fill success, devPtr[%p]", __func__, devChannelEntity_);
     650            1 :     return HCCL_SUCCESS;
     651              : }
     652              : 
     653            1 : HcclResult AivUrmaChannel::GetNotifyNum([[maybe_unused]] uint32_t* notifyNum) const
     654              : {
     655            1 :     HCCL_INFO("AivUrmaChannel GetNotifyNum is not supported.");
     656            1 :     return HCCL_SUCCESS;
     657              : }
     658              : 
     659            0 : HcclResult AivUrmaChannel::GetRemoteMems(uint32_t* memNum, CommMem** remoteMem, char*** memInfos)
     660              : {
     661            0 :     return transport_->GetRemoteMems(memNum, remoteMem, memInfos);
     662              : }
     663              : 
     664            3 : HcclResult AivUrmaChannel::Clean()
     665              : {
     666            3 :     ReleaseDeviceChannelEntity();
     667            3 :     ReleasePtrArrayDevMems();
     668            3 :     transport_.reset();
     669            3 :     return HCCL_SUCCESS;
     670              : }
     671              : 
     672            1 : HcclResult AivUrmaChannel::Resume()
     673              : {
     674            1 :     BuildConnection();
     675            1 :     BuildAivUrmaTransport();
     676            1 :     return HCCL_SUCCESS;
     677              : }
     678              : 
     679            1 : HcclResult AivUrmaChannel::NotifyRecord([[maybe_unused]] const uint32_t remoteNotifyIdx)
     680              : {
     681            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     682            1 :     return HCCL_E_NOT_SUPPORT;
     683              : }
     684              : 
     685              : HcclResult
     686            1 : AivUrmaChannel::NotifyWait([[maybe_unused]] const uint32_t localNotifyIdx, [[maybe_unused]] const uint32_t timeout)
     687              : {
     688            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     689            1 :     return HCCL_E_NOT_SUPPORT;
     690              : }
     691              : 
     692            1 : HcclResult AivUrmaChannel::WriteWithNotify(
     693              :     [[maybe_unused]] void* dst, [[maybe_unused]] const void* src, [[maybe_unused]] const uint64_t len,
     694              :     [[maybe_unused]] uint32_t remoteNotifyIdx)
     695              : {
     696            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     697            1 :     return HCCL_E_NOT_SUPPORT;
     698              : }
     699              : 
     700              : HcclResult
     701            1 : AivUrmaChannel::Write([[maybe_unused]] void* dst, [[maybe_unused]] const void* src, [[maybe_unused]] uint64_t len)
     702              : {
     703            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     704            1 :     return HCCL_E_NOT_SUPPORT;
     705              : }
     706              : 
     707              : HcclResult
     708            1 : AivUrmaChannel::Read([[maybe_unused]] void* dst, [[maybe_unused]] const void* src, [[maybe_unused]] uint64_t len)
     709              : {
     710            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     711            1 :     return HCCL_E_NOT_SUPPORT;
     712              : }
     713              : 
     714            1 : HcclResult AivUrmaChannel::ChannelFence()
     715              : {
     716            1 :     HCCL_INFO("[AivUrmaChannel::%s] not supported yet.", __func__);
     717            1 :     return HCCL_E_NOT_SUPPORT;
     718              : }
     719              : 
     720            3 : HcclResult AivUrmaChannel::Init()
     721              : {
     722              :     /*
     723              :         Argue result: make_unique 配合一场捕获的宏 EXCEPTION CATCH
     724              :         Attention: const 和引用
     725              :     */
     726            3 :     CHK_RET(ParseInputParam());
     727            2 :     CHK_RET(StartListen());
     728            2 :     CHK_RET(BuildSocket());
     729            2 :     CHK_RET(BuildAttr());
     730              : 
     731            2 :     CHK_RET(HccpRaGetDevBaseAttr(rdmaHandle_, &devBaseAttr_));
     732            2 :     CHK_RET(BuildConnection());
     733            2 :     CHK_RET(BuildAivUrmaTransport());
     734            2 :     return HCCL_SUCCESS;
     735              : }
     736              : 
     737            1 : ChannelStatus AivUrmaChannel::GetStatus()
     738              : {
     739            1 :     Hccl::TransportStatus transportStatus = transport_->GetStatus();
     740            1 :     ChannelStatus out = ChannelStatus::INIT;
     741            1 :     switch (transportStatus) {
     742            0 :         case Hccl::TransportStatus::INIT:
     743            0 :             out = ChannelStatus::INIT;
     744            0 :             break;
     745            0 :         case Hccl::TransportStatus::SOCKET_OK:
     746            0 :             out = ChannelStatus::SOCKET_OK;
     747            0 :             break;
     748            1 :         case Hccl::TransportStatus::SOCKET_TIMEOUT:
     749            1 :             out = ChannelStatus::SOCKET_TIMEOUT;
     750            1 :             break;
     751            0 :         case Hccl::TransportStatus::READY:
     752            0 :             out = ChannelStatus::READY;
     753            0 :             break;
     754            0 :         default:
     755            0 :             HCCL_ERROR("[AivUrmaChannel][%s] Invalid TransportStatus[%d]", __func__, transportStatus);
     756            0 :             out = ChannelStatus::INVALID;
     757            0 :             break;
     758              :     }
     759            1 :     return out;
     760              : }
     761              : 
     762              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1