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

Generated by: LCOV version 2.0-1