LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/task - dispatcher_graph.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 25.1 % 455 114
Test Date: 2026-08-04 10:52:23 Functions: 30.4 % 23 7

            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 "externalinput.h"
      12              : #include "adapter_rts.h"
      13              : #include "log.h"
      14              : #include "dtype_common.h"
      15              : #include "dispatcher_graph.h"
      16              : #include "hccl_tbe_task.h"
      17              : #include "graph_ctx_mgr_common.h"
      18              : #include "config_plf_log.h"
      19              : 
      20              : constexpr u32 UB_BLOCK_SIZE = 32;
      21              : constexpr u64 TBE_REDUCE_MAX_COUNT = INT32_MAX;
      22              : 
      23              : __attribute__((weak)) HcclResult GraphAddRecordTaskWithSignalAddr(void *fftsPubInfo, void *ctx, uint32_t streamId,
      24              :     void *signal, bool inchip, u64 signalAddr, uint32_t *ctxIdx);
      25              : __attribute__((weak)) HcclResult LaunchGraphAndGetGraphInfo(void *fftsPubInfo, void *streamPtr, void *ctx,
      26              :     uint32_t timeout, uint32_t *ctxNum, void **descBuf, size_t *descBufLen);
      27              : 
      28              : namespace hccl {
      29          119 : DispatcherGraph::DispatcherGraph(const s32 deviceLogicId)
      30          119 :     : DispatcherPub(deviceLogicId), fftsCtxsPtr(nullptr), disableFfts_(true), multiQpMode_(false)
      31          119 : {}
      32              : 
      33          234 : DispatcherGraph::~DispatcherGraph()
      34          234 : {}
      35              : 
      36            0 : void DispatcherGraph::SetNormalMode()
      37              : {
      38            0 :     disableFfts_ = true;
      39            0 : }
      40              : 
      41            0 : HcclResult DispatcherGraph::SetMultiQpMode(bool multiQpMode)
      42              : {
      43            0 :     multiQpMode_ = multiQpMode;
      44            0 :     HCCL_DEBUG("[MultiQp][DispatcherGraph::SetMultiQpMode] [%d]", multiQpMode);
      45            0 :     return HcclResult::HCCL_SUCCESS;
      46              : }
      47              : 
      48            0 : HcclResult DispatcherGraph::ResetGraphCtx(bool enableCache, const std::string &key, bool useGraphConstructorV2)
      49              : {
      50            0 :     disableFfts_ = false;
      51            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
      52            0 :         HCCL_DEBUG("ffts task is disabled.");
      53            0 :         disableFfts_ = true;
      54              :     } else {
      55            0 :         if (multiQpMode_) {
      56            0 :             enableCache = false;
      57              :         }
      58              :         
      59            0 :         std::string sKey = key;
      60            0 :         if (UNLIKELY(!enableCache)) {
      61              :             // 当enableCache使能时,key传空值,用来区分当enableCache
      62            0 :             sKey = "";
      63              :         }
      64            0 :         HCCL_INFO("useGraphConstructorV2[%d] sKey[%s] length[%u] key[%s]",
      65              :             useGraphConstructorV2, sKey.c_str(), sKey.length(), key.c_str());
      66            0 :         if (useGraphConstructorV2) {
      67            0 :             fftsCtxsPtr = GetGraphCtxV2(fftsPubInfo_, sKey.c_str(), sKey.length());
      68              :         } else {
      69            0 :             fftsCtxsPtr = GetGraphCtx(fftsPubInfo_, sKey.c_str(), sKey.length());
      70              :         }
      71            0 :         CHK_PTR_NULL(fftsCtxsPtr);
      72            0 :         disableFfts_ = false;
      73            0 :     }
      74            0 :     return HCCL_SUCCESS;
      75              : }
      76              : 
      77           19 : HcclResult DispatcherGraph::LaunchTasksEx(Stream &stream, std::vector<Stream> &subStreams)
      78              : {
      79           19 :     if (UNLIKELY(disableFfts_)) {
      80           18 :         return HCCL_SUCCESS;
      81              :     }
      82              : 
      83            1 :     uint64_t beginTime = GetMsprofSysCycleTime();
      84            1 :     CHK_PTR_NULL(fftsCtxsPtr); // 检查Context是否进行过Reset
      85              : 
      86            1 :     u32 timeout = 0;
      87              :     // 配置notify wait 超时时间
      88              :     // 因为老版本用户设置HCCL_EXEC_TIMEOUT为0,hccl将0传递给rts,rts将0转换为1770s传递给硬件, 未达到永不超时效果,不符合预期;
      89              :     // 所以现版用户配置为0时,hccl转换成65535,rts识别到65535后会又会转换成0,去硬件设置永不超时
      90            1 :     if (execTimeOut_  == 0) {
      91            0 :         timeout = FFTS_TIMEOUT_MAX;
      92              :     // 因为65535被当作永不超时处理,所以当用户配置65535时需要改变他的值,防止误错做成永不超时
      93            1 :     } else if (execTimeOut_  == FFTS_TIMEOUT_MAX) {
      94            0 :         timeout = FFTS_TIMEOUT_MAX - 1;
      95              :     } else {
      96            1 :         timeout = execTimeOut_ ;
      97              :     }
      98              :     u32 ctxNum;
      99            1 :     void *descBuf = nullptr;
     100            1 :     size_t descBufLen = 0;
     101            1 :     if (LaunchGraphAndGetGraphInfo != nullptr) {
     102            1 :         CHK_RET(LaunchGraphAndGetGraphInfo(fftsPubInfo_, stream.ptr(), fftsCtxsPtr, timeout, &ctxNum, &descBuf, &descBufLen));
     103              :     } else {
     104            0 :         CHK_RET(LaunchGraph(fftsPubInfo_, stream.ptr(), fftsCtxsPtr, timeout, &ctxNum));
     105              :     }
     106            1 :     disableFfts_ = true;
     107              :     // 调用回调来保存task信息
     108            1 :     if (callback_ != nullptr) {
     109            1 :         struct TaskPara taskPara;
     110            1 :         taskPara.type = TaskType::TASK_GRAPH_LAUNCH;
     111            1 :         taskPara.stream = stream.ptr();
     112            1 :         taskPara.isMainStream = stream.IsMainStream();
     113            1 :         taskPara.beginTime = beginTime;
     114            1 :         taskPara.graphLaunch.ctxNum = ctxNum;
     115            1 :         taskPara.graphLaunch.descBuf = descBuf;
     116            1 :         taskPara.graphLaunch.descBufLen = descBufLen;
     117            1 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     118            1 :     }
     119              : 
     120            1 :     return HCCL_SUCCESS;
     121              : }
     122              : 
     123            0 : HcclResult DispatcherGraph::GetNotifyDfxInfo(HcclRtNotify signal, u32 userRank, u64 &offset, u32 &remoteUserRank,
     124              :     u64 &notifyID)
     125              : {
     126            0 :     if (offset == INVALID_U64) {
     127            0 :         CHK_RET(hrtNotifyGetOffset(static_cast<HcclRtNotify>(signal), offset));
     128              :     }
     129            0 :     notifyID = userRank;
     130            0 :     notifyID = (notifyID << 32) | (offset & 0x00000000FFFFFFFF);  // 0x00000000FFFFFFFF用于取offset的低32位
     131            0 :     remoteUserRank = (remoteUserRank == INVALID_UINT) ? static_cast<u32>(notifyID >> 32) : remoteUserRank;
     132            0 :     return HCCL_SUCCESS;
     133              : }
     134              : 
     135              : HcclResult DispatcherGraph::SignalTaskParaSave(HcclRtNotify signal, Stream &stream, u32 userRank, u32 remoteUserRank,
     136              :     u64 offset, s32 stage, TaskType taskType, uint64_t beginTime, u32 ctxIdx)
     137              : {
     138            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     139              :         u64 notifyID;
     140            0 :         CHK_RET(GetNotifyDfxInfo(signal, userRank, offset, remoteUserRank, notifyID));
     141              :         // 调用回调来保存task信息
     142            0 :         hccl::TaskParaNotify para(notifyID, stage, remoteUserRank, (ctxIdx - 1));
     143            0 :         struct TaskPara taskPara;
     144            0 :         taskPara.stream = stream.ptr();
     145            0 :         taskPara.isMainStream = stream.IsMainStream();
     146            0 :         taskPara.beginTime = beginTime;
     147            0 :         taskPara.notify = para;
     148            0 :         taskPara.type = taskType;
     149            0 :         taskPara.isFftsDispatcher = true;
     150            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     151            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     152            0 :     }
     153            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     154            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     155              :         u64 notifyID;
     156            0 :         CHK_RET(GetNotifyDfxInfo(signal, userRank, offset, remoteUserRank, notifyID));
     157            0 :         hccl::TaskParaNotify para(notifyID, stage, remoteUserRank, (ctxIdx - 1));
     158            0 :         struct TaskPara taskPara;
     159            0 :         taskPara.stream = stream.ptr();
     160            0 :         taskPara.isMainStream = stream.IsMainStream();
     161            0 :         taskPara.beginTime = beginTime;
     162            0 :         taskPara.notify = para;
     163            0 :         taskPara.type = taskType;
     164            0 :         taskPara.isFftsDispatcher = true;
     165            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     166            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     167            0 :     }
     168              : 
     169            0 :     return HCCL_SUCCESS;
     170              : }
     171              : 
     172            0 : HcclResult DispatcherGraph::SignalRecord(HcclRtNotify signal, Stream &stream, u32 userRank, u64 offset, s32 stage,
     173              :     bool inchip, u64 signalAddr, u32 notifyId)
     174              : {
     175            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     176              :     (void)notifyId;
     177            0 :     if (UNLIKELY(disableFfts_)) {
     178            0 :         return DispatcherPub::SignalRecord(signal, stream, userRank, offset, stage, inchip);
     179              :     }
     180              :     u32 ctxIdx;
     181            0 :     if (GraphAddRecordTaskWithSignalAddr != nullptr) {
     182            0 :         CHK_RET(GraphAddRecordTaskWithSignalAddr(fftsPubInfo_, fftsCtxsPtr, stream.id(), signal, inchip, signalAddr, &ctxIdx));
     183              :     } else {
     184            0 :         CHK_RET(GraphAddRecordTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), signal, inchip, &ctxIdx));
     185              :     }
     186            0 :     if (!inchip && ctxIdx > 0) {
     187            0 :         CHK_RET(SignalTaskParaSave(signal, stream, userRank, INVALID_UINT,
     188              :                 offset, stage, TaskType::TASK_NOTIFY_RECORD, beginTime, ctxIdx));
     189              :     }
     190              : 
     191            0 :     if (HcclCheckLogLevel(HCCL_LOG_INFO) || (GetExternalInputDebugConfig() & PLF_TASK)) {
     192            0 :         u64 notifyID = userRank;
     193            0 :         u32 remoteUserRank = INVALID_UINT;
     194            0 :         CHK_RET(GetNotifyDfxInfo(signal, userRank, offset, remoteUserRank, notifyID));
     195            0 :         PLF_CONFIG_INFO(PLF_TASK,
     196              :             "%s para: notifyId[0x%016llx] streamId[%u] userRank[%u] remoteUserRank[%u] offset[%llu] stage[%d] inchip[%d]",
     197              :             __func__, notifyID, stream.id(), userRank, remoteUserRank, offset, stage, inchip);
     198              :     }
     199            0 :     return HCCL_SUCCESS;
     200              : }
     201              : 
     202            0 : HcclResult DispatcherGraph::SignalWait(HcclRtNotify signal, Stream &stream, u32 userRank, u32 remoteUserRank, s32 stage,
     203              :     bool inchip, u32 notifyId, u32 timeOut)
     204              : {
     205            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     206            0 :     if (UNLIKELY(disableFfts_)) {
     207            0 :         return DispatcherPub::SignalWait(signal, stream, userRank, remoteUserRank, stage, inchip, notifyId, timeOut);
     208              :     }
     209              :     u32 ctxIdx;
     210            0 :     CHK_RET(GraphAddWaitTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), signal, inchip, &ctxIdx));
     211            0 :     if (!inchip && ctxIdx > 0) {
     212            0 :         CHK_RET(SignalTaskParaSave(signal, stream, userRank, remoteUserRank,
     213              :                 INVALID_U64, stage, TaskType::TASK_NOTIFY_WAIT, beginTime, ctxIdx));
     214              :     }
     215              : 
     216            0 :     if (HcclCheckLogLevel(HCCL_LOG_INFO) || (GetExternalInputDebugConfig() & PLF_TASK)) {
     217            0 :         u64 notifyID = userRank;
     218            0 :         u64 offset = INVALID_U64;
     219            0 :         CHK_RET(GetNotifyDfxInfo(signal, userRank, offset, remoteUserRank, notifyID));
     220            0 :         PLF_CONFIG_INFO(PLF_TASK,
     221              :             "%s para: notifyId[0x%016llx] streamId[%u] userRank[%u] remoteUserRank[%u] offset[%llu] stage[%d] inchip[%d]",
     222              :             __func__, notifyID, stream.id(), userRank, remoteUserRank, offset, stage, inchip);
     223              :     }
     224            0 :     return HCCL_SUCCESS;
     225              : }
     226              : 
     227            5 : HcclResult DispatcherGraph::MemcpyAsync(hccl::DeviceMem &dst, const hccl::DeviceMem &src, hccl::Stream &stream,
     228              :     u32 remoteUserRank, hccl::LinkType inLinkType)
     229              : {
     230            5 :     uint64_t beginTime = GetMsprofSysCycleTime();
     231            5 :     if (dst.size() < src.size()) {
     232            0 :         HCCL_ERROR(
     233              :             "The size of dst is smaller than that of src. dst addr[%p], dst size[%llu], src addr[%p], src size[%llu]",
     234              :             dst.ptr(), dst.size(), src.ptr(), src.size());
     235            0 :         return HCCL_E_PTR;
     236              :     }
     237              : 
     238            5 :     if (UNLIKELY(disableFfts_)) {
     239            5 :         return DispatcherPub::MemcpyAsync(dst, src, stream, remoteUserRank, inLinkType);
     240              :     }
     241            0 :     PLF_CONFIG_INFO(PLF_TASK,
     242              :         "%s para: dst[%p] destMax[%llu] src[%p] count[%llu] rtMemcpyKind[%d] inLinkType[%d] remoteUserRank[%u] streamId[%u]",
     243              :         __func__, dst.ptr(), dst.size(), src.ptr(), src.size(), HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_DEVICE,
     244              :         inLinkType, remoteUserRank, stream.id());
     245              :     u32 ctxIdx;
     246            0 :     CHK_RET(GraphAddMemcpyTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), dst.ptr(), src.ptr(), src.size(), &ctxIdx));
     247              :     // 调用回调来保存task信息
     248            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     249            0 :         hccl::TaskParaDMA para(src.ptr(), dst.ptr(), src.size(), inLinkType, remoteUserRank,
     250            0 :             hccl::RdmaType::RDMA_TYPE_RESERVED, (ctxIdx - 1));
     251            0 :         struct TaskPara taskPara;
     252            0 :         taskPara.stream = stream.ptr();
     253            0 :         taskPara.isMainStream = stream.IsMainStream();
     254            0 :         taskPara.beginTime = beginTime;
     255            0 :         taskPara.dma = para;
     256            0 :         taskPara.type = TaskType::TASK_SDMA;
     257            0 :         taskPara.isFftsDispatcher = true;
     258            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     259            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     260            0 :     }
     261            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     262            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     263            0 :         hccl::TaskParaDMA para(src.ptr(), dst.ptr(), src.size(), inLinkType, remoteUserRank,
     264            0 :             hccl::RdmaType::RDMA_TYPE_RESERVED, (ctxIdx - 1));
     265            0 :         struct TaskPara taskPara;
     266            0 :         taskPara.stream = stream.ptr();
     267            0 :         taskPara.isMainStream = stream.IsMainStream();
     268            0 :         taskPara.beginTime = beginTime;
     269            0 :         taskPara.dma = para;
     270            0 :         taskPara.type = TaskType::TASK_SDMA;
     271            0 :         taskPara.isFftsDispatcher = true;
     272            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     273            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     274            0 :     }
     275            0 :     return HCCL_SUCCESS;
     276              : }
     277              : 
     278            0 : HcclResult DispatcherGraph::ReduceAsync(const void *src, void *dst, u64 dataCount, const HcclDataType datatype,
     279              :     HcclReduceOp redOp, Stream &stream, HcclReduceType reduceType)
     280              : {
     281            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     282            0 :     if (UNLIKELY(disableFfts_)) {
     283            0 :         return DispatcherPub::ReduceAsync(src, dst, dataCount, datatype, redOp, stream, reduceType);
     284              :     }
     285            0 :     PLF_CONFIG_INFO(PLF_TASK,
     286              :         "%s para: src[%p] dst[%p] dataCount[%llu] datatype[%s] redOp[%s] reduceType[%d]  streamID[%u]",
     287              :         __func__, src, dst, dataCount, GetDataTypeEnumStr(datatype).c_str(),
     288              :         GetReduceOpEnumStr(redOp).c_str(), reduceType, stream.id());
     289              : 
     290            0 :     if (reduceType == HcclReduceType::HCCL_TBE_REDUCE) {
     291              :         // dtype=int64 或者 redOp=prod 都会走TbeReduce, 算法层控制的
     292            0 :         return TbeReduceAsync(src, dst, dataCount, datatype, redOp, stream, dst);
     293              :     }
     294              : 
     295            0 :     u32 ctxIdx = 0;
     296            0 :     CHK_RET(GraphAddReduceTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), dst, src, dataCount, datatype,
     297              :         redOp, &ctxIdx));
     298              :     // 调用回调来保存 task 信息
     299            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     300            0 :         hccl::TaskParaReduce para(src, dst, dataCount * SIZE_TABLE[datatype], redOp, datatype,
     301            0 :             LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID, (ctxIdx - 1));
     302            0 :         struct TaskPara taskPara;
     303            0 :         taskPara.stream = stream.ptr();
     304            0 :         taskPara.isMainStream = stream.IsMainStream();
     305            0 :         taskPara.beginTime = beginTime;
     306            0 :         taskPara.reduce = para;
     307            0 :         taskPara.type = TaskType::TASK_REDUCE_INLINE;
     308            0 :         taskPara.isFftsDispatcher = true;
     309            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     310            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     311            0 :     }
     312            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     313            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     314            0 :         hccl::TaskParaReduce para(src, dst, dataCount * SIZE_TABLE[datatype], redOp, datatype,
     315            0 :                 LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID, (ctxIdx - 1));
     316            0 :         struct TaskPara taskPara;
     317            0 :         taskPara.stream = stream.ptr();
     318            0 :         taskPara.isMainStream = stream.IsMainStream();
     319            0 :         taskPara.beginTime = beginTime;
     320            0 :         taskPara.reduce = para;
     321            0 :         taskPara.type = TaskType::TASK_REDUCE_INLINE;
     322            0 :         taskPara.isFftsDispatcher = true;
     323            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     324            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     325            0 :     }
     326              : 
     327            0 :     return HCCL_SUCCESS;
     328              : }
     329              : 
     330            0 : HcclResult DispatcherGraph::InlineReduceAsync(const void *src, u64 dataCount, const HcclDataType datatype,
     331              :     HcclReduceOp redOp, Stream &stream, void *dst, u32 remoteUserRank, hccl::LinkType inLinkType)
     332              : {
     333            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     334            0 :     if (UNLIKELY(disableFfts_)) {
     335            0 :         return DispatcherPub::InlineReduceAsync(
     336            0 :             src, dataCount, datatype, redOp, stream, dst, remoteUserRank, inLinkType);
     337              :     }
     338            0 :     PLF_CONFIG_INFO(PLF_TASK,
     339              :         "%s para: src[%p] dst[%p] dataCount[%llu] datatype[%s] redOp[%s] inLinkType[%d] remoteUserRank[%u]  streamID[%u]",
     340              :             __func__, src, dst, dataCount, GetDataTypeEnumStr(datatype).c_str(), GetReduceOpEnumStr(redOp).c_str(),
     341              :             inLinkType, remoteUserRank, stream.id());
     342            0 :     u32 ctxIdx = 0;
     343            0 :     CHK_RET(GraphAddInlineReduceTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), dst, src, dataCount, datatype,
     344              :         redOp, &ctxIdx));
     345              : 
     346              :     // 调用回调来保存 task 信息
     347            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     348            0 :         hccl::TaskParaReduce para(src, dst, dataCount * SIZE_TABLE[datatype], redOp, datatype, inLinkType,
     349            0 :             remoteUserRank, (ctxIdx - 1));
     350            0 :         struct TaskPara taskPara;
     351            0 :         taskPara.stream = stream.ptr();
     352            0 :         taskPara.isMainStream = stream.IsMainStream();
     353            0 :         taskPara.beginTime = beginTime;
     354            0 :         taskPara.reduce = para;
     355            0 :         taskPara.type = TaskType::TASK_REDUCE_INLINE;
     356            0 :         taskPara.isFftsDispatcher = true;
     357            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     358            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     359            0 :     }
     360            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     361            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     362            0 :         hccl::TaskParaReduce para(src, dst, dataCount * SIZE_TABLE[datatype], redOp, datatype, inLinkType,
     363            0 :             remoteUserRank, (ctxIdx - 1));
     364            0 :         struct TaskPara taskPara;
     365            0 :         taskPara.stream = stream.ptr();
     366            0 :         taskPara.isMainStream = stream.IsMainStream();
     367            0 :         taskPara.beginTime = beginTime;
     368            0 :         taskPara.reduce = para;
     369            0 :         taskPara.type = TaskType::TASK_REDUCE_INLINE;
     370            0 :         taskPara.isFftsDispatcher = true;
     371            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     372            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     373            0 :     }
     374            0 :     return HCCL_SUCCESS;
     375              : }
     376              : 
     377            1 : HcclResult DispatcherGraph::RdmaSend(u32 dbindex, u64 dbinfo, const struct SendWr &wr, hccl::Stream &stream,
     378              :     u32 remoteUserRank, bool isCapture)
     379              : {
     380            1 :     uint64_t beginTime = GetMsprofSysCycleTime();
     381            1 :     if (UNLIKELY(disableFfts_)) {
     382            0 :         return DispatcherPub::RdmaSend(dbindex, dbinfo, wr, stream, remoteUserRank);
     383              :     }
     384              : 
     385            1 :     u64 notifyID = (static_cast<u64>(remoteUserRank) << 32) | (0x00000000FFFFFFFF);
     386            1 :     PLF_CONFIG_INFO(PLF_TASK,
     387              :         "%s para: dbindex[%u], dbinfo[%llu], notifyId[0x%016llx], remoteUserRank[%u], isCapture[%d], streamID[%u]",
     388              :         __func__, dbindex, dbinfo, notifyID, remoteUserRank, stream.id(), isCapture);
     389              : 
     390            1 :     u32 ctxIdx = 0;
     391            1 :     CHK_RET(GraphAddRdmaSendTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), dbindex, dbinfo, isCapture, &ctxIdx));
     392              :     // 调用回调来保存task信息
     393            1 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     394              :         // 0x00000000FFFFFFFF usrrank位于notifyID的高32位
     395            1 :         hccl::TaskParaDMA para(reinterpret_cast<void *>(static_cast<uintptr_t>(wr.bufList[0].addr)),
     396            1 :                             reinterpret_cast<void *>(static_cast<uintptr_t>(wr.dstAddr)),
     397            1 :                             wr.bufList[0].len, notifyID, hccl::LinkType::LINK_ROCE, RdmaType::RDMA_SEND_PAYLOAD,
     398            1 :                             (ctxIdx - 1));
     399            1 :         struct TaskPara taskPara;
     400            1 :         taskPara.stream = stream.ptr();
     401            1 :         taskPara.isMainStream = stream.IsMainStream();
     402            1 :         taskPara.beginTime = beginTime;
     403            1 :         taskPara.dma = para;
     404            1 :         taskPara.type = TaskType::TASK_RDMA;
     405            1 :         taskPara.isFftsDispatcher = true;
     406            1 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     407            1 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     408            1 :     }
     409            2 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     410            2 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     411            1 :         hccl::TaskParaDMA para(reinterpret_cast<void *>(static_cast<uintptr_t>(wr.bufList[0].addr)),
     412            1 :                             reinterpret_cast<void *>(static_cast<uintptr_t>(wr.dstAddr)),
     413            1 :                             wr.bufList[0].len, notifyID, hccl::LinkType::LINK_ROCE, RdmaType::RDMA_SEND_PAYLOAD,
     414            1 :                             (ctxIdx - 1));
     415            1 :         struct TaskPara taskPara;
     416            1 :         taskPara.stream = stream.ptr();
     417            1 :         taskPara.isMainStream = stream.IsMainStream();
     418            1 :         taskPara.beginTime = beginTime;
     419            1 :         taskPara.dma = para;
     420            1 :         taskPara.type = TaskType::TASK_RDMA;
     421            1 :         taskPara.isFftsDispatcher = true;
     422            1 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     423            1 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     424            1 :     }
     425            1 :     return HCCL_SUCCESS;
     426              : }
     427              : 
     428            1 : HcclResult DispatcherGraph::RdmaSend(u32 dbindex, u64 dbinfo, const struct SendWr &wr, hccl::Stream &stream,
     429              :     u32 userRank, u64 offset, bool isCapture)
     430              : {
     431            1 :     uint64_t beginTime = GetMsprofSysCycleTime();
     432            1 :     if (UNLIKELY(disableFfts_)) {
     433            0 :         return DispatcherPub::RdmaSend(dbindex, dbinfo, wr, stream, userRank, offset);
     434              :     }
     435              : 
     436            1 :     u64 notifyID = (static_cast<u64>(userRank) << 32) | (offset & 0x00000000FFFFFFFF);
     437            1 :     PLF_CONFIG_INFO(PLF_TASK,
     438              :         "%s para: dbindex[%u], dbinfo[%llu], notifyId[0x%016llx], userRank[%u], offset[%llu], streamID[%u]",
     439              :         __func__, dbindex, dbinfo, notifyID, userRank, offset, stream.id());
     440              : 
     441            1 :     u32 ctxIdx = 0;
     442            1 :     CHK_RET(GraphAddRdmaSendTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), dbindex, dbinfo, isCapture, &ctxIdx));
     443              :     // 调用回调来保存task信息
     444            1 :      if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     445              :         // 0x00000000FFFFFFFF usrrank位于notifyID的高32位
     446            1 :         hccl::TaskParaDMA para(reinterpret_cast<void *>(static_cast<uintptr_t>(wr.bufList[0].addr)),
     447            1 :                             reinterpret_cast<void *>(static_cast<uintptr_t>(wr.dstAddr)),
     448            1 :                             wr.bufList[0].len, notifyID, hccl::LinkType::LINK_ROCE, RdmaType::RDMA_SEND_NOTIFY,
     449            1 :                             (ctxIdx - 1));
     450            1 :         struct TaskPara taskPara;
     451            1 :         taskPara.stream = stream.ptr();
     452            1 :         taskPara.isMainStream = stream.IsMainStream();
     453            1 :         taskPara.beginTime = beginTime;
     454            1 :         taskPara.dma = para;
     455            1 :         taskPara.type = TaskType::TASK_RDMA;
     456            1 :         taskPara.isFftsDispatcher = true;
     457            1 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     458            1 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     459            1 :     }
     460            2 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     461            2 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     462            1 :         hccl::TaskParaDMA para(reinterpret_cast<void *>(static_cast<uintptr_t>(wr.bufList[0].addr)),
     463            1 :                             reinterpret_cast<void *>(static_cast<uintptr_t>(wr.dstAddr)),
     464            1 :                             wr.bufList[0].len, notifyID, hccl::LinkType::LINK_ROCE, RdmaType::RDMA_SEND_NOTIFY,
     465            1 :                             (ctxIdx - 1));
     466            1 :         struct TaskPara taskPara;
     467            1 :         taskPara.stream = stream.ptr();
     468            1 :         taskPara.isMainStream = stream.IsMainStream();
     469            1 :         taskPara.beginTime = beginTime;
     470            1 :         taskPara.dma = para;
     471            1 :         taskPara.type = TaskType::TASK_RDMA;
     472            1 :         taskPara.isFftsDispatcher = true;
     473            1 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     474            1 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     475            1 :     }
     476            1 :     return HCCL_SUCCESS;
     477              : }
     478              : 
     479            0 : HcclResult DispatcherGraph::VectorReduce(const void *src1, const void *src2, u64 count, const HcclDataType dataType,
     480              :     HcclReduceOp redOp, Stream &stream, const void *dst)
     481              : {
     482            0 :     TbeReduceArg args{};
     483            0 :     if (count != 0) {
     484              : #ifndef HCCD
     485            0 :         TbeReduceParam param;
     486            0 :         std::vector<void *> overflowAddrs;
     487            0 :         overflowAddrs.push_back(overflowAddr_);
     488            0 :         param.src1 = const_cast<void*>(src1);
     489            0 :         param.src2 = const_cast<void*>(src2);
     490            0 :         param.dst = const_cast<void*>(dst);
     491            0 :         param.count = count;
     492            0 :         param.dataType = dataType;
     493            0 :         param.redOp = redOp;
     494            0 :         CHK_RET(HcclTbeReduceGenArgs(&param, stream.ptr(), overflowAddrs.data(), overflowAddrs.size(),
     495              :             &args, deviceLogicId_));
     496              : #else
     497              :         HCCL_ERROR("[DispatcherGraph][VectorReduce] does not support this interface.");
     498              :         return HCCL_E_PARA;
     499              : #endif
     500            0 :         GraphAddVectorReduceArgs(fftsPubInfo_, args.argsHandle);
     501            0 :     }
     502            0 :     CHK_RET(SetGraphDescVectorReduce(src1, dst, count, args.addrListDevMem, args.funcAddr,
     503              :         args.blockDim, dataType, redOp, stream));
     504            0 :     return HCCL_SUCCESS;
     505              : }
     506              : 
     507            0 : HcclResult DispatcherGraph::VectorReduceLoop(const void *src1, const void *src2, u64 count, const HcclDataType dataType,
     508              :     HcclReduceOp redOp, Stream &stream, const void *dst)
     509              : {
     510            0 :     const u32 unitSize = SIZE_TABLE[dataType];
     511            0 :     void *currentSrc1 = const_cast<void *>(src1);
     512            0 :     void *currentSrc2 = const_cast<void *>(src2);
     513            0 :     void *currentDst = const_cast<void *>(dst);
     514              :  
     515              :     // 计算出字节数为32字节整倍数的最大count
     516            0 :     const u64 maxCountPerLoop = ((TBE_REDUCE_MAX_COUNT * unitSize) / UB_BLOCK_SIZE * UB_BLOCK_SIZE) / unitSize;
     517              :  
     518            0 :     u64 countLeft = count;
     519              : 
     520              :     // 使用do while循环,是为了保证count为0时也进入一次VectorReduce,避免子图复用出错
     521              :     do  {
     522            0 :         u64 currentCount = countLeft > maxCountPerLoop ? maxCountPerLoop : countLeft;
     523            0 :         HCCL_DEBUG(
     524              :             "[VectorReduceLoop] currentCount[%llu], countLeft[%llu], currentSrc1[%p], currentSrc2[%p], currentDst[%p]",
     525              :             currentCount, countLeft, currentSrc1, currentSrc2, currentDst);
     526              :  
     527            0 :         CHK_RET(VectorReduce(currentSrc1, currentSrc2, currentCount, dataType, redOp, stream, currentDst));
     528              :  
     529            0 :         currentSrc1 = static_cast<void *>(static_cast<s8 *>(currentSrc1) + currentCount * unitSize);
     530            0 :         currentSrc2 = static_cast<void *>(static_cast<s8 *>(currentSrc2) + currentCount * unitSize);
     531            0 :         currentDst = static_cast<void *>(static_cast<s8 *>(currentDst) + currentCount * unitSize);
     532            0 :         countLeft -= currentCount;
     533            0 :     } while (countLeft > 0);
     534              : 
     535            0 :     return HCCL_SUCCESS;
     536              : }
     537              : 
     538            0 : HcclResult DispatcherGraph::SetGraphTailVectorReduceDescSdma(void *devMem, const void *tailSrc, u64 count,
     539              :     const HcclDataType dataType, HcclReduceOp redOp, Stream &stream)
     540              : {
     541            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     542            0 :     u32 ctxIdx = 0;
     543            0 :     CHK_RET(GraphAddTailVectorReduceTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), devMem, tailSrc, count, &ctxIdx));
     544              : 
     545              :     // 调用回调来保存 task 信息
     546            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     547              :         hccl::TaskParaDMA para(tailSrc, devMem, count, LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID,
     548            0 :             hccl::RdmaType::RDMA_TYPE_RESERVED, (ctxIdx - 1));
     549            0 :         struct TaskPara taskPara;
     550            0 :         taskPara.stream = stream.ptr();
     551            0 :         taskPara.isMainStream = stream.IsMainStream();
     552            0 :         taskPara.beginTime = beginTime;
     553            0 :         taskPara.dma = para;
     554            0 :         taskPara.type = TaskType::TASK_SDMA;
     555            0 :         taskPara.isFftsDispatcher = true;
     556            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     557            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     558            0 :     }
     559            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     560            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     561              :         hccl::TaskParaDMA para(tailSrc, devMem, count, LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID,
     562            0 :             hccl::RdmaType::RDMA_TYPE_RESERVED, (ctxIdx - 1));
     563            0 :         struct TaskPara taskPara;
     564            0 :         taskPara.stream = stream.ptr();
     565            0 :         taskPara.isMainStream = stream.IsMainStream();
     566            0 :         taskPara.beginTime = beginTime;
     567            0 :         taskPara.dma = para;
     568            0 :         taskPara.type = TaskType::TASK_SDMA;
     569            0 :         taskPara.isFftsDispatcher = true;
     570            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     571            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     572            0 :     }
     573            0 :     return HCCL_SUCCESS;
     574              : }
     575              : 
     576            0 : HcclResult DispatcherGraph::SetGraphDescVectorReduce(const void *src, const void *dst, int count, void *addrListDevMemPtr,
     577              :     void *funcAddr, uint32_t numBlocks, const HcclDataType dataType, HcclReduceOp redOp, Stream &stream)
     578              : {
     579            0 :     uint64_t beginTime = GetMsprofSysCycleTime();
     580            0 :     u32 ctxIdx = 0;
     581            0 :     CHK_RET(GraphAddVectorReduceTask(fftsPubInfo_, fftsCtxsPtr, stream.id(), count, addrListDevMemPtr,
     582              :         funcAddr, numBlocks, &ctxIdx));
     583              : 
     584              :     // 调用回调来保存 task 信息
     585            0 :     if (DispatcherPub::IsProfSubscribeAdditionInfo() && callback_ != nullptr) {
     586            0 :         hccl::TaskParaReduce para(src, dst, count * SIZE_TABLE[dataType], redOp, dataType,
     587            0 :             LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID, (ctxIdx - 1));
     588            0 :         struct TaskPara taskPara;
     589            0 :         taskPara.stream = stream.ptr();
     590            0 :         taskPara.isMainStream = stream.IsMainStream();
     591            0 :         taskPara.beginTime = beginTime;
     592            0 :         taskPara.reduce = para;
     593            0 :         taskPara.type = TaskType::TASK_REDUCE_TBE;
     594            0 :         taskPara.isFftsDispatcher = true;
     595            0 :         taskPara.profilerType = ProfilerType::TASK_PROFILING;
     596            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     597            0 :     }
     598            0 :     if (GetExternalInputHcclEnableFfts() && GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE &&
     599            0 :         GetExternalInputTaskExceptionSwitch() == 1 && callback_ != nullptr) {
     600            0 :         hccl::TaskParaReduce para(src, dst, count * SIZE_TABLE[dataType], redOp, dataType,
     601            0 :             LinkType::LINK_ONCHIP, INVALID_VALUE_RANKID, (ctxIdx - 1));
     602            0 :         struct TaskPara taskPara;
     603            0 :         taskPara.stream = stream.ptr();
     604            0 :         taskPara.isMainStream = stream.IsMainStream();
     605            0 :         taskPara.beginTime = beginTime;
     606            0 :         taskPara.reduce = para;
     607            0 :         taskPara.type = TaskType::TASK_REDUCE_TBE;
     608            0 :         taskPara.isFftsDispatcher = true;
     609            0 :         taskPara.profilerType = ProfilerType::TASK_EXCEPTION;
     610            0 :         callback_(callBackUserPtr_, (void *)&taskPara, sizeof(struct TaskPara));
     611            0 :     }
     612            0 :     return HCCL_SUCCESS;
     613              : }
     614              : 
     615            0 : HcclResult DispatcherGraph::TailVectorReduce(const void *tailSrc1, const void *tailSrc2, u64 tailCount,
     616              :     const HcclDataType dataType, HcclReduceOp redOp, Stream &stream, void *tailDst)
     617              : {
     618            0 :     void *devMem1 = nullptr;
     619            0 :     void *devMem2 = nullptr;
     620            0 :     TbeReduceArg args{};
     621            0 :     if (tailCount != 0) {
     622              : #ifndef HCCD
     623            0 :         CHK_RET(DevMemMalloc(stream.ptr(), devMem1, devMem2));
     624            0 :         TbeReduceParam param;
     625            0 :         std::vector<void *> overflowAddrs;
     626            0 :         overflowAddrs.push_back(overflowAddr_);
     627            0 :         param.src1 = devMem1;
     628            0 :         param.src2 = devMem2;
     629            0 :         param.dst = devMem2;
     630            0 :         param.count = tailCount;
     631            0 :         param.dataType = dataType;
     632            0 :         param.redOp = redOp;
     633            0 :         CHK_RET(HcclTbeReduceGenArgs(&param, stream.ptr(), overflowAddrs.data(), overflowAddrs.size(),
     634              :             &args, deviceLogicId_));
     635              : #else
     636              :         HCCL_ERROR("[DispatcherGraph][VectorReduce] does not support this interface.");
     637              :         return HCCL_E_PARA;
     638              : #endif
     639            0 :         GraphAddVectorReduceArgs(fftsPubInfo_, args.argsHandle);
     640            0 :     }
     641            0 :     u64 dataCount = tailCount * SIZE_TABLE[dataType];
     642              : 
     643            0 :     CHK_RET(SetGraphTailVectorReduceDescSdma(devMem1, tailSrc1, dataCount, dataType, redOp, stream));
     644            0 :     CHK_RET(SetGraphTailVectorReduceDescSdma(devMem2, tailSrc2, dataCount, dataType, redOp, stream));
     645            0 :     CHK_RET(SetGraphDescVectorReduce(devMem1, tailDst, tailCount, args.addrListDevMem, args.funcAddr,
     646              :         args.blockDim, dataType, redOp, stream));
     647            0 :     CHK_RET(SetGraphTailVectorReduceDescSdma(tailDst, devMem2, dataCount, dataType, redOp, stream));
     648            0 :     return HCCL_SUCCESS;
     649              : }
     650              : 
     651            0 : HcclResult DispatcherGraph::TbeReduceAsync(const void *src1, const void *src2, u64 count, const HcclDataType dataType,
     652              :     HcclReduceOp redOp, Stream &stream, const void *dst)
     653              : {
     654            0 :     void *tailSrc1 = nullptr;
     655            0 :     void *tailSrc2 = nullptr;
     656            0 :     void *tailDst = nullptr;
     657            0 :     u64 headCount = 0;
     658            0 :     u64 tailCount = 0;
     659              : #ifndef HCCD
     660            0 :     CHK_RET(JudgeIsTail(src1, src2, dst, count, dataType, headCount, tailCount, tailSrc1, tailSrc2,
     661              :         tailDst));
     662              : #else
     663              :         HCCL_ERROR("[DispatcherGraph][TbeReduceAsync] does not support this interface.");
     664              :         return HCCL_E_PARA;
     665              : #endif
     666            0 :     CHK_RET(VectorReduceLoop(src1, src2, headCount, dataType, redOp, stream, dst));
     667            0 :     CHK_RET(TailVectorReduce(tailSrc1, tailSrc2, tailCount, dataType, redOp, stream, tailDst));
     668              : 
     669            0 :     return HCCL_SUCCESS;
     670              : }
     671              : 
     672            0 : HcclResult DispatcherGraph::SignalRecord(Stream &stream, u64 notifyId)
     673              : {
     674            0 :     if (UNLIKELY(disableFfts_)) {
     675            0 :         return DispatcherPub::SignalRecord(stream, notifyId);
     676              :     }
     677              : 
     678            0 :     CHK_RET(GraphAddRecordTaskById(fftsPubInfo_, fftsCtxsPtr, static_cast<u32>(notifyId), stream.id()));
     679              : 
     680            0 :     if (HcclCheckLogLevel(HCCL_LOG_INFO) || (GetExternalInputDebugConfig() & PLF_TASK)) {
     681            0 :         PLF_CONFIG_INFO(PLF_TASK,
     682              :             "%s para: notifyId[0x%016llx] streamId[%u]", __func__, notifyId, stream.id());
     683              :     }
     684              : 
     685            0 :     return HCCL_SUCCESS;
     686              : }
     687              : 
     688            0 : HcclResult DispatcherGraph::SignalWait(Stream &stream, u32 notifyId, u32 timeOut)
     689              : {
     690            0 :     if (UNLIKELY(disableFfts_)) {
     691            0 :         return DispatcherPub::SignalWait(stream, notifyId, timeOut);
     692              :     }
     693            0 :     CHK_RET(GraphAddWaitTaskById(fftsPubInfo_, fftsCtxsPtr, static_cast<u32>(notifyId), stream.id()));
     694              : 
     695            0 :     if (HcclCheckLogLevel(HCCL_LOG_INFO) || (GetExternalInputDebugConfig() & PLF_TASK)) {
     696            0 :         PLF_CONFIG_INFO(PLF_TASK,
     697              :             "%s para: notifyId[0x%016llx] streamId[%u]", __func__, notifyId, stream.id());
     698              :     }
     699              : 
     700            0 :     return HCCL_SUCCESS;
     701              : }
     702              : 
     703              : } // namespace hccl
        

Generated by: LCOV version 2.0-1