LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_executor/ins_alg_executor/scatter - ins_scatter_sole_executor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 216 0
Test Date: 2026-07-28 12:11:00 Functions: 0.0 % 10 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 "log.h"
      12              : #include "ins_coll_alg_registry.h"
      13              : #ifndef CCL_KERNEL_AICPU
      14              : #include "ccu_temp_scatter_mesh_2D.h"
      15              : #endif
      16              : #include "topo_match_concurr_mesh.h"
      17              : #include "ins_scatter_sole_executor.h"
      18              : 
      19              : namespace Hccl {
      20              : template <typename AlgTopoMatch, typename InsAlgTemplate>
      21            0 : InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::InsScatterSoleExecutor() : InsCollAlgBase()
      22              : {
      23            0 : }
      24              : 
      25              : template <typename AlgTopoMatch, typename InsAlgTemplate>
      26            0 : InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::~InsScatterSoleExecutor()
      27              : {
      28            0 : }
      29              : 
      30              : template <typename AlgTopoMatch, typename InsAlgTemplate>
      31            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcResOffload(const RankGraph *rankGraph,
      32              :                                                                                   const u64 &dataSize,
      33              :                                                                                   CollOffloadOpResReq &resReq)
      34              : {
      35              :     // Topo Match
      36            0 :     AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
      37            0 :     CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
      38              : 
      39              :     // instantiate a template
      40            0 :     InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
      41              :     // 通过判断哪层通信域能有到所有remoteRank的path,判断当前算法跑在哪一层    
      42            0 :     std::map<u32, u32>rank2PathNumMap;
      43            0 :     HCCL_INFO("[InsV2ScatterSoleExecutor] CalcRes SetPathNumMap");
      44            0 :     CHK_RET(SetPathNumMapByRankGraphMultiLevel(rankGraph, virtRanks_, myRank_, rank2PathNumMap));
      45            0 :     tempAlg.setPathNumMap(rank2PathNumMap);  
      46            0 :     tempAlg.SetDmaMode(dmaMode_);
      47            0 :     tempAlg.SetRoot(root_);
      48              : 
      49            0 :     if ( tempAlg.GetExpandedMode() == DeviceMode::CCU ) {
      50            0 :         resReq.requiredScratchMemSize = dataSize * rankSize_;
      51            0 :         HCCL_DEBUG("[InsScatterSoleExecutor][CalcResOffload][CCU] reqiredScratchSize:[%llu], dataSize:[%llu], rankSize:[%llu]", resReq.requiredScratchMemSize, dataSize, rankSize_);
      52              :     }
      53              :     else {
      54              :         (void)dataSize;
      55            0 :         resReq.requiredScratchMemSize = 0;
      56              :     }
      57              : 
      58              :     // calculate required insQueues and prepare queue
      59            0 :     AlgTempResReq tempResReq;
      60            0 :     if (enableDetour_) {
      61            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor], CalcRes with detouring enabled.");
      62            0 :         CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
      63              :     } else {
      64            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor], CalcRes with detouring disabled.");
      65            0 :         CHK_RET(tempAlg.CalcRes(tempResReq));
      66              :     }
      67              : 
      68            0 :     resReq.requiredSubQueNum = tempResReq.streamNum - 1;
      69              : 
      70            0 :     return HcclResult::HCCL_SUCCESS;
      71            0 : }
      72              : 
      73              : template <typename AlgTopoMatch, typename InsAlgTemplate>
      74            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::CalcRes(const RankGraph *rankGraph,
      75              :                                                                            CollAlgResReq     &algResReq)
      76              : {
      77              :     // Topo Match
      78            0 :     AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
      79            0 :     CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
      80            0 :     algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
      81              : 
      82              :     // instantiate a template
      83            0 :     InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
      84              :     // 通过判断哪层通信域能有到所有remoteRank的path,判断当前算法跑在哪一层    
      85            0 :     std::map<u32, u32>rank2PathNumMap;
      86            0 :     HCCL_INFO("[InsV2ScatterSoleExecutor] CalcRes SetPathNumMap");
      87            0 :     CHK_RET(SetPathNumMapByRankGraphMultiLevel(rankGraph, virtRanks_, myRank_, rank2PathNumMap));
      88            0 :     tempAlg.setPathNumMap(rank2PathNumMap);
      89            0 :     tempAlg.SetDmaMode(dmaMode_);
      90            0 :     tempAlg.SetRoot(root_);
      91              : 
      92              :     // calculate required insQues and prepare queue
      93            0 :     AlgTempResReq tempResReq;
      94            0 :     if (enableDetour_) {
      95            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
      96            0 :         CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
      97              :     } else {
      98            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
      99            0 :         CHK_RET(tempAlg.CalcRes(tempResReq));
     100              :     }
     101            0 :     CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
     102            0 :     algResReq.primQueueNum = tempResReq.streamNum;
     103            0 :     algResReq.queueNotifys = tempResReq.queNotifys;
     104            0 :     algResReq.localWaitGroupCntNotify = tempResReq.localWaitGroupCntNotify;
     105            0 :     algResReq.localBcastPostCntNotify = tempResReq.localBcastPostCntNotify;
     106            0 :     HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], requiredQueNum [%u].", myRank_, algResReq.primQueueNum);
     107            0 :     CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
     108              : 
     109            0 :     return HcclResult::HCCL_SUCCESS;
     110            0 : }
     111              : 
     112              : // dataSize_ as input
     113              : template <typename AlgTopoMatch, typename InsAlgTemplate>
     114            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(const RankGraph     *rankGraph,
     115              :                                                                               const CollAlgOperator &op,
     116              :                                                                               const CollAlgParams   &params,
     117              :                                                                               InsQuePtr              insQue)
     118              : {
     119            0 :     HCCL_INFO("[InsScatterSoleExecutor]ScatterSoleExecutor Orchestrate begin");
     120              :     // init and check params
     121            0 :     CHK_RET(Init(op, params, insQue));
     122              :     
     123              :     // Topo Match
     124            0 :     AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
     125            0 :     CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
     126            0 :     HCCL_INFO("[InsScatterSoleExecutor] Rank[%d], [%s].", myRank_, topoMatch.Describe().c_str());
     127            0 :     dataType_ = op.dataType;
     128              :     // instantiate a template
     129            0 :     InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
     130            0 :     tempAlg.SetDmaMode(dmaMode_);
     131            0 :     tempAlg.SetCollOp(op); // ccu需要传递op信息
     132            0 :     tempAlg.SetRoot(root_);
     133            0 :     tempAlg.SetDataType(dataType_);
     134              :     // 通过判断哪层通信域能有到所有remoteRank的path,判断当前算法跑在哪一层    
     135            0 :     std::map<u32, u32>rank2PathNumMap;
     136            0 :     HCCL_INFO("[InsV2ScatterSoleExecutor] CalcRes SetPathNumMap");
     137            0 :     CHK_RET(SetPathNumMapByRankGraphMultiLevel(rankGraph, virtRanks_, myRank_, rank2PathNumMap));
     138            0 :     tempAlg.setPathNumMap(rank2PathNumMap);
     139              :     // calculate required insQues and prepare queue
     140            0 :     AlgTempResReq tempResReq;
     141            0 :     if (enableDetour_) {
     142            0 :         tempAlg.SetDataType(dataType_);
     143            0 :         CHK_RET(tempAlg.CalcResDetour(rankGraph, tempResReq));
     144              :     } else {
     145            0 :         CHK_RET(tempAlg.CalcRes(tempResReq));
     146              :     }
     147              : 
     148            0 :     CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
     149            0 :     HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], template [%s], requiredQue Num [%u].", myRank_,
     150              :                tempAlg.Describe().c_str(), tempResReq.queNum);
     151              : 
     152            0 :     CHK_RET(PrepResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, tempResLinks_));
     153              : 
     154              :     // 令Scatter算子的dataSize_为outputSize
     155            0 :     u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
     156            0 :     dataSize_             = dataCount_ * dataSizePerVolume;
     157            0 :     HCCL_DEBUG("[InsScatterSoleExecutor][Orchestrate] dataSize[%llu]", dataSize_);
     158              : 
     159            0 :     if ( tempAlg.GetExpandedMode() == DeviceMode::CCU) {
     160            0 :         HCCL_DEBUG("[InsScatterSoleExecutor] Rank[%d], Generating Instruction Queues for CCU.", myRank_);
     161            0 :         CHK_RET(GenInsQues4Ccu(tempAlg));
     162            0 :         return HcclResult::HCCL_SUCCESS;
     163              :     }
     164            0 :     if (opMode_ == OpMode::OFFLOAD) {
     165            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], Generating Instruction Queues in OFFLOAD Mode for HOST.", myRank_);
     166            0 :         CHK_RET(GenInsQues4Offload(tempAlg));
     167              :     } else { // OPBASE
     168            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], Generating Instruction Queues in OPBASE Mode for HOST.", myRank_);
     169            0 :         CHK_RET(GenInsQues4Opbase(tempAlg));
     170              :     }
     171            0 :     return HcclResult::HCCL_SUCCESS;
     172            0 : }
     173              : 
     174              : // 算子执行aicpu接口
     175              : template <typename AlgTopoMatch, typename InsAlgTemplate>
     176            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::Orchestrate(const AlgTopoInfo     &topoInfo,
     177              :                                                                                  const CollAlgOperator &op,
     178              :                                                                                  const CollAlgParams   &params,
     179              :                                                                                  ConnectedLinkMgr      *linkMgr,
     180              :                                                                                  InsQuePtr              insQue)
     181              : {
     182            0 :     HCCL_INFO("[InsCollAlgFactory] [InsScatterSoleExecutor] [InsScatterSoleExecutor] AiCpu Orchestrate begins.");
     183              :     // 参数校验和初始化
     184            0 :     CHK_RET(Init(op, params, insQue));
     185              : 
     186              :     // soleEsecutor 只支持单层拓扑, 所以只取第 0 级通信域的信息
     187            0 :     vTopo_ = topoInfo.vTopo[0];               // 本通信域内的通信平面
     188            0 :     virtRankMap_ = topoInfo.virtRankMap[0];   // 本通信域内的 rank 映射表
     189            0 :     virtRanks_ = topoInfo.virtRanks[0];       // 本通信域内的 rank 集合
     190            0 :     dataTypeSize_ = DataTypeSizeGet(dataType_);
     191            0 :     dataSize_ = dataCount_ * dataTypeSize_;
     192            0 :     dataType_ = op.dataType;
     193            0 :     CHK_PRT_RET(dataTypeSize_ == 0,
     194              :                 HCCL_ERROR("Scatter_[CollAlgFactory] Rank [%d], Invalid dataTypeSize_ [%u].", myRank_, dataTypeSize_),
     195              :                 HcclResult::HCCL_E_INTERNAL);
     196              : 
     197              :     // 实例化算法模板类
     198            0 :     HCCL_DEBUG("Scatter_[InsScatterSoleExecutor] Rank[%d], Init insAlgTemplate with rankSize [%u] and dmaMode [%s].",
     199              :             myRank_, rankSize_, dmaMode_.Describe().c_str());
     200            0 :     InsAlgTemplate tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
     201            0 :     tempAlg.SetDataType(dataType_);
     202              :     // 通过判断哪层通信域能有到所有remoteRank的path,判断当前算法跑在哪一层    
     203            0 :     std::map<u32, u32>rank2PathNumMap;
     204            0 :     HCCL_INFO("[InsV2ScatterSoleExecutor] CalcRes SetPathNumMap");
     205            0 :     CHK_RET(SetPathNumMapByLinkMgrMultiLevel(linkMgr, virtRanks_, myRank_, rank2PathNumMap));
     206            0 :     tempAlg.setPathNumMap(rank2PathNumMap);
     207            0 :     tempAlg.SetDmaMode(dmaMode_);
     208            0 :     tempAlg.SetCollOp(op); // ccu需要传递op信息
     209            0 :     tempAlg.SetRoot(root_);
     210              : 
     211              :     // 计算算法模板所需资源
     212            0 :     AlgTempResReq tempResReq;
     213            0 :     if (enableDetour_) {
     214            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], CalcRes with detouring enabled for Orchestrate.", myRank_);
     215            0 :         CHK_RET(tempAlg.CalcResDetour(linkMgr, tempResReq));
     216              :     } else {
     217            0 :         HCCL_DEBUG("[InsCollAlgFactory] [InsScatterSoleExecutor] Rank[%d], CalcRes with detouring disabled for Orchestrate.", myRank_);
     218            0 :         CHK_RET(tempAlg.CalcRes(tempResReq));
     219              :     }
     220              : 
     221              :     // 申请算法模板所需资源
     222            0 :     CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
     223            0 :     CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
     224              : 
     225              :     // 令Scatter算子的dataSize_为outputSize
     226            0 :     u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
     227            0 :     dataSize_             = dataCount_ * dataSizePerVolume;
     228              : 
     229            0 :     if (opMode_ == OpMode::OFFLOAD) {
     230            0 :         HCCL_DEBUG("[InsScatterSoleExecutor] Rank[%d], Generating Instruction Queues in OFFLOAD Mode for AICPU.",
     231              :                    myRank_);
     232            0 :         CHK_RET(GenInsQues4Offload(tempAlg));
     233              :     } else { // OPBASE
     234            0 :         HCCL_DEBUG("[InsScatterSoleExecutor] Rank[%d], Generating Instruction Queues in OPBASE Mode for AICPU.",
     235              :                    myRank_);
     236            0 :         CHK_RET(GenInsQues4Opbase(tempAlg));
     237              :     }
     238              : 
     239            0 :     return HcclResult::HCCL_SUCCESS;
     240            0 : }
     241              : 
     242              : template <typename AlgTopoMatch, typename InsAlgTemplate>
     243            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GenInsQues4Offload(InsAlgTemplate &tempAlg)
     244              : {
     245            0 :     RankSliceInfo sliceInfoVec;
     246            0 :     AllignInfo    allignInfo = {enableAllign_, allignSize_, dataType_};
     247            0 :     CHK_RET(tempAlg.CalcSliceInfo(allignInfo, dataSize_, sliceInfoVec));
     248            0 :     HCCL_DEBUG("[InsCollAlgFactory] Rank[%d], done calculating slice information.", myRank_);
     249              : 
     250            0 :     BuffInfo buffInfo;
     251            0 :     buffInfo.inBuffType     = BufferType::INPUT;
     252            0 :     buffInfo.outBuffType    = BufferType::OUTPUT;
     253            0 :     buffInfo.inBuffBaseOff  = 0;
     254            0 :     buffInfo.outBuffBaseOff = 0;
     255            0 :     HCCL_DEBUG("[CollAlgFactory] AlgTemplate is [%s]", tempAlg.Describe().c_str());
     256            0 :     HCCL_DEBUG("[InsCollAlgFactory] Rank[%d], input buffer type [%s], output buffer type [%s], input buffer base "
     257              :                "offset [%u], output buffer base offset [%u].",
     258              :                myRank_, buffInfo.inBuffType.Describe().c_str(), buffInfo.outBuffType.Describe().c_str(),
     259              :                buffInfo.inBuffBaseOff, buffInfo.outBuffBaseOff);
     260              : 
     261            0 :     TempFuncs tempFuncs;
     262            0 :     tempFuncs.opMode              = opMode_;
     263            0 :     tempFuncs.enableCounterNotify = IsEnableCounterNotify();
     264            0 :     tempFuncs.isForepart          = true; // only have one Temp, soleExecutor is always true
     265            0 :     tempFuncs.isBottom            = true; // only have one Temp, soleExecutor is always true
     266            0 :     HCCL_DEBUG("[CollAlgFactory] AlgTemplate is [%s]", tempAlg.Describe().c_str());
     267              : 
     268            0 :     CHK_RET(tempAlg.Run(tempFuncs, sliceInfoVec, buffInfo, tempResLinks_, requiredQue_));
     269            0 :     HCCL_DEBUG("[InsCollAlgFactory] Rank[%d], done generating instruction queues.", myRank_);
     270              : 
     271            0 :     return HcclResult::HCCL_SUCCESS;
     272            0 : }
     273              : 
     274              : template <typename AlgTopoMatch, typename InsAlgTemplate>
     275            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GenInsQues4Opbase(InsAlgTemplate &tempAlg)
     276              : {
     277            0 :     HCCL_DEBUG("[CollAlgFactory] AlgTemplate is [%s]", tempAlg.Describe().c_str());
     278            0 :     u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
     279            0 :     CHK_PRT_RET(dataSizePerVolume == 0,
     280              :                 HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid dataSizePerVolume [%u].", myRank_, dataSizePerVolume),
     281              :                 HcclResult::HCCL_E_INTERNAL);
     282              : 
     283            0 :     CHK_PRT_RET(rankSize_ == 0, HCCL_ERROR("[CollAlgFactory] RankSize is zero!"), HcclResult::HCCL_E_PARA);
     284              :     // maxTmpMemSize_为整个Scratch的大小
     285            0 :     u64 scratchOutputMemSize
     286            0 :         = static_cast<u64>(floor(maxTmpMemSize_ / (rankSize_ * dataSizePerVolume)) * dataSizePerVolume);
     287              : 
     288            0 :     CHK_PRT_RET(scratchOutputMemSize == 0,
     289              :                 HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid input maxTmpMemSize [%u].", myRank_, maxTmpMemSize_),
     290              :                 HcclResult::HCCL_E_PARA);
     291              : 
     292              :     // 统一管理基地址偏移
     293            0 :     BuffInfo buffInfo;
     294            0 :     buffInfo.outBuffType    = BufferType::SCRATCH;
     295            0 :     buffInfo.inBuffBaseOff  = 0;
     296            0 :     buffInfo.outBuffBaseOff = 0;
     297            0 :     buffInfo.scratchBuffBaseOff = 0;
     298              : 
     299            0 :     TempFuncs tempFuncs;
     300            0 :     tempFuncs.opMode              = opMode_;
     301            0 :     tempFuncs.enableCounterNotify = IsEnableCounterNotify();
     302            0 :     tempFuncs.isForepart          = true; // Usr Buff to CCL Buff required
     303            0 :     tempFuncs.isBottom            = true; // CCL Buff to Usr Buff required
     304              : 
     305              :     // 计算CCL的循环次数,dataSize_为Scatter的outputSize(小的),看CCLout与ScatterOut的倍数关系
     306            0 :     u64 sendRecvTimes = (dataSize_ / scratchOutputMemSize) + ((dataSize_ % scratchOutputMemSize) == 0 ? 0 : 1);
     307            0 :     HCCL_INFO("[insScatterSoleExecutor] Rank [%d], sendRecvTimes [%u].", myRank_, sendRecvTimes);
     308              : 
     309            0 :     for (u32 idx = 0; idx < sendRecvTimes; idx++) {
     310              :         // 本轮的ScratchOut的大小(小的)
     311            0 :         u64 currDataSize = (idx == (sendRecvTimes - 1)) ? (dataSize_ - idx * scratchOutputMemSize) : scratchOutputMemSize;
     312              : 
     313            0 :         RankSliceInfo sliceInfoVec;
     314            0 :         AllignInfo    allignInfo = {enableAllign_, allignSize_, dataType_};
     315              : 
     316              :         //每轮cclLoop,准备好usrData的input本地拷贝到scratch的dataSlices,和scratch本地拷贝到output的dataSlices;存放在tempFunc.usrData中
     317            0 :         UsrData usrData;
     318            0 :         u64 usrInOffset = idx * scratchOutputMemSize;
     319            0 :         u64 usrInRankStride = dataSize_;
     320            0 :         for ( RankId r : virtRanks_ ) {
     321            0 :             u32 rankId = virtRankMap_[r];
     322            0 :             usrData.usrInSlices.emplace_back( DataSlice(BufferType::INPUT, usrInOffset + rankId * usrInRankStride, currDataSize) );
     323            0 :             usrData.scratchInSlices.emplace_back( DataSlice(BufferType::SCRATCH, rankId * currDataSize, currDataSize) );
     324              :         }
     325              : 
     326            0 :         usrData.scratchOutSlices.emplace_back( DataSlice(BufferType::SCRATCH, myRank_ * currDataSize, currDataSize) );
     327            0 :         usrData.usrOutSlices.emplace_back( DataSlice(BufferType::OUTPUT, usrInOffset, currDataSize) );
     328            0 :         tempFuncs.usrData = usrData;
     329              : 
     330              :         // 计算SliceInfo,nhr也按照mesh的方式,分rankSize片,每片的大小为curDataSize(按照output计算)
     331            0 :         CHK_RET(tempAlg.CalcSliceInfo(allignInfo, currDataSize, sliceInfoVec));
     332            0 :         CHK_RET(tempAlg.Run(tempFuncs, sliceInfoVec, buffInfo, tempResLinks_, requiredQue_));
     333              :     }
     334              : 
     335            0 :     return HcclResult::HCCL_SUCCESS;
     336            0 : }
     337              : 
     338              : template <typename AlgTopoMatch, typename InsAlgTemplate>
     339            0 : HcclResult InsScatterSoleExecutor<AlgTopoMatch, InsAlgTemplate>::GenInsQues4Ccu(InsAlgTemplate &tempAlg)
     340              : {
     341            0 :     HCCL_DEBUG("[ScatterSoleExecutor][GenInsQues4Ccu] Gen InsQue start");
     342            0 :     u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
     343            0 :     CHK_PRT_RET(dataSizePerVolume == 0,
     344              :                 HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid dataSizePerVolume [%u].", myRank_, dataSizePerVolume),
     345              :                 HcclResult::HCCL_E_INTERNAL);
     346              : 
     347              :     // maxTmpMemSize_为整个Scratch的大小,按scatter的output的计算
     348            0 :     u64 scratchOutputMemSize
     349            0 :         = static_cast<u64>(floor(maxTmpMemSize_ / (rankSize_ * dataSizePerVolume)) * dataSizePerVolume);
     350              : 
     351            0 :     CHK_PRT_RET(scratchOutputMemSize == 0,
     352              :                 HCCL_ERROR("[CollAlgFactory] Rank [%d], Invalid input maxTmpMemSize [%u].", myRank_, maxTmpMemSize_),
     353              :                 HcclResult::HCCL_E_PARA);
     354              : 
     355              :     // 统一管理基地址偏移
     356            0 :     BuffInfo buffInfo;
     357            0 :     buffInfo.inBuffBaseOff  = 0;
     358            0 :     buffInfo.outBuffBaseOff = 0;
     359            0 :     buffInfo.scratchBuffBaseOff = 0;
     360              : 
     361              :     // CCLBuf的切分,UB的最大传输值的切分,统一在executor中处理
     362              :     // dataSize_为Scatter的outputSize(小的,已含DataType)
     363            0 :     uint64_t tempMaxSliceSize = tempAlg.GetMaxSliceSize();
     364            0 :     uint64_t blockSize = dataSize_ < tempMaxSliceSize ? dataSize_ : tempMaxSliceSize;
     365            0 :     blockSize = blockSize < scratchOutputMemSize ? blockSize : scratchOutputMemSize; // 按blockSize切分,则可以同时满足UB传输上限、CCLbuff上限
     366              :     // 将dataSize_按照blockSize切分
     367            0 :     u32 loopTimes = ( dataSize_ / blockSize ) + ((dataSize_ % blockSize) == 0 ? 0 : 1);
     368            0 :     HCCL_DEBUG("[ins_scatter_sole_executor][GenInsQues4Ccu] dataSize_[%llu], blockSize[%llu], loopTimes[%u], scratchOutputMemSize[%u], maxTmpMemSize[%u] ", dataSize_, blockSize, loopTimes, scratchOutputMemSize, maxTmpMemSize_);
     369            0 :     TempFuncs tempFuncs;
     370            0 :     for (uint64_t idx = 0; idx < loopTimes; idx++) {
     371            0 :         uint64_t sliceSize = ( (idx == loopTimes-1) ? (dataSize_ - idx * blockSize ) : blockSize);
     372            0 :         uint64_t offset = idx * blockSize;
     373              :         // tempAlg从op_中可以获取input,output,scratch的基地址, 从dataSize_获取Stride
     374              :         // 从buffInfo中可以获取每次的偏移
     375            0 :         buffInfo.inBuffBaseOff = offset;
     376            0 :         buffInfo.outBuffBaseOff = offset;
     377            0 :         RankSliceInfo sliceInfoVec;
     378            0 :         AllignInfo    allignInfo = {enableAllign_, allignSize_, dataType_};
     379              :         // 从sliceInfoVec中获取sliceSize
     380            0 :         CHK_RET(tempAlg.CalcSliceInfo(allignInfo, sliceSize, sliceInfoVec));
     381            0 :         CHK_RET(tempAlg.Run(tempFuncs, sliceInfoVec, buffInfo, tempResLinks_, requiredQue_));
     382              :     }
     383            0 :     return HcclResult::HCCL_SUCCESS;
     384            0 : }
     385              : 
     386              : #ifndef CCL_KERNEL_AICPU
     387              :     INS_REGISTER_IMPL_BY_TEMP(OpType::SCATTER, CcuScatterMesh2D, InsScatterSoleExecutor, TopoMatchConcurrMesh,
     388              :                           CcuTempScatterMesh2D);
     389              : #endif
     390              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1