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: 82.8 % 198 164
Test Date: 2026-08-04 10:52:23 Functions: 92.9 % 14 13

            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              : #include <cstring>
      11              : #include <vector>
      12              : 
      13              : #include "hcomm_c_adpt.h"
      14              : #include "hcomm_c_adpt_common.h"
      15              : #include "hcomm_res.h"
      16              : #include "hcomm_result_defs.h"
      17              : #include "hcomm_res_defs.h"
      18              : #include "log.h"
      19              : #include "param_check_pub.h"
      20              : #include "comm_engine_utils.h"
      21              : #include "channel_process.h"
      22              : #include "aicpu_ts_channel_helper.h"
      23              : #ifdef ENABLE_EXPERIMENTAL
      24              : #include "nic_plugin_dispatcher.h"
      25              : #endif
      26              : 
      27              : using namespace hcomm;
      28              : 
      29           38 : HcommResult CheckUbAttr(HcommChannelDesc &channelDesc)
      30              : {
      31           38 :     if (channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBC_TP
      32           38 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBOE
      33           38 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBG
      34           38 :         && channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_UBC_CTP) {
      35           19 :         return HCCL_SUCCESS;
      36              :     }
      37              : 
      38              :     // check sqDepth
      39           19 :     if (channelDesc.ubAttr.sqDepth == 0xFFFFFFFF) { // 0xFFFFFFFF表示使用默认值
      40           15 :         HCCL_INFO("[%s] use default ubAttr.sqDepth.", __func__);
      41           15 :         return HCCL_SUCCESS;
      42              :     }
      43              : 
      44              :     // sqDepth的合理范围在[16, 256]
      45            4 :     if (channelDesc.ubAttr.sqDepth < 16 || channelDesc.ubAttr.sqDepth > 256) {
      46            2 :         HCCL_ERROR(
      47              :             "[%s] invalid ubAttr.sqDepth[%u], should be 0 or >= 16 and <= 256.", __func__, channelDesc.ubAttr.sqDepth);
      48            2 :         return HCCL_E_PARA;
      49              :     }
      50              : 
      51              :     // channelDesc.ubAttr.sqDepth调整到2的整数次幂
      52            2 :     auto GetNextPowerOfTwo = [](uint32_t n) -> uint32_t {
      53            2 :         n--;
      54            2 :         n |= n >> 1;
      55            2 :         n |= n >> 2;
      56            2 :         n |= n >> 4;
      57            2 :         n |= n >> 8;
      58            2 :         n |= n >> 16;
      59            2 :         return n + 1;
      60              :     };
      61              : 
      62            2 :     channelDesc.ubAttr.sqDepth = GetNextPowerOfTwo(channelDesc.ubAttr.sqDepth);
      63              : 
      64            2 :     return HCCL_SUCCESS;
      65              : }
      66              : 
      67           31 : HcommResult CheckRoceAttr(HcommChannelDesc &channelDesc)
      68              : {
      69           31 :     if (channelDesc.remoteEndpoint.protocol != COMM_PROTOCOL_ROCE) {
      70           31 :         return HCCL_SUCCESS;
      71              :     }
      72              : 
      73            0 :     if (channelDesc.roceAttr.queueNum == INVALID_UINT) {
      74            0 :         channelDesc.roceAttr.queueNum = 1;
      75            0 :         HCCL_INFO("[%s] set roceAttr.queueNum to 1.", __func__);
      76              :     }
      77              : 
      78            0 :     return HCCL_SUCCESS;
      79              : }
      80              : 
      81              : namespace {
      82           31 : void ApplyHcommChannelDescV1Fields(const HcommChannelDesc &channelDesc, HcommChannelDesc &channelDescFinal)
      83              : {
      84           31 :     if (channelDesc.header.version < HCOMM_CHANNEL_VERSION_ONE) {
      85            0 :         return;
      86              :     }
      87              : 
      88           31 :     channelDescFinal.remoteEndpoint = channelDesc.remoteEndpoint;
      89           31 :     channelDescFinal.notifyNum = channelDesc.notifyNum;
      90           31 :     channelDescFinal.exchangeAllMems = channelDesc.exchangeAllMems;
      91           31 :     channelDescFinal.memHandles = channelDesc.memHandles;
      92           31 :     channelDescFinal.memHandleNum = channelDesc.memHandleNum;
      93           31 :     channelDescFinal.socket = channelDesc.socket;
      94           31 :     channelDescFinal.role = channelDesc.role;
      95           31 :     channelDescFinal.port = channelDesc.port;
      96              : }
      97              : 
      98           31 : HcommResult ProcessHcommChannelDescs(const HcommChannelDesc &channelDesc, HcommChannelDesc &channelDescFinal)
      99              : {
     100           31 :     if (channelDesc.header.size < sizeof(CommAbiHeader)) {
     101            0 :         HCCL_ERROR("[%s] invalid channelDesc.header.size[%u].", __func__, channelDesc.header.size);
     102            0 :         return HCCL_E_PARA;
     103              :     }
     104              : 
     105           31 :     if (channelDesc.header.magicWord != channelDescFinal.header.magicWord) {
     106            0 :         HCCL_ERROR("[%s] channelDesc.header.magicWord[0x%08x] is invalid, expected[0x%08x].", __func__,
     107              :             channelDesc.header.magicWord, channelDescFinal.header.magicWord);
     108            0 :         return HCCL_E_PARA;
     109              :     }
     110              : 
     111           31 :     const uint32_t copySize = (channelDescFinal.header.size < channelDesc.header.size ? channelDescFinal.header.size
     112           31 :                                                                                       : channelDesc.header.size)
     113            0 :                               - sizeof(CommAbiHeader);
     114           31 :     CHK_SAFETY_FUNC_RET(memcpy_s(reinterpret_cast<uint8_t *>(&channelDescFinal) + sizeof(CommAbiHeader), copySize,
     115              :         reinterpret_cast<const uint8_t *>(&channelDesc) + sizeof(CommAbiHeader), copySize));
     116           31 :     ApplyHcommChannelDescV1Fields(channelDesc, channelDescFinal);
     117           31 :     if (channelDesc.header.version > HCOMM_CHANNEL_VERSION) {
     118            0 :         HCCL_RUN_WARNING("The version of provided [%u] is higher than the current version[%u], "
     119              :                          "unsupported configuration will be ignored.",
     120              :             channelDesc.header.version, HCOMM_CHANNEL_VERSION);
     121           31 :     } else if (channelDesc.header.version < HCOMM_CHANNEL_VERSION) {
     122            1 :         HCCL_RUN_WARNING("The version of provided [%u] is lower than the current version[%u], "
     123              :                          "configurations supported by later versions will be ignored.",
     124              :             channelDesc.header.version, HCOMM_CHANNEL_VERSION);
     125              :     }
     126              : 
     127              :     // qos:低版本时置默认值
     128           31 :     if (channelDesc.header.version <= HCOMM_CHANNEL_VERSION_ONE) {
     129            1 :         channelDescFinal.qos = 0xFFFFFFFFU;
     130              :     } else {
     131           30 :         channelDescFinal.qos = channelDesc.qos;
     132              :     }
     133              : 
     134              :     // v3:channelName,低版本时置 NULL
     135           31 :     if (channelDesc.header.version < HCOMM_CHANNEL_VERSION) {
     136            1 :         channelDescFinal.channelName = nullptr;
     137              :     } else {
     138           30 :         channelDescFinal.channelName = channelDesc.channelName;
     139           30 :         if (channelDescFinal.channelName != nullptr
     140            1 :             && reinterpret_cast<uintptr_t>(channelDescFinal.channelName) == static_cast<uintptr_t>(-1)) {
     141            0 :             channelDescFinal.channelName = nullptr;
     142              :         }
     143              :     }
     144              : 
     145           31 :     if (channelDescFinal.channelName != nullptr) {
     146            1 :         size_t nameLen = strnlen(channelDescFinal.channelName, HCOMM_CHANNEL_NAME_MAX_LEN + 1);
     147            1 :         if (nameLen > HCOMM_CHANNEL_NAME_MAX_LEN) {
     148            0 :             HCCL_ERROR("[%s] channelName too long, max len[%u].", __func__, HCOMM_CHANNEL_NAME_MAX_LEN);
     149            0 :             return HCCL_E_PARA;
     150              :         }
     151              :     }
     152              : 
     153           31 :     return HCOMM_SUCCESS;
     154              : }
     155              : 
     156           31 : HcommResult NormalizeHcommChannelDescs(
     157              :     HcommChannelDesc *channelDescs, uint32_t channelNum, std::vector<HcommChannelDesc> &channelDescFinals)
     158              : {
     159           31 :     channelDescFinals.clear();
     160           31 :     channelDescFinals.reserve(channelNum);
     161           62 :     for (uint32_t idx = 0; idx < channelNum; ++idx) {
     162           31 :         HcommChannelDesc channelDescFinal{};
     163           31 :         HcommResult ret = HcommChannelDescInit(&channelDescFinal, 1);
     164           31 :         if (ret != HCOMM_SUCCESS) {
     165            0 :             return ret;
     166              :         }
     167           31 :         ret = ProcessHcommChannelDescs(channelDescs[idx], channelDescFinal);
     168           31 :         if (ret != HCOMM_SUCCESS) {
     169            0 :             HCCL_ERROR("[%s] failed to normalize channelDesc[%u], ret[%d].", __func__, idx, ret);
     170            0 :             return ret;
     171              :         }
     172           31 :         ret = CheckUbAttr(channelDescFinal);
     173           31 :         if (ret != HCOMM_SUCCESS) {
     174            0 :             HCCL_ERROR("[%s] CheckUbAttr failed, ret[%d].", __func__, ret);
     175            0 :             return ret;
     176              :         }
     177           31 :         ret = CheckRoceAttr(channelDescFinal);
     178           31 :         if (ret != HCOMM_SUCCESS) {
     179            0 :             HCCL_ERROR("[%s] CheckRoceAttr failed, ret[%d].", __func__, ret);
     180            0 :             return ret;
     181              :         }
     182              : 
     183           31 :         channelDescFinals.push_back(channelDescFinal);
     184              :     }
     185           31 :     return HCOMM_SUCCESS;
     186              : }
     187              : } // namespace
     188              : 
     189              : // 集合通信使用,待归一到HcommChannelCreate
     190           12 : HcommResult HcommCollectiveChannelCreate(EndpointHandle endpointHandle, CommEngine engine,
     191              :     HcommChannelDesc *channelDescs, uint32_t channelNum, ChannelHandle *channels)
     192              : {
     193           12 :     CHK_PTR_NULL(channelDescs);
     194           10 :     CHK_PTR_NULL(channels);
     195           10 :     CHK_PRT_RET(
     196              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     197            8 :     HCCL_INFO("[%s] START. endpointHandle[0x%llx], engine[%s], channelNum[%u].", __func__, endpointHandle,
     198              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum);
     199              : 
     200            8 :     std::vector<HcommChannelDesc> channelDescFinals;
     201            8 :     CHK_RET(static_cast<HcclResult>(NormalizeHcommChannelDescs(channelDescs, channelNum, channelDescFinals)));
     202            8 :     return ChannelProcess::CreateChannelsLoop(endpointHandle, engine, channelDescFinals.data(), channelNum, channels);
     203            8 : }
     204              : 
     205            0 : HcommResult HcommChannelUpdateMemInfo(HcommMemHandle *memHandles, uint32_t memHandleNum, ChannelHandle channelHandle)
     206              : {
     207            0 :     CHK_PTR_NULL(memHandles);
     208            0 :     CHK_PRT_RET((memHandleNum == 0), HCCL_ERROR("[%s]Invalid memHandleNum, memHandleNum is 0.", __func__), HCCL_E_PARA);
     209              : #ifdef ENABLE_EXPERIMENTAL
     210            0 :     bool handled = false;
     211            0 :     CHK_RET(static_cast<HcclResult>(PluginChannelUpdateMemInfo(channelHandle, memHandles, memHandleNum, handled)));
     212            0 :     if (handled) {
     213            0 :         return HCCL_SUCCESS;
     214              :     }
     215              : #endif
     216              : 
     217            0 :     return ChannelProcess::ChannelUpdateMemInfo(memHandles, memHandleNum, channelHandle);
     218              : }
     219              : 
     220           28 : HcommResult HcommChannelCreate(EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc *channelDescs,
     221              :     uint32_t channelNum, ChannelHandle *channels)
     222              : {
     223           28 :     CHK_PTR_NULL(endpointHandle);
     224           25 :     CHK_PTR_NULL(channelDescs);
     225           24 :     CHK_PTR_NULL(channels);
     226           24 :     CHK_PRT_RET(
     227              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     228           23 :     HCCL_INFO("[%s] START. endpointHandle[0x%llx], engine[%s], channelNum[%u].", __func__, endpointHandle,
     229              :         GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), channelNum);
     230           23 :     auto endpoint = GetEndpointMap().GetEndpoint(endpointHandle);
     231           23 :     if (endpoint != nullptr) {
     232           17 :         CHK_RET(RefreshEndpointContext(endpoint->GetEndpointDesc()));
     233              :     }
     234           23 :     (void)HcommResMgrInit();
     235           23 :     std::vector<HcommChannelDesc> channelDescFinals;
     236           23 :     CHK_RET(static_cast<HcclResult>(NormalizeHcommChannelDescs(channelDescs, channelNum, channelDescFinals)));
     237              : 
     238              : #ifdef ENABLE_EXPERIMENTAL
     239           23 :     bool pluginHandled = false;
     240           23 :     CHK_RET(static_cast<HcclResult>(
     241              :         PluginChannelCreate(endpointHandle, engine, channelDescFinals.data(), channelNum, channels, pluginHandled)));
     242           20 :     if (pluginHandled) {
     243            1 :         return HCCL_SUCCESS;
     244              :     }
     245              : #endif
     246              : 
     247           19 :     std::vector<ChannelHandle> hostChannelHandles(channelNum);
     248           19 :     ChannelHandle *targetChannels = hostChannelHandles.data();
     249              : 
     250           19 :     CHK_RET(ChannelProcess::CreateChannelsLoop(
     251              :         endpointHandle, engine, channelDescFinals.data(), channelNum, targetChannels));
     252           19 :     CHK_RET(
     253              :         ChannelProcess::PrepareUserChannels(targetChannels, channels, channelDescFinals.data(), channelNum, engine));
     254              : 
     255           18 :     return HCCL_SUCCESS;
     256           23 : }
     257              : 
     258           58 : HcommResult HcommChannelGet(ChannelHandle channelHandle, void **channel)
     259              : {
     260           58 :     CHK_PTR_NULL(channel);
     261              : #ifdef ENABLE_EXPERIMENTAL
     262           57 :     bool handled = false;
     263           57 :     CHK_RET(static_cast<HcclResult>(PluginChannelGet(channelHandle, channel, handled)));
     264           57 :     if (handled) {
     265            0 :         return HCCL_SUCCESS;
     266              :     }
     267              : #endif
     268           57 :     return ChannelProcess::ChannelGet(channelHandle, channel);
     269              : }
     270              : 
     271           33 : HcommResult HcommChannelGetStatus(const ChannelHandle *channelList, uint32_t listNum, int32_t *statusList)
     272              : {
     273           33 :     CHK_PTR_NULL(channelList);
     274           31 :     CHK_PTR_NULL(statusList);
     275           29 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     276           27 :     (void)HcommResMgrInit();
     277              : #ifdef ENABLE_EXPERIMENTAL
     278           27 :     bool allHandled = true;
     279           58 :     for (uint32_t i = 0; i < listNum; i++) {
     280           31 :         bool handled = false;
     281           31 :         CHK_RET(static_cast<HcclResult>(PluginChannelGetStatus(channelList[i], &statusList[i], handled)));
     282           31 :         if (!handled) {
     283           31 :             allHandled = false;
     284              :         }
     285              :     }
     286           27 :     if (allHandled) {
     287            0 :         return HCCL_SUCCESS;
     288              :     }
     289              : #endif
     290              : 
     291           27 :     std::vector<CommEngine> engines;
     292           27 :     std::vector<HcommChannelDesc> channelDescFinals;
     293           27 :     std::vector<ChannelStatus> internalStatus(listNum);
     294           27 :     HcclResult ret = ChannelProcess::GetChannelsInfo(channelList, listNum, engines, channelDescFinals, internalStatus);
     295           27 :     if (ret != HCCL_SUCCESS) {
     296            2 :         HCCL_ERROR("[%s] GetChannelsInfo failed, ret[%d]", __func__, ret);
     297            2 :         return HCCL_E_INTERNAL;
     298              :     }
     299           25 :     ret = ChannelProcess::HandleStatusByEngine(
     300              :         channelList, listNum, engines, channelDescFinals, internalStatus, statusList);
     301           25 :     if (ret != HCCL_SUCCESS) {
     302            0 :         HCCL_ERROR("[%s] HandleStatusByEngine failed, ret[%d]", __func__, ret);
     303            0 :         return HCCL_E_INTERNAL;
     304              :     }
     305           25 :     return HCCL_SUCCESS;
     306           27 : }
     307              : 
     308            2 : HcommResult HcommChannelGetNotifyNum(ChannelHandle channelHandle, uint32_t *notifyNum)
     309              : {
     310            2 :     CHK_PTR_NULL(notifyNum);
     311              : #ifdef ENABLE_EXPERIMENTAL
     312            1 :     bool handled = false;
     313            1 :     CHK_RET(static_cast<HcclResult>(PluginChannelGetNotifyNum(channelHandle, notifyNum, handled)));
     314            1 :     if (handled) {
     315            0 :         return HCCL_SUCCESS;
     316              :     }
     317              : #endif
     318            1 :     return ChannelProcess::ChannelGetNotifyNum(channelHandle, notifyNum);
     319              : }
     320              : 
     321           21 : HcommResult HcommChannelDestroy(const ChannelHandle *channels, uint32_t channelNum)
     322              : {
     323           21 :     CHK_PTR_NULL(channels);
     324           20 :     (void)HcommResMgrInit();
     325           20 :     CHK_PRT_RET(
     326              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     327           19 :     std::vector<ChannelHandle> builtinChannels;
     328           19 :     builtinChannels.reserve(channelNum);
     329           39 :     for (uint32_t idx = 0; idx < channelNum; ++idx) {
     330              : #ifdef ENABLE_EXPERIMENTAL
     331           20 :         bool handled = false;
     332           20 :         CHK_RET(static_cast<HcclResult>(PluginChannelDestroy(channels[idx], handled)));
     333           20 :         if (handled) {
     334            1 :             continue;
     335              :         }
     336              : #endif
     337           19 :         builtinChannels.push_back(channels[idx]);
     338              :     }
     339           19 :     if (builtinChannels.empty()) {
     340            1 :         return HCCL_SUCCESS;
     341              :     }
     342           36 :     return ChannelProcess::ChannelDestroy(
     343           36 :         builtinChannels.data(), builtinChannels.size(), AicpuTsChannelHelper::GetBinHandle());
     344           19 : }
     345              : 
     346            8 : HcommResult HcommChannelGetRemoteMems(
     347              :     ChannelHandle channelHandle, uint32_t *memNum, CommMem **remoteMem, char ***memInfos)
     348              : {
     349            8 :     CHK_PTR_NULL(remoteMem);
     350            7 :     CHK_PTR_NULL(memNum);
     351            6 :     CHK_PTR_NULL(memInfos);
     352              : #ifdef ENABLE_EXPERIMENTAL
     353            6 :     bool handled = false;
     354            6 :     CHK_RET(static_cast<HcclResult>(PluginChannelGetRemoteMems(channelHandle, memNum, remoteMem, memInfos, handled)));
     355            6 :     if (handled) {
     356            1 :         return HCCL_SUCCESS;
     357              :     }
     358              : #endif
     359              : 
     360            5 :     return ChannelProcess::ChannelGetRemoteMems(channelHandle, memNum, remoteMem, memInfos);
     361              : }
        

Generated by: LCOV version 2.0-1