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

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2026 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "coll_reduce_scatter_pipeline_for_910_93_executor.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15              : namespace {
      16              :     constexpr u32 PIPELINE_BUFFER_NUM = 2;
      17              :     constexpr u32 PIPELINE_PINGPONG_NOTIFY_PAIRS = PIPELINE_BUFFER_NUM;
      18              :     // HCCL 按 stream:notify = 1:1 分配;pipeline 仅使用最后一条额外 stream 承载 L2,
      19              :     // 其余额外 stream 仅用于获取 ping-pong notify 对。
      20              :     constexpr u32 PIPELINE_EXTRA_STREAM_NUM = PIPELINE_PINGPONG_NOTIFY_PAIRS;
      21              : } // namespace
      22              : 
      23            0 : CollReduceScatterPipelineFor91093Executor::CollReduceScatterPipelineFor91093Executor(
      24            0 :     const HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher>& topoMatcher)
      25            0 :     : CollReduceScatterRingFor91093Executor(dispatcher, topoMatcher)
      26            0 : {}
      27              : 
      28            0 : HcclResult CollReduceScatterPipelineFor91093Executor::CalcStreamNum(u32& streamNum)
      29              : {
      30            0 :     CHK_RET(CollReduceScatterRingFor91093Executor::CalcStreamNum(streamNum));
      31            0 :     streamNum += PIPELINE_EXTRA_STREAM_NUM;
      32            0 :     HCCL_INFO(
      33              :         "[CollReduceScatterPipelineFor91093Executor][CalcStreamNum] tag[%s] streamNum[%u]", tag_.c_str(), streamNum);
      34            0 :     return HCCL_SUCCESS;
      35              : }
      36              : 
      37            0 : u64 CollReduceScatterPipelineFor91093Executor::CalcLoopMaxCount(const u32 unitSize)
      38              : {
      39            0 :     const u64 maxSizePerLoopUnaligned = inCCLbufferSize_ / topoAttr_.userRankSize / PIPELINE_BUFFER_NUM;
      40            0 :     const u64 maxSizePerLoop = maxSizePerLoopUnaligned / HCCL_MIN_SLICE_ALIGN * HCCL_MIN_SLICE_ALIGN;
      41            0 :     const u64 maxCountPerLoop = maxSizePerLoop / unitSize;
      42            0 :     HCCL_INFO(
      43              :         "[CollReduceScatterPipelineFor91093Executor][CalcLoopMaxCount] "
      44              :         "maxCountPerLoop[%llu], maxSizePerLoop[%llu]",
      45              :         maxCountPerLoop, maxSizePerLoop);
      46            0 :     return maxCountPerLoop;
      47              : }
      48              : 
      49            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunLoop(OpParam& param, AlgResourceResponse& algRes)
      50              : {
      51            0 :     if (param.DataDes.count == 0) {
      52            0 :         return HCCL_SUCCESS;
      53              :     }
      54              : 
      55            0 :     const u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
      56              : 
      57            0 :     Stream streamL0L1 = param.stream;
      58            0 :     Stream streamL2 = algResResp_->slaveStreams.back();
      59            0 :     const u32 baseNotifyIndex = algResResp_->notifiesMain.size() - PIPELINE_PINGPONG_NOTIFY_PAIRS;
      60            0 :     auto notifyL0L1toL2A = algResResp_->notifiesAux[baseNotifyIndex];
      61            0 :     auto notifyL0L1toL2B = algResResp_->notifiesAux[baseNotifyIndex + 1];
      62            0 :     auto notifyL2toL0L1A = algResResp_->notifiesMain[baseNotifyIndex];
      63            0 :     auto notifyL2toL0L1B = algResResp_->notifiesMain[baseNotifyIndex + 1];
      64            0 :     HCCL_INFO(
      65              :         "[CollReduceScatterPipelineFor91093Executor][RunLoop] NotifyIds: "
      66              :         "L0L1toL2A: Aux[%u], L0L1toL2B: Aux[%u], L2toL0L1A: Main[%u], L2toL0L1B: Main[%u]",
      67              :         baseNotifyIndex, baseNotifyIndex + 1, baseNotifyIndex, baseNotifyIndex + 1);
      68            0 :     PipelineLoopContext ctx;
      69            0 :     CHK_RET(BuildPipelineLoopContext(param, algRes, unitSize, ctx));
      70            0 :     CHK_RET(GetLevelCommInfo());
      71              : 
      72            0 :     auto getForwardNotify = [&](u64 blockIdx) -> std::shared_ptr<LocalNotify> {
      73            0 :         return (blockIdx % PIPELINE_PINGPONG_NOTIFY_PAIRS == 0) ? notifyL0L1toL2A : notifyL0L1toL2B;
      74            0 :     };
      75            0 :     auto getBackwardNotify = [&](u64 blockIdx) -> std::shared_ptr<LocalNotify> {
      76            0 :         return (blockIdx % PIPELINE_PINGPONG_NOTIFY_PAIRS == 0) ? notifyL2toL0L1A : notifyL2toL0L1B;
      77            0 :     };
      78              : 
      79            0 :     const u64 numLoopTotal = ctx.numBlockTotal + 1;
      80            0 :     for (u64 i = 0; i < numLoopTotal; ++i) {
      81            0 :         if (i < ctx.numBlockTotal) {
      82            0 :             if (i >= PIPELINE_BUFFER_NUM) {
      83            0 :                 CHK_RET(LocalNotify::Wait(streamL0L1, dispatcher_, getBackwardNotify(i)));
      84              :             }
      85            0 :             CHK_RET(RunL0L1Phase(param, ctx, i, streamL0L1));
      86            0 :             CHK_RET(LocalNotify::Post(streamL0L1, dispatcher_, getForwardNotify(i)));
      87              :         }
      88            0 :         if (i >= 1 && i <= ctx.numBlockTotal) {
      89            0 :             const u64 blockIdx = i - 1;
      90            0 :             CHK_RET(LocalNotify::Wait(streamL2, dispatcher_, getForwardNotify(blockIdx)));
      91            0 :             CHK_RET(RunL2Phase(param, ctx, blockIdx, streamL2));
      92            0 :             CHK_RET(LocalNotify::Post(streamL2, dispatcher_, getBackwardNotify(blockIdx)));
      93              :         }
      94            0 :         CHK_RET(LaunchTaskExtend(dispatcher_, param.stream, algResResp_->slaveStreams));
      95              :     }
      96              : 
      97            0 :     CHK_RET(WaitForRemainingL2Signals(param, ctx.numBlockTotal, streamL0L1, notifyL2toL0L1A, notifyL2toL0L1B));
      98            0 :     CHK_RET(LaunchTaskExtend(dispatcher_, param.stream, algResResp_->slaveStreams));
      99            0 :     HCCL_INFO("[CollReduceScatterPipelineFor91093Executor][RunLoop] Pipeline run success");
     100            0 :     return HCCL_SUCCESS;
     101            0 : }
     102              : 
     103              : // 由 RunLoop 调用
     104            0 : HcclResult CollReduceScatterPipelineFor91093Executor::BuildPipelineLoopContext(
     105              :     OpParam& param, AlgResourceResponse& algRes, const u32 unitSize, PipelineLoopContext& ctx)
     106              : {
     107            0 :     u8* curInputPtr = static_cast<u8*>(param.inputPtr);
     108            0 :     u8* curOutputPtr = static_cast<u8*>(param.outputPtr);
     109            0 :     CHK_PTR_NULL(curInputPtr);
     110            0 :     CHK_PTR_NULL(curOutputPtr);
     111              : 
     112            0 :     const u64 maxCountDataPerLoop = CalcLoopMaxCount(unitSize);
     113            0 :     const u64 targetCountDataPerLoop = HCCL_SMALL_COUNT_8_MB / unitSize;
     114            0 :     const u64 countDataPerLoop
     115            0 :         = maxCountDataPerLoop < targetCountDataPerLoop ? maxCountDataPerLoop : targetCountDataPerLoop;
     116            0 :     CHK_PRT_RET(
     117              :         countDataPerLoop == 0,
     118              :         HCCL_ERROR("[CollReduceScatterPipelineFor91093Executor][BuildPipelineLoopContext]"
     119              :                    " countDataPerLoop is zero."),
     120              :         HCCL_E_INTERNAL);
     121              : 
     122            0 :     const u64 countDataLastLoopTemp = param.DataDes.count % countDataPerLoop;
     123            0 :     const u64 countDataLastLoop = countDataLastLoopTemp > 0 ? countDataLastLoopTemp : countDataPerLoop;
     124            0 :     const u64 cclInputBufferSize = algRes.cclInputMem.size() / PIPELINE_BUFFER_NUM;
     125            0 :     const u64 cclOutputBufferSize = algRes.cclOutputMem.size() / PIPELINE_BUFFER_NUM;
     126            0 :     ctx.countDataPerLoop = countDataPerLoop;
     127            0 :     ctx.countDataLastLoop = countDataLastLoop;
     128            0 :     ctx.sizeDataPerLoop = countDataPerLoop * unitSize;
     129            0 :     ctx.numBlockTotal = (param.DataDes.count - countDataLastLoop) / countDataPerLoop + 1;
     130            0 :     ctx.cclInputBufferSize = cclInputBufferSize;
     131            0 :     ctx.cclInputAMem = algRes.cclInputMem.range(0, cclInputBufferSize);
     132            0 :     ctx.cclInputBMem = algRes.cclInputMem.range(cclInputBufferSize, cclInputBufferSize);
     133            0 :     ctx.cclOutputAMem = algRes.cclOutputMem.range(0, cclOutputBufferSize);
     134            0 :     ctx.cclOutputBMem = algRes.cclOutputMem.range(cclOutputBufferSize, cclOutputBufferSize);
     135            0 :     ctx.curInputPtr = curInputPtr;
     136            0 :     ctx.curOutputPtr = curOutputPtr;
     137              : 
     138            0 :     HCCL_INFO(
     139              :         "[CollReduceScatterPipelineFor91093Executor][BuildPipelineLoopContext] "
     140              :         "tag[%s] numBlockTotal[%llu] numLoopTotal[%llu] maxCountDataPerLoop[%llu] "
     141              :         "targetCountDataPerLoop[%llu] countDataPerLoop[%llu] countDataLastLoop[%llu]",
     142              :         param.tag.c_str(), ctx.numBlockTotal, ctx.numBlockTotal + 1, maxCountDataPerLoop, targetCountDataPerLoop,
     143              :         ctx.countDataPerLoop, ctx.countDataLastLoop);
     144            0 :     return HCCL_SUCCESS;
     145              : }
     146              : 
     147              : // 由 RunLoop 调用
     148            0 : HcclResult CollReduceScatterPipelineFor91093Executor::WaitForRemainingL2Signals(
     149              :     const OpParam& param, u64 numBlockTotal, Stream& streamL0L1, const std::shared_ptr<LocalNotify>& notifyL2toL0L1A,
     150              :     const std::shared_ptr<LocalNotify>& notifyL2toL0L1B)
     151              : {
     152            0 :     const u64 remainingSignals
     153              :         = (numBlockTotal >= PIPELINE_PINGPONG_NOTIFY_PAIRS) ? PIPELINE_PINGPONG_NOTIFY_PAIRS : numBlockTotal;
     154            0 :     const u64 firstBlockIdx = numBlockTotal - remainingSignals;
     155            0 :     for (u64 blockIdx = firstBlockIdx; blockIdx < numBlockTotal; ++blockIdx) {
     156            0 :         auto notify = (blockIdx % PIPELINE_PINGPONG_NOTIFY_PAIRS == 0) ? notifyL2toL0L1A : notifyL2toL0L1B;
     157            0 :         HcclResult ret = LocalNotify::Wait(streamL0L1, dispatcher_, notify);
     158            0 :         CHK_PRT_RET(
     159              :             ret != HCCL_SUCCESS,
     160              :             HCCL_ERROR(
     161              :                 "[CollReduceScatterPipelineFor91093Executor][WaitForRemainingL2Signals] "
     162              :                 "PostSync wait error, tag[%s] blockIdx[%llu]",
     163              :                 param.tag.c_str(), blockIdx),
     164              :             ret);
     165            0 :     }
     166            0 :     return HCCL_SUCCESS;
     167              : }
     168              : 
     169              : // 由 RunLoop 循环体调用
     170            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunL0L1Phase(
     171              :     OpParam& param, const PipelineLoopContext& ctx, u64 blockIdx, Stream& streamL0L1)
     172              : {
     173            0 :     HCCL_CONFIG_INFO(
     174              :         HCCL_ALG, "[CollReduceScatterPipelineFor91093Executor][RunL0L1Phase] blockIdx[%llu] useBufferA[%d]", blockIdx,
     175              :         (blockIdx % PIPELINE_BUFFER_NUM == 0));
     176              : 
     177            0 :     const bool useBufferA = (blockIdx % PIPELINE_BUFFER_NUM == 0);
     178            0 :     const bool isLastBlock = (blockIdx == ctx.numBlockTotal - 1);
     179            0 :     ExecMem execMem;
     180            0 :     execMem.count = isLastBlock ? ctx.countDataLastLoop : ctx.countDataPerLoop;
     181            0 :     execMem.inputMem = useBufferA ? ctx.cclInputAMem : ctx.cclInputBMem;
     182            0 :     execMem.outputMem = useBufferA ? ctx.cclOutputAMem : ctx.cclOutputBMem;
     183            0 :     execMem.scratchMem = execMem.outputMem;
     184            0 :     execMem.inputPtr = ctx.curInputPtr + blockIdx * ctx.sizeDataPerLoop;
     185            0 :     execMem.outputPtr = ctx.curOutputPtr + blockIdx * ctx.sizeDataPerLoop;
     186              : 
     187            0 :     const u64 bufferBaseOffset = useBufferA ? 0 : ctx.cclInputBufferSize;
     188            0 :     SliceExecMem(param, execMem);
     189              : 
     190            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[CollReduceScatterPipelineFor91093Executor][RunL0L1Phase] chunk starts");
     191              : 
     192            0 :     HcclResult ret = KernelRunLevel0To1(param, execMem, streamL0L1, bufferBaseOffset);
     193            0 :     CHK_PRT_RET(
     194              :         ret != HCCL_SUCCESS,
     195              :         HCCL_ERROR(
     196              :             "[CollReduceScatterPipelineFor91093Executor][RunL0L1Phase] kernel run error, tag[%s]", param.tag.c_str()),
     197              :         ret);
     198            0 :     return HCCL_SUCCESS;
     199            0 : }
     200              : 
     201              : // 由 RunLoop 循环体调用
     202            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunL2Phase(
     203              :     OpParam& param, const PipelineLoopContext& ctx, u64 blockIdx, Stream& streamL2)
     204              : {
     205            0 :     HCCL_CONFIG_INFO(
     206              :         HCCL_ALG, "[CollReduceScatterPipelineFor91093Executor][RunL2Phase] blockIdx[%llu] L2 phase", blockIdx);
     207              : 
     208            0 :     const bool useBufferA = (blockIdx % PIPELINE_BUFFER_NUM == 0);
     209            0 :     const bool isLastBlock = (blockIdx == ctx.numBlockTotal - 1);
     210            0 :     ExecMem execMem;
     211            0 :     execMem.count = isLastBlock ? ctx.countDataLastLoop : ctx.countDataPerLoop;
     212            0 :     execMem.inputMem = useBufferA ? ctx.cclInputAMem : ctx.cclInputBMem;
     213            0 :     execMem.outputMem = useBufferA ? ctx.cclOutputAMem : ctx.cclOutputBMem;
     214            0 :     execMem.scratchMem = execMem.outputMem;
     215            0 :     execMem.inputPtr = ctx.curInputPtr + blockIdx * ctx.sizeDataPerLoop;
     216            0 :     execMem.outputPtr = ctx.curOutputPtr + blockIdx * ctx.sizeDataPerLoop;
     217              : 
     218            0 :     const u64 l2BaseOffset = useBufferA ? 0 : ctx.cclInputBufferSize;
     219            0 :     SliceExecMem(param, execMem);
     220              : 
     221            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[CollReduceScatterPipelineFor91093Executor][RunL2Phase] chunk starts");
     222              : 
     223            0 :     HcclResult ret = KernelRunLevel2(param, execMem, streamL2, l2BaseOffset);
     224            0 :     CHK_PRT_RET(
     225              :         ret != HCCL_SUCCESS,
     226              :         HCCL_ERROR(
     227              :             "[CollReduceScatterPipelineFor91093Executor][RunL2Phase] kernel run error, tag[%s]", param.tag.c_str()),
     228              :         ret);
     229            0 :     return HCCL_SUCCESS;
     230            0 : }
     231              : 
     232              : // 由 RunL0L1Phase、RunL2Phase 调用
     233            0 : void CollReduceScatterPipelineFor91093Executor::SliceExecMem(const OpParam& param, ExecMem& execMem)
     234              : {
     235            0 :     u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
     236            0 :     u64 curSize = execMem.count * unitSize;
     237            0 :     u32 sliceNum = topoAttr_.userRankSize;
     238            0 :     execMem.inputMem = execMem.inputMem.range(0, curSize * sliceNum);
     239            0 :     execMem.outputMem = execMem.outputMem.range(0, curSize);
     240            0 : }
     241              : 
     242              : // 由 KernelRunLevel0To1、KernelRunLevel2 调用
     243              : // Pipeline 约束 !isAHCAlgo,AHC 分支不可达,直接走 COMM_LEVEL2。
     244            0 : HcclResult CollReduceScatterPipelineFor91093Executor::GetLevel2CommInfo(SubCommInfo& level2CommInfo)
     245              : {
     246            0 :     CHK_RET(CheckCommSize(COMM_LEVEL2, COMM_INDEX_0 + 1));
     247            0 :     level2CommInfo = GetSubCommInfo(COMM_LEVEL2, COMM_INDEX_0);
     248            0 :     return HCCL_SUCCESS;
     249              : }
     250              : 
     251            0 : u32 CollReduceScatterPipelineFor91093Executor::GetLevel0RingNum() const
     252              : {
     253              :     // slaveStreams 不包含主流,先 +1 补回主流,再减去 2 条 Pipeline 专用流,得到基类 ring 数。
     254            0 :     return algResResp_->slaveStreams.size() + 1 - PIPELINE_EXTRA_STREAM_NUM;
     255              : }
     256              : 
     257            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunIntraSeverReduceScatter(
     258              :     const std::string& tag, DeviceMem& inputMem, DeviceMem& outputMem, const u64 count, const HcclDataType& dataType,
     259              :     const HcclReduceOp& reductionOp, const std::vector<std::vector<Slice>>& multRingsSliceZero, const Stream& stream,
     260              :     s32 profStage, const u64 baseOffset, const HcomCollOpInfo* opInfo,
     261              :     const std::vector<std::vector<Slice>>& multRingsUserMemSlice, const bool disableDMAReduce)
     262              : {
     263              :     // SemiRing(IsUnifiedMarch)分支不可达:Pipeline 约束 workflowMode_==OP_BASE 排除图模式,
     264              :     // superPodNum>1 排除单 server,IsUnifiedMarch 恒为 false。
     265            0 :     HcclResult ret = HCCL_SUCCESS;
     266            0 :     if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
     267            0 :         ret = DoubleRingReduceScatter(
     268              :             tag, inputMem, outputMem, count, dataType, reductionOp, multRingsSliceZero, stream, profStage, baseOffset,
     269              :             opInfo, multRingsUserMemSlice, disableDMAReduce);
     270              :     } else {
     271            0 :         ret = CollReduceScatterRingFor91093Executor::RunIntraSeverReduceScatter(
     272              :             tag, inputMem, outputMem, count, dataType, reductionOp, multRingsSliceZero, stream, profStage, baseOffset,
     273              :             opInfo, multRingsUserMemSlice, disableDMAReduce);
     274              :     }
     275              : 
     276            0 :     CHK_RET(ret);
     277            0 :     return HCCL_SUCCESS;
     278              : }
     279              : 
     280              : // 逻辑与 CollAlignedReduceScatterDoubleRingFor91093Executor::DoubleRingReduceScatter 一致
     281            0 : HcclResult CollReduceScatterPipelineFor91093Executor::DoubleRingReduceScatter(
     282              :     const std::string& tag, DeviceMem inputMem, DeviceMem outputMem, const u64 count, const HcclDataType dataType,
     283              :     const HcclReduceOp reductionOp, const std::vector<std::vector<Slice>> multRingsSliceZero, Stream stream,
     284              :     s32 profStage, const u64 baseOffset, const HcomCollOpInfo* opInfo,
     285              :     const std::vector<std::vector<Slice>> multRingsUserMemSlice, const bool disableDMAReduce)
     286              : {
     287              :     (void)tag;
     288            0 :     HCCL_CONFIG_INFO(
     289              :         HCCL_ALG,
     290              :         "[CollReduceScatterPipelineFor91093Executor][DoubleRingReduceScatter] DoubleRingReduceScatter starts");
     291            0 :     u32 ringNum = multRingsSliceZero.size();
     292            0 :     CHK_RET(CheckCommSize(COMM_LEVEL0, ringNum));
     293              : 
     294            0 :     u64 reduceAttr = GetReduceAttr(inputMem, outputMem, dataType, reductionOp);
     295            0 :     SubCommInfo level0RingCommInfo = GetSubCommInfo(COMM_LEVEL0, COMM_INDEX_0);
     296              : 
     297            0 :     std::vector<std::vector<Slice>> userMemInputSlicesOfDoubleRing;
     298            0 :     std::vector<std::vector<u32>> rankOrders;
     299            0 :     CHK_RET(PrepareDoubleRingSlices(
     300              :         ringNum, dataType, opInfo, multRingsSliceZero, multRingsUserMemSlice, userMemInputSlicesOfDoubleRing,
     301              :         rankOrders));
     302              : 
     303              :     std::unique_ptr<AlgTemplateBase> tempAlg
     304            0 :         = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_DB_RING, dispatcher_);
     305            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_DB_RING in COMM_LEVEL0", __func__);
     306            0 :     CHK_SMART_PTR_NULL(tempAlg);
     307              :     // 排除尾部 Pipeline 专用资源流(NotifyReserve + StreamL2),使模板看到与基类一致的流数
     308              :     std::vector<Stream> baseSlaveStreams(
     309            0 :         algResResp_->slaveStreams.begin(), algResResp_->slaveStreams.end() - PIPELINE_EXTRA_STREAM_NUM);
     310              :     std::vector<std::shared_ptr<LocalNotify>> baseNotifiesMain(
     311            0 :         algResResp_->notifiesMain.begin(), algResResp_->notifiesMain.end() - PIPELINE_PINGPONG_NOTIFY_PAIRS);
     312              :     std::vector<std::shared_ptr<LocalNotify>> baseNotifiesAux(
     313            0 :         algResResp_->notifiesAux.begin(), algResResp_->notifiesAux.end() - PIPELINE_PINGPONG_NOTIFY_PAIRS);
     314            0 :     HcclResult ret = tempAlg->Prepare(
     315              :         inputMem, inputMem, outputMem, count, dataType, stream, multRingsSliceZero, reductionOp, LEVEL0_BRIDGE_RANK_ID,
     316            0 :         baseOffset, disableDMAReduce, reduceAttr, opInfo, topoAttr_.userRank, baseSlaveStreams, baseNotifiesMain,
     317              :         baseNotifiesAux, rankOrders, userMemInputSlicesOfDoubleRing);
     318            0 :     CHK_PRT_RET(
     319              :         ret != HCCL_SUCCESS,
     320              :         HCCL_ERROR(
     321              :             "[CollReduceScatterPipelineFor91093Executor][DoubleRingReduceScatter] "
     322              :             "Double ring ReduceScatter failed,return[%d]",
     323              :             ret),
     324              :         ret);
     325              : 
     326            0 :     u32 ringIndexOp = COMM_INDEX_0;
     327            0 :     u32 rankSize = level0RingCommInfo.localRankSize;
     328            0 :     ret = tempAlg->RegisterProfiler(
     329            0 :         ((ringIndexOp + 1) << PROF_RINGINDEX_OFFSET_OF_PLANEID) + (rankSize << PROF_RANKSIZE_OFFSET_OF_PLANEID)
     330            0 :             + level0RingCommInfo.localRank,
     331              :         profStage, HCCL_EXEC_STEP_NOT_SET, stream);
     332            0 :     CHK_PRT_RET(
     333              :         ret != HCCL_SUCCESS,
     334              :         HCCL_ERROR(
     335              :             "[CollReduceScatterPipelineFor91093Executor][DoubleRingReduceScatter] "
     336              :             "Double ring ReduceScatter RegisterProfiler failed,return[%d]",
     337              :             ret),
     338              :         ret);
     339              : 
     340            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem, outputMem, stream, dispatcher_));
     341            0 :     ret = RunTemplate(tempAlg, level0RingCommInfo);
     342            0 :     CHK_PRT_RET(
     343              :         ret != HCCL_SUCCESS,
     344              :         HCCL_ERROR(
     345              :             "[CollReduceScatterPipelineFor91093Executor][DoubleRingReduceScatter] "
     346              :             "Double ring ReduceScatter RunTemplate failed,return[%d]",
     347              :             ret),
     348              :         ret);
     349              : 
     350            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem, outputMem, stream, dispatcher_));
     351            0 :     return HCCL_SUCCESS;
     352            0 : }
     353              : 
     354              : // 由 DoubleRingReduceScatter 调用
     355            0 : HcclResult CollReduceScatterPipelineFor91093Executor::PrepareDoubleRingSlices(
     356              :     u32 ringNum, const HcclDataType dataType, const HcomCollOpInfo* opInfo,
     357              :     const std::vector<std::vector<Slice>>& multRingsSliceZero,
     358              :     const std::vector<std::vector<Slice>>& multRingsUserMemSlice,
     359              :     std::vector<std::vector<Slice>>& userMemInputSlicesOfDoubleRing, std::vector<std::vector<u32>>& rankOrders)
     360              : {
     361            0 :     SubCommInfo level0ZeroCommInfo = GetSubCommInfo(COMM_LEVEL0, COMM_INDEX_0);
     362            0 :     auto nicList = topoAttr_.nicList;
     363              :     std::vector<std::vector<u32>> multiRingsOrder
     364            0 :         = GetRingsOrderByTopoType(level0ZeroCommInfo.localRankSize, topoType_, nicList);
     365            0 :     CHK_RET(CollectMultiRingsUserMemSlices(
     366              :         ringNum, dataType, opInfo, multRingsSliceZero, multiRingsOrder, multRingsUserMemSlice,
     367              :         userMemInputSlicesOfDoubleRing));
     368            0 :     CHK_RET(CollectMultiRingsRankOrder(ringNum, multiRingsOrder, rankOrders));
     369            0 :     return HCCL_SUCCESS;
     370            0 : }
     371              : 
     372              : // 拆分自 CollReduceScatterRingFor91093Executor::KernelRun 的 L0+L1 部分
     373            0 : HcclResult CollReduceScatterPipelineFor91093Executor::KernelRunLevel0To1(
     374              :     const OpParam& param, ExecMem& execMem, Stream& streamL0L1, const u64 baseOffset)
     375              : {
     376            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[%s] executor starts", __func__);
     377            0 :     u32 perDataSize = 0;
     378            0 :     const HcclDataType dataType = param.GetDataType();
     379            0 :     CHK_RET(SalGetDataTypeSize(dataType, perDataSize));
     380              : 
     381              :     u32 ringNum;
     382            0 :     u32 sliceNum = logicalLevel0CommInfo_.localRankSize;
     383            0 :     u32 commIndex = logicalLevel0CommInfo_.localRank;
     384              : 
     385            0 :     if (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
     386            0 :         ringNum = LEVEL0_PLANE_NUM_IN_NPRING_DOUBLE;
     387              :     } else {
     388            0 :         ringNum = LEVEL0_PLANE_NUM_IN_NPRING_SINGLE;
     389              :     }
     390              : 
     391            0 :     SubCommInfo level2CommInfo;
     392            0 :     CHK_RET(GetLevel2CommInfo(level2CommInfo));
     393            0 :     const u32 level2RankSize = level2CommInfo.localRankSize;
     394            0 :     const u32 level1RankSize = logicalLevel1CommInfo_.localRankSize;
     395              : 
     396            0 :     std::vector<std::vector<Slice>> multiStreamSlice;
     397            0 :     std::vector<std::vector<Slice>> level0DataSegsSlice;
     398            0 :     CHK_RET(CalLevel0DataSegsSlice(
     399              :         execMem, multiStreamSlice, param, ringNum, sliceNum, level1RankSize, level2RankSize, dataType,
     400              :         level0DataSegsSlice));
     401              : 
     402            0 :     HcomCollOpInfo opInfo = GetHcomCollOpInfo(param, execMem);
     403            0 :     HcomCollOpInfo* opInfoPtr = &opInfo;
     404              : 
     405            0 :     bool disableDMAReduce = algOpContext_.opRetryHandler.retryEnable
     406            0 :                             && (algOpContext_.opRetryHandler.inPlaceSupportRetryStatus
     407              :                                     == InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE1
     408            0 :                                 || algOpContext_.opRetryHandler.inPlaceSupportRetryStatus
     409              :                                        == InplaceSupportRetryStatus::RETRY_1_ALLOW_NO_DMA_REDUCE_CASE2);
     410            0 :     std::vector<std::vector<Slice>> multRingsUserMemSlice;
     411            0 :     CHK_RET(CalUserMemDataSegsSlice(
     412              :         execMem, level0DataSegsSlice, multiStreamSlice, param, ringNum, sliceNum, level1RankSize, level2RankSize,
     413              :         dataType, perDataSize, opInfoPtr, disableDMAReduce, multRingsUserMemSlice));
     414              : 
     415            0 :     HcomCollOpInfo opInfoByReduceScatterDMAreduce = *opInfoPtr;
     416            0 :     opInfoByReduceScatterDMAreduce.outputAddr = nullptr;
     417            0 :     CHK_RET(RunIntraSeverReduceScatter(
     418              :         param.tag, execMem.inputMem, execMem.scratchMem, execMem.count, dataType, param.reduceType, level0DataSegsSlice,
     419              :         streamL0L1, PROF_STAGE_1, baseOffset, &opInfoByReduceScatterDMAreduce, multRingsUserMemSlice,
     420              :         disableDMAReduce));
     421              : 
     422            0 :     if (level1RankSize > 1) {
     423            0 :         CHK_RET(RunLevel1Template(
     424              :             param, execMem, streamL0L1, baseOffset, commIndex, sliceNum, level1RankSize, level2RankSize, perDataSize));
     425              :     }
     426              : 
     427            0 :     return HCCL_SUCCESS;
     428            0 : }
     429              : 
     430              : // 由 KernelRunLevel0To1 调用
     431            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunLevel1Template(
     432              :     const OpParam& param, ExecMem& execMem, Stream& streamL0L1, u64 baseOffset, u32 commIndex, u32 sliceNum,
     433              :     u32 level1RankSize, u32 level2RankSize, u32 perDataSize)
     434              : {
     435            0 :     const HcclDataType dataType = param.GetDataType();
     436            0 :     u64 reduceAttr = GetReduceAttr(execMem.inputMem, execMem.scratchMem, dataType, param.reduceType);
     437            0 :     std::unique_ptr<AlgTemplateBase> level1TempAlg;
     438              : 
     439            0 :     std::vector<Slice> level1DataSegsSlice;
     440            0 :     CHK_RET(CalLevel1DataSegsSlice(
     441              :         execMem, param, logicalLevel1plane_, commIndex, sliceNum, level1RankSize, level2RankSize, perDataSize,
     442              :         level1DataSegsSlice));
     443              : 
     444            0 :     if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING) {
     445              :         level1TempAlg
     446            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_RING, dispatcher_);
     447            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_RING in COMM_LEVEL1", __func__);
     448            0 :         CHK_SMART_PTR_NULL(level1TempAlg);
     449            0 :         CHK_RET(level1TempAlg->Prepare(reduceAttr));
     450            0 :     } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB) {
     451              :         level1TempAlg
     452            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NB, dispatcher_);
     453            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NB in COMM_LEVEL1", __func__);
     454            0 :         CHK_SMART_PTR_NULL(level1TempAlg);
     455            0 :         CHK_RET(level1TempAlg->Prepare(reduceAttr));
     456              :     } else {
     457              :         level1TempAlg
     458            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NHR, dispatcher_);
     459            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NHR in COMM_LEVEL1", __func__);
     460            0 :         CHK_SMART_PTR_NULL(level1TempAlg);
     461            0 :         CHK_RET(level1TempAlg->Prepare(reduceAttr, false));
     462              :     }
     463              : 
     464            0 :     CHK_RET(level1TempAlg->Prepare(
     465              :         execMem.inputMem, execMem.inputMem, execMem.scratchMem, execMem.count, dataType, streamL0L1, param.reduceType,
     466              :         LEVEL0_BRIDGE_RANK_ID, level1DataSegsSlice, baseOffset));
     467            0 :     CHK_RET(level1TempAlg->RegisterProfiler(
     468              :         (level1RankSize << PROF_RANKSIZE_OFFSET_OF_PLANEID) + logicalLevel1CommInfo_.localRank, PROF_STAGE_2,
     469              :         HCCL_EXEC_STEP_NOT_SET, streamL0L1));
     470            0 :     CHK_RET(RunTemplate(level1TempAlg, logicalLevel1CommInfo_));
     471            0 :     return HCCL_SUCCESS;
     472            0 : }
     473              : 
     474              : // 拆分自 CollReduceScatterRingFor91093Executor::KernelRun 的 L2+copyOut 部分,stream 替换为 streamL2
     475            0 : HcclResult CollReduceScatterPipelineFor91093Executor::KernelRunLevel2(
     476              :     const OpParam& param, ExecMem& execMem, Stream& streamL2, const u64 baseOffset)
     477              : {
     478            0 :     HCCL_CONFIG_INFO(HCCL_ALG, "[%s] executor starts", __func__);
     479            0 :     u32 perDataSize = 0;
     480            0 :     const HcclDataType dataType = param.GetDataType();
     481            0 :     CHK_RET(SalGetDataTypeSize(dataType, perDataSize));
     482              : 
     483            0 :     SubCommInfo level2CommInfo;
     484            0 :     CHK_RET(GetLevel2CommInfo(level2CommInfo));
     485            0 :     const u32 level2RankSize = level2CommInfo.localRankSize;
     486              : 
     487            0 :     CHK_RET(RunLevel2Template(param, execMem, streamL2, baseOffset, level2CommInfo, level2RankSize, perDataSize));
     488              : 
     489            0 :     HcomCollOpInfo opInfo = GetHcomCollOpInfo(param, execMem);
     490            0 :     HcomCollOpInfo* opInfoPtr = &opInfo;
     491              : 
     492            0 :     const u64 offset = CalcSrcMemOffset(execMem, param, perDataSize);
     493            0 :     DeviceMem srcMem = execMem.inputMem.range(offset, execMem.outputMem.size());
     494            0 :     if (opInfoPtr != nullptr) {
     495            0 :         DeviceMem dstMem = DeviceMem::create(static_cast<u8*>(opInfoPtr->outputAddr), execMem.outputMem.size());
     496            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstMem, srcMem, streamL2));
     497            0 :     } else {
     498            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, execMem.outputMem, srcMem, streamL2));
     499              :     }
     500              : 
     501            0 :     return HCCL_SUCCESS;
     502            0 : }
     503              : 
     504              : // 由 KernelRunLevel2 调用
     505            0 : HcclResult CollReduceScatterPipelineFor91093Executor::RunLevel2Template(
     506              :     const OpParam& param, ExecMem& execMem, Stream& streamL2, u64 baseOffset, const SubCommInfo& level2CommInfo,
     507              :     u32 level2RankSize, u32 perDataSize)
     508              : {
     509            0 :     const HcclDataType dataType = param.GetDataType();
     510            0 :     u64 reduceAttr = GetReduceAttr(execMem.inputMem, execMem.scratchMem, dataType, param.reduceType);
     511              : 
     512            0 :     std::vector<Slice> level2DataSegsSlice;
     513            0 :     CHK_RET(CalLevel2DataSegsSlice(execMem, param, level2RankSize, perDataSize, level2DataSegsSlice));
     514              : 
     515            0 :     std::unique_ptr<AlgTemplateBase> level2TempAlg;
     516            0 :     if (algType_.algoLevel2 == AlgTypeLevel2::ALG_LEVEL2_NB) {
     517              :         level2TempAlg
     518            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NB, dispatcher_);
     519            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NB in COMM_LEVEL2", __func__);
     520            0 :         CHK_SMART_PTR_NULL(level2TempAlg);
     521            0 :         CHK_RET(level2TempAlg->Prepare(reduceAttr));
     522            0 :     } else if (algType_.algoLevel2 == AlgTypeLevel2::ALG_LEVEL2_NHR) {
     523              :         level2TempAlg
     524            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_NHR, dispatcher_);
     525            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_NHR in COMM_LEVEL2", __func__);
     526            0 :         CHK_SMART_PTR_NULL(level2TempAlg);
     527            0 :         CHK_RET(level2TempAlg->Prepare(reduceAttr, false));
     528            0 :         if (algoAttr_.isSupportAtomicWrite) {
     529            0 :             level2TempAlg->CloseBarrier();
     530              :         }
     531              :     } else {
     532              :         level2TempAlg
     533            0 :             = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_RING, dispatcher_);
     534            0 :         HCCL_CONFIG_INFO(HCCL_ALG, "[%s] Run TEMPLATE_REDUCESCATTER_RING in COMM_LEVEL2", __func__);
     535            0 :         CHK_SMART_PTR_NULL(level2TempAlg);
     536            0 :         CHK_RET(level2TempAlg->Prepare(reduceAttr));
     537              :     }
     538              : 
     539            0 :     CHK_RET(level2TempAlg->Prepare(
     540              :         execMem.inputMem, execMem.inputMem, execMem.scratchMem, execMem.count, dataType, streamL2, param.reduceType,
     541              :         LEVEL0_BRIDGE_RANK_ID, level2DataSegsSlice, baseOffset));
     542            0 :     CHK_RET(level2TempAlg->RegisterProfiler(
     543              :         (level2RankSize << PROF_RANKSIZE_OFFSET_OF_PLANEID) + level2CommInfo.localRank, PROF_STAGE_2,
     544              :         HCCL_EXEC_STEP_NOT_SET, streamL2));
     545            0 :     CHK_RET(RunTemplate(level2TempAlg, level2CommInfo));
     546            0 :     return HCCL_SUCCESS;
     547            0 : }
     548              : 
     549              : REGISTER_EXEC(
     550              :     "ReduceScatterPipelineFor91093Executor", ReduceScatterPipelineFor91093, CollReduceScatterPipelineFor91093Executor);
     551              : } // namespace hccl
        

Generated by: LCOV version 2.0-1