LCOV - code coverage report
Current view: top level - base_comm/resources/comm_engine_res/launch - aicpu_launch_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 52.6 % 171 90
Test Date: 2026-07-28 12:11:00 Functions: 46.2 % 13 6

            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 "aicpu_launch_manager.h"
      12              : #include "adapter_rts_common.h"
      13              : #include "mem_device_pub.h"
      14              : #include "notify_manager.h"
      15              : #include "launch_aicpu.h"
      16              : #include "comm_configer.h"
      17              : #include <iomanip>
      18              : #include "hcom_host_profiling.h"
      19              : #include "adapter_prof.h"
      20              : 
      21              : namespace hccl {
      22              : template <typename OpParam, typename ApiParam>
      23              : HcclResult AicpuLaunchMgr::KernelLaunch(OpParam &opParam, ApiParam &apiParam, rtStream_t aicpuInitStream)
      24              : {
      25              :     return HCCL_SUCCESS;
      26              : }
      27              : 
      28            2 : HcclResult AicpuLaunchMgr::KernelLaunchAicpuCustom(uint64_t context, std::string kernelName, rtStream_t aicpuInitStream,
      29              :     aclrtBinHandle binCustomHandle)
      30              : {
      31            2 :     u16 timeOut = NOTIFY_DEFAULT_WAIT_TIME > std::numeric_limits<uint16_t>::max() ? 
      32              :                     std::numeric_limits<uint16_t>::max() : NOTIFY_DEFAULT_WAIT_TIME;
      33            2 :     CHK_RET(AicpuAclKernelLaunch(aicpuInitStream, &context,
      34              :         sizeof(context), binCustomHandle, kernelName, true, timeOut));
      35            2 :     return HCCL_SUCCESS;
      36              : }
      37              : 
      38            0 : HcclResult AicpuLaunchMgr::AiCpuStreamAllocAndGet(rtStream_t &aiCpuStream)
      39              : {
      40            0 :     if (opStream_.ptr() != nullptr) {
      41            0 :         HCCL_INFO("%s already alloc, stream id:%u", __func__, opStream_.id());
      42            0 :         aiCpuStream = opStream_.ptr();
      43            0 :         return HCCL_SUCCESS;
      44              :     }
      45              : 
      46            0 :     constexpr u32 aicpuStreamMode = 1; // 单独申请的kernel流,使能遇错即停,避免出错后流卡住不退
      47            0 :     opStream_ = Stream(StreamType::STREAM_TYPE_ONLINE);
      48            0 :     CHK_RET(hrtStreamSetMode(opStream_.ptr(), aicpuStreamMode));
      49            0 :     aiCpuStream = opStream_.ptr();
      50            0 :     HCCL_RUN_INFO("[AicpuLaunchMgr][%s] alloc success, stream id:%u, aicpuStreamMode:%u",
      51              :                     __func__, opStream_.id(), aicpuStreamMode);
      52            0 :     return HCCL_SUCCESS;
      53              : }
      54              : 
      55            2 : static HcclResult CreateLocalStream(Stream &localStream)
      56              : {
      57            2 :     HCCL_INFO("[%s] create local stream", __func__);
      58            2 :     localStream = Stream(StreamType::STREAM_TYPE_ONLINE);
      59            2 :     constexpr u32 aicpuStreamMode = 1;
      60            2 :     CHK_RET(hrtStreamSetMode(localStream.ptr(), aicpuStreamMode));
      61            2 :     return HCCL_SUCCESS;
      62              : }
      63              : 
      64            1 : static HcclResult PrepareThreadMgrParam(const std::vector<std::shared_ptr<Thread>> &newThreads,
      65              :                                         const ThreadKernelLaunchConfig &config,
      66              :                                         ThreadMgrAicpuParam &opParam,
      67              :                                         DeviceMem &deviceHandle)
      68              : {
      69            1 :     HCCL_INFO("[%s] fill opParam", __func__);
      70            1 :     (void)memset_s(&opParam, sizeof(opParam), 0, sizeof(opParam));
      71            1 :     opParam.threadNum = newThreads.size();
      72              : 
      73              :     // 拷贝 commId
      74            1 :     errno_t sRet = strncpy_s(opParam.hcomId, HCOMID_MAX_SIZE, config.commId.c_str(), config.commId.length());
      75            1 :     CHK_PRT_RET(sRet != EOK,
      76              :         HCCL_ERROR("[%s] strncpy_s failed, return [%d].", __func__, sRet),
      77              :         HCCL_E_MEMORY);
      78            1 :     opParam.hcomId[HCOMID_MAX_SIZE - 1] = '\0';
      79              : 
      80              :     // 拷贝每个线程的 unique id
      81            2 :     for (u32 i = 0; i < opParam.threadNum; ++i) {
      82            1 :         const std::string &uid = newThreads[i]->GetUniqueId();
      83            1 :         size_t copyLen = std::min(uid.size(), static_cast<size_t>(THREAD_UNIQUE_ID_MAX_SIZE));
      84            1 :         sRet = memcpy_s(opParam.threadParam[i], THREAD_UNIQUE_ID_MAX_SIZE, uid.c_str(), copyLen);
      85            1 :         CHK_PRT_RET(sRet != EOK,
      86              :             HCCL_ERROR("[%s] memcpy_s failed, return [%d].", __func__, sRet),
      87              :             HCCL_E_MEMORY);
      88            1 :         opParam.threadParam[i][THREAD_UNIQUE_ID_MAX_SIZE - 1] = '\0';
      89              : 
      90            1 :         if (UNLIKELY(HcclCheckLogLevel(HCCL_LOG_INFO))) {
      91            1 :             std::ostringstream oss;
      92            1 :             oss << "threadParam[" << i << "] raw bytes: ";
      93            1 :             constexpr u32 HEX_WIDTH = 2;
      94         6001 :             for (u32 j = 0; j < THREAD_UNIQUE_ID_MAX_SIZE; ++j) {
      95         6000 :                 oss << std::hex << std::setw(HEX_WIDTH) << std::setfill('0')
      96         6000 :                     << static_cast<unsigned int>(static_cast<unsigned char>(opParam.threadParam[i][j])) << " ";
      97              :             }
      98            1 :             HCCL_INFO("[%s] %s", __func__, oss.str().c_str());
      99            1 :         }
     100              :     }
     101              : 
     102              :     // 分配设备内存
     103            1 :     size_t handleLen = sizeof(ThreadHandle) * newThreads.size();
     104            1 :     deviceHandle = DeviceMem::alloc(handleLen);
     105            1 :     CHK_SMART_PTR_NULL(deviceHandle);
     106            1 :     opParam.deviceHandle = deviceHandle.ptr();
     107              : 
     108              :     // 基础通信需要设备信息
     109            1 :     if (config.needDeviceInfo) {
     110            0 :         CHK_RET(hrtGetDevice(&opParam.deviceLogicId));
     111              :         DevType devType;
     112            0 :         CHK_RET(hrtGetDeviceType(devType));
     113            0 :         opParam.deviceType = static_cast<u32>(devType);
     114              :     }
     115            1 :     return HCCL_SUCCESS;
     116              : }
     117              : 
     118            1 : HcclResult AicpuLaunchMgr::ThreadKernelLaunchImpl(
     119              :     std::vector<std::shared_ptr<Thread>> &newThreads,
     120              :     std::unique_ptr<ThreadHandle[]> &aicpuHandle,
     121              :     const ThreadKernelLaunchConfig &config)
     122              : {
     123              :     // 参数检查
     124            1 :     CHK_PRT_RET(newThreads.size() > SIGNAL_DEV_STREAM_MAX_NUM,
     125              :         HCCL_ERROR("[AicpuLaunchMgr][%s] streamNum[%zu] > SIGNAL_DEV_STREAM_MAX_NUM[%u]", __func__,
     126              :         newThreads.size(), SIGNAL_DEV_STREAM_MAX_NUM), HCCL_E_PARA);
     127              : 
     128            1 :     uint64_t beginTime = (config.needProfiling ? hrtMsprofSysCycleTime() : 0);
     129              : 
     130              :     // Step 1. 创建局部 stream
     131            1 :     Stream localStream;
     132            1 :     CHK_RET(CreateLocalStream(localStream));
     133              : 
     134              :     // Step 2. 填写 opParam 并分配设备内存
     135            1 :     ThreadMgrAicpuParam opParam{};
     136            1 :     DeviceMem deviceHandle;
     137            1 :     CHK_RET(PrepareThreadMgrParam(newThreads, config, opParam, deviceHandle));
     138              : 
     139            1 :     size_t handleLen = sizeof(ThreadHandle) * newThreads.size();
     140              :     // Step 3. 补充notify,将threadHanle拷到device侧
     141            1 :     if (config.isSupplementNotify) {
     142            0 :         CHK_RET(hrtMemSyncCopy(opParam.deviceHandle, handleLen, aicpuHandle.get(), handleLen,
     143              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     144              :     }
     145              : 
     146              :     // Step 4. 调用 KernelLaunch
     147            1 :     DeviceMem addr = DeviceMem::alloc(sizeof(opParam));
     148            1 :     CHK_RET(hrtMemSyncCopy(addr.ptr(), sizeof(opParam), &opParam, sizeof(opParam),
     149              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     150            1 :     uint64_t context = reinterpret_cast<uint64_t>(addr.ptr());
     151            1 :     HCCL_INFO("AicpuLaunchMgr::%s, call KernelLaunch", __func__);
     152            1 :     HcclResult ret = KernelLaunchAicpuCustom(context, config.kernelName.c_str(),
     153            1 :                                              localStream.ptr(), config.binHandle);
     154            1 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     155              :         HCCL_ERROR("[AicpuLaunchMgr][%s] KernelLaunch failed, return [%d].", __func__, ret), ret);
     156              : 
     157              :     // Step 5. 等待流完成
     158            1 :     CHK_RET(hcclStreamSynchronize(localStream.ptr(), config.timeoutSec));
     159              : 
     160              :     // Step 6. 非补充notify,返回 device 侧句柄
     161            1 :     if (!config.isSupplementNotify) {
     162            1 :         CHK_RET(hrtMemSyncCopy(aicpuHandle.get(), handleLen, opParam.deviceHandle, handleLen,
     163              :             HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
     164              :     }
     165              : 
     166              :     // 性能分析上报
     167            1 :     if (config.needProfiling) {
     168            1 :         HcommProfilingReportKernel(beginTime, config.kernelName.c_str());
     169              :     }
     170            1 :     return HCCL_SUCCESS;
     171            1 : }
     172              : 
     173              : // 集合通信使用,待归一到基础通信接口
     174            1 : HcclResult AicpuLaunchMgr::ThreadKernelLaunchForComm(std::vector<std::shared_ptr<Thread>> &newThreads,
     175              :     const std::string &commId, std::unique_ptr<ThreadHandle[]> &aicpuHandle, aclrtBinHandle binHandle)
     176              : {
     177              :     ThreadKernelLaunchConfig config(
     178              :         commId,
     179              :         binHandle,
     180              :         "RunAicpuIndOpThreadInit",
     181              :         false,
     182            1 :         CommConfiger::GetInstance().GetCommConfigExecTimeOut(commId),
     183              :         true,
     184              :         false
     185            2 :     );
     186            2 :     return ThreadKernelLaunchImpl(newThreads, aicpuHandle, config);
     187            1 : }
     188              : 
     189              : // 基础通信使用
     190            0 : HcclResult AicpuLaunchMgr::ThreadKernelLaunchForBase(std::vector<std::shared_ptr<Thread>> &newThreads,
     191              :     std::unique_ptr<ThreadHandle[]> &aicpuHandle, aclrtBinHandle binHandle)
     192              : {
     193            0 :     constexpr uint32_t defaultTimeOutSec = 120;
     194              :     ThreadKernelLaunchConfig config(
     195              :         "",      
     196              :         binHandle,
     197              :         "RunAicpuThreadInit",
     198              :         true,    
     199              :         defaultTimeOutSec,     
     200              :         false,
     201              :         false
     202            0 :     );
     203            0 :     return ThreadKernelLaunchImpl(newThreads, aicpuHandle, config);
     204            0 : }
     205              : 
     206              : // 补充notify使用
     207            0 : HcclResult AicpuLaunchMgr::SupplementNotifyKernelLaunch(std::vector<std::shared_ptr<Thread>> &newThreads,
     208              :     const std::string &commId, std::unique_ptr<ThreadHandle[]> &aicpuHandle, aclrtBinHandle binHandle)
     209              : {
     210            0 :     constexpr uint32_t defaultTimeOutSec = 120;
     211              :     ThreadKernelLaunchConfig config(
     212              :         commId,      
     213              :         binHandle,
     214              :         "RunAicpuThreadSupplementNotify",
     215              :         true,    
     216              :         defaultTimeOutSec,     
     217              :         false,
     218              :         true
     219            0 :     );
     220            0 :     return ThreadKernelLaunchImpl(newThreads, aicpuHandle, config);
     221            0 : }
     222              : 
     223            1 : HcclResult AicpuLaunchMgr::ThreadKernelLaunchDestroy(ThreadHandle *threadHandles, uint32_t listNum, 
     224              :     aclrtBinHandle binHandle)
     225              : {
     226            1 :     HCCL_INFO("[AicpuLaunchMgr][%s] Start. listNum=%u, threadHandles=%p, binHandle=%p", 
     227              :         __func__, listNum, threadHandles, binHandle);
     228              :     // Step 1. 创建局部 stream
     229            1 :     Stream localStream;
     230            1 :     CHK_RET(CreateLocalStream(localStream));
     231              : 
     232              :     // Step 2. 填写 opParam
     233            1 :     ThreadMgrAicpuParam opParam{};
     234            1 :     (void)memset_s(&opParam, sizeof(opParam), 0, sizeof(opParam));
     235            1 :     opParam.threadNum = listNum;
     236            1 :     size_t handleLen = sizeof(ThreadHandle) * listNum;
     237            1 :     DeviceMem deviceHandle = DeviceMem::alloc(handleLen);
     238            1 :     CHK_SMART_PTR_NULL(deviceHandle);
     239            1 :     opParam.deviceHandle = deviceHandle.ptr();
     240            1 :     CHK_RET(hrtMemSyncCopy(deviceHandle.ptr(), handleLen,
     241              :         threadHandles, handleLen,
     242              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     243              : 
     244              :     // Step 3. 调用 KernelLaunch
     245            1 :     std::string kernelName = "RunAicpuThreadDestroy";
     246            1 :     HCCL_INFO("[AicpuLaunchMgr][%s] call KernelLaunch, kernelName=%s, stream=%p, binHandle=%p", 
     247              :         __func__, kernelName.c_str(), localStream.ptr(), binHandle);
     248            1 :     DeviceMem addr = DeviceMem::alloc(sizeof(opParam));
     249            1 :     CHK_RET(hrtMemSyncCopy(addr.ptr(), sizeof(opParam), &opParam, sizeof(opParam),
     250              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     251            1 :     uint64_t context = reinterpret_cast<uint64_t>(addr.ptr());
     252            2 :     HcclResult ret = KernelLaunchAicpuCustom(context, kernelName.c_str(), localStream.ptr(), binHandle);
     253            1 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     254              :         HCCL_ERROR("[AicpuLaunchMgr][%s] KernelLaunch failed, return [%d].", __func__, ret), ret);
     255              : 
     256              :     // Step 4. 等待流完成
     257            1 :     constexpr uint32_t defaultTimeOutSec = 120;
     258            1 :     CHK_RET(hcclStreamSynchronize(localStream.ptr(), defaultTimeOutSec));
     259            1 :     return HCCL_SUCCESS;
     260            1 : }
     261              : 
     262              : // 准备 opParam
     263            0 : HcclResult AicpuLaunchMgr::PrepareAicpuNotifyParam(NotifyMgrAicpuParam &opParam,
     264              :     const std::string &commId, size_t notifyNum, bool freeFlag, void *deviceHandle)
     265              : {
     266            0 :     (void)memset_s(&opParam, sizeof(opParam), 0, sizeof(opParam));
     267              : 
     268            0 :     opParam.notifyNum = notifyNum;
     269            0 :     opParam.freeFlag = freeFlag;
     270            0 :     opParam.deviceHandle = deviceHandle;
     271              : 
     272            0 :     errno_t sRet = strncpy_s(opParam.hcomId, HCOMID_MAX_SIZE, commId.c_str(), commId.length());
     273            0 :     CHK_PRT_RET(sRet != EOK,
     274              :         HCCL_ERROR("[AicpuLaunchMgr][PrepareAicpuNotifyParam] strncpy_s failed, ret[%d]", sRet),
     275              :         HCCL_E_MEMORY);
     276            0 :     opParam.hcomId[HCOMID_MAX_SIZE - 1] = '\0';
     277            0 :     return HCCL_SUCCESS;
     278              : }
     279              : 
     280            0 : HcclResult AicpuLaunchMgr::LaunchNotifyKernel(NotifyMgrAicpuParam &opParam, aclrtBinHandle binCustomHandle)
     281              : {
     282            0 :     Stream localStream(StreamType::STREAM_TYPE_ONLINE);
     283            0 :     constexpr u32 aicpuStreamMode = 1;
     284            0 :     CHK_RET(hrtStreamSetMode(localStream.ptr(), aicpuStreamMode));
     285              : 
     286            0 :     DeviceMem addr = DeviceMem::alloc(sizeof(opParam));
     287            0 :     CHK_RET(hrtMemSyncCopy(addr.ptr(), sizeof(opParam), &opParam, sizeof(opParam),
     288              :         HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     289            0 :     uint64_t context = reinterpret_cast<uint64_t>(addr.ptr());
     290            0 :     HcclResult ret = KernelLaunchAicpuCustom(context, "RunAicpuIndOpNotify", localStream.ptr(), binCustomHandle);
     291            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     292              :         HCCL_ERROR("[AicpuLaunchMgr][LaunchNotifyKernel] KernelLaunch failed, ret[%d]", ret), ret);
     293            0 :     CHK_RET(hcclStreamSynchronize(localStream.ptr(), CommConfiger::GetInstance().GetCommConfigExecTimeOut(opParam.hcomId)));
     294            0 :     return HCCL_SUCCESS;
     295            0 : }
     296              : 
     297            0 : HcclResult AicpuLaunchMgr::NotifyKernelLaunchAlloc(std::vector<std::unique_ptr<LocalNotify>> &newNotifys,
     298              :     const std::string &commId, std::unique_ptr<NotifyHandle[]> &hostHandle, aclrtBinHandle binCustomHandle)
     299              : {
     300            0 :     size_t handleLen = sizeof(NotifyHandle) * newNotifys.size();
     301            0 :     DeviceMem deviceHandle = DeviceMem::alloc(handleLen);
     302            0 :     CHK_SMART_PTR_NULL(deviceHandle);
     303              : 
     304              :     NotifyMgrAicpuParam opParam;
     305            0 :     CHK_RET(PrepareAicpuNotifyParam(opParam, commId, newNotifys.size(), false, deviceHandle.ptr()));
     306            0 :     std::string uid = NotifyManager::GetBinNotifys(newNotifys, NotifyLoadType::DEVICE_NOTIFY);
     307            0 :     if (UNLIKELY(uid.empty())) {
     308            0 :         HCCL_ERROR("[AicpuLaunchMgr][%s] uid is empty.", __func__, HCCL_E_MEMORY);
     309            0 :         return HCCL_E_MEMORY;
     310              :     }
     311            0 :     size_t copyLen = std::min(uid.size(), static_cast<size_t>(NOTIFY_UNIQUE_ID_MAX_SIZE));
     312            0 :     errno_t sRet = memcpy_s(opParam.notifyParam, NOTIFY_UNIQUE_ID_MAX_SIZE, uid.c_str(), copyLen);
     313            0 :     CHK_PRT_RET(sRet != EOK, HCCL_ERROR("[AicpuLaunchMgr][%s] call memcpy_s failed, return [%d].", __func__, sRet),
     314              :         HCCL_E_MEMORY);
     315              :     // 打印每个字节
     316            0 :     if (UNLIKELY(HcclCheckLogLevel(HCCL_LOG_INFO))) {
     317            0 :         std::ostringstream oss;
     318            0 :         oss << "notifyParam" << " raw bytes: ";
     319            0 :         for (u32 i = 0; i < NOTIFY_UNIQUE_ID_MAX_SIZE; ++i) {
     320            0 :             oss << std::hex << std::setw(2) << std::setfill('0')
     321            0 :                 << static_cast<unsigned int>(static_cast<unsigned char>(opParam.notifyParam[i])) << " ";
     322              :         }
     323            0 :         HCCL_INFO("[AicpuLaunchMgr][%s] %s", __func__, oss.str().c_str());
     324            0 :     }
     325              : 
     326            0 :     CHK_RET(LaunchNotifyKernel(opParam, binCustomHandle));
     327              : 
     328            0 :     CHK_RET(hrtMemSyncCopy(hostHandle.get(), handleLen, opParam.deviceHandle,
     329              :         handleLen, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_HOST));
     330            0 :     HCCL_RUN_INFO("[AicpuLaunchMgr][%s] notify alloc success, commid[%s], notifyNum[%u]",
     331              :         __func__, commId.c_str(), newNotifys.size());
     332            0 :     return HCCL_SUCCESS;
     333            0 : }
     334              : 
     335            0 : HcclResult AicpuLaunchMgr::NotifyKernelLaunchFree(std::vector<NotifyHandle> &aicpuNotifys, uint32_t notifyNum,
     336              :     const std::string &commId, aclrtBinHandle binCustomHandle)
     337              : {
     338            0 :     size_t handleLen = sizeof(NotifyHandle) * notifyNum;
     339            0 :     DeviceMem deviceHandle = DeviceMem::alloc(handleLen);
     340            0 :     CHK_SMART_PTR_NULL(deviceHandle);
     341              : 
     342            0 :     CHK_RET(hrtMemSyncCopy(deviceHandle.ptr(), handleLen, aicpuNotifys.data(),
     343              :         handleLen, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_HOST_TO_DEVICE));
     344              : 
     345              :     NotifyMgrAicpuParam opParam;
     346            0 :     CHK_RET(PrepareAicpuNotifyParam(opParam, commId, notifyNum, true, deviceHandle.ptr()));
     347              : 
     348            0 :     CHK_RET(LaunchNotifyKernel(opParam, binCustomHandle));
     349            0 :     HCCL_RUN_INFO("[AicpuLaunchMgr][%s] notify free kernalLaunch success, commid[%s], notifyNum[%u]",
     350              :         __func__, commId.c_str(), aicpuNotifys.size());
     351            0 :     return HCCL_SUCCESS;
     352            0 : }
     353              : }
        

Generated by: LCOV version 2.0-1