LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/communicator/impl - hccl_dpu_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.8 % 234 182
Test Date: 2026-08-17 10:19:35 Functions: 93.8 % 16 15

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : #include <chrono>
      11              : #include <climits>
      12              : #include <memory>
      13              : #include <atomic>
      14              : #include "config_log.h"
      15              : #include "launch_device.h"
      16              : #include "op_task_config.h"
      17              : #include "hccl_common_v2.h"
      18              : #include "ascend_hal.h"
      19              : #include "orion_adapter_rts.h"
      20              : #include "orion_adapter_hal.h"
      21              : #include "hccl_dpu_manager.h"
      22              : 
      23              : namespace hccl {
      24              : static std::atomic<u32> g_commDpuManagerNum(0);
      25              : constexpr uint8_t DEVICE_SIGNAL_SECOND = 2;
      26              : constexpr uint8_t DEVICE_SIGNAL_THIRD = 3;
      27              : constexpr uint32_t TEMP_DEV_TYPE_DPU = 0; // 临时适配,后续rts接口上库之后使用rts的定义
      28              : struct DpuKernelLaunchParam {             // 需要和RunDpuRpcSrvLaunch入参定义保持一致
      29              :     u64 memorySize;
      30              :     void* deviceMem;
      31              :     void* hostMem;
      32              :     int32_t deviceId;
      33              :     std::string commId;
      34              : };
      35              : DpuKernelLaunchParam g_hostArgsTemp;
      36              : 
      37          839 : DpuManager::DpuManager() {}
      38              : 
      39          839 : DpuManager::~DpuManager() {}
      40              : 
      41            6 : HcclResult DpuManager::CreateWorkspaceBuf(const char* memTag, uint64_t* size, bool* newCreated)
      42              : {
      43           13 :     std::string tag = memTag != nullptr ? std::string(memTag) : "";
      44            6 :     if (tagWorkspaceMap_.find(tag) == tagWorkspaceMap_.end()) {
      45            5 :         std::shared_ptr<Hccl::DevBuffer> workspace = std::make_shared<Hccl::DevBuffer>(*size);
      46            5 :         tagWorkspaceMap_.insert(make_pair(tag, workspace));
      47            5 :         HCCL_INFO(
      48              :             "[DpuManager::%s] Create tagMem[%s] WorkspaceBuf success, WorkspaceBuf = %p", __func__, tag.c_str(),
      49              :             workspace.get());
      50            5 :         if (newCreated != nullptr) {
      51            3 :             *newCreated = true;
      52              :         }
      53            5 :     }
      54            6 :     return HCCL_SUCCESS;
      55            6 : }
      56              : 
      57            3 : std::shared_ptr<Hccl::DevBuffer> DpuManager::GetKFCWorkSpace(const char* memTag)
      58              : {
      59            7 :     std::string tag = memTag != nullptr ? std::string(memTag) : "";
      60            3 :     auto it = tagWorkspaceMap_.find(tag);
      61            6 :     return it != tagWorkspaceMap_.end() ? it->second : nullptr;
      62            3 : }
      63              : 
      64            8 : HcclResult DpuManager::AllocAndRegKFCWorkSpace(uint64_t size)
      65              : {
      66            8 :     accessVA_ = nullptr;
      67            8 :     drvError_t ret = DRV_ERROR_NONE;
      68              : 
      69            8 :     va_ = Hccl::HrtMalloc(size, ACL_MEM_TYPE_HIGH_BAND_WIDTH);
      70            8 :     ret = halHostRegister(va_, size, DEV_SVM_MAP_HOST, devLogicId_, &accessVA_);
      71            8 :     if (ret != DRV_ERROR_NONE) {
      72            0 :         HCCL_ERROR("DpuManager halHostRegister failed, ret: %d", ret);
      73            0 :         if (va_ != nullptr) {
      74            0 :             Hccl::HrtFree(va_);
      75              :         }
      76            0 :         return HCCL_E_DRV;
      77              :     }
      78              : 
      79            8 :     return HCCL_SUCCESS;
      80              : }
      81              : 
      82            0 : HcclResult DpuManager::DestroyKFCWorkSpaceVA()
      83              : {
      84            0 :     if (accessVA_ == nullptr && va_ == nullptr) {
      85            0 :         HCCL_RUN_WARNING("[%s]accessVA_/va_ is nullptr", __func__);
      86            0 :         return HCCL_E_INTERNAL;
      87              :     }
      88              : 
      89              :     // 必须先halHostUnregister解除映射,再释放设备内存,否则HrtFree会因内存被pin住而异常
      90            0 :     if (accessVA_ != nullptr) {
      91            0 :         drvError_t drvRet = halHostUnregister(accessVA_, devLogicId_);
      92            0 :         if (drvRet != DRV_ERROR_NONE) {
      93            0 :             HCCL_ERROR("DpuManager halHostUnregister failed, drvRet[%d]", drvRet);
      94              :         }
      95              :     }
      96              : 
      97            0 :     if (va_ != nullptr) {
      98            0 :         Hccl::HrtFree(va_);
      99              :     }
     100              : 
     101            0 :     va_ = nullptr;
     102            0 :     accessVA_ = nullptr;
     103            0 :     tagWorkspaceVAMap_.erase(DPUTAG);
     104            0 :     return HCCL_SUCCESS;
     105              : }
     106              : 
     107            8 : HcclResult DpuManager::GetKFCWorkSpaceVA(const std::string& memTag, uint64_t* size, void** addr, bool* newCreated)
     108              : {
     109            8 :     if (memTag != DPUTAG) {
     110            0 :         HCCL_ERROR("DpuManager::GetKFCWorkSpaceVA, memTag is invalid, memTag: %s", memTag.c_str());
     111            0 :         return HCCL_E_PARA;
     112              :     }
     113            8 :     auto iter = tagWorkspaceVAMap_.find(memTag);
     114            8 :     if (iter != tagWorkspaceVAMap_.end()) {
     115            0 :         std::shared_ptr<Hccl::DevBuffer> oldWorkspace = iter->second;
     116            0 :         if (*size != static_cast<uint64_t>(oldWorkspace.get()->GetSize())) {
     117            0 :             HCCL_ERROR(
     118              :                 "DpuManager::GetKFCWorkSpaceVA, The size of oldWorkspace %p is non-consistent, target size compare now "
     119              :                 "size: %llu->%llu",
     120              :                 *addr, *size, oldWorkspace.get()->GetSize());
     121            0 :             return HCCL_E_PARA;
     122              :         }
     123            0 :         *addr = reinterpret_cast<void*>(oldWorkspace.get()->GetAddr());
     124            0 :         if (newCreated != nullptr) {
     125            0 :             *newCreated = false;
     126              :         }
     127            0 :         return HcclResult::HCCL_SUCCESS;
     128            0 :     }
     129              : 
     130            8 :     CHK_RET(AllocAndRegKFCWorkSpace(*size));
     131              :     std::shared_ptr<Hccl::DevBuffer> newWorkspace
     132            8 :         = Hccl::DevBuffer::Create(reinterpret_cast<uintptr_t>(accessVA_), *size);
     133            8 :     tagWorkspaceVAMap_.insert(make_pair(memTag, newWorkspace));
     134            8 :     if (newCreated != nullptr) {
     135            8 :         *newCreated = true;
     136              :     }
     137            8 :     *addr = reinterpret_cast<void*>(newWorkspace.get()->GetAddr());
     138            8 :     return HcclResult::HCCL_SUCCESS;
     139            8 : }
     140              : 
     141            6 : HcclResult DpuManager::GetDevMemWorkSpace(const std::string& memTag, uint64_t* size, void** addr, bool* newCreated)
     142              : {
     143            6 :     if (memTag == DPUTAG) {
     144            0 :         return GetKFCWorkSpaceVA(memTag, size, addr, newCreated);
     145              :     }
     146            6 :     auto iter = tagWorkspaceMap_.find(memTag);
     147            6 :     if (iter != tagWorkspaceMap_.end()) {
     148            2 :         std::shared_ptr<Hccl::DevBuffer> oldWorkspace = iter->second;
     149            2 :         if (*size != static_cast<uint64_t>(oldWorkspace.get()->GetSize())) {
     150            1 :             HCCL_ERROR(
     151              :                 "DpuManager::GetDevMemWorkSpace, The size of oldWorkspace %p is non-consistent, "
     152              :                 "target size compare now size: %llu->%llu",
     153              :                 *addr, *size, oldWorkspace.get()->GetSize());
     154            1 :             return HCCL_E_PARA;
     155              :         }
     156            1 :         *addr = reinterpret_cast<void*>(oldWorkspace.get()->GetAddr());
     157            1 :         if (newCreated != nullptr) {
     158            1 :             *newCreated = false;
     159              :         }
     160            1 :         return HcclResult::HCCL_SUCCESS;
     161            2 :     }
     162              : 
     163            4 :     std::shared_ptr<Hccl::DevBuffer> newWorkspace = std::make_shared<Hccl::DevBuffer>(*size);
     164            4 :     tagWorkspaceMap_.insert(make_pair(memTag, newWorkspace));
     165            4 :     HCCL_INFO(
     166              :         "Create tagMem[%s] WorkspaceBuf success, WorkspaceBuf: %p -> %p, size[%llu]", memTag.c_str(),
     167              :         newWorkspace.get(), newWorkspace.get()->GetAddr(), *size);
     168            4 :     if (newCreated != nullptr) {
     169            3 :         *newCreated = true;
     170              :     }
     171            4 :     *addr = reinterpret_cast<void*>(newWorkspace.get()->GetAddr());
     172            4 :     return HcclResult::HCCL_SUCCESS;
     173            4 : }
     174              : 
     175            8 : HcclResult DpuManager::Init(const std::string& commId, u32 deviceLogicId)
     176              : {
     177            8 :     commId_ = commId;
     178            8 :     devLogicId_ = deviceLogicId;
     179            8 :     return InitDpuKernel();
     180              : }
     181              : 
     182            3 : HcclResult DpuManager::LaunchDpuKernel(aclrtFuncHandle& funcHandle)
     183              : {
     184            3 :     HCCL_INFO("[DpuManager::%s] Launch Dpu Kernel", __func__);
     185              :     aclrtLaunchKernelCfg cfg;
     186              :     aclrtLaunchKernelAttr kernelAttr;
     187            3 :     kernelAttr.id = ACL_RT_LAUNCH_KERNEL_ATTR_TIMEOUT;
     188            3 :     kernelAttr.value.timeout = Hccl::NOTIFY_DEFAULT_WAIT_TIME > std::numeric_limits<uint16_t>::max() ?
     189            0 :                                    std::numeric_limits<uint16_t>::max() :
     190              :                                    Hccl::NOTIFY_DEFAULT_WAIT_TIME;
     191            3 :     cfg.numAttrs = 1;
     192            3 :     cfg.attrs = &kernelAttr;
     193            3 :     constexpr u32 numBlocks = 1;
     194              : 
     195            3 :     g_hostArgsTemp.commId = commId_;
     196            3 :     g_hostArgsTemp.memorySize = SHARE_HBM_MEMORY_SIZE;
     197            3 :     g_hostArgsTemp.hostMem = hostShareBuf_;
     198            3 :     g_hostArgsTemp.deviceMem = accessVA_;
     199            3 :     g_hostArgsTemp.deviceId = devLogicId_;
     200              : 
     201            3 :     HCCL_INFO(
     202              :         "[DpuManager::%s] DpuKernelLaunchParam{commId:%s; memorySize:%u; deviceMem:%p; hostMem:%p}", __func__,
     203              :         g_hostArgsTemp.commId.c_str(), g_hostArgsTemp.memorySize, g_hostArgsTemp.deviceMem, g_hostArgsTemp.hostMem);
     204              : 
     205            3 :     size_t argsSize = sizeof(g_hostArgsTemp);
     206              :     aclrtPlaceHolderInfo placeHolderArrays;
     207            3 :     size_t placeHolderNum = 0;
     208            3 :     if (aclrtLaunchKernelWithHostArgs(
     209              :             funcHandle, numBlocks, dpuStream_, &cfg, &g_hostArgsTemp, argsSize, &placeHolderArrays, placeHolderNum)
     210            3 :         != ACL_SUCCESS) {
     211            1 :         HCCL_ERROR("[DpuManager::%s] Launch Dpu Kernel Failed", __func__);
     212            1 :         return HCCL_E_INTERNAL;
     213              :     }
     214            2 :     return HCCL_SUCCESS;
     215              : }
     216              : 
     217            6 : HcclResult DpuManager::PrepareDpuKernelResource(aclrtFuncHandle& funcHandle)
     218              : {
     219              :     // 获取二进制文件路径
     220            6 :     std::string jsonPath;
     221            6 :     const char* envPath = getenv("ASCEND_HOME_PATH");
     222            6 :     if (envPath != nullptr && envPath[0] != '\0') {
     223            0 :         jsonPath = envPath;
     224              :     } else {
     225            6 :         jsonPath = "/usr/local/Ascend/cann/";
     226            6 :         HCCL_WARNING("[DpuManager::%s] ENV:ASCEND_HOME_PATH is not set", __func__);
     227              :     }
     228              : 
     229            6 :     jsonPath += "/opp/built-in/op_impl/dpu/";
     230            6 :     HCCL_DEBUG("[DpuManager::%s] kernel folder path[%s]", __func__, jsonPath.c_str());
     231              : 
     232              :     // cpuKernelMode为1时,json命名需与so命名保持一致, 即libccl_dpu.json与libccl_dpu.so
     233            6 :     jsonPath += "libccl_dpu.json";
     234            6 :     char realPath[PATH_MAX] = {0};
     235            6 :     CHK_PRT_RET(
     236              :         realpath(jsonPath.c_str(), realPath) == nullptr,
     237              :         HCCL_ERROR("[DpuManager::%s]: %s is not a valid real path, err[%d]", __func__, jsonPath.c_str(), errno),
     238              :         HCCL_E_INTERNAL);
     239            6 :     HCCL_INFO("[DpuManager::%s] realPath: %s", __func__, realPath);
     240              : 
     241              :     aclrtBinHandle binHandle;
     242              :     aclrtBinaryLoadOptions options;
     243              :     aclrtBinaryLoadOption option;
     244            6 :     option.type = ACL_RT_BINARY_LOAD_OPT_CPU_KERNEL_MODE;
     245            6 :     option.value.cpuKernelMode = 1;
     246            6 :     options.numOpt = 1;
     247            6 :     options.options = &option;
     248            6 :     if (aclrtBinaryLoadFromFile(realPath, &options, &binHandle) != ACL_SUCCESS) {
     249            1 :         HCCL_ERROR("[DpuManager::%s] load binary from file error.", __func__);
     250            1 :         return HCCL_E_OPEN_FILE_FAILURE;
     251              :     }
     252              : 
     253              :     // 创建dpustream
     254            5 :     if (aclrtCreateStreamWithConfig(&dpuStream_, 0, ACL_STREAM_FAST_LAUNCH) != ACL_SUCCESS) {
     255            1 :         HCCL_ERROR("[DpuManager::%s] Create Local Stream Failed", __func__);
     256            1 :         return HCCL_E_INTERNAL;
     257              :     }
     258              : 
     259              :     // 查找核函数
     260            4 :     if (aclrtBinaryGetFunction(binHandle, "RunDpuRpcSrvLaunch", &funcHandle) != ACL_SUCCESS) {
     261            1 :         HCCL_ERROR("[DpuManager::%s] Get Function Failed", __func__);
     262            1 :         return HCCL_E_INTERNAL;
     263              :     }
     264              : 
     265            3 :     return HCCL_SUCCESS;
     266            6 : }
     267              : 
     268            8 : HcclResult DpuManager::InitAndLaunchDpuKernel()
     269              : {
     270            8 :     HCCL_INFO("[DpuManager::%s] Start to Launch Dpu Kernel", __func__);
     271            8 :     bool newCreate = false;
     272            8 :     uint64_t memSize = static_cast<uint64_t>(SHARE_HBM_MEMORY_SIZE);
     273           16 :     HcclResult memRet = GetKFCWorkSpaceVA(DPUTAG, &memSize, &accessVA_, &newCreate);
     274            8 :     if (memRet != HCCL_SUCCESS) {
     275            0 :         HCCL_ERROR("[DpuManager::InitCommResource] Alloc Share HBM Failed");
     276            0 :         return HCCL_E_RUNTIME;
     277              :     }
     278              : 
     279              :     // 设置XPU
     280            8 :     HCCL_INFO("[DpuManager::%s] Switch to Dpu Ctx", __func__);
     281            8 :     if (aclrtGetCurrentContext(&npuContext_) != ACL_SUCCESS) {
     282            1 :         HCCL_ERROR("[DpuManager::%s] Get Npu Ctx Failed", __func__);
     283            1 :         return HCCL_E_INTERNAL;
     284              :     }
     285            7 :     if (Hccl::HrtSetXpuDevice(TEMP_DEV_TYPE_DPU, 0) != HCCL_SUCCESS) {
     286            1 :         HCCL_ERROR("[DpuManager::%s] Switch to Dpu Ctx Failed", __func__);
     287            1 :         return HCCL_E_INTERNAL;
     288              :     }
     289            6 :     if (aclrtGetCurrentContext(&dpuContext_) != ACL_SUCCESS) {
     290            0 :         HCCL_ERROR("[DpuManager::%s] Get Dpu Ctx Failed", __func__);
     291            0 :         return HCCL_E_INTERNAL;
     292              :     }
     293              : 
     294              :     // 准备资源
     295              :     aclrtFuncHandle funcHandle;
     296            6 :     CHK_RET(PrepareDpuKernelResource(funcHandle));
     297              : 
     298            3 :     hostShareBuf_ = malloc(SHARE_HBM_MEMORY_SIZE);
     299            3 :     CHK_PTR_NULL(hostShareBuf_);
     300              : 
     301              :     // 下发
     302            3 :     HcclResult ret = LaunchDpuKernel(funcHandle);
     303            3 :     if (ret != HCCL_SUCCESS) {
     304            1 :         HCCL_ERROR("[CommunicatorImpl::%s] Launch Dpu Kernel Failed", __func__);
     305            1 :         free(hostShareBuf_);
     306            1 :         hostShareBuf_ = nullptr;
     307            1 :         return ret;
     308              :     }
     309              : 
     310              :     // 切换回当前Ctx
     311            2 :     HCCL_INFO("[DpuManager::%s] Switch to Npu Ctx", __func__);
     312            2 :     if (ACL_SUCCESS != aclrtSetCurrentContext(npuContext_)) {
     313            1 :         HCCL_ERROR("[DpuManager::%s] Reset Current Ctx Failed", __func__);
     314            1 :         free(hostShareBuf_);
     315            1 :         hostShareBuf_ = nullptr;
     316            1 :         return HCCL_E_INTERNAL;
     317              :     }
     318              : 
     319            1 :     HCCL_INFO("[DpuManager::%s] Launch Dpu Kernel End", __func__);
     320            1 :     isDpuKernelLaunched_ = true;
     321            1 :     g_commDpuManagerNum++;
     322            1 :     return HCCL_SUCCESS;
     323              : }
     324              : 
     325            8 : HcclResult DpuManager::InitDpuKernel()
     326              : {
     327              :     /* kernel Launch */
     328            8 :     CHK_RET(InitAndLaunchDpuKernel());
     329            1 :     return HCCL_SUCCESS;
     330              : }
     331              : 
     332          807 : HcclResult DpuManager::DeInitDpuKernel()
     333              : {
     334          807 :     if (!isDpuKernelLaunched_) {
     335          809 :         return HCCL_SUCCESS;
     336              :     }
     337            0 :     (void)DestroyDpuKernelResource();
     338            0 :     (void)DestroyKFCWorkSpaceVA();
     339            0 :     if (hostShareBuf_ != nullptr) {
     340            0 :         free(hostShareBuf_);
     341            0 :         hostShareBuf_ = nullptr;
     342              :     }
     343            0 :     return HCCL_SUCCESS;
     344              : }
     345              : 
     346            3 : HcclResult DpuManager::WaitDpuKernelThreadTerminate()
     347              : {
     348            3 :     if (!isDpuKernelLaunched_) {
     349            1 :         return HCCL_SUCCESS;
     350              :     }
     351            2 :     if (accessVA_ == nullptr) {
     352            1 :         HCCL_ERROR("[CommunicatorImpl::%s] accessVA_ is nullptr", __func__);
     353            1 :         return HCCL_E_MEMORY;
     354              :     }
     355            1 :     uint8_t flag = DEVICE_SIGNAL_SECOND;
     356            1 :     errno_t ret = memcpy_s(accessVA_, sizeof(flag), &flag, sizeof(flag));
     357            1 :     if (ret != EOK) {
     358            0 :         HCCL_ERROR("Terminate TaskRun Fail, return[%d]", ret);
     359            0 :         return HCCL_E_MEMORY;
     360              :     }
     361              :     do {
     362         3156 :         ret = memcpy_s(&flag, sizeof(flag), accessVA_, sizeof(flag));
     363         3156 :         if (ret != EOK) {
     364            0 :             HCCL_ERROR("Read Terminate TaskRun Signal Fail, return[%d]", ret);
     365            0 :             return HCCL_E_MEMORY;
     366              :         }
     367         3156 :     } while (flag != DEVICE_SIGNAL_THIRD);
     368              : 
     369            1 :     return HCCL_SUCCESS;
     370              : }
     371              : 
     372            4 : HcclResult DpuManager::DestroyDpuKernelResource()
     373              : {
     374              :     // 终止Dpu Kernel的TaskRun
     375            4 :     if (!isDpuKernelLaunched_) {
     376            0 :         return HCCL_SUCCESS;
     377              :     }
     378              : 
     379            4 :     CHK_RET(WaitDpuKernelThreadTerminate());
     380              : 
     381              :     // 切换回 dpu ctx
     382            4 :     aclError aclRet = aclrtSetCurrentContext(dpuContext_);
     383            4 :     if (ACL_SUCCESS != aclRet) {
     384            1 :         HCCL_ERROR("set dpu Ctx Failed, aclReturn[%d]", aclRet);
     385            1 :         return HCCL_E_RUNTIME;
     386              :     }
     387              :     // 销毁局部流
     388            3 :     aclRet = aclrtDestroyStreamForce(dpuStream_);
     389            3 :     if (ACL_SUCCESS != aclRet) {
     390            1 :         HCCL_ERROR("Destroy Stream Failed, aclReturn[%d]", aclRet);
     391            1 :         aclRet = aclrtSetCurrentContext(npuContext_);
     392            1 :         CHK_PRT_RET(aclRet == ACL_SUCCESS, HCCL_ERROR("set npu Ctx Failed, aclReturn[%d]", aclRet), HCCL_E_RUNTIME);
     393            0 :         return HCCL_E_RUNTIME;
     394              :     }
     395            2 :     if (g_commDpuManagerNum > 1) {
     396            0 :         g_commDpuManagerNum--;
     397              :     } else {
     398              :         // reset DPU kernel 线程
     399            2 :         HcclResult ret = Hccl::HrtResetXpuDevice(TEMP_DEV_TYPE_DPU, 0);
     400            2 :         if (HCCL_SUCCESS != ret) {
     401            1 :             HCCL_ERROR("ResetXpuDevice Failed, return[%d]", ret);
     402            1 :             aclRet = aclrtSetCurrentContext(npuContext_);
     403            1 :             CHK_PRT_RET(aclRet == ACL_SUCCESS, HCCL_ERROR("set npu Ctx Failed, aclReturn[%d]", aclRet), HCCL_E_RUNTIME);
     404            0 :             return HCCL_E_RUNTIME;
     405              :         }
     406              :     }
     407              :     // 切回 npu ctx
     408            1 :     aclRet = aclrtSetCurrentContext(npuContext_);
     409            1 :     if (ACL_SUCCESS != aclRet) {
     410            0 :         HCCL_ERROR("set npu Ctx Failed, aclReturn[%d]", aclRet);
     411            0 :         return HCCL_E_RUNTIME;
     412              :     }
     413              : 
     414            1 :     return HCCL_SUCCESS;
     415              : }
     416              : 
     417              : } // namespace hccl
        

Generated by: LCOV version 2.0-1