LCOV - code coverage report
Current view: top level - base_comm/resources/endpoint_pairs/channels - channel_process.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.0 % 604 296
Test Date: 2026-08-18 17:47:01 Functions: 55.1 % 49 27

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "channel_process.h"
      12              : #include <cstdint>
      13              : #include <map>
      14              : #include <memory>
      15              : #include <vector>
      16              : #include "exception_handler.h"
      17              : #include "channel_param.h"
      18              : #include "channel.h"
      19              : #include "aicpu_ts_channel_helper.h"
      20              : #include "aiv_channel_helper.h"
      21              : #include "aicpu_ts_urma_channel.h"
      22              : #include "aicpu_ts_uboe_channel.h"
      23              : #include "aicpu_ts_ub_rtp_channel.h"
      24              : #include "aicpu_ts_roce_channel_v2.h"
      25              : #include "acl/acl_rt.h"
      26              : #include "launch_aicpu.h"
      27              : #include "hcclCommDfx.h"
      28              : #include "env_config/env_config_v2.h"
      29              : #include "aicpu_ts_p2p_channel.h"
      30              : #include "aiv_urma_channel.h"
      31              : #include "mem_device_pub.h"
      32              : #include "comm_engine_utils.h"
      33              : #include "comm_configer.h"
      34              : #include "builtin_channel_ops.h"
      35              : 
      36              : namespace hcomm {
      37              : 
      38              : std::unordered_map<ChannelHandle, std::shared_ptr<Channel>> ChannelProcess::g_ChannelMap;
      39              : std::unordered_map<DeviceChannelKey, ChannelHandle, DeviceChannelKeyHash> ChannelProcess::g_ChannelD2HMap;
      40              : std::mutex ChannelProcess::g_ChannelMapMtx;
      41              : 
      42              : template <typename Func>
      43           43 : HcclResult ChannelProcess::WithChannelByHandleLocked(ChannelHandle inHandle, Func&& func)
      44              : {
      45           43 :     int32_t deviceId = 0;
      46           43 :     CHK_RET(hrtGetDevice(&deviceId));
      47              : 
      48           43 :     std::shared_ptr<Channel> channelPtr = nullptr;
      49              :     {
      50              :         // 单锁:该锁同时保护 g_ChannelD2HMap 和 g_ChannelMap
      51           43 :         std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
      52              : 
      53              :         // 1) D2H 映射
      54           43 :         DeviceChannelKey key{deviceId, inHandle};
      55           43 :         auto itH = g_ChannelD2HMap.find(key);
      56           43 :         if (itH == g_ChannelD2HMap.end()) {
      57            4 :             HCCL_ERROR(
      58              :                 "[%s] handle not found in g_ChannelD2HMap, deviceId[%d], inHandle[0x%llx].", __func__, deviceId,
      59              :                 inHandle);
      60            4 :             return HcclResult::HCCL_E_NOT_FOUND;
      61              :         }
      62           39 :         const ChannelHandle mappedHandle = itH->second;
      63              : 
      64              :         // 2) ChannelMap 查找
      65           39 :         auto itC = g_ChannelMap.find(mappedHandle);
      66           39 :         if (itC == g_ChannelMap.end() || !itC->second) {
      67            0 :             HCCL_ERROR(
      68              :                 "[%s] channel not found in g_ChannelMap, deviceId[%d], inHandle[0x%llx], mappedHandle[0x%llx].",
      69              :                 __func__, deviceId, inHandle, mappedHandle);
      70            0 :             return HcclResult::HCCL_E_INTERNAL;
      71              :         }
      72              : 
      73           39 :         channelPtr = itC->second;
      74           39 :         if (channelPtr == nullptr) {
      75            0 :             HCCL_ERROR(
      76              :                 "[%s] null channel pointer, deviceId[%d], inHandle[0x%llx], mappedHandle[0x%llx].", __func__, deviceId,
      77              :                 inHandle, mappedHandle);
      78            0 :             return HcclResult::HCCL_E_INTERNAL;
      79              :         }
      80           43 :     }
      81              : 
      82              :     // 3) 执行用户逻辑
      83           39 :     return std::forward<Func>(func)(*channelPtr);
      84           43 : }
      85              : 
      86           19 : HcclResult ChannelProcess::CreateChannelsLoop(
      87              :     EndpointHandle endpointHandle, CommEngine engine, HcommChannelDesc* channelDescs, uint32_t channelNum,
      88              :     ChannelHandle* outHandles, bool isSharedQueue)
      89              : {
      90           19 :     CHK_PTR_NULL(endpointHandle);
      91              : 
      92           18 :     int32_t deviceId = 0;
      93           18 :     CHK_RET(hrtGetDevice(&deviceId));
      94              : 
      95           36 :     for (uint32_t i = 0; i < channelNum; ++i) {
      96           18 :         std::shared_ptr<Channel> tmpPtr = nullptr;
      97           18 :         CHK_RET_UNAVAIL(Channel::CreateChannel(endpointHandle, engine, channelDescs[i], tmpPtr, isSharedQueue));
      98           18 :         CHK_SMART_PTR_NULL(tmpPtr);
      99              : 
     100           18 :         tmpPtr->SetNicChannelCtx(&g_BuiltinChannelOps, tmpPtr.get());
     101              : 
     102           18 :         ChannelHandle handle = reinterpret_cast<ChannelHandle>(tmpPtr.get());
     103           18 :         outHandles[i] = handle;
     104           18 :         HCCL_INFO("%s deviceId[%d], handle[0x%llx], ptr[%p]", __func__, deviceId, handle, tmpPtr.get());
     105              : 
     106              :         // 仅在修改全局表时持锁
     107              :         {
     108           18 :             std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     109              : 
     110           18 :             if (g_ChannelMap.find(handle) != g_ChannelMap.end()) {
     111            0 :                 HCCL_ERROR("[%s] channel handle already exists [0x%llx] in ChannelMap", __func__, handle);
     112            0 :                 return HCCL_E_INTERNAL;
     113              :             }
     114           18 :             DeviceChannelKey key{deviceId, handle};
     115           18 :             if (g_ChannelD2HMap.find(key) != g_ChannelD2HMap.end()) {
     116            0 :                 HCCL_ERROR(
     117              :                     "[%s] channel handle already exists deviceId[%d], handle[0x%llx] in g_ChannelD2HMap", __func__,
     118              :                     deviceId, handle);
     119            0 :                 return HCCL_E_INTERNAL;
     120              :             }
     121              : 
     122           18 :             g_ChannelMap.emplace(handle, std::move(tmpPtr));
     123           18 :             g_ChannelD2HMap.emplace(key, handle);
     124           18 :         }
     125           18 :     }
     126           18 :     return HCCL_SUCCESS;
     127              : }
     128              : 
     129            2 : HcclResult ChannelProcess::InsertPluginChannelToMap(ChannelHandle handle, std::shared_ptr<Channel> channelPtr)
     130              : {
     131            2 :     std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     132            2 :     if (g_ChannelMap.find(handle) != g_ChannelMap.end()) {
     133            0 :         HCCL_ERROR("[NicPlugin][%s] channel handle already exists [0x%llx] in ChannelMap", __func__, handle);
     134            0 :         return HCCL_E_INTERNAL;
     135              :     }
     136              : 
     137            2 :     g_ChannelMap.emplace(handle, std::move(channelPtr));
     138            2 :     HCCL_INFO("[NicPlugin][%s] plugin channel inserted, handle[0x%llx].", __func__, handle);
     139              : 
     140            2 :     return HCCL_SUCCESS;
     141            2 : }
     142              : 
     143            2 : HcclResult ChannelProcess::RemovePluginChannelFromMap(ChannelHandle handle)
     144              : {
     145            2 :     std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     146              : 
     147            2 :     auto iter = g_ChannelMap.find(handle);
     148            2 :     if (iter == g_ChannelMap.end()) {
     149            0 :         HCCL_ERROR("[%s] channel not found in g_ChannelMap, handle[0x%llx].", __func__, handle);
     150            0 :         return HCCL_E_NOT_FOUND;
     151              :     }
     152            2 :     g_ChannelMap.erase(iter);
     153              : 
     154            2 :     HCCL_INFO("[%s] unregister plugin channel, handle[0x%llx].", __func__, handle);
     155            2 :     return HCCL_SUCCESS;
     156            2 : }
     157              : 
     158              : HcclResult
     159            0 : ChannelProcess::ChannelUpdateMemInfo(HcommMemHandle* memHandles, uint32_t memHandleNum, ChannelHandle channelHandle)
     160              : {
     161              :     EXCEPTION_HANDLE_BEGIN
     162            0 :     int32_t deviceId = 0;
     163            0 :     CHK_RET(hrtGetDevice(&deviceId));
     164              : 
     165            0 :     Channel* channel = nullptr;
     166              :     {
     167            0 :         std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     168              :         // 1) D2H 映射
     169            0 :         DeviceChannelKey key{deviceId, channelHandle};
     170            0 :         auto itH = g_ChannelD2HMap.find(key);
     171            0 :         if (itH == g_ChannelD2HMap.end()) {
     172            0 :             HCCL_ERROR(
     173              :                 "[%s] handle not found in g_ChannelD2HMap, deviceId[%d], channelHandle[0x%llx].", __func__, deviceId,
     174              :                 channelHandle);
     175            0 :             return HcclResult::HCCL_E_NOT_FOUND;
     176              :         }
     177            0 :         const ChannelHandle mappedHandle = itH->second;
     178              : 
     179              :         // 2) ChannelMap 查找
     180            0 :         auto itC = g_ChannelMap.find(mappedHandle);
     181            0 :         if (itC == g_ChannelMap.end() || !itC->second) {
     182            0 :             HCCL_ERROR(
     183              :                 "[%s] channel not found in g_ChannelMap, deviceId[%d], channelHandle[0x%llx], mappedHandle[0x%llx].",
     184              :                 __func__, deviceId, channelHandle, mappedHandle);
     185            0 :             return HcclResult::HCCL_E_INTERNAL;
     186              :         }
     187            0 :         channel = itC->second.get();
     188            0 :     }
     189              :     // UpdateMemInfo需要rank间交互,若在锁内执行会导致单进程多线程场景其他rank被锁拦住
     190            0 :     CHK_RET(channel->UpdateMemInfo(memHandles, memHandleNum));
     191            0 :     EXCEPTION_HANDLE_END
     192            0 :     return HCCL_SUCCESS;
     193              : }
     194              : 
     195           10 : HcclResult ChannelProcess::ChannelGetStatus(const ChannelHandle* channelList, uint32_t listNum, int32_t* statusList)
     196              : {
     197              :     EXCEPTION_HANDLE_BEGIN
     198              : 
     199              :     // 不得随意添加无效日志,可能造成刷屏
     200           10 :     CHK_PTR_NULL(channelList);
     201            9 :     CHK_PTR_NULL(statusList);
     202              : 
     203            8 :     u32 readyCount = 0;
     204            8 :     u32 failCount = 0;
     205              : 
     206           18 :     for (uint32_t i = 0; i < listNum; ++i) {
     207           11 :         const ChannelHandle inHandle = channelList[i];
     208           11 :         int32_t status = 0;
     209              :         // 当前通道状态如果已为FAILED/SOCKET_TIMEOUT,说明前面已经失败过,无需再重新获取状态,继续轮询下一个通道,避免日志刷屏
     210           11 :         if (statusList[i] == ChannelStatus::FAILED || statusList[i] == ChannelStatus::SOCKET_TIMEOUT) {
     211            1 :             failCount++;
     212            1 :             continue;
     213              :         }
     214              :         // 单锁:D2H 映射 + 查 map + 锁内调用 GetStatus()
     215           10 :         HcclResult ret = WithChannelByHandleLocked(inHandle, [&status](Channel& channel) -> HcclResult {
     216            9 :             status = channel.GetStatus(); // 锁内调用,防止 destroy 并发释放
     217            9 :             return HcclResult::HCCL_SUCCESS;
     218              :         });
     219           10 :         if (ret != HcclResult::HCCL_SUCCESS) {
     220            1 :             HCCL_ERROR("[%s] Get ChannelHandle failed.", __func__);
     221            1 :             return ret;
     222              :         }
     223              :         // 某一个channel状态为FAILED/SOCKET_TIMEOUT时不直接返回,否则后面的channel无法轮询完,状态无法到达终态;
     224            9 :         if (status == ChannelStatus::FAILED) {
     225            2 :             HCCL_ERROR("[%s] FAILED, channel idx[%u], status[%d]", __func__, i, status);
     226            2 :             failCount++;
     227              :         }
     228            9 :         if (status == ChannelStatus::SOCKET_TIMEOUT) {
     229            1 :             HCCL_ERROR("[%s] TIMEOUT, channel idx[%u], status[%d]", __func__, i, status);
     230            1 :             failCount++;
     231              :         }
     232              : 
     233            9 :         readyCount += (status == ChannelStatus::READY) ? 1 : 0;
     234            9 :         statusList[i] = status;
     235              :     }
     236            7 :     if (readyCount + failCount < listNum) {
     237            2 :         return HCCL_E_AGAIN;
     238              :     }
     239            5 :     if (readyCount != listNum) {
     240            4 :         HCCL_ERROR(
     241              :             "[%s] NETWORK, readyCount[%u], failCount[%u], listNum[%u]", __func__, readyCount, failCount, listNum);
     242            4 :         return HCCL_E_NETWORK;
     243              :     }
     244            0 :     EXCEPTION_HANDLE_END
     245            1 :     return HCCL_SUCCESS;
     246              : }
     247              : 
     248           32 : HcclResult ChannelProcess::GetChannelsInfo(
     249              :     const ChannelHandle* channelList, uint32_t listNum, std::vector<CommEngine>& engines,
     250              :     std::vector<HcommChannelDesc>& channelDescs, std::vector<ChannelStatus>& statusList)
     251              : {
     252           32 :     CHK_PTR_NULL(channelList);
     253           31 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     254              : 
     255           30 :     channelDescs.resize(listNum);
     256           30 :     statusList.resize(listNum);
     257           30 :     engines.resize(listNum);
     258           60 :     for (uint32_t i = 0; i < listNum; ++i) {
     259           66 :         HcclResult ret = WithChannelByHandleLocked(
     260           33 :             channelList[i], [i, &engines, &channelDescs, &statusList](Channel& channel) -> HcclResult {
     261           30 :                 engines[i] = channel.GetEngine();
     262           30 :                 channelDescs[i] = channel.GetChannelDesc();
     263           30 :                 statusList[i] = channel.GetStatus();
     264           30 :                 return HcclResult::HCCL_SUCCESS;
     265              :             });
     266           33 :         if (ret != HcclResult::HCCL_SUCCESS) {
     267            3 :             HCCL_ERROR("[%s] Get channel[%u] info failed.", __func__, i);
     268            3 :             return ret;
     269              :         }
     270           30 :         if (statusList[i] == ChannelStatus::FAILED || statusList[i] == ChannelStatus::SOCKET_TIMEOUT) {
     271            5 :             HCCL_RUN_WARNING("[%s] FAILED, channel idx[%u], status[%d]", __func__, i, statusList[i]);
     272              :         }
     273              :     }
     274           27 :     HCCL_DEBUG("[%s] SUCCESS.", __func__);
     275           27 :     return HCCL_SUCCESS;
     276              : }
     277              : 
     278           26 : void ConvertToLinkStatus(const std::vector<ChannelStatus>& internalStatus, std::vector<int32_t>& linkStatusList)
     279              : {
     280           55 :     for (size_t i = 0; i < internalStatus.size(); i++) {
     281           29 :         switch (internalStatus[i]) {
     282            4 :             case ChannelStatus::FAILED:
     283            4 :                 linkStatusList[i] = HCOMM_CHANNEL_STATUS_FAILED;
     284            4 :                 break;
     285            1 :             case ChannelStatus::SOCKET_TIMEOUT:
     286            1 :                 linkStatusList[i] = HCOMM_CHANNEL_STATUS_TIMEOUT;
     287            1 :                 break;
     288            5 :             case ChannelStatus::READY:
     289            5 :                 linkStatusList[i] = HCOMM_CHANNEL_STATUS_READY;
     290            5 :                 break;
     291           19 :             default:
     292           19 :                 linkStatusList[i] = HCOMM_CHANNEL_STATUS_CONNECTING;
     293           19 :                 break;
     294              :         }
     295              :     }
     296           26 : }
     297              : 
     298           18 : void CopyLinkStatusToOutput(const std::vector<int32_t>& linkStatusList, int32_t* statusList, uint32_t listNum)
     299              : {
     300           36 :     for (uint32_t i = 0; i < listNum; i++) {
     301           18 :         statusList[i] = linkStatusList[i];
     302              :     }
     303           18 : }
     304              : 
     305           26 : HcclResult ChannelProcess::HandleStatusByEngine(
     306              :     const ChannelHandle* channelList, uint32_t listNum, const std::vector<CommEngine>& engines,
     307              :     const std::vector<HcommChannelDesc>& channelDescFinals, const std::vector<ChannelStatus>& internalStatus,
     308              :     int32_t* statusList)
     309              : {
     310           26 :     std::vector<int32_t> linkStatusList(listNum);
     311           26 :     ConvertToLinkStatus(internalStatus, linkStatusList);
     312              : 
     313           26 :     std::map<CommEngine, std::vector<uint32_t>> groups;
     314           55 :     for (uint32_t i = 0; i < listNum; i++) {
     315           29 :         groups[engines[i]].push_back(i);
     316              :     }
     317              : 
     318           54 :     for (auto& entry : groups) {
     319           28 :         CommEngine engine = entry.first;
     320           28 :         const std::vector<uint32_t>& indices = entry.second;
     321           28 :         uint32_t subNum = static_cast<uint32_t>(indices.size());
     322           56 :         std::vector<ChannelHandle> subChannels(subNum);
     323           56 :         std::vector<HcommChannelDesc> subDescs(subNum);
     324           28 :         std::vector<int32_t> subLinkStatus(subNum);
     325           57 :         for (uint32_t j = 0; j < subNum; j++) {
     326           29 :             subChannels[j] = channelList[indices[j]];
     327           29 :             subDescs[j] = channelDescFinals[indices[j]];
     328           29 :             subLinkStatus[j] = linkStatusList[indices[j]];
     329              :         }
     330              : 
     331           28 :         std::vector<int32_t> subStatus(subNum);
     332           28 :         if (engine == COMM_ENGINE_AICPU || engine == COMM_ENGINE_AICPU_TS) {
     333            6 :             CHK_RET(AicpuTsChannelHelper::HandleStatus(
     334              :                 subChannels.data(), subNum, engine, subDescs.data(), subLinkStatus, subStatus.data()));
     335           28 :         } else if (engine == COMM_ENGINE_AIV) {
     336            4 :             CHK_RET(AivChannelHelper::HandleStatus(
     337              :                 subChannels.data(), subNum, subDescs.data(), subLinkStatus, subStatus.data()));
     338              :         } else {
     339           18 :             CopyLinkStatusToOutput(subLinkStatus, subStatus.data(), subNum);
     340              :         }
     341              : 
     342           57 :         for (uint32_t j = 0; j < subNum; j++) {
     343           29 :             statusList[indices[j]] = subStatus[j];
     344              :         }
     345           28 :     }
     346              : 
     347           26 :     return HCCL_SUCCESS;
     348           26 : }
     349              : 
     350              : HcclResult
     351            0 : ChannelProcess::CombineHostMemory(const std::vector<std::vector<char>>& hostPackBuffers, hccl::HostMem& hostPackBuf)
     352              : {
     353            0 :     if (hostPackBuffers.empty()) {
     354            0 :         HCCL_ERROR("[%s] hostPackBuffers is empty, please check.", __func__);
     355            0 :         return HCCL_E_PARA;
     356              :     }
     357              : 
     358              :     // 将离散数据复制到连续内存中
     359            0 :     u8* dstPtr = static_cast<u8*>(hostPackBuf.ptr()); // 目标内存起始地址
     360            0 :     u64 dstMax = hostPackBuf.size();
     361            0 :     u64 packSize = 0;
     362              : 
     363            0 :     for (const auto& mem : hostPackBuffers) {
     364            0 :         packSize += mem.size();
     365            0 :         CHK_PRT_RET(
     366              :             packSize > dstMax,
     367              :             HCCL_ERROR("[%s] fail, packSize[%llu] is bigger than dstMax[%llu]", __func__, packSize, dstMax),
     368              :             HCCL_E_PARA);
     369              : 
     370            0 :         CHK_SAFETY_FUNC_RET(memcpy_s(dstPtr, mem.size(), mem.data(), mem.size()));
     371            0 :         dstPtr += mem.size(); // 移动目标指针
     372              :     }
     373              : 
     374            0 :     HCCL_INFO(
     375              :         "[%s] end of merging host memory, hostPackBuf.addr[%p], hostPackBuf.size[%zu]", __func__, hostPackBuf.ptr(),
     376              :         hostPackBuf.size());
     377              : 
     378            0 :     return HCCL_SUCCESS;
     379              : }
     380              : 
     381            5 : HcclResult ChannelProcess::FillChannelD2HMap(
     382              :     ChannelHandle* deviceChannelHandles, ChannelHandle* hostChannelHandles, uint32_t listNum)
     383              : {
     384            5 :     CHK_PTR_NULL(deviceChannelHandles);
     385            4 :     CHK_PTR_NULL(hostChannelHandles);
     386            3 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     387              : 
     388            2 :     int32_t deviceId = 0;
     389            2 :     CHK_RET(hrtGetDevice(&deviceId));
     390              : 
     391            2 :     std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     392            4 :     for (uint32_t idx = 0; idx < listNum; idx++) {
     393            2 :         auto deviceChannelHandle = deviceChannelHandles[idx];
     394            2 :         auto hostChannelHandle = hostChannelHandles[idx];
     395            2 :         HCCL_INFO(
     396              :             "%s deviceId[%d], deviceChannelHandle[0x%llx], hostChannelHandle[0x%llx]", __func__, deviceId,
     397              :             deviceChannelHandle, hostChannelHandle);
     398            2 :         DeviceChannelKey key{deviceId, deviceChannelHandle};
     399            2 :         g_ChannelD2HMap[key] = hostChannelHandle;
     400              :     }
     401              : 
     402            2 :     return HCCL_SUCCESS;
     403            2 : }
     404              : 
     405            0 : HcclResult ChannelProcess::RegisterChannelD2HMap(
     406              :     ChannelHandle* deviceChannelHandles, ChannelHandle* hostChannelHandles, uint32_t listNum)
     407              : {
     408            0 :     return FillChannelD2HMap(deviceChannelHandles, hostChannelHandles, listNum);
     409              : }
     410              : 
     411            0 : static HcclResult FillChannelParam(
     412              :     HcclChannelUrmaRes& channelParam, const std::string& commTag, hccl::DeviceMem& deviceChannelList,
     413              :     hccl::DeviceMem& devicePackBuf, uint32_t listNum, uint32_t totalListNum, hccl::DeviceMem& channelSizeAddr)
     414              : {
     415              :     // channelParam资源参数填充
     416            0 :     s32 sRet = strncpy_s(channelParam.hcomId, HCOMID_MAX_LENGTH, commTag.c_str(), HCOMID_MAX_LENGTH - 1);
     417            0 :     CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[%s] str copy fail. return[%d]", __func__, sRet), HCCL_E_INTERNAL);
     418              : 
     419            0 :     channelParam.channelList = static_cast<void*>(deviceChannelList.ptr());
     420            0 :     channelParam.listNum = listNum;
     421            0 :     channelParam.uniqueIdAddr = static_cast<void*>(devicePackBuf.ptr());
     422            0 :     channelParam.uniqueIdSize = totalListNum;
     423            0 :     channelParam.channelSizeAddr = static_cast<void*>(channelSizeAddr.ptr());
     424              : 
     425            0 :     CHK_RET(hrtGetDevice(&channelParam.deviceLogicId));
     426              :     DevType devType;
     427            0 :     CHK_RET(hrtGetDeviceType(devType));
     428            0 :     channelParam.deviceType = static_cast<u32>(devType);
     429              : 
     430            0 :     return HCCL_SUCCESS;
     431              : }
     432              : 
     433              : template <typename T>
     434              : static HcclResult
     435            0 : LaunchKernelDeviceParam(const T& channelParam, aclrtBinHandle binHandle, const std::string& kernelName)
     436              : {
     437            0 :     hccl::Stream localStream = hccl::Stream(hccl::StreamType::STREAM_TYPE_ONLINE);
     438            0 :     constexpr u32 aicpuStreamMode = 1;
     439            0 :     CHK_RET(hrtStreamSetMode(localStream.ptr(), aicpuStreamMode));
     440              : 
     441            0 :     hccl::DeviceMem addr = hccl::DeviceMem::alloc(sizeof(T));
     442            0 :     CHK_PTR_NULL(addr.ptr());
     443              : 
     444            0 :     CHK_RET(hrtMemSyncCopy(
     445              :         addr.ptr(), sizeof(T), &channelParam, sizeof(T), HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     446              : 
     447            0 :     uint64_t context = reinterpret_cast<uint64_t>(addr.ptr());
     448              : 
     449            0 :     uint32_t envTimeout = 0;
     450              :     DevType devType;
     451            0 :     CHK_RET(hrtGetDeviceType(devType));
     452            0 :     if (devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
     453            0 :         envTimeout = Hccl::EnvConfig::GetInstance().GetRtsConfig().GetExecTimeOut();
     454              :     } else {
     455            0 :         envTimeout = hccl::CommConfiger::GetInstance().GetCommConfigExecTimeOut("");
     456              :     }
     457            0 :     s32 timeOut = envTimeout + 25 > std::numeric_limits<u16>::max() ? std::numeric_limits<u16>::max() :
     458            0 :                                                                       envTimeout + 25; // 多25s,避免超时
     459              : 
     460            0 :     CHK_RET(hccl::AicpuAclKernelLaunch(
     461              :         localStream.ptr(), reinterpret_cast<void*>(&context), sizeof(context), binHandle, kernelName, true,
     462              :         static_cast<u16>(timeOut)));
     463              : 
     464            0 :     CHK_RET(hcclStreamSynchronize(localStream.ptr(), timeOut));
     465              : 
     466            0 :     HCCL_INFO("[%s] kernel[%s] launch success.", __func__, kernelName.c_str());
     467            0 :     return HCCL_SUCCESS;
     468            0 : }
     469              : 
     470              : static HcclResult
     471            0 : LaunchKernel(const HcclChannelUrmaRes& channelParam, aclrtBinHandle binHandle, const std::string& kernelName)
     472              : {
     473            0 :     return LaunchKernelDeviceParam(channelParam, binHandle, kernelName);
     474              : }
     475              : 
     476            1 : static HcclResult PackAicpuTsChannelH2DRes(ChannelHandle hostChannelHandle, std::vector<char>& hostPackBuffer)
     477              : {
     478            1 :     CHK_PRT_RET(hostChannelHandle == 0, HCCL_ERROR("[%s] hostChannelHandle is null.", __func__), HCCL_E_PARA);
     479            1 :     Channel* channel = reinterpret_cast<Channel*>(hostChannelHandle);
     480            1 :     switch (channel->GetChannelKind()) {
     481            0 :         case HcommChannelKind::AICPU_TS_URMA:
     482            0 :             return reinterpret_cast<AicpuTsUrmaChannel*>(hostChannelHandle)->H2DResPack(hostPackBuffer);
     483            0 :         case HcommChannelKind::AICPU_TS_UBOE:
     484            0 :             return reinterpret_cast<AicpuTsUboeChannel*>(hostChannelHandle)->H2DResPack(hostPackBuffer);
     485            0 :         case HcommChannelKind::AICPU_TS_UB_RTP:
     486            0 :             return reinterpret_cast<AicpuTsUbRtpChannel*>(hostChannelHandle)->H2DResPack(hostPackBuffer);
     487            0 :         case HcommChannelKind::AICPU_TS_ROCE_V2:
     488            0 :             return reinterpret_cast<AicpuTsRoceChannelV2*>(hostChannelHandle)->H2DResPack(hostPackBuffer);
     489            1 :         default:
     490            1 :             HCCL_ERROR(
     491              :                 "[%s] unsupported channel kind[%s].", __func__, HcommChannelKindToString(channel->GetChannelKind()));
     492            1 :             return HCCL_E_NOT_SUPPORT;
     493              :     }
     494              : }
     495              : 
     496            1 : HcclResult ChannelProcess::CopyUpdateKernelPackResToDevice(
     497              :     const std::vector<std::vector<char>>& hostPackBuffers, const std::vector<u32>& channelSizeVec,
     498              :     uint32_t totalListNum, hccl::DeviceMem& channelSizeAddr, hccl::DeviceMem& devicePackBuf)
     499              : {
     500            1 :     channelSizeAddr = hccl::DeviceMem::alloc(channelSizeVec.size() * sizeof(u32));
     501            1 :     CHK_PTR_NULL(channelSizeAddr.ptr());
     502            1 :     CHK_RET(hrtMemSyncCopy(
     503              :         channelSizeAddr.ptr(), channelSizeVec.size() * sizeof(u32), channelSizeVec.data(),
     504              :         channelSizeVec.size() * sizeof(u32), HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     505              : 
     506            1 :     hccl::HostMem hostPackBuf = hccl::HostMem::alloc(totalListNum);
     507            1 :     CHK_PTR_NULL(hostPackBuf.ptr());
     508            1 :     u8* dstPtr = static_cast<u8*>(hostPackBuf.ptr());
     509            1 :     const u64 dstMax = static_cast<u64>(totalListNum);
     510            1 :     u64 copiedSize = 0;
     511            2 :     for (const auto& mem : hostPackBuffers) {
     512            2 :         const u64 memSize = static_cast<u64>(mem.size());
     513            3 :         CHK_PRT_RET(
     514              :             copiedSize > dstMax,
     515              :             HCCL_ERROR("[%s] copiedSize[%llu] is bigger than dstMax[%llu]", __func__, copiedSize, dstMax), HCCL_E_PARA);
     516            2 :         const u64 remainingSize = dstMax - copiedSize;
     517            2 :         CHK_PRT_RET(
     518              :             memSize > remainingSize,
     519              :             HCCL_ERROR("[%s] memSize[%llu] is bigger than remainingSize[%llu]", __func__, memSize, remainingSize),
     520              :             HCCL_E_PARA);
     521            1 :         CHK_SAFETY_FUNC_RET(memcpy_s(dstPtr, remainingSize, mem.data(), mem.size()));
     522            1 :         dstPtr += mem.size();
     523            1 :         copiedSize += memSize;
     524              :     }
     525            0 :     CHK_PRT_RET(
     526              :         copiedSize != dstMax,
     527              :         HCCL_ERROR("[%s] copiedSize[%llu] is not equal to dstMax[%llu]", __func__, copiedSize, dstMax), HCCL_E_PARA);
     528              : 
     529            0 :     devicePackBuf = hccl::DeviceMem::alloc(totalListNum);
     530            0 :     CHK_PTR_NULL(devicePackBuf.ptr());
     531            0 :     CHK_RET(hrtMemSyncCopy(
     532              :         devicePackBuf.ptr(), totalListNum, hostPackBuf.ptr(), totalListNum,
     533              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     534            0 :     return HCCL_SUCCESS;
     535            1 : }
     536              : 
     537            0 : static HcclResult CopyUpdateKernelChannelListToDevice(
     538              :     ChannelHandle* deviceChannelHandles, uint32_t listNum, hccl::DeviceMem& deviceChannelList)
     539              : {
     540            0 :     deviceChannelList = hccl::DeviceMem::alloc(listNum * sizeof(ChannelHandle));
     541            0 :     CHK_PTR_NULL(deviceChannelList.ptr());
     542            0 :     CHK_RET(hrtMemSyncCopy(
     543              :         deviceChannelList.ptr(), listNum * sizeof(ChannelHandle), deviceChannelHandles, listNum * sizeof(ChannelHandle),
     544              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     545            0 :     return HCCL_SUCCESS;
     546              : }
     547              : 
     548            3 : HcclResult ChannelProcess::LaunchChannelKernelCommon(
     549              :     ChannelHandle* channelHandles, ChannelHandle* hostChannelHandles, HcommChannelDesc* hcommDesc, uint32_t listNum,
     550              :     const std::string& commTag, aclrtBinHandle binHandle, const std::string& kernelName, bool needProfiling)
     551              : {
     552            3 :     CHK_PTR_NULL(channelHandles);
     553            2 :     CHK_PTR_NULL(hostChannelHandles);
     554            1 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     555              : 
     556            0 :     HCCL_RUN_INFO("[%s] listNum[%u], commTag[%s]", __func__, listNum, commTag.c_str());
     557            0 :     std::vector<std::vector<char>> hostPackBuffers(listNum);
     558            0 :     HcclChannelUrmaRes channelParam{};
     559            0 :     CHK_SAFETY_FUNC_RET(memset_s(&channelParam, sizeof(channelParam), 0, sizeof(channelParam)));
     560              : 
     561              :     // 获取host侧序列化的地址
     562            0 :     std::vector<u32> channelSizeVec{};
     563            0 :     uint32_t totalListNum = 0;
     564            0 :     for (uint32_t index = 0; index < listNum; index++) {
     565            0 :         if (hcommDesc[index].remoteEndpoint.protocol == CommProtocol::COMM_PROTOCOL_PCIE) {
     566            0 :             auto aicpuTsP2pChannel = reinterpret_cast<AicpuTsP2pChannel*>(hostChannelHandles[index]);
     567            0 :             CHK_PRT(aicpuTsP2pChannel->H2DResPack(hostPackBuffers[index]));
     568            0 :         } else if (hcommDesc[index].remoteEndpoint.protocol == CommProtocol::COMM_PROTOCOL_UBOE) {
     569            0 :             auto aicpuTsUboeChannel = reinterpret_cast<AicpuTsUboeChannel*>(hostChannelHandles[index]);
     570            0 :             CHK_PRT(aicpuTsUboeChannel->H2DResPack(hostPackBuffers[index]));
     571            0 :         } else if (hcommDesc[index].remoteEndpoint.protocol == CommProtocol::COMM_PROTOCOL_UB_RTP) {
     572            0 :             auto aicpuTsUbRtpChannel = reinterpret_cast<AicpuTsUbRtpChannel*>(hostChannelHandles[index]);
     573            0 :             CHK_PRT(aicpuTsUbRtpChannel->H2DResPack(hostPackBuffers[index]));
     574            0 :         } else if (hcommDesc[index].remoteEndpoint.protocol == CommProtocol::COMM_PROTOCOL_ROCE) {
     575            0 :             auto aicpuTsRoceChannelV2 = reinterpret_cast<AicpuTsRoceChannelV2*>(hostChannelHandles[index]);
     576            0 :             CHK_PRT(aicpuTsRoceChannelV2->H2DResPack(hostPackBuffers[index]));
     577              :         } else {
     578            0 :             auto aicpuTsUrmaChannel = reinterpret_cast<AicpuTsUrmaChannel*>(hostChannelHandles[index]);
     579            0 :             CHK_PRT(aicpuTsUrmaChannel->H2DResPack(hostPackBuffers[index]));
     580              :         }
     581            0 :         totalListNum += hostPackBuffers[index].size();
     582            0 :         channelSizeVec.push_back(hostPackBuffers[index].size());
     583              :     }
     584            0 :     HCCL_INFO("[%s] totalListNum[%llu]", __func__, totalListNum);
     585              : 
     586              :     // 分配连续的host内存,将序列化的地址放入其中
     587            0 :     hccl::HostMem hostPackBuf = hccl::HostMem::alloc(totalListNum);
     588            0 :     CHK_PTR_NULL(hostPackBuf.ptr());
     589            0 :     CHK_RET(CombineHostMemory(hostPackBuffers, hostPackBuf));
     590            0 :     hccl::DeviceMem devicePackBuf = hccl::DeviceMem::alloc(totalListNum);
     591            0 :     CHK_PTR_NULL(devicePackBuf.ptr());
     592              : 
     593              :     // 将host侧序列化内容拷贝到device侧内存中
     594            0 :     CHK_RET(hrtMemSyncCopy(
     595              :         devicePackBuf.ptr(), totalListNum, hostPackBuf.ptr(), totalListNum,
     596              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     597              : 
     598            0 :     hccl::DeviceMem channelSizeAddr = hccl::DeviceMem::alloc(channelSizeVec.size() * sizeof(u32));
     599            0 :     CHK_PTR_NULL(channelSizeAddr.ptr());
     600              : 
     601            0 :     CHK_RET(hrtMemSyncCopy(
     602              :         channelSizeAddr.ptr(), channelSizeVec.size() * sizeof(u32), channelSizeVec.data(),
     603              :         channelSizeVec.size() * sizeof(u32), HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     604              :     // 为device侧的channelList分配内存
     605            0 :     hccl::DeviceMem deviceChannelList = hccl::DeviceMem::alloc(listNum * sizeof(ChannelHandle));
     606            0 :     CHK_PTR_NULL(deviceChannelList.ptr());
     607              : 
     608              :     // 填充channelParam参数
     609            0 :     CHK_RET(FillChannelParam(
     610              :         channelParam, commTag, deviceChannelList, devicePackBuf, listNum, totalListNum, channelSizeAddr));
     611              : 
     612              :     // ctx模式:检测channel是否预分配了ctx,复用deviceChannelList填ctx指针,跳过D2H
     613            0 :     bool isCtxMode = false;
     614            0 :     CHK_RET(AicpuTsChannelHelper::TryFillCtxList(
     615              :         hostChannelHandles, listNum, deviceChannelList, channelParam.ctxList, isCtxMode));
     616              : 
     617              :     // profiling信息
     618            0 :     hccl::DeviceMem remoteRankList = hccl::DeviceMem::alloc(listNum * sizeof(u32));
     619            0 :     CHK_PTR_NULL(remoteRankList.ptr());
     620            0 :     std::vector<u32> remoteRankIdList(listNum);
     621              :     // 集合通信场景才能开启
     622            0 :     if (needProfiling) {
     623            0 :         for (u32 i = 0; i < listNum; ++i) {
     624            0 :             CHK_RET(hccl::HcclCommDfx::GetChannelRemoteRankId(commTag, hostChannelHandles[i], remoteRankIdList[i]));
     625              :         }
     626              :         // 通过安全的内存拷贝将主机内存数据传输到设备内存
     627            0 :         CHK_RET(hrtMemSyncCopy(
     628              :             remoteRankList.ptr(), listNum * sizeof(u32), remoteRankIdList.data(), listNum * sizeof(u32),
     629              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     630            0 :         channelParam.remoteRankList = static_cast<u32*>(remoteRankList.ptr());
     631              :     }
     632              : 
     633              :     // 调用抽离的通用内核启动函数
     634            0 :     CHK_RET(LaunchKernel(channelParam, binHandle, kernelName));
     635              : 
     636            0 :     if (!isCtxMode) {
     637              :         // 将device侧的channelList拷贝回host侧的channelList
     638            0 :         CHK_RET(hrtMemSyncCopy(
     639              :             channelHandles, listNum * sizeof(ChannelHandle), deviceChannelList.ptr(), listNum * sizeof(ChannelHandle),
     640              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
     641              : 
     642            0 :         CHK_RET(FillChannelD2HMap(channelHandles, hostChannelHandles, listNum));
     643              :     }
     644              : 
     645            0 :     HCCL_INFO("[%s] channel kernel launch success.", __func__);
     646            0 :     return HCCL_SUCCESS;
     647            0 : }
     648              : 
     649            0 : HcclResult ChannelProcess::ChannelKernelLaunchForComm(
     650              :     ChannelHandle* channelHandles, ChannelHandle* hostChannelHandles, HcommChannelDesc* hcommDesc, uint32_t listNum,
     651              :     const std::string& commTag, aclrtBinHandle binHandle)
     652              : {
     653            0 :     return LaunchChannelKernelCommon(
     654            0 :         channelHandles, hostChannelHandles, hcommDesc, listNum, commTag, binHandle, "RunAicpuIndOpChannelInitV2", true);
     655              : }
     656              : 
     657            1 : HcclResult ChannelProcess::ChannelKernelLaunchForBase(
     658              :     ChannelHandle* channelHandles, ChannelHandle* hostChannelHandles, HcommChannelDesc* hcommDesc, uint32_t listNum,
     659              :     aclrtBinHandle binHandle)
     660              : {
     661            5 :     return LaunchChannelKernelCommon(
     662            2 :         channelHandles, hostChannelHandles, hcommDesc, listNum, "", binHandle, "RunAicpuChannelInitV2", false);
     663              : }
     664              : 
     665              : namespace {
     666              : 
     667              :     struct KHost {
     668              :         std::vector<std::shared_ptr<hccl::DeviceMem>> mem;
     669              :         std::vector<void*> ptr;
     670              :         std::vector<u64> sz;
     671              :         std::vector<u32> kind;
     672              :     };
     673              : 
     674              :     struct KDev {
     675              :         hccl::DeviceMem data;
     676              :         hccl::DeviceMem size;
     677              :         hccl::DeviceMem type;
     678              :     };
     679              : 
     680            0 :     HcclResult PackHost(ChannelHandle* host, uint32_t n, HcommChannelKind k, KHost& out)
     681              :     {
     682            0 :         out.mem.resize(n);
     683            0 :         out.ptr.resize(n);
     684            0 :         out.sz.resize(n);
     685            0 :         out.kind.resize(n);
     686            0 :         for (uint32_t i = 0; i < n; ++i) {
     687            0 :             auto* channel = reinterpret_cast<Channel*>(host[i]);
     688            0 :             CHK_PTR_NULL(channel);
     689            0 :             CHK_RET(channel->Serialize(out.mem[i]));
     690            0 :             CHK_PTR_NULL(out.mem[i]);
     691            0 :             CHK_PTR_NULL(out.mem[i]->ptr());
     692            0 :             out.ptr[i] = out.mem[i]->ptr();
     693            0 :             out.sz[i] = out.mem[i]->size();
     694            0 :             out.kind[i] = static_cast<u32>(k);
     695              :         }
     696            0 :         return HCCL_SUCCESS;
     697              :     }
     698              : 
     699            0 :     HcclResult PushDev(uint32_t n, const KHost& in, KDev& out)
     700              :     {
     701            0 :         out.data = hccl::DeviceMem::alloc(n * sizeof(void*));
     702            0 :         CHK_PTR_NULL(out.data.ptr());
     703            0 :         out.size = hccl::DeviceMem::alloc(n * sizeof(u64));
     704            0 :         CHK_PTR_NULL(out.size.ptr());
     705            0 :         out.type = hccl::DeviceMem::alloc(n * sizeof(u32));
     706            0 :         CHK_PTR_NULL(out.type.ptr());
     707              : 
     708            0 :         CHK_RET(hrtMemSyncCopy(
     709              :             out.data.ptr(), n * sizeof(void*), in.ptr.data(), n * sizeof(void*),
     710              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     711            0 :         CHK_RET(hrtMemSyncCopy(
     712              :             out.size.ptr(), n * sizeof(u64), in.sz.data(), n * sizeof(u64),
     713              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     714            0 :         CHK_RET(hrtMemSyncCopy(
     715              :             out.type.ptr(), n * sizeof(u32), in.kind.data(), n * sizeof(u32),
     716              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     717            0 :         return HCCL_SUCCESS;
     718              :     }
     719              : 
     720              : } // namespace
     721              : 
     722            0 : HcclResult ChannelProcess::LaunchCommonChannelKernel(
     723              :     ChannelHandle* channelHandles, ChannelHandle* hostChannelHandles, uint32_t listNum, HcommChannelKind channelKind,
     724              :     aclrtBinHandle binHandle)
     725              : {
     726            0 :     HCCL_RUN_INFO("[%s] listNum[%u] HcommChannelRes path", __func__, listNum);
     727            0 :     CHK_PRT_RET((listNum == 0), HCCL_ERROR("[%s]Invalid listNum, listNum[%u]", __func__, listNum), HCCL_E_PARA);
     728              : 
     729            0 :     KHost host;
     730            0 :     CHK_RET(PackHost(hostChannelHandles, listNum, channelKind, host));
     731            0 :     KDev dev;
     732            0 :     CHK_RET(PushDev(listNum, host, dev));
     733              : 
     734            0 :     hccl::DeviceMem deviceChannelList = hccl::DeviceMem::alloc(listNum * sizeof(ChannelHandle));
     735            0 :     CHK_PTR_NULL(deviceChannelList.ptr());
     736              : 
     737            0 :     HcommChannelRes channelParam{};
     738            0 :     channelParam.channelList = static_cast<void*>(deviceChannelList.ptr());
     739            0 :     channelParam.listNum = listNum;
     740            0 :     channelParam.channelDataListAddr = static_cast<void*>(dev.data.ptr());
     741            0 :     channelParam.channelDataSizeListAddr = static_cast<void*>(dev.size.ptr());
     742            0 :     channelParam.channelTypeListAddr = static_cast<void*>(dev.type.ptr());
     743            0 :     CHK_RET(hrtGetDevice(&channelParam.deviceInfo.deviceLogicId));
     744            0 :     CHK_RET(hrtGetDevicePhyIdByIndex(
     745              :         static_cast<u32>(channelParam.deviceInfo.deviceLogicId), channelParam.deviceInfo.devicePhyId));
     746              :     DevType devType;
     747            0 :     CHK_RET(hrtGetDeviceType(devType));
     748            0 :     channelParam.deviceInfo.deviceType = static_cast<u32>(devType);
     749              : 
     750              :     // ctx模式:检测channel是否预分配了ctx,复用deviceChannelList填ctx指针,跳过D2H
     751            0 :     bool isCtxMode = false;
     752            0 :     CHK_RET(AicpuTsChannelHelper::TryFillCtxList(
     753              :         hostChannelHandles, listNum, deviceChannelList, channelParam.ctxList, isCtxMode));
     754              : 
     755            0 :     CHK_RET(LaunchKernelDeviceParam(channelParam, binHandle, "RunAicpuChannelInitV3"));
     756              : 
     757            0 :     if (!isCtxMode) {
     758            0 :         CHK_RET(hrtMemSyncCopy(
     759              :             channelHandles, listNum * sizeof(ChannelHandle), deviceChannelList.ptr(), listNum * sizeof(ChannelHandle),
     760              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
     761              : 
     762            0 :         CHK_RET(FillChannelD2HMap(channelHandles, hostChannelHandles, listNum));
     763              :     }
     764            0 :     HCCL_INFO("[%s] channel kernel (HcommChannelRes) launch success.", __func__);
     765            0 :     return HCCL_SUCCESS;
     766            0 : }
     767              : 
     768            1 : HcclResult ChannelProcess::LaunchChannelKernel(
     769              :     ChannelHandle* channelHandles, ChannelHandle* hostChannelHandles, HcommChannelDesc* hcommDesc, uint32_t listNum,
     770              :     aclrtBinHandle binHandle)
     771              : {
     772            1 :     HCCL_RUN_INFO("[%s] listNum[%u]", __func__, listNum);
     773            1 :     CHK_PRT_RET(listNum == 0U, HCCL_ERROR("[%s] listNum is 0", __func__), HCCL_E_PARA);
     774            1 :     auto* ch = reinterpret_cast<Channel*>(hostChannelHandles[0]);
     775            1 :     CHK_PTR_NULL(ch);
     776            1 :     if (ch->GetChannelKind() == HcommChannelKind::AICPU_TS_URMA
     777            1 :         || ch->GetChannelKind() == HcommChannelKind::AICPU_TS_UBOE
     778            2 :         || ch->GetChannelKind() == HcommChannelKind::AICPU_TS_UB_RTP) {
     779            1 :         return ChannelKernelLaunchForBase(channelHandles, hostChannelHandles, hcommDesc, listNum, binHandle);
     780              :     }
     781            0 :     return LaunchCommonChannelKernel(channelHandles, hostChannelHandles, listNum, ch->GetChannelKind(), binHandle);
     782              : }
     783              : 
     784           23 : HcclResult ChannelProcess::PrepareUserChannels(
     785              :     ChannelHandle* targetChannels, ChannelHandle* userChannels, HcommChannelDesc* channelDescs, uint32_t channelNum,
     786              :     CommEngine engine)
     787              : {
     788           23 :     CHK_PTR_NULL(targetChannels);
     789           22 :     CHK_PTR_NULL(userChannels);
     790           22 :     CHK_PRT_RET(
     791              :         (channelNum == 0), HCCL_ERROR("[%s]Invalid channelNum, channelNum[%u]", __func__, channelNum), HCCL_E_PARA);
     792              : 
     793           21 :     HCCL_INFO(
     794              :         "[%s] engine[%s], channelNum[%u].", __func__, GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(),
     795              :         channelNum);
     796           21 :     if (engine == COMM_ENGINE_AICPU || engine == COMM_ENGINE_AICPU_TS) {
     797            3 :         CHK_RET(AicpuTsChannelHelper::PreAllocChannels(targetChannels, userChannels, channelDescs, channelNum));
     798           20 :     } else if (engine == COMM_ENGINE_AIV) {
     799            0 :         CHK_RET(AivChannelHelper::PreAllocChannels(targetChannels, userChannels, channelDescs, channelNum));
     800              :     } else {
     801           18 :         HCCL_INFO(
     802              :             "[%s] engine[%s] no need to pre-alloc.", __func__,
     803              :             GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str());
     804           36 :         for (uint32_t i = 0; i < channelNum; i++) {
     805           18 :             userChannels[i] = targetChannels[i];
     806              :         }
     807              :     }
     808           20 :     return HCCL_SUCCESS;
     809              : }
     810              : 
     811            0 : HcclResult ChannelProcess::ChannelGetNotifyNum(ChannelHandle channelHandle, uint32_t* notifyNum)
     812              : {
     813            0 :     return WithChannelByHandleLocked(channelHandle, [&notifyNum](Channel& channel) -> HcclResult {
     814              :         // 锁内调用,避免 destroy 并发释放
     815            0 :         channel.GetNotifyNum(notifyNum);
     816            0 :         return HcclResult::HCCL_SUCCESS;
     817            0 :     });
     818              : }
     819              : 
     820            3 : HcclResult ChannelProcess::ChannelGetRemoteMems(
     821              :     ChannelHandle channelHandle, uint32_t* memNum, CommMem** remoteMem, char*** memInfos)
     822              : {
     823            3 :     CHK_PTR_NULL(remoteMem);
     824            2 :     CHK_PTR_NULL(memNum);
     825            1 :     CHK_PTR_NULL(memInfos);
     826              : 
     827            0 :     return WithChannelByHandleLocked(channelHandle, [&memNum, &remoteMem, &memInfos](Channel& channel) -> HcclResult {
     828              :         // 锁内调用,避免 destroy 并发释放
     829            0 :         return channel.GetRemoteMems(memNum, remoteMem, memInfos);
     830            0 :     });
     831              : }
     832              : 
     833           62 : HcclResult ChannelProcess::ChannelGet(const ChannelHandle channelHandle, void** channel)
     834              : {
     835           62 :     CHK_PTR_NULL(channel);
     836           62 :     int32_t deviceId = 0;
     837           62 :     CHK_RET(hrtGetDevice(&deviceId));
     838              : 
     839           62 :     std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     840           62 :     DeviceChannelKey key{deviceId, channelHandle};
     841           62 :     const auto& D2HhandleIter = g_ChannelD2HMap.find(key);
     842           62 :     if (D2HhandleIter == g_ChannelD2HMap.end()) {
     843            0 :         HCCL_ERROR("[ChannelProcess][%s] deviceId[%d], channel[%llx] not found.", __func__, deviceId, channelHandle);
     844            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     845              :     }
     846              : 
     847           62 :     const auto handle = D2HhandleIter->second;
     848           62 :     const auto& handleIter = g_ChannelMap.find(handle);
     849           62 :     if (handleIter == g_ChannelMap.end()) {
     850            0 :         HCCL_ERROR("[ChannelProcess][%s] deviceId[%d], channel[%llx] not found.", __func__, deviceId, handle);
     851            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     852              :     }
     853           62 :     *channel = reinterpret_cast<void*>(handleIter->second.get());
     854           62 :     return HcclResult::HCCL_SUCCESS;
     855           62 : }
     856              : 
     857              : HcclResult
     858            0 : ChannelProcess::ChannelKernelDestroy(ChannelHandle* channelHandles, uint32_t listNum, aclrtBinHandle binHandle)
     859              : {
     860            0 :     HCCL_RUN_INFO("[%s] listNum[%u]", __func__, listNum);
     861            0 :     HcclChannelUrmaRes channelParam{};
     862            0 :     CHK_SAFETY_FUNC_RET(memset_s(&channelParam, sizeof(channelParam), 0, sizeof(channelParam)));
     863              : 
     864              :     // 将 host 侧的 channel handles 拷贝到 device 内存,供内核使用
     865            0 :     hccl::DeviceMem deviceChannelList = hccl::DeviceMem::alloc(listNum * sizeof(ChannelHandle));
     866            0 :     CHK_PTR_NULL(deviceChannelList.ptr());
     867            0 :     CHK_RET(hrtMemSyncCopy(
     868              :         deviceChannelList.ptr(), listNum * sizeof(ChannelHandle), channelHandles, listNum * sizeof(ChannelHandle),
     869              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     870              : 
     871              :     // 填充 channelParam(只需 channelList 和 listNum)
     872            0 :     channelParam.channelList = static_cast<void*>(deviceChannelList.ptr());
     873            0 :     channelParam.listNum = listNum;
     874              : 
     875              :     // 下 kernel
     876            0 :     std::string kernelName = "RunAicpuChannelDestroyV2";
     877              : 
     878              :     // 调用抽离的通用内核启动函数
     879            0 :     CHK_RET(LaunchKernel(channelParam, binHandle, kernelName));
     880              : 
     881            0 :     HCCL_INFO("[%s] channel kernel destroy success.", __func__);
     882            0 :     return HCCL_SUCCESS;
     883            0 : }
     884              : 
     885              : HcclResult
     886           32 : ChannelProcess::RemoveSingleChannel(int32_t deviceId, ChannelHandle inHandle, std::vector<ChannelHandle>& deviceHandles)
     887              : {
     888           32 :     DeviceChannelKey key{deviceId, inHandle};
     889           32 :     auto itH = g_ChannelD2HMap.find(key);
     890           32 :     if (itH == g_ChannelD2HMap.end()) {
     891           14 :         HCCL_ERROR(
     892              :             "[Hcomm][%s] failed to find handle mapping in g_ChannelD2HMap, deviceId[%d], inHandle[0x%llx].", __func__,
     893              :             deviceId, inHandle);
     894           14 :         return HcclResult::HCCL_E_NOT_FOUND;
     895              :     }
     896           18 :     const ChannelHandle mappedHandle = itH->second;
     897              : 
     898           18 :     auto itC = g_ChannelMap.find(mappedHandle);
     899           18 :     if (itC == g_ChannelMap.end()) {
     900            0 :         HCCL_ERROR(
     901              :             "[Hcomm][%s] failed to find channel in g_ChannelMap, deviceId[%d], inHandle[0x%llx], mappedHandle[0x%llx].",
     902              :             __func__, deviceId, inHandle, mappedHandle);
     903            0 :         return HcclResult::HCCL_E_NOT_FOUND;
     904              :     }
     905           18 :     deviceHandles.push_back(inHandle);
     906              : 
     907           18 :     HCCL_INFO(
     908              :         "[Hcomm][%s] erase channel: deviceId[%d], inHandle[0x%llx], mappedHandle[0x%llx], ptr[%p]", __func__, deviceId,
     909              :         inHandle, mappedHandle, itC->second.get());
     910              : 
     911           18 :     g_ChannelMap.erase(itC);
     912              : 
     913           40 :     for (auto it = g_ChannelD2HMap.begin(); it != g_ChannelD2HMap.end();) {
     914           22 :         if (it->first.deviceId == deviceId && it->second == mappedHandle) {
     915           20 :             it = g_ChannelD2HMap.erase(it);
     916              :         } else {
     917            2 :             ++it;
     918              :         }
     919              :     }
     920           18 :     return HCCL_SUCCESS;
     921              : }
     922              : 
     923           32 : HcclResult ChannelProcess::ChannelDestroy(const ChannelHandle* channels, uint32_t channelNum, aclrtBinHandle binHandle)
     924              : {
     925           32 :     CHK_PTR_NULL(channels);
     926           32 :     CHK_PRT_RET((channelNum == 0), HCCL_ERROR("[%s] Invalid channelNum[0]", __func__), HCCL_E_PARA);
     927           32 :     HCCL_INFO("[%s] START. channelNum[%u].", __func__, channelNum);
     928              : 
     929           32 :     int32_t deviceId = 0;
     930           32 :     CHK_RET(hrtGetDevice(&deviceId));
     931              : 
     932           32 :     std::vector<ChannelHandle> deviceHandles;
     933              : 
     934              :     {
     935           32 :         std::lock_guard<std::mutex> lock(g_ChannelMapMtx);
     936           50 :         for (uint32_t i = 0; i < channelNum; ++i) {
     937           32 :             HcclResult ret = RemoveSingleChannel(deviceId, channels[i], deviceHandles);
     938           32 :             if (ret != HCCL_SUCCESS) {
     939           14 :                 return ret;
     940              :             }
     941              :         }
     942           32 :     }
     943              : 
     944           18 :     if (!deviceHandles.empty() && binHandle) {
     945            0 :         CHK_RET(ChannelKernelDestroy(deviceHandles.data(), deviceHandles.size(), binHandle));
     946              :     }
     947           18 :     HCCL_INFO("[%s] SUCCESS.", __func__);
     948           18 :     return HCCL_SUCCESS;
     949           32 : }
     950              : 
     951            1 : HcclResult ChannelProcess::ChannelClean(const ChannelHandle* channelList, uint32_t channelNum)
     952              : {
     953            1 :     CHK_PTR_NULL(channelList);
     954              : 
     955            0 :     for (uint32_t i = 0; i < channelNum; ++i) {
     956            0 :         const ChannelHandle inHandle = channelList[i];
     957              :         // 单锁:D2H 映射 + 查 map + 锁内调用 Clean()
     958            0 :         HcclResult ret = WithChannelByHandleLocked(inHandle, [](Channel& channel) -> HcclResult {
     959            0 :             return channel.Clean();
     960              :         });
     961            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
     962            0 :             HCCL_ERROR("[%s] ChannelHandle Clean failed, ret = 0x%016llx, i = %u", __func__, HCCL_ERROR_CODE(ret), i);
     963            0 :             return ret;
     964              :         }
     965              :     }
     966              : 
     967            0 :     return HcclResult::HCCL_SUCCESS;
     968              : }
     969              : 
     970            1 : HcclResult ChannelProcess::ChannelResumeConcurrency(const ChannelHandle* channelList, uint32_t channelNum)
     971              : {
     972            1 :     for (uint32_t i = 0; i < channelNum; ++i) {
     973            0 :         const ChannelHandle inHandle = channelList[i];
     974            0 :         HcclResult ret = WithChannelByHandleLocked(inHandle, [](Channel& channel) -> HcclResult {
     975            0 :             return channel.Resume();
     976              :         });
     977            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
     978            0 :             HCCL_ERROR("[%s] Get ChannelHandle failed, ret = 0x%016llx, i = %u", __func__, HCCL_ERROR_CODE(ret), i);
     979            0 :             return ret;
     980              :         }
     981              :     }
     982            1 :     return HCCL_SUCCESS;
     983              : }
     984            2 : HcclResult ChannelProcess::ChannelResume(const ChannelHandle* channelList, uint32_t channelNum)
     985              : {
     986            2 :     CHK_PTR_NULL(channelList);
     987              : 
     988              :     // 1.resume resource
     989            1 :     HcclResult ret = ChannelResumeConcurrency(channelList, channelNum);
     990            1 :     if (ret != HcclResult::HCCL_SUCCESS) {
     991            1 :         HCCL_ERROR("HcommChannelResumeConcurrency error, ret = 0x%016llx", HCCL_ERROR_CODE(ret));
     992            1 :         return ret;
     993              :     }
     994              : 
     995            0 :     auto timeout = std::chrono::seconds(Hccl::EnvConfig::GetInstance().GetSocketConfig().GetLinkTimeOut());
     996            0 :     auto startTime = std::chrono::steady_clock::now();
     997            0 :     HCCL_INFO("[%s] start resuming channels, timeout[%u]sec", __func__, timeout);
     998              : 
     999            0 :     std::vector<int32_t> statusVec(channelNum, 0);
    1000            0 :     int32_t* statusList = statusVec.data();
    1001            0 :     uint32_t retryCount{0};
    1002              :     while (true) {
    1003            0 :         HcclResult ret = ChannelGetStatus(channelList, channelNum, statusList);
    1004              :         // 1. 检查超时
    1005            0 :         if ((std::chrono::steady_clock::now() - startTime) >= timeout) {
    1006              :             auto elapsed
    1007            0 :                 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTime)
    1008            0 :                       .count();
    1009            0 :             HCCL_ERROR(
    1010              :                 "[%s] channel resume timeout after %u sec, channelNum[%u], elapsed[%lld]ms, retryCount[%u]", __func__,
    1011              :                 timeout, channelNum, elapsed, retryCount);
    1012            0 :             return HCCL_E_TIMEOUT;
    1013              :         }
    1014              : 
    1015              :         // 2. 处理重试(去除频繁的重试日志,一秒可能重试上千次)
    1016            0 :         if (ret == HCCL_E_AGAIN) {
    1017            0 :             ++retryCount;
    1018            0 :             continue;
    1019              :         }
    1020              : 
    1021              :         // 3. 处理失败
    1022            0 :         if (ret != HCCL_SUCCESS) {
    1023              :             auto elapsed
    1024            0 :                 = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTime)
    1025            0 :                       .count();
    1026            0 :             HCCL_ERROR(
    1027              :                 "[%s] channel connect failed, channelNum[%u], ret[%d], elapsed[%lld]ms, retryCount[%u]", __func__,
    1028              :                 channelNum, ret, elapsed, retryCount);
    1029            0 :             return ret;
    1030              :         }
    1031              : 
    1032              :         // 4. 正常情况:所有通道连接成功
    1033              :         auto elapsed
    1034            0 :             = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - startTime)
    1035            0 :                   .count();
    1036            0 :         HCCL_INFO(
    1037              :             "[%s] all channels connected successfully, channelNum[%u], elapsed[%lld]ms, retryCount[%u]", __func__,
    1038              :             channelNum, elapsed, retryCount);
    1039            0 :         break;
    1040            0 :     }
    1041              : 
    1042            0 :     return HcclResult::HCCL_SUCCESS;
    1043            0 : }
    1044              : 
    1045            1 : HcclResult ChannelProcess::ChannelUpdateKernelLaunch(
    1046              :     ChannelHandle* deviceChannelHandles, ChannelHandle* hostChannelHandles, uint32_t listNum,
    1047              :     const std::string& commTag, aclrtBinHandle binHandle)
    1048              : {
    1049            1 :     HCCL_RUN_INFO("[%s] listNum[%u], commTag[%s]", __func__, listNum, commTag.c_str());
    1050            1 :     std::vector<std::vector<char>> hostPackBuffers(listNum);
    1051            1 :     HcclChannelUrmaRes channelParam{};
    1052            1 :     CHK_SAFETY_FUNC_RET(memset_s(&channelParam, sizeof(channelParam), 0, sizeof(channelParam)));
    1053              : 
    1054              :     // 获取host侧序列化的地址
    1055            1 :     uint32_t totalListNum = 0;
    1056            1 :     std::vector<u32> channelSizeVec{};
    1057            1 :     for (uint32_t index = 0; index < listNum; index++) {
    1058            1 :         Channel* channel = reinterpret_cast<Channel*>(hostChannelHandles[index]);
    1059            1 :         if (channel->GetChannelKind() != HcommChannelKind::AICPU_TS_URMA) {
    1060            1 :             CHK_RET(PackAicpuTsChannelH2DRes(hostChannelHandles[index], hostPackBuffers[index]));
    1061            0 :             totalListNum += hostPackBuffers[index].size();
    1062            0 :             channelSizeVec.push_back(hostPackBuffers[index].size());
    1063            0 :             continue;
    1064            0 :         }
    1065            0 :         auto aicpuTsUrmaChannel = reinterpret_cast<AicpuTsUrmaChannel*>(hostChannelHandles[index]);
    1066            0 :         CHK_RET(aicpuTsUrmaChannel->H2DResPack(hostPackBuffers[index])); // todo:后续只打包connction
    1067            0 :         totalListNum += hostPackBuffers[index].size();
    1068            0 :         channelSizeVec.push_back(hostPackBuffers[index].size());
    1069              :     }
    1070            0 :     HCCL_INFO("[%s] totalListNum[%llu]", __func__, totalListNum);
    1071              : 
    1072            0 :     hccl::DeviceMem channelSizeAddr;
    1073            0 :     hccl::DeviceMem devicePackBuf;
    1074            0 :     CHK_RET(
    1075              :         CopyUpdateKernelPackResToDevice(hostPackBuffers, channelSizeVec, totalListNum, channelSizeAddr, devicePackBuf));
    1076              : 
    1077            0 :     s32 sRet = strncpy_s(channelParam.hcomId, HCOMID_MAX_LENGTH, commTag.c_str(), HCOMID_MAX_LENGTH - 1);
    1078            0 :     CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[%s] str copy fail. return[%d]", __func__, sRet), HCCL_E_INTERNAL);
    1079            0 :     channelParam.listNum = listNum;
    1080            0 :     channelParam.uniqueIdAddr = static_cast<void*>(devicePackBuf.ptr());
    1081            0 :     channelParam.uniqueIdSize = totalListNum;
    1082            0 :     channelParam.channelSizeAddr = static_cast<void*>(channelSizeAddr.ptr());
    1083              : 
    1084              :     // 将 host 侧的 channel handles 拷贝到 device 内存,供内核使用
    1085            0 :     hccl::DeviceMem deviceChannelList;
    1086            0 :     CHK_RET(CopyUpdateKernelChannelListToDevice(deviceChannelHandles, listNum, deviceChannelList));
    1087            0 :     channelParam.channelList = static_cast<void*>(deviceChannelList.ptr());
    1088              : 
    1089            0 :     std::string kernelName = "RunAicpuIndOpChannelUpdateV2";
    1090            0 :     CHK_RET(LaunchKernel(channelParam, binHandle, kernelName));
    1091              : 
    1092            0 :     HCCL_INFO("[%s] channel kernel launch success.", __func__);
    1093            0 :     return HCCL_SUCCESS;
    1094            1 : }
    1095              : 
    1096              : } // namespace hcomm
        

Generated by: LCOV version 2.0-1