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: 52.3 % 687 359
Test Date: 2026-08-25 19:18:03 Functions: 57.4 % 54 31

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

Generated by: LCOV version 2.0-1