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: 45.4 % 535 243
Test Date: 2026-07-28 12:11:00 Functions: 50.0 % 44 22

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

Generated by: LCOV version 2.0-1