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

Generated by: LCOV version 2.0-1