LCOV - code coverage report
Current view: top level - base_comm/primitives/api_c_adpt - hcomm_channel_c_adpt.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.6 % 359 239
Test Date: 2026-08-25 19:18:03 Functions: 64.3 % 28 18

            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 <cstring>
      12              : #include <chrono>
      13              : #include <vector>
      14              : 
      15              : #include "hcomm_c_adpt.h"
      16              : #include "hcomm_c_adpt_common.h"
      17              : #include "hcomm_res.h"
      18              : #include "hcomm_result_defs.h"
      19              : #include "hcomm_res_defs.h"
      20              : #include "hcomm_channel.h"
      21              : #include "log.h"
      22              : #include "param_check_pub.h"
      23              : #include "comm_engine_utils.h"
      24              : #include "channel_process.h"
      25              : #include "aicpu_ts_channel_helper.h"
      26              : #include "channel_config.h"
      27              : #include "shared_jetty_mgr.h"
      28              : #include "endpoint.h"
      29              : #include "builtin_endpoint_ops.h"
      30              : #include "nic_plugin_holder.h"
      31              : #include "nic_plugin_manager.h"
      32              : #include "acl/acl_rt.h"
      33              : #include "adapter_rts_common.h"
      34              : #include "tp_qos.h"
      35              : #include "hccl/hccl_types.h"
      36              : 
      37              : using namespace hcomm;
      38              : 
      39              : constexpr uint32_t kDscpToRoceTcShift = 2U; // RoCE TC = DSCP << 2(DiffServ 高 6 位为 DSCP)
      40              : 
      41            7 : static void ApplyRoceQosCompatToSlTc(HcommChannelDesc& channelDesc)
      42              : {
      43            7 :     if (channelDesc.qos == HCCL_COMM_QOS_CONFIG_NOT_SET) {
      44            3 :         return;
      45              :     }
      46              : 
      47            4 :     const uint8_t sl = static_cast<uint8_t>(channelDesc.qos & 0xFFU);
      48            4 :     uint8_t dscp = Hccl::kUboeDefaultDscp;
      49            4 :     s32 userDevId = 0;
      50            4 :     s32 phyDevId = 0;
      51            4 :     if (hrtGetDevice(&userDevId) != HCCL_SUCCESS || aclrtGetPhyDevIdByUserDevId(userDevId, &phyDevId) != ACL_SUCCESS) {
      52            0 :         HCCL_WARNING(
      53              :             "[ApplyRoceQosCompatToSlTc] get phyDevId failed, userDevId[%d], fallback to default dscp[%u].", userDevId,
      54              :             static_cast<unsigned>(dscp));
      55              :     } else {
      56            4 :         (void)Hccl::TpQosGetDscpByQosFromHccnCfg(static_cast<uint32_t>(phyDevId), sl, dscp);
      57              :     }
      58              : 
      59            4 :     channelDesc.roceAttr.sl = sl;
      60            4 :     channelDesc.roceAttr.tc = static_cast<uint8_t>((static_cast<uint32_t>(dscp) << kDscpToRoceTcShift) & 0xFFU);
      61            4 :     HCCL_INFO(
      62              :         "[ApplyRoceQosCompatToSlTc] qos compat: qos[%u] userDevId[%d] phyDevId[%d] dscp[%u] sl[%u] tc[%u].",
      63              :         channelDesc.qos, userDevId, phyDevId, static_cast<unsigned>(dscp),
      64              :         static_cast<unsigned>(channelDesc.roceAttr.sl), static_cast<unsigned>(channelDesc.roceAttr.tc));
      65              : }
      66              : 
      67              : namespace {
      68            0 : void DestroyPluginCtx(HcommNicChannelOps* ops, void* pluginCtx)
      69              : {
      70            0 :     if (ops != nullptr && ops->destroy != nullptr) {
      71            0 :         int32_t ret = ops->destroy(pluginCtx);
      72            0 :         if (ret != HCCL_SUCCESS) {
      73            0 :             HCCL_WARNING("[%s] plugin channel destroy failed, ret[%d].", __func__, ret);
      74              :         }
      75              :     }
      76            0 : }
      77              : 
      78            0 : void RollbackPluginChannels(ChannelHandle* channels, uint32_t count)
      79              : {
      80            0 :     for (uint32_t i = 0; i < count; ++i) {
      81            0 :         if (channels[i] == 0)
      82            0 :             continue;
      83            0 :         auto* ch = CHANNEL_FROM_HANDLE(channels[i]);
      84            0 :         if (ch != nullptr) {
      85            0 :             HcclResult ret = ChannelProcess::RemovePluginChannelFromMap(reinterpret_cast<ChannelHandle>(ch));
      86            0 :             if (ret != HCCL_SUCCESS) {
      87            0 :                 HCCL_WARNING(
      88              :                     "[%s] plugin channel not found in map during rollback, handle[0x%llx], ret[%d].", __func__,
      89              :                     channels[i], ret);
      90              :             }
      91              :         }
      92            0 :         channels[i] = 0;
      93              :     }
      94            0 : }
      95              : 
      96            2 : HcommResult CreateOnePluginChannel(
      97              :     const NicPluginEntry* entry, void* epCtx, HcommChannelDesc* channelDesc, ChannelHandle* outChannel)
      98              : {
      99            2 :     *outChannel = 0;
     100              : 
     101            2 :     void* pluginCtx = nullptr;
     102            2 :     HcommNicChannelOps* pluginOps = nullptr;
     103            2 :     HcommResult ret = static_cast<HcommResult>(entry->createChannel(epCtx, channelDesc, &pluginCtx, &pluginOps));
     104            2 :     CHK_PRT_RET(
     105              :         (ret != HCCL_SUCCESS), HCCL_ERROR("[NicPlugin][%s] createChannel failed, ret[%d].", __func__, ret), ret);
     106              : 
     107            2 :     if (!ValidateChannelOps(pluginOps)) {
     108            0 :         HCCL_ERROR("[NicPlugin][%s] invalid channel ops.", __func__);
     109            0 :         DestroyPluginCtx(pluginOps, pluginCtx);
     110            0 :         return HCCL_E_INTERNAL;
     111              :     }
     112              : 
     113            2 :     HcommNicChannelOps* filledOps = nullptr;
     114            2 :     ret = FillDefaultChannelOps(pluginOps, &filledOps);
     115            2 :     if (ret != HCCL_SUCCESS) {
     116            0 :         HCCL_ERROR("[NicPlugin][%s] FillDefaultChannelOps failed, ret[%d].", __func__, ret);
     117            0 :         DestroyPluginCtx(pluginOps, pluginCtx);
     118            0 :         return ret;
     119              :     }
     120              : 
     121            2 :     ret = static_cast<HcommResult>(filledOps->init(pluginCtx));
     122            2 :     if (ret != HCCL_SUCCESS) {
     123            0 :         int32_t destroyRet = filledOps->destroy(pluginCtx);
     124            0 :         if (destroyRet != HCCL_SUCCESS) {
     125            0 :             HCCL_WARNING("[%s] plugin channel destroy failed after init failure, ret[%d].", __func__, destroyRet);
     126              :         }
     127            0 :         delete filledOps;
     128            0 :         HCCL_ERROR("[NicPlugin][%s] plugin channel init failed, ret[%d].", __func__, ret);
     129            0 :         return ret;
     130              :     }
     131              : 
     132            2 :     auto holder = std::make_shared<hcomm::PluginChannelHolder>(entry);
     133            2 :     holder->SetNicChannelCtx(filledOps, pluginCtx);
     134            2 :     ChannelHandle handle = reinterpret_cast<ChannelHandle>(holder.get());
     135              : 
     136            2 :     ret = static_cast<HcommResult>(ChannelProcess::InsertPluginChannelToMap(handle, std::move(holder)));
     137            2 :     CHK_PRT_RET(
     138              :         (ret != HCCL_SUCCESS), HCCL_ERROR("[NicPlugin][%s] InsertChannelToMap failed, ret[%d].", __func__, ret), ret);
     139              : 
     140            2 :     *outChannel = MAKE_PLUGIN_CH_HANDLE(handle);
     141            2 :     HCCL_INFO("[%s] plugin channel created, handle[0x%llx].", __func__, handle);
     142            2 :     return HCCL_SUCCESS;
     143            2 : }
     144              : 
     145              : } // namespace
     146              : 
     147           48 : HcommResult CheckUbAttr(HcommChannelDesc& channelDesc, [[maybe_unused]] CommEngine engine)
     148              : {
     149           48 :     if (channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBC_TP
     150           47 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBOE
     151           47 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UB_RTP
     152           47 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UB_CTP) {
     153           24 :         return HCCL_SUCCESS;
     154              :     }
     155              : 
     156              :     // 暂不支持UBOE场景下配置SqDepth
     157           24 :     if (channelDesc.remoteEndpoint.protocol == COMM_PROTOCOL_UBOE) {
     158            0 :         return HCCL_SUCCESS;
     159              :     }
     160              : 
     161              :     // check sqDepth
     162           24 :     if (channelDesc.ubAttr.sqDepth == UB_SQ_DEPTH_NOT_SET) {
     163           16 :         HCCL_INFO("[%s] use default ubAttr.sqDepth.", __func__);
     164           16 :         return HCCL_SUCCESS;
     165              :     }
     166              : 
     167              :     // channelDesc.ubAttr.sqDepth调整到2的整数次幂
     168            8 :     auto GetNextPowerOfTwo = [](uint32_t n) -> uint32_t {
     169            8 :         n--;
     170            8 :         n |= n >> 1;
     171            8 :         n |= n >> 2;
     172            8 :         n |= n >> 4;
     173            8 :         n |= n >> 8;
     174            8 :         n |= n >> 16;
     175            8 :         return n + 1;
     176              :     };
     177              : 
     178            8 :     channelDesc.ubAttr.sqDepth = GetNextPowerOfTwo(channelDesc.ubAttr.sqDepth);
     179              : 
     180            8 :     return HCCL_SUCCESS;
     181              : }
     182              : 
     183           47 : HcommResult CheckUbMemAttr(HcommChannelDesc& channelDesc)
     184              : {
     185           47 :     if (channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UB_MEM) {
     186           28 :         return HCOMM_SUCCESS;
     187              :     }
     188              : 
     189           19 :     if (channelDesc.ubMemAttr.pathMode == 0xFF) {
     190            1 :         HCCL_INFO("[%s] use default ubMemAttr.pathMode, set to 0.", __func__);
     191            1 :         channelDesc.ubMemAttr.pathMode = 0;
     192            1 :         return HCOMM_SUCCESS;
     193              :     }
     194              : 
     195           18 :     if (channelDesc.ubMemAttr.pathMode > 2) {
     196            3 :         HCCL_ERROR("[%s] invalid ubMemAttr.pathMode[%u], should be 0 ~ 2.", __func__, channelDesc.ubMemAttr.pathMode);
     197            3 :         return HCCL_E_PARA;
     198              :     }
     199           15 :     return HCOMM_SUCCESS;
     200              : }
     201              : 
     202           46 : HcommResult CheckRoceAttr(HcommChannelDesc& channelDesc)
     203              : {
     204           46 :     if (channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_ROCE) {
     205           39 :         return HCCL_SUCCESS;
     206              :     }
     207              : 
     208            7 :     if (channelDesc.roceAttr.queueNum == INVALID_UINT) {
     209            3 :         channelDesc.roceAttr.queueNum = 1;
     210            3 :         HCCL_INFO("[%s] set roceAttr.queueNum to 1.", __func__);
     211              :     }
     212              : 
     213            7 :     if (channelDesc.roceAttr.cqAttrFlags == INVALID_UINT) {
     214            7 :         channelDesc.roceAttr.cqAttrFlags = 0;
     215            7 :         HCCL_INFO("[%s] set roceAttr.cqAttrFlags to 0.", __func__);
     216              :     }
     217              : 
     218            7 :     ApplyRoceQosCompatToSlTc(channelDesc);
     219              : 
     220            7 :     return HCCL_SUCCESS;
     221              : }
     222              : 
     223              : namespace {
     224           40 : void ApplyHcommChannelDescV1Fields(const HcommChannelDesc& channelDesc, HcommChannelDesc& channelDescFinal)
     225              : {
     226           40 :     if (channelDesc.header.version < HCOMM_CHANNEL_VERSION_ONE) {
     227            0 :         return;
     228              :     }
     229              : 
     230           40 :     channelDescFinal.remoteEndpoint = channelDesc.remoteEndpoint;
     231           40 :     channelDescFinal.notifyNum = channelDesc.notifyNum;
     232           40 :     channelDescFinal.exchangeAllMems = channelDesc.exchangeAllMems;
     233           40 :     channelDescFinal.memHandles = channelDesc.memHandles;
     234           40 :     channelDescFinal.memHandleNum = channelDesc.memHandleNum;
     235           40 :     channelDescFinal.socket = channelDesc.socket;
     236           40 :     channelDescFinal.role = channelDesc.role;
     237           40 :     channelDescFinal.port = channelDesc.port;
     238              : }
     239              : 
     240           40 : HcommResult ProcessHcommChannelDescs(const HcommChannelDesc& channelDesc, HcommChannelDesc& channelDescFinal)
     241              : {
     242           40 :     if (channelDesc.header.size < sizeof(CommAbiHeader)) {
     243            0 :         HCCL_ERROR("[%s] invalid channelDesc.header.size[%u].", __func__, channelDesc.header.size);
     244            0 :         return HCCL_E_PARA;
     245              :     }
     246              : 
     247           40 :     if (channelDesc.header.magicWord != channelDescFinal.header.magicWord) {
     248            0 :         HCCL_ERROR(
     249              :             "[%s] channelDesc.header.magicWord[0x%08x] is invalid, expected[0x%08x].", __func__,
     250              :             channelDesc.header.magicWord, channelDescFinal.header.magicWord);
     251            0 :         return HCCL_E_PARA;
     252              :     }
     253              : 
     254           40 :     const uint32_t copySize = (channelDescFinal.header.size < channelDesc.header.size ? channelDescFinal.header.size :
     255           40 :                                                                                         channelDesc.header.size)
     256            0 :                               - sizeof(CommAbiHeader);
     257           40 :     CHK_SAFETY_FUNC_RET(memcpy_s(
     258              :         reinterpret_cast<uint8_t*>(&channelDescFinal) + sizeof(CommAbiHeader), copySize,
     259              :         reinterpret_cast<const uint8_t*>(&channelDesc) + sizeof(CommAbiHeader), copySize));
     260           40 :     ApplyHcommChannelDescV1Fields(channelDesc, channelDescFinal);
     261           40 :     if (channelDesc.header.version > HCOMM_CHANNEL_VERSION) {
     262            0 :         HCCL_RUN_WARNING(
     263              :             "The version of provided [%u] is higher than the current version[%u], "
     264              :             "unsupported configuration will be ignored.",
     265              :             channelDesc.header.version, HCOMM_CHANNEL_VERSION);
     266           40 :     } else if (channelDesc.header.version < HCOMM_CHANNEL_VERSION) {
     267            1 :         HCCL_RUN_WARNING(
     268              :             "The version of provided [%u] is lower than the current version[%u], "
     269              :             "configurations supported by later versions will be ignored.",
     270              :             channelDesc.header.version, HCOMM_CHANNEL_VERSION);
     271              :     }
     272              : 
     273              :     // qos:低版本时置默认值
     274           40 :     if (channelDesc.header.version <= HCOMM_CHANNEL_VERSION_ONE) {
     275            1 :         channelDescFinal.qos = 0xFFFFFFFFU;
     276              :     } else {
     277           39 :         channelDescFinal.qos = channelDesc.qos;
     278              :     }
     279              : 
     280              :     // v3:channelName,低版本时置 NULL
     281           40 :     constexpr uint32_t HCOMM_CHANNEL_VERSION_THREE = 3U;
     282           40 :     if (channelDesc.header.version < HCOMM_CHANNEL_VERSION_THREE) {
     283            1 :         channelDescFinal.channelName = nullptr;
     284              :     } else {
     285           39 :         channelDescFinal.channelName = channelDesc.channelName;
     286           39 :         if (channelDescFinal.channelName != nullptr
     287            1 :             && reinterpret_cast<uintptr_t>(channelDescFinal.channelName) == static_cast<uintptr_t>(-1)) {
     288            0 :             channelDescFinal.channelName = nullptr;
     289              :         }
     290              :     }
     291              : 
     292           40 :     if (channelDescFinal.channelName != nullptr) {
     293            1 :         size_t nameLen = strnlen(channelDescFinal.channelName, HCOMM_CHANNEL_NAME_MAX_LEN + 1);
     294            1 :         if (nameLen > HCOMM_CHANNEL_NAME_MAX_LEN) {
     295            0 :             HCCL_ERROR("[%s] channelName too long, max len[%u].", __func__, HCOMM_CHANNEL_NAME_MAX_LEN);
     296            0 :             return HCCL_E_PARA;
     297              :         }
     298              :     }
     299              : 
     300              :     // v4:roceAttr.srcPortList,低版本时 union 内该位置为脏数据,置 NULL
     301           40 :     if (channelDesc.header.version < HCOMM_CHANNEL_VERSION) {
     302            1 :         channelDescFinal.roceAttr.srcPortList = nullptr;
     303              :     } else {
     304           39 :         channelDescFinal.roceAttr.srcPortList = channelDesc.roceAttr.srcPortList;
     305              :     }
     306              : 
     307           40 :     return HCOMM_SUCCESS;
     308              : }
     309              : 
     310           40 : HcommResult NormalizeHcommChannelDescs(
     311              :     HcommChannelDesc* channelDescs, uint32_t channelNum, std::vector<HcommChannelDesc>& channelDescFinals,
     312              :     CommEngine engine)
     313              : {
     314           40 :     channelDescFinals.clear();
     315           40 :     channelDescFinals.reserve(channelNum);
     316           80 :     for (uint32_t idx = 0; idx < channelNum; ++idx) {
     317           40 :         HcommChannelDesc channelDescFinal{};
     318           40 :         HcommResult ret = HcommChannelDescInit(&channelDescFinal, 1);
     319           40 :         if (ret != HCOMM_SUCCESS) {
     320            0 :             return ret;
     321              :         }
     322           40 :         ret = ProcessHcommChannelDescs(channelDescs[idx], channelDescFinal);
     323           40 :         if (ret != HCOMM_SUCCESS) {
     324            0 :             HCCL_ERROR("[%s] failed to normalize channelDesc[%u], ret[%d].", __func__, idx, ret);
     325            0 :             return ret;
     326              :         }
     327           40 :         ret = CheckUbAttr(channelDescFinal, engine);
     328           40 :         if (ret != HCOMM_SUCCESS) {
     329            0 :             HCCL_ERROR("[%s] CheckUbAttr failed, ret[%d].", __func__, ret);
     330            0 :             return ret;
     331              :         }
     332           40 :         ret = CheckUbMemAttr(channelDescFinal);
     333           40 :         if (ret != HCOMM_SUCCESS) {
     334            0 :             HCCL_ERROR("[%s] CheckUbMemAttr failed, ret[%d].", __func__, ret);
     335            0 :             return ret;
     336              :         }
     337           40 :         ret = CheckRoceAttr(channelDescFinal);
     338           40 :         if (ret != HCOMM_SUCCESS) {
     339            0 :             HCCL_ERROR("[%s] CheckRoceAttr failed, ret[%d].", __func__, ret);
     340            0 :             return ret;
     341              :         }
     342              : 
     343           40 :         channelDescFinals.push_back(channelDescFinal);
     344              :     }
     345           40 :     return HCOMM_SUCCESS;
     346              : }
     347              : } // namespace
     348              : 
     349              : // 集合通信使用,待归一到HcommChannelCreate
     350           22 : HcommResult HcommCollectiveChannelCreate(
     351              :     EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc* channelDescs, uint32_t channelNum,
     352              :     ChannelHandle* channels)
     353              : {
     354           22 :     CHK_PTR_NULL(channelDescs);
     355           20 :     CHK_PTR_NULL(channels);
     356           20 :     CHK_PRT_RET(
     357              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     358           18 :     std::vector<HcommChannelDesc> channelDescFinals;
     359           18 :     CHK_RET(static_cast<HcclResult>(NormalizeHcommChannelDescs(channelDescs, channelNum, channelDescFinals, engine)));
     360           18 :     auto startut = std::chrono::steady_clock::now();
     361           18 :     HCCL_INFO(
     362              :         "[%s] START. endpointHandle[0x%llx], engine[%s], channelNum[%u].", __func__, endpointHandle,
     363              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum);
     364              :     HcommResult ret
     365           18 :         = ChannelProcess::CreateChannelsLoop(endpointHandle, engine, channelDescFinals.data(), channelNum, channels);
     366           18 :     HCCL_INFO(
     367              :         "[%s] END. channelNum[%u], take time [%lld]us.", __func__, channelNum,
     368              :         std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startut).count());
     369           18 :     return ret;
     370           18 : }
     371              : 
     372            0 : HcommResult HcommChannelUpdateMemInfo(HcommMemHandle* memHandles, uint32_t memHandleNum, ChannelHandle channelHandle)
     373              : {
     374            0 :     CHK_PTR_NULL(memHandles);
     375            0 :     CHK_PRT_RET((memHandleNum == 0), HCCL_ERROR("[%s]Invalid memHandleNum, memHandleNum is 0.", __func__), HCCL_E_PARA);
     376            0 :     return ChannelProcess::ChannelUpdateMemInfo(memHandles, memHandleNum, channelHandle);
     377              : }
     378              : 
     379            2 : HcommResult CreatePluginChannels(
     380              :     hcomm::Endpoint* endpoint, HcommChannelDesc* channelDescs, uint32_t channelNum, ChannelHandle* channels)
     381              : {
     382            2 :     auto* epHolder = dynamic_cast<hcomm::PluginEndpointHolder*>(endpoint);
     383            2 :     CHK_PTR_NULL(epHolder);
     384            2 :     const NicPluginEntry* entry = epHolder->GetPluginEntry();
     385            2 :     CHK_PTR_NULL(entry);
     386            2 :     void* epCtx = endpoint->GetNicCtx();
     387              : 
     388            4 :     for (uint32_t idx = 0; idx < channelNum; ++idx) {
     389            2 :         HcommResult ret = CreateOnePluginChannel(entry, epCtx, &channelDescs[idx], &channels[idx]);
     390            2 :         if (ret != HCCL_SUCCESS) {
     391            0 :             (void)RollbackPluginChannels(channels, idx);
     392            0 :             return ret;
     393              :         }
     394              :     }
     395              : 
     396            2 :     return HCCL_SUCCESS;
     397              : }
     398              : 
     399           27 : HcommResult HcommChannelCreate(
     400              :     EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc* channelDescs, uint32_t channelNum,
     401              :     ChannelHandle* channels)
     402              : {
     403           27 :     CHK_PTR_NULL(endpointHandle);
     404           24 :     CHK_PTR_NULL(channelDescs);
     405           23 :     CHK_PTR_NULL(channels);
     406           23 :     CHK_PRT_RET(
     407              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     408           22 :     std::vector<HcommChannelDesc> channelDescFinals;
     409           22 :     CHK_RET(static_cast<HcclResult>(NormalizeHcommChannelDescs(channelDescs, channelNum, channelDescFinals, engine)));
     410           22 :     auto endpoint = GetEndpointMap().GetEndpoint(endpointHandle);
     411           22 :     auto startut = std::chrono::steady_clock::now();
     412           22 :     HCCL_INFO(
     413              :         "[%s] START. endpointHandle[0x%llx], engine[%s], channelNum[%u].", __func__, endpointHandle,
     414              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum);
     415           22 :     if (endpoint != nullptr && endpoint->GetNicOps() != nullptr && endpoint->GetNicOps() != &g_BuiltinEndpointOps) {
     416            2 :         CHK_RET(
     417              :             static_cast<HcclResult>(CreatePluginChannels(endpoint, channelDescFinals.data(), channelNum, channels)));
     418            2 :         HCCL_INFO(
     419              :             "[%s] END. channelNum[%u], take time [%lld]us.", __func__, channelNum,
     420              :             std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startut).count());
     421            2 :         return HCCL_SUCCESS;
     422              :     }
     423           20 :     (void)HcommResMgrInit();
     424           20 :     if (endpoint != nullptr) {
     425           18 :         CHK_RET(RefreshEndpointContext(endpoint->GetEndpointDesc()));
     426              :     }
     427           20 :     std::vector<ChannelHandle> hostChannelHandles(channelNum);
     428           20 :     ChannelHandle* targetChannels = hostChannelHandles.data();
     429           20 :     CHK_RET(ChannelProcess::CreateChannelsLoop(
     430              :         endpointHandle, engine, channelDescFinals.data(), channelNum, targetChannels));
     431           20 :     CHK_RET(
     432              :         ChannelProcess::PrepareUserChannels(targetChannels, channels, channelDescFinals.data(), channelNum, engine));
     433           19 :     HCCL_INFO(
     434              :         "[%s] END. channelNum[%u], take time [%lld]us.", __func__, channelNum,
     435              :         std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startut).count());
     436           19 :     HCCL_RUN_INFO(
     437              :         "[%s] channels created, channelNum[%u], engine[%s]", __func__, channelNum,
     438              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     439           19 :     return HCCL_SUCCESS;
     440           22 : }
     441              : 
     442           59 : HcommResult HcommChannelGet(ChannelHandle channelHandle, void** channel)
     443              : {
     444           59 :     CHK_PTR_NULL(channel);
     445           58 :     return ChannelProcess::ChannelGet(channelHandle, channel);
     446              : }
     447              : 
     448           36 : HcommResult HcommChannelGetStatus(const ChannelHandle* channelList, uint32_t listNum, int32_t* statusList)
     449              : {
     450           36 :     CHK_PTR_NULL(channelList);
     451           34 :     CHK_PTR_NULL(statusList);
     452           32 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     453              : 
     454           30 :     if (IS_PLUGIN_HANDLE(channelList[0])) {
     455            3 :         for (uint32_t i = 0; i < listNum; i++) {
     456            2 :             auto* ch = CHANNEL_FROM_HANDLE(channelList[i]);
     457            3 :             CHK_PTR_NULL(ch);
     458            2 :             int32_t status = 0;
     459            2 :             HcommResult ret = static_cast<HcommResult>(ch->GetNicOps()->getStatus(ch->GetNicCtx(), &status));
     460            2 :             if (ret != HCCL_SUCCESS) {
     461            1 :                 HCCL_ERROR("[%s] plugin getStatus failed, idx[%u], ret[%d].", __func__, i, ret);
     462            1 :                 return ret;
     463              :             }
     464            1 :             statusList[i] = status;
     465              :         }
     466            1 :         return HCCL_SUCCESS;
     467              :     } else {
     468           28 :         (void)HcommResMgrInit();
     469           28 :         std::vector<CommEngine> engines;
     470           28 :         std::vector<HcommChannelDesc> channelDescFinals;
     471           28 :         std::vector<ChannelStatus> internalStatus(listNum);
     472           28 :         auto startut = std::chrono::steady_clock::now();
     473              :         HcclResult ret
     474           28 :             = ChannelProcess::GetChannelsInfo(channelList, listNum, engines, channelDescFinals, internalStatus);
     475           28 :         if (ret != HCCL_SUCCESS) {
     476            2 :             HCCL_ERROR("[%s] GetChannelsInfo failed, ret[%d]", __func__, ret);
     477            2 :             return HCCL_E_INTERNAL;
     478              :         }
     479           26 :         ret = ChannelProcess::HandleStatusByEngine(
     480              :             channelList, listNum, engines, channelDescFinals, internalStatus, statusList);
     481           26 :         if (ret != HCCL_SUCCESS) {
     482            0 :             HCCL_ERROR("[%s] HandleStatusByEngine failed, ret[%d]", __func__, ret);
     483            0 :             return HCCL_E_INTERNAL;
     484              :         }
     485           26 :         HCCL_INFO(
     486              :             "[%s] END. listNum[%u], take time [%lld]us.", __func__, listNum,
     487              :             std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - startut).count());
     488           26 :         return HCCL_SUCCESS;
     489           28 :     }
     490              : }
     491              : 
     492            2 : HcommResult HcommChannelGetNotifyNum(ChannelHandle channelHandle, uint32_t* notifyNum)
     493              : {
     494            2 :     CHK_PTR_NULL(notifyNum);
     495            1 :     return ChannelProcess::ChannelGetNotifyNum(channelHandle, notifyNum);
     496              : }
     497              : 
     498           19 : static HcclResult DestroyBuiltinChannels(std::vector<ChannelHandle>& builtinChannels)
     499              : {
     500              :     // 即使 plugin channel 销毁失败,也需继续销毁 builtin channel,避免 RDMA/jetty 资源泄漏
     501              :     // 及 SharedJettyMgr 残留记录永久阻塞 Endpoint 销毁。最终返回首个错误(优先 plugin 错误)。
     502           19 :     HcclResult builtinRet = HCCL_SUCCESS;
     503           19 :     if (builtinChannels.empty()) {
     504            0 :         return builtinRet;
     505              :     }
     506           38 :     builtinRet = ChannelProcess::ChannelDestroy(
     507           19 :         builtinChannels.data(), builtinChannels.size(), AicpuTsChannelHelper::GetBinHandle());
     508              :     // 无论 ChannelDestroy 成功与否都注销 SharedJettyMgr 记录:
     509              :     // 成功时正常清理;失败时 channel 已不可用,若不注销会永久阻塞 Endpoint 销毁。
     510           19 :     if (builtinRet != HCCL_SUCCESS) {
     511            0 :         HCCL_WARNING(
     512              :             "[%s] ChannelDestroy failed, ret[%d], force unregister shared jetty channels.", __func__, builtinRet);
     513              :     }
     514           19 :     (void)hcomm::SharedJettyMgr::GetInstance().UnregisterChannels(builtinChannels.data(), builtinChannels.size());
     515           19 :     return builtinRet;
     516              : }
     517              : 
     518           23 : HcommResult HcommChannelDestroy(const ChannelHandle* channels, uint32_t channelNum)
     519              : {
     520           23 :     CHK_PTR_NULL(channels);
     521           22 :     CHK_PRT_RET(
     522              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     523           21 :     if (IS_PLUGIN_HANDLE(channels[0])) {
     524            4 :         for (uint32_t idx = 0; idx < channelNum; ++idx) {
     525            2 :             auto* ch = CHANNEL_FROM_HANDLE(channels[idx]);
     526            2 :             HcclResult ret = ChannelProcess::RemovePluginChannelFromMap(reinterpret_cast<ChannelHandle>(ch));
     527            2 :             if (ret != HCCL_SUCCESS) {
     528            0 :                 HCCL_WARNING(
     529              :                     "[%s] plugin channel not found in map during destroy, handle[0x%llx], ret[%d].", __func__,
     530              :                     channels[idx], ret);
     531              :             }
     532              :         }
     533            2 :         return HCCL_SUCCESS;
     534              :     }
     535           19 :     (void)HcommResMgrInit();
     536           19 :     std::vector<ChannelHandle> builtinChannels;
     537           19 :     builtinChannels.reserve(channelNum);
     538           39 :     for (uint32_t idx = 0; idx < channelNum; ++idx) {
     539           20 :         builtinChannels.push_back(channels[idx]);
     540              :     }
     541           19 :     return static_cast<HcommResult>(DestroyBuiltinChannels(builtinChannels));
     542           19 : }
     543              : 
     544            0 : HcommResult HcommChannelConfigCreate(HcommChannelConfig* config)
     545              : {
     546            0 :     return static_cast<HcommResult>(hcomm::ChannelConfigCreate(config));
     547              : }
     548              : 
     549            0 : HcommResult HcommChannelConfigDestroy(HcommChannelConfig config)
     550              : {
     551            0 :     return static_cast<HcommResult>(hcomm::ChannelConfigDestroy(config));
     552              : }
     553              : 
     554            0 : HcommResult HcommChannelConfigSetInt(HcommChannelConfig config, HcommChannelConfigType type, uint32_t value)
     555              : {
     556            0 :     return static_cast<HcommResult>(hcomm::ChannelConfigSetInt(config, type, value));
     557              : }
     558              : 
     559            0 : static bool IsUbProtocol(CommProtocol protocol)
     560              : {
     561            0 :     return protocol == COMM_PROTOCOL_UB_CTP || protocol == COMM_PROTOCOL_UBC_TP;
     562              : }
     563              : 
     564            0 : static HcclResult ValidateSharedQueueConfig(const std::vector<HcommChannelDesc>& channelDescs)
     565              : {
     566            0 :     for (uint32_t i = 0; i < channelDescs.size(); ++i) {
     567            0 :         CommProtocol protocol = channelDescs[i].remoteEndpoint.protocol;
     568            0 :         if (!IsUbProtocol(protocol)) {
     569            0 :             HCCL_ERROR(
     570              :                 "[%s] IS_SHARED_QUEUE only supports UB protocols (UB_CTP/UBC_TP), "
     571              :                 "channelDesc[%u] protocol[%d].",
     572              :                 __func__, i, protocol);
     573            0 :             return HCCL_E_NOT_SUPPORT;
     574              :         }
     575              :     }
     576            0 :     return HCCL_SUCCESS;
     577              : }
     578              : 
     579            0 : static HcclResult CreateAndRegisterSharedQueueBuiltinChannels(
     580              :     EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc* channelDescFinals, uint32_t channelNum,
     581              :     ChannelHandle* channels)
     582              : {
     583              :     // 共享模式建链流程与 HcommChannelCreate 一致:CreateChannelsLoop 传 isSharedQueue=true,
     584              :     // channel 的 BuildConnection 据此走共享 jetty 复用路径;PrepareUserChannels 完成 AICPU/AIV 预分配。
     585            0 :     std::vector<ChannelHandle> hostChannelHandles(channelNum);
     586            0 :     ChannelHandle* targetChannels = hostChannelHandles.data();
     587              : 
     588            0 :     CHK_RET(ChannelProcess::CreateChannelsLoop(
     589              :         endpointHandle, engine, channelDescFinals, channelNum, targetChannels, true));
     590              :     HcclResult prepRet
     591            0 :         = ChannelProcess::PrepareUserChannels(targetChannels, channels, channelDescFinals, channelNum, engine);
     592            0 :     if (prepRet != HCCL_SUCCESS) {
     593            0 :         HCCL_ERROR("[%s] PrepareUserChannels failed, ret[%d], destroying created channels.", __func__, prepRet);
     594            0 :         (void)ChannelProcess::ChannelDestroy(targetChannels, channelNum, AicpuTsChannelHelper::GetBinHandle());
     595            0 :         return prepRet;
     596              :     }
     597              : 
     598            0 :     HcclResult regRet = hcomm::SharedJettyMgr::GetInstance().RegisterChannels(endpointHandle, channels, channelNum);
     599            0 :     if (regRet != HCCL_SUCCESS) {
     600            0 :         HCCL_ERROR("[%s] failed to register shared jetty channels, ret[%d].", __func__, regRet);
     601            0 :         (void)ChannelProcess::ChannelDestroy(channels, channelNum, AicpuTsChannelHelper::GetBinHandle());
     602            0 :         return regRet;
     603              :     }
     604            0 :     return HCCL_SUCCESS;
     605            0 : }
     606              : 
     607            0 : HcommResult HcommChannelCreateWithConfig(
     608              :     EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc* channelDescs, uint32_t channelNum,
     609              :     HcommChannelConfig config, ChannelHandle* channels)
     610              : {
     611            0 :     CHK_PTR_NULL(endpointHandle);
     612            0 :     CHK_PTR_NULL(channelDescs);
     613            0 :     CHK_PTR_NULL(channels);
     614            0 :     CHK_PRT_RET(
     615              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     616            0 :     HCCL_INFO(
     617              :         "[%s] START. endpointHandle[0x%llx], engine[%s], channelNum[%u], config[%p].", __func__, endpointHandle,
     618              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum, config);
     619              : 
     620            0 :     bool isSharedQueue = false;
     621            0 :     if (config != nullptr) {
     622            0 :         auto* cfg = static_cast<hcomm::HcommChannelConfigData*>(config);
     623            0 :         isSharedQueue = cfg->isSharedQueue;
     624              :     }
     625              : 
     626              :     // 非共享模式直接复用 HcommChannelCreate 流程,避免重复维护两套建链逻辑
     627            0 :     if (!isSharedQueue) {
     628            0 :         return HcommChannelCreate(endpointHandle, engine, channelDescs, channelNum, channels);
     629              :     }
     630              : 
     631              :     // 共享 jetty 仅支持 AIV 引擎:AICPU 等 channel 的 BuildConnection 不处理共享 jetty 路径,
     632              :     // 强行创建会导致 channel 注册到 SharedJettyMgr 但无实际 jetty 共享,多 channel 共用同一 SQ
     633              :     // 但 PI/CI 未协调,引发 WQE 覆盖、doorbell 不前进、notify 超时。
     634            0 :     if (engine != COMM_ENGINE_AIV) {
     635            0 :         HCCL_ERROR(
     636              :             "[%s] IS_SHARED_QUEUE currently only supports AIV engine, engine[%d].", __func__, static_cast<int>(engine));
     637            0 :         return HCCL_E_NOT_SUPPORT;
     638              :     }
     639              : 
     640            0 :     auto endpoint = GetEndpointMap().GetEndpoint(endpointHandle);
     641            0 :     if (endpoint != nullptr) {
     642            0 :         CHK_RET(RefreshEndpointContext(endpoint->GetEndpointDesc()));
     643              :     }
     644            0 :     (void)HcommResMgrInit();
     645              : 
     646            0 :     std::vector<HcommChannelDesc> channelDescFinals;
     647            0 :     CHK_RET(static_cast<HcclResult>(NormalizeHcommChannelDescs(channelDescs, channelNum, channelDescFinals, engine)));
     648              :     // NormalizeHcommChannelDescs 内部已调 CheckUbAttr,此处仅补共享模式专有校验
     649            0 :     CHK_RET(ValidateSharedQueueConfig(channelDescFinals));
     650              : 
     651            0 :     HcclResult ret = CreateAndRegisterSharedQueueBuiltinChannels(
     652              :         endpointHandle, engine, channelDescFinals.data(), channelNum, channels);
     653            0 :     if (ret != HCCL_SUCCESS) {
     654            0 :         return static_cast<HcommResult>(ret);
     655              :     }
     656              : 
     657            0 :     HCCL_INFO("[%s] SUCCESS. isSharedQueue[%d], channelNum[%u].", __func__, isSharedQueue, channelNum);
     658            0 :     return HCCL_SUCCESS;
     659            0 : }
     660              : 
     661              : HcommResult
     662            7 : HcommChannelGetRemoteMems(ChannelHandle channelHandle, uint32_t* memNum, CommMem** remoteMem, char*** memInfos)
     663              : {
     664            7 :     CHK_PTR_NULL(remoteMem);
     665            6 :     CHK_PTR_NULL(memNum);
     666            5 :     CHK_PTR_NULL(memInfos);
     667              : 
     668            5 :     return ChannelProcess::ChannelGetRemoteMems(channelHandle, memNum, remoteMem, memInfos);
     669              : }
        

Generated by: LCOV version 2.0-1