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

Generated by: LCOV version 2.0-1