LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/impl/coll_executor/coll_reduce_scatter - coll_reduce_scatter_mix_executor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 242 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 14 0

            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 "coll_reduce_scatter_mix_executor.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15            0 : CollReduceScatterMixExecutor::CollReduceScatterMixExecutor(
      16            0 :     const HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher>& topoMatcher)
      17            0 :     : CollReduceScatterExecutor(dispatcher, topoMatcher)
      18              : {
      19            0 :     DMAReduceFlag_ = workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
      20            0 :                      && topoAttr_.deviceType == DevType::DEV_TYPE_910_93;
      21            0 : }
      22              : 
      23            0 : void CollReduceScatterMixExecutor::ParseParam(const OpParam& param)
      24              : {
      25            0 :     tag_ = param.tag;
      26            0 :     aicpuUnfoldMode_ = param.aicpuUnfoldMode;
      27              : 
      28              :     // 是否需要scratch memory
      29            0 :     if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && isSupportSDMAReduce_
      30            0 :         && IsSupportRDMAReduce(param.DataDes.dataType, param.reduceType)) {
      31            0 :         scratchMemFlag_ = false;
      32              :     } else {
      33            0 :         scratchMemFlag_ = true;
      34              :     }
      35              : 
      36              :     // 记录图模式总数据量
      37            0 :     totalSize_ = topoAttr_.userRankSize * param.DataDes.count * SIZE_TABLE[param.DataDes.dataType];
      38              : 
      39              :     // 910B 图模式非确定计算,inlineReduce使能,MESH拓扑场景下,创建一个mesh平面
      40              :     bool isInlineReduce
      41            0 :         = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
      42            0 :     meshSinglePlane_ = (topoAttr_.deviceType == DevType::DEV_TYPE_910B)
      43            0 :                        && topoMatcher_->GetExternalInputHcclDeterministic() == DETERMINISTIC_DISABLE && isInlineReduce
      44            0 :                        && (workflowMode_ != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
      45              : 
      46            0 :     bool isAlsoSupportDMAReduce = topoAttr_.deviceType == DevType::DEV_TYPE_910B && isInlineReduce
      47            0 :                                   && workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
      48            0 :                                   && topoMatcher_->GetExternalInputHcclDeterministic() == DETERMINISTIC_DISABLE
      49            0 :                                   && param.DataDes.dataType != HCCL_DATA_TYPE_INT64
      50            0 :                                   && param.reduceType != HCCL_REDUCE_PROD;
      51            0 :     if (isAlsoSupportDMAReduce) {
      52            0 :         DMAReduceFlag_ = true;
      53              :     }
      54            0 : }
      55              : 
      56            0 : HcclResult CollReduceScatterMixExecutor::CalcScratchMemSize(u64& scratchMemSize)
      57              : {
      58            0 :     if (scratchMemFlag_) {
      59            0 :         if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
      60            0 :             scratchMemSize = inCCLbufferSize_;
      61              :         } else {
      62            0 :             scratchMemSize = totalSize_;
      63              :         }
      64              :     } else {
      65            0 :         scratchMemSize = 0U;
      66              :     }
      67            0 :     HCCL_INFO(
      68              :         "[CollReduceScatterMixExecutor][CalcScratchMemSize] tag[%s] scratchMemSize[%llu]", tag_.c_str(),
      69              :         scratchMemSize);
      70            0 :     return HCCL_SUCCESS;
      71              : }
      72              : 
      73            0 : HcclResult CollReduceScatterMixExecutor::CalcStreamNum(u32& streamNum)
      74              : {
      75            0 :     u32 totalStreamNum = 0;
      76            0 :     if (topoAttr_.deviceType == DevType::DEV_TYPE_910B) { // mesh
      77            0 :         totalStreamNum = topoAttr_.deviceNumPerAggregation;
      78            0 :         HCCL_DEBUG("[CollReduceScatterMixExecutor][CalcStreamNum]totalStreamNum is %u", totalStreamNum);
      79            0 :     } else if (topoAttr_.deviceType == DevType::DEV_TYPE_910_93) { // dbring
      80              :         totalStreamNum
      81            0 :             = (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING ? LEVEL0_PLANE_NUM_IN_NPRING_DOUBLE :
      82              :                                                                  LEVEL0_PLANE_NUM_IN_NPRING_SINGLE);
      83            0 :         if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
      84            0 :             totalStreamNum *= STREAM_NUM_FOR_DMAREDUCE_ONE_RING;
      85              :         }
      86              :     }
      87              : 
      88            0 :     streamNum = totalStreamNum - 1U;
      89            0 :     HCCL_INFO("[CollReduceScatterMixExecutor][CalcStreamNum] tag[%s] streamNum[%u]", tag_.c_str(), streamNum);
      90            0 :     return HCCL_SUCCESS;
      91              : }
      92              : 
      93            0 : bool CollReduceScatterMixExecutor::IsHugeData(const u64 curSize, OpParam* param)
      94              : {
      95            0 :     const u64 TBE_REDUCE_MAX_COUNT = INT32_MAX;
      96              : 
      97            0 :     u64 curCount = curSize / SIZE_TABLE[param->DataDes.dataType];
      98            0 :     bool issupportRDMAInlineReduce = IsSupportRDMAReduce(param->DataDes.dataType, param->reduceType);
      99              :     // 这里如果CheckCommSize返回ERROR,相当于HugeData true,防止GetSubCommInfo越界
     100            0 :     CHK_RET(CheckCommSize(COMM_LEVEL0, COMM_INDEX_0 + 1));
     101            0 :     SubCommInfo level0CommInfo = GetSubCommInfo(COMM_LEVEL0, COMM_INDEX_0);
     102            0 :     u32 level0RankSize = level0CommInfo.localRankSize;
     103              : 
     104            0 :     bool hugeData = (curSize * level0RankSize / HCCL_INTERNODE_MAX_DATA_RATE > RDMA_SEND_MAX_SIZE)
     105            0 :                     || (curSize > SDMA_SEND_MAX_SIZE) || ((!isSupportSDMAReduce_) && (curCount > TBE_REDUCE_MAX_COUNT))
     106            0 :                     || ((!issupportRDMAInlineReduce)
     107            0 :                         && (curCount * level0RankSize / HCCL_INTERNODE_MAX_DATA_RATE > TBE_REDUCE_MAX_COUNT));
     108              : 
     109            0 :     return hugeData;
     110            0 : }
     111              : 
     112            0 : bool CollReduceScatterMixExecutor::IsSmallData(const u64 totalSize, [[maybe_unused]] const u64 curSize)
     113              : {
     114            0 :     bool smallData = totalSize <= HCCL_SMALL_COUNT_32_KB;
     115            0 :     return smallData;
     116              : }
     117              : 
     118            0 : HcclResult CollReduceScatterMixExecutor::CalcCommInfo(std::vector<LevelNSubCommTransport>& opTransport)
     119              : {
     120            0 :     TransportMemType inputType = TransportMemType::RESERVED;
     121            0 :     TransportMemType outputType = TransportMemType::RESERVED;
     122            0 :     CHK_RET(CalcTransportMemType(inputType, outputType));
     123            0 :     CHK_RET(CalcLevel0CommInfo(inputType, outputType, opTransport));
     124            0 :     CHK_RET(CalcLevel1CommInfo(inputType, outputType, opTransport));
     125              : 
     126              :     // mix在server间使用NHR通信域,并在多机A+X场景下当未设置使用RDMA时,默认使用RDMA
     127            0 :     std::vector<SingleSubCommTransport>& commTransportLevel1 = opTransport[COMM_LEVEL1];
     128            0 :     for (u32 ringIndex = 0; ringIndex < commTransportLevel1.size(); ringIndex++) {
     129            0 :         for (auto& transportRequest : commTransportLevel1[ringIndex].transportRequests) {
     130            0 :             transportRequest.isUsedRdma = true;
     131              :         }
     132              :     }
     133            0 :     return HCCL_SUCCESS;
     134              : }
     135              : 
     136            0 : HcclResult CollReduceScatterMixExecutor::CalcTransportMemType(TransportMemType& inputType, TransportMemType& outputType)
     137              : {
     138            0 :     if (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     139            0 :         inputType = TransportMemType::CCL_INPUT;
     140            0 :         if (scratchMemFlag_) {
     141            0 :             outputType = TransportMemType::SCRATCH;
     142              :         } else {
     143            0 :             outputType = TransportMemType::CCL_OUTPUT;
     144              :         }
     145              :     } else {
     146            0 :         inputType = TransportMemType::PARAM_INPUT;
     147            0 :         if (scratchMemFlag_) {
     148            0 :             outputType = TransportMemType::SCRATCH;
     149              :         } else {
     150            0 :             outputType = TransportMemType::PARAM_OUTPUT;
     151              :         }
     152              :     }
     153            0 :     HCCL_INFO(
     154              :         "[CollReduceScatterMixExecutor][CalcTransportMemType] tag[%s] inputType[%d], outputType[%d]", tag_.c_str(),
     155              :         inputType, outputType);
     156            0 :     return HCCL_SUCCESS;
     157              : }
     158              : 
     159            0 : HcclResult CollReduceScatterMixExecutor::CalcLevel0CommInfo(
     160              :     TransportMemType inputType, TransportMemType outputType, std::vector<LevelNSubCommTransport>& opTransport)
     161              : {
     162            0 :     if (topoAttr_.deviceType == DevType::DEV_TYPE_910B) {
     163            0 :         CommParaInfo commParaLevel0(COMM_LEVEL0, CommType::COMM_TAG_MESH);
     164            0 :         commParaLevel0.meshSinglePlane = meshSinglePlane_;
     165            0 :         CHK_RET(CalcCommPlaneInfo(tag_, commParaLevel0, opTransport[COMM_LEVEL0], inputType, outputType));
     166            0 :     } else if (topoAttr_.deviceType == DevType::DEV_TYPE_910_93) {
     167            0 :         CommParaInfo commParaLevel0(COMM_LEVEL0, CommType::COMM_TAG_RING_INNER);
     168            0 :         CHK_RET(CalcCommPlaneInfo(tag_, commParaLevel0, opTransport[COMM_LEVEL0], inputType, outputType));
     169            0 :     }
     170              : 
     171            0 :     return HCCL_SUCCESS;
     172              : }
     173              : 
     174            0 : u64 CollReduceScatterMixExecutor::CalcLoopMaxCount(const u32 unitSize)
     175              : {
     176            0 :     u64 maxCountPerLoop = inCCLbufferSize_ / (topoAttr_.userRankSize * unitSize);
     177            0 :     return maxCountPerLoop;
     178              : }
     179              : 
     180            0 : void CollReduceScatterMixExecutor::CalLevel0DataSegsSlice(
     181              :     const ExecMem& execMem, const std::vector<std::vector<Slice>>& multiStreamSlice, u32 sliceNum, u32 level1RankSize,
     182              :     std::vector<std::vector<Slice>>& level0DataSegsSlice)
     183              : {
     184            0 :     for (u32 ringIndex = 0; ringIndex < multiStreamSlice.size(); ringIndex++) {
     185            0 :         std::vector<Slice> dataSlice;
     186            0 :         FillMultiRingSlice(execMem, multiStreamSlice, sliceNum, level1RankSize, ringIndex, dataSlice);
     187            0 :         level0DataSegsSlice.push_back(dataSlice);
     188            0 :     }
     189            0 : }
     190              : 
     191            0 : void CollReduceScatterMixExecutor::FillMultiRingSlice(
     192              :     const ExecMem& execMem, const std::vector<std::vector<Slice>>& multiStreamSlice, u32 sliceNum, u32 level1RankSize,
     193              :     const u32 ringIndex, std::vector<Slice>& dataSlice)
     194              : {
     195            0 :     for (u32 level0Idx = 0; level0Idx < sliceNum; level0Idx++) {
     196            0 :         Slice sliceTemp;
     197            0 :         for (u32 level1Idx = 0; level1Idx < level1RankSize; level1Idx++) {
     198            0 :             sliceTemp.size = multiStreamSlice[ringIndex][level0Idx].size;
     199              :             sliceTemp.offset
     200            0 :                 = multiStreamSlice[ringIndex][level0Idx].offset + level1Idx * sliceNum * execMem.outputMem.size();
     201            0 :             dataSlice.push_back(sliceTemp);
     202            0 :             HCCL_DEBUG(
     203              :                 "rank[%u] sliceTemp.size[%zu], sliceTemp.offset[%llu]", topoAttr_.userRank, sliceTemp.size,
     204              :                 sliceTemp.offset);
     205              :         }
     206              :     }
     207            0 : }
     208              : 
     209            0 : HcclResult CollReduceScatterMixExecutor::CalLevel1DataSegsSlice(
     210              :     const ExecMem& execMem, const u32& commIndex, u32 sliceNum, u32 level1RankSize,
     211              :     std::vector<Slice>& level1DataSegsSlice)
     212              : {
     213              :     (void)sliceNum;
     214            0 :     for (u32 i = 0; i < level1RankSize; i++) {
     215            0 :         Slice sliceTemp;
     216              :         u32 level1UserRank;
     217            0 :         CHK_RET(GetUserRankByRank(COMM_LEVEL1, commIndex, i, level1UserRank));
     218            0 :         sliceTemp.size = execMem.outputMem.size();
     219            0 :         sliceTemp.offset = level1UserRank * execMem.outputMem.size();
     220            0 :         level1DataSegsSlice.push_back(sliceTemp);
     221            0 :         HCCL_DEBUG(
     222              :             "rank[%u], level1DataSegsSlice[%u].offset=%llu, size=[%llu]", topoAttr_.userRank, i, sliceTemp.offset,
     223              :             sliceTemp.size);
     224              :     }
     225            0 :     return HCCL_SUCCESS;
     226              : }
     227              : 
     228            0 : HcclResult CollReduceScatterMixExecutor::KernelRun(const OpParam& param, ExecMem& execMem)
     229              : {
     230            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[CollReduceScatterMixExecutor][KernelRun] The ReduceScatterMixExecutor starts.");
     231            0 :     u32 perDataSize = 0;
     232            0 :     CHK_RET(SalGetDataTypeSize(param.DataDes.dataType, perDataSize));
     233              : 
     234            0 :     CHK_RET(CheckCommSize(COMM_LEVEL0, COMM_INDEX_0 + 1));
     235            0 :     SubCommInfo level0CommInfo = GetSubCommInfo(COMM_LEVEL0, COMM_INDEX_0);
     236            0 :     u32 level0RankSize = level0CommInfo.localRankSize;
     237            0 :     u32 commIndex = level0CommInfo.localRank; // 找到rank所在的节点间平面
     238              : 
     239            0 :     CHK_RET(CheckCommSize(COMM_LEVEL1, commIndex + 1));
     240            0 :     SubCommInfo level1CommInfo = GetSubCommInfo(COMM_LEVEL1, commIndex);
     241            0 :     u32 serverIndex = level1CommInfo.localRank;
     242            0 :     u32 level1RankSize = level1CommInfo.localRankSize;
     243            0 :     HCCL_DEBUG(
     244              :         "ReduceScatterMixExecutor inputSize=%llu, level0RankSize=%u,commIndex=%u, level1RankSize=%u, serverIndex=%u",
     245              :         execMem.inputMem.size(), level0RankSize, commIndex, level1RankSize, serverIndex);
     246              : 
     247            0 :     HcomCollOpInfo opInfo = {"",
     248            0 :                              execMem.inputPtr,
     249            0 :                              execMem.outputPtr,
     250            0 :                              param.DataDes.count,
     251            0 :                              param.DataDes.dataType,
     252            0 :                              param.root,
     253            0 :                              param.reduceType,
     254            0 :                              0};
     255            0 :     HCCL_DEBUG(
     256              :         "[CollReduceScatterMixExecutor][KernelRun] execMem.inputPtr[%p], execMem.outputPtr[%p], "
     257              :         "execMem.inputMem[%p], execMem.outputMem[%p]",
     258              :         execMem.inputPtr, execMem.outputPtr, execMem.inputMem.ptr(), execMem.outputMem.ptr());
     259            0 :     HcomCollOpInfo* opInfoPtr = nullptr;
     260            0 :     if (DMAReduceFlag_) {
     261            0 :         opInfoPtr = &opInfo;
     262              :     }
     263              : 
     264              :     //  第一步,AI server内reduce scatter mesh/dbring
     265            0 :     u32 sliceNum = level0CommInfo.localRankSize;
     266            0 :     if (topoAttr_.deviceType == DevType::DEV_TYPE_910_93) {
     267              :         u32 ringNum;
     268            0 :         if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
     269            0 :             ringNum = LEVEL0_PLANE_NUM_IN_NPRING_DOUBLE;
     270              :         } else {
     271            0 :             ringNum = LEVEL0_PLANE_NUM_IN_NPRING_SINGLE;
     272              :         }
     273              : 
     274            0 :         Slice sliceTemp;
     275              : 
     276            0 :         std::vector<Slice> dataSegsSlice;                 // 数据分成ranksize份,每份的起始偏移和大小
     277            0 :         std::vector<std::vector<Slice>> multiStreamSlice; // 每个stream使用的数据基于用户buffer的偏移
     278              : 
     279            0 :         CHK_RET(ActiveSlaveStreams(param.stream));
     280              : 
     281              :         // 计算slice
     282            0 :         std::vector<std::vector<Slice>> level0DataSegsSlice;
     283            0 :         bool useInlineRduce = false;
     284            0 :         bool isInlineReduce = IsSupportSDMAReduce(
     285            0 :             execMem.inputMem.ptr(), execMem.scratchMem.ptr(), param.DataDes.dataType, param.reduceType);
     286            0 :         useInlineRduce = isInlineReduce && algoAttr_.inlineReduceSwitchOn;
     287            0 :         multiStreamSlice = ReduceScatterRingSlicePrepare(
     288            0 :             ringNum, sliceNum, useInlineRduce, execMem.outputMem, dataSegsSlice,
     289            0 :             param.tag); // 2个ring,每条ring上数据的偏移和大小
     290              : 
     291            0 :         CalLevel0DataSegsSlice(execMem, multiStreamSlice, sliceNum, level1RankSize, level0DataSegsSlice);
     292              : 
     293            0 :         std::vector<std::vector<Slice>> multRingsUserMemSlice;
     294              : 
     295            0 :         if (opInfoPtr == nullptr
     296            0 :             && (!(
     297            0 :                 topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING
     298            0 :                 && workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB))) {
     299            0 :             multRingsUserMemSlice = level0DataSegsSlice;
     300              :         } else {
     301            0 :             for (u32 ringIndex = 0; ringIndex < level0DataSegsSlice.size(); ringIndex++) {
     302            0 :                 std::vector<Slice> level1UserMemSlice;
     303            0 :                 for (auto& cclSlice : level0DataSegsSlice[ringIndex]) {
     304            0 :                     Slice tmpSlice;
     305            0 :                     tmpSlice.size = cclSlice.size;
     306            0 :                     tmpSlice.offset = (cclSlice.offset / execMem.outputMem.size()) * param.DataDes.count * perDataSize
     307            0 :                                       + multiStreamSlice[ringIndex][0].offset;
     308            0 :                     level1UserMemSlice.push_back(tmpSlice);
     309            0 :                     HCCL_DEBUG(
     310              :                         "rank[%u], ringIndex[%u], tmpSlice.offset=[%llu], size=[%llu]", topoAttr_.userRank, ringIndex,
     311              :                         tmpSlice.offset, tmpSlice.size);
     312              :                 }
     313            0 :                 multRingsUserMemSlice.push_back(level1UserMemSlice);
     314            0 :             }
     315              :         }
     316              :         // 区分消减拷贝场景
     317            0 :         if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING
     318            0 :             && workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
     319              :             // 图模式opinfo不为空
     320            0 :             HcomCollOpInfo graphModeOpInfo
     321            0 :                 = {"",         execMem.inputMem.ptr(), nullptr, param.DataDes.count, param.DataDes.dataType,
     322            0 :                    param.root, param.reduceType,       0};
     323            0 :             CHK_RET(MultiRingReduceScatter(
     324              :                 param.tag, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
     325              :                 param.reduceType, level0DataSegsSlice, param.stream, PROF_STAGE_0, 0, &graphModeOpInfo,
     326              :                 multRingsUserMemSlice));
     327            0 :         } else if (opInfoPtr != nullptr) {
     328            0 :             HcomCollOpInfo opInfoByReduceScatterDMAreduce = *opInfoPtr;
     329            0 :             opInfoByReduceScatterDMAreduce.outputAddr = nullptr;
     330            0 :             CHK_RET(MultiRingReduceScatter(
     331              :                 param.tag, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
     332              :                 param.reduceType, level0DataSegsSlice, param.stream, PROF_STAGE_0, 0, &opInfoByReduceScatterDMAreduce,
     333              :                 multRingsUserMemSlice));
     334              :         } else {
     335            0 :             CHK_RET(MultiRingReduceScatter(
     336              :                 param.tag, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
     337              :                 param.reduceType, level0DataSegsSlice, param.stream, PROF_STAGE_0, 0, opInfoPtr,
     338              :                 multRingsUserMemSlice));
     339              :         }
     340            0 :     } else if (topoAttr_.deviceType == DevType::DEV_TYPE_910B) {
     341            0 :         CHK_RET(ActiveSlaveStreams(param.stream));
     342              : 
     343              :         // 根据数据量算每个环上数据的偏移和大小,把做完hd的slice均分成RankSize份
     344            0 :         std::vector<Slice> dataSegsSlice;
     345            0 :         CHK_RET(PrepareReduceScatterSliceData(execMem.count, perDataSize, sliceNum, dataSegsSlice));
     346              : 
     347            0 :         if (opInfoPtr != nullptr) {
     348              :             u64 reduceAttr
     349            0 :                 = GetReduceAttr(execMem.inputMem, execMem.scratchMem, param.DataDes.dataType, param.reduceType);
     350            0 :             std::unique_ptr<AlgTemplateBase> level0Executor = AlgTemplateRegistry::Instance().GetAlgTemplate(
     351            0 :                 TemplateType::TEMPLATE_REDUCESCATTER_MESH_MIX, dispatcher_);
     352              : 
     353            0 :             CHK_SMART_PTR_NULL(level0Executor);
     354            0 :             CHK_RET(level0Executor->Prepare(
     355              :                 execMem.inputMem, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
     356              :                 param.stream, param.reduceType, LEVEL0_BRIDGE_RANK_ID, dataSegsSlice, 0, reduceAttr,
     357              :                 algResResp_->slaveStreams, algResResp_->notifiesMain, algResResp_->notifiesAux, serverIndex,
     358              :                 level1RankSize, opInfoPtr));
     359            0 :             CHK_RET(level0Executor->RegisterProfiler(
     360              :                 (level0RankSize << PROF_RANKSIZE_OFFSET_OF_PLANEID) + commIndex, PROF_STAGE_0, HCCL_EXEC_STEP_NOT_SET,
     361              :                 param.stream));
     362            0 :             CHK_RET(RunTemplate(level0Executor, level0CommInfo));
     363            0 :         } else {
     364            0 :             std::vector<std::vector<Slice>> multiStreamSlice; // 每个stream使用的数据基于用户buffer的偏移
     365              :             // mesh算法stream数量为rank数减1
     366            0 :             CHK_RET(AlgTemplateBase::PrepareSliceMeshStreams(dataSegsSlice, sliceNum - 1, multiStreamSlice));
     367              : 
     368              :             // 计算slice
     369            0 :             std::vector<std::vector<Slice>> level0DataSegsSlice;
     370            0 :             CalLevel0DataSegsSlice(execMem, multiStreamSlice, sliceNum, level1RankSize, level0DataSegsSlice);
     371              : 
     372            0 :             CHK_RET(MultiStreamReduceScatterMesh(
     373              :                 param.tag, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType,
     374              :                 param.reduceType, level0DataSegsSlice, param.stream, COMM_LEVEL0, 0));
     375            0 :         }
     376            0 :     }
     377              : 
     378              :     //  第二步,节点间reduce scatter
     379            0 :     u64 reduceAttr = GetReduceAttr(execMem.inputMem, execMem.scratchMem, param.DataDes.dataType, param.reduceType);
     380              : 
     381            0 :     std::unique_ptr<AlgTemplateBase> level1Executor;
     382              : 
     383              :     // 计算slice
     384            0 :     std::vector<Slice> level1DataSegsSlice;
     385              : 
     386            0 :     CHK_RET(CalLevel1DataSegsSlice(execMem, commIndex, sliceNum, level1RankSize, level1DataSegsSlice));
     387              : 
     388            0 :     if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING) {
     389              :         level1Executor
     390            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_RING, dispatcher_);
     391            0 :         CHK_SMART_PTR_NULL(level1Executor);
     392            0 :         CHK_RET(level1Executor->Prepare(reduceAttr));
     393            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_RING in COMM_LEVEL1", __func__);
     394            0 :     } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR) {
     395              :         level1Executor
     396            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NHR, dispatcher_);
     397            0 :         CHK_SMART_PTR_NULL(level1Executor);
     398            0 :         CHK_RET(level1Executor->Prepare(reduceAttr, false));
     399            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NHR in COMM_LEVEL1", __func__);
     400              :     } else {
     401            0 :         HCCL_ERROR(
     402              :             "[CollReduceScatterMixExecutor][KernelRun]ReduceScatter mix: algType[%u] is not supported.",
     403              :             algType_.algoLevel1);
     404            0 :         return HCCL_E_NOT_SUPPORT;
     405              :     }
     406              : 
     407            0 :     CHK_RET(level1Executor->Prepare(
     408              :         execMem.inputMem, execMem.inputMem, execMem.scratchMem, execMem.count, param.DataDes.dataType, param.stream,
     409              :         param.reduceType, LEVEL0_BRIDGE_RANK_ID, level1DataSegsSlice));
     410            0 :     CHK_RET(level1Executor->RegisterProfiler(
     411              :         (level1RankSize << PROF_RANKSIZE_OFFSET_OF_PLANEID) + level1CommInfo.localRank, PROF_STAGE_1,
     412              :         HCCL_EXEC_STEP_NOT_SET, param.stream));
     413            0 :     CHK_RET(RunTemplate(level1Executor, level1CommInfo));
     414              : 
     415              :     // 区分消减拷贝场景(消减拷贝数据需要拷贝到user output上)
     416            0 :     DeviceMem srcMem = execMem.inputMem.range(topoAttr_.userRank * execMem.outputMem.size(), execMem.outputMem.size());
     417            0 :     if (opInfoPtr != nullptr) {
     418            0 :         DeviceMem dstMem = DeviceMem::create(static_cast<u8*>(opInfoPtr->outputAddr), execMem.outputMem.size());
     419            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, const_cast<Stream&>(param.stream)));
     420            0 :     } else {
     421            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, execMem.outputMem, srcMem, const_cast<Stream&>(param.stream)));
     422              :     }
     423              : 
     424            0 :     HCCL_INFO("[CollReduceScatterMixExecutor][KernelRun]ReduceScatter mix run success");
     425            0 :     return HCCL_SUCCESS;
     426            0 : }
     427              : 
     428              : REGISTER_EXEC("ReduceScatterMixExecutor", ReduceScatterMix, CollReduceScatterMixExecutor);
     429              : } // namespace hccl
        

Generated by: LCOV version 2.0-1