LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_template/ins_alg_template - ins_temp_gather_nhr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 191 0
Test Date: 2026-07-28 12:11:00 Functions: 0.0 % 15 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 "ins_temp_gather_nhr.h"
      12              : #include "ins_temp_all_gather_nhr.h"
      13              : #include "alg_data_trans_wrapper.h"
      14              : #include "dev_mode.h"
      15              : #include "log.h"
      16              : 
      17              : 
      18              : namespace Hccl {
      19            0 : InsTempGatherNHR::InsTempGatherNHR(const RankId virtualRank, const u32 tempRankSize,
      20              :                                              const std::vector<std::vector<RankId>> &tempVTopo,
      21            0 :                                              const std::map<RankId, u32>            &tempVirtRankMap)
      22            0 :     : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
      23              : {
      24            0 : }
      25              : 
      26            0 : InsTempGatherNHR::~InsTempGatherNHR()
      27              : {
      28            0 : }
      29              : 
      30              : //  NHR 算法需要的资源计算
      31            0 : HcclResult InsTempGatherNHR::CalcRes(AlgTempResReq &tempResReq)
      32              : {
      33              :     // NHR 需要的 que Num 为 1
      34            0 :     tempResReq.queNum = 1;
      35            0 :     tempResReq.streamNum = tempResReq.queNum;
      36            0 :     tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
      37            0 :     CHK_PRT_RET(CalcResLinksNHR(myRank_, tempRankSize_, tempVTopo_, tempResReq) != HcclResult::HCCL_SUCCESS,
      38              :                 HCCL_ERROR("[CollAlgFactory] [InsTempGatherNHR] Rank [%d], resLinks calculation error!", myRank_),
      39              :                 HcclResult::HCCL_E_INTERNAL);
      40              : 
      41            0 :     return HcclResult::HCCL_SUCCESS;
      42              : }
      43              : 
      44            0 : uint64_t InsTempGatherNHR::GetExpandedMode() const
      45              : {
      46            0 :     return DeviceMode::AICPU;
      47              : }
      48              : 
      49              : /*
      50              : 按照mesh的方式计算SliceInfo,例如N张卡,就是N份slice
      51              : */
      52            0 : HcclResult InsTempGatherNHR::CalcSliceInfo(const AllignInfo &allignInfo, const u64 dataSize, RankSliceInfo &sliceInfoVec)
      53              : {
      54              :     // 一般情况下,nhr的temp是单级的, Gather nhr的dataSize为output大小
      55            0 :     CHK_PRT_RET(tempVTopo_.size() != 1,
      56              :                 HCCL_ERROR("[CollAlgFactory] [InsTempGatherNHR], tempVtopo size is [%zu] one stage NHR only support one template.", tempVTopo_.size()),
      57              :                 HcclResult::HCCL_E_INTERNAL);
      58              : 
      59            0 :     std::vector<SliceInfo> tmp(tempVTopo_.size());
      60            0 :     sliceInfoVec.resize(tempRankSize_, tmp);
      61              : 
      62            0 :     CHK_RET(CalcRsAgSliceInfoNHR(myRank_, tempRankSize_, allignInfo, dataSize, sliceInfoVec));
      63              : 
      64            0 :     return HcclResult::HCCL_SUCCESS;
      65            0 : }
      66              : 
      67            0 : HcclResult InsTempGatherNHR::PreCopy(const TempFuncs &tempFuncs, const RankSliceInfo &sliceInfoVec,
      68              :     std::vector<InsQuePtr> &tempInsQues)
      69              : {
      70              :     // 前拷贝数据量
      71            0 :     u64 preCopyDataSize = sliceInfoVec[tempVirtRankMap_[myRank_]][0].size;
      72              :     // 前拷贝数据在 main buffer 上的偏移
      73            0 :     u64 preCopyOffset = sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset + mainBufferBaseOffset_;
      74              : 
      75            0 :     HCCL_INFO("[InsTempGatherNHR][PreCopy] mainBufferType[%d], preCopyOffset[%llu], preCopyDataSize[%llu]",
      76              :         mainBufferType_, preCopyOffset, preCopyDataSize);
      77            0 :     if (preCopyDataSize == 0) {
      78            0 :         HCCL_INFO("[InsTempGatherNHR][PreCopy] preCopyDataSize is 0, no need copy");
      79            0 :          return HcclResult::HCCL_SUCCESS;
      80              :     }
      81            0 :     if (tempFuncs.isForepart && opMode_ == OpMode::OPBASE) {
      82              :         // 单算子模式下,第一个算子,直接使用 user data 拷贝
      83            0 :         HCCL_INFO("[InsTempGatherNHR][PreCopy] Opbase Forepart, copy base on user data");
      84            0 :         CHK_RET(LocalCopySlices(tempInsQues[0], tempFuncs.usrData.usrInSlices,
      85              :             tempFuncs.usrData.scratchInSlices));
      86            0 :     } else if (tempFuncs.isForepart && opMode_ == OpMode::OFFLOAD) {
      87              :         // 图模式下,第一个算子,从 inBuff 拷贝到 scratchBuff
      88            0 :         if (buffInfo_.inBuffType == mainBufferType_ && buffInfo_.inBuffBaseOff == preCopyOffset) {
      89              :             // 如果 inBuff 就是 mainBuffer,不需要拷贝
      90            0 :             HCCL_INFO("[InsTempGatherNHR][PreCopy] isForepart inBuff is same as scratchBuff, no need pre copy");
      91              :         } else {
      92            0 :             HCCL_INFO("[InsTempGatherNHR][PreCopy] isForepart, copy from inBuff to scratchBuff");
      93            0 :             DataSlice srcSlice  = DataSlice(buffInfo_.inBuffType, buffInfo_.inBuffBaseOff, preCopyDataSize);
      94            0 :             DataSlice dstSlice  = DataSlice(mainBufferType_, preCopyOffset, preCopyDataSize);
      95            0 :             CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
      96              :         }
      97            0 :     } else if (tempFuncs.forAlgSeqComb) {
      98              :         // 作为融合算子的一部分,需要将 inBuff 拷贝到 scratchbuff
      99            0 :         if (buffInfo_.inBuffType == mainBufferType_ && buffInfo_.inBuffBaseOff == preCopyOffset) {
     100              :             // 如果 inBuff 就是 mainBuffer,不需要拷贝
     101            0 :             HCCL_INFO("[InsTempGatherNHR][PreCopy] forAlgSeqComb inBuff is same as scratchBuff, no need pre copy");
     102              :         } else {
     103            0 :             HCCL_INFO("[InsTempGatherNHR][PreCopy] forAlgSeqComb, copy from inBuff to scratchBuff");
     104            0 :             DataSlice srcSlice  = DataSlice(buffInfo_.inBuffType, buffInfo_.inBuffBaseOff, preCopyDataSize);
     105            0 :             DataSlice dstSlice  = DataSlice(mainBufferType_, preCopyOffset, preCopyDataSize);
     106            0 :             CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
     107              :         }
     108              :     }
     109            0 :     return HcclResult::HCCL_SUCCESS;
     110              : }
     111              : 
     112            0 : HcclResult InsTempGatherNHR::PostCopy(const TempFuncs &tempFuncs, const RankSliceInfo &sliceInfoVec,
     113              :     std::vector<InsQuePtr> &tempInsQues)
     114              : {
     115            0 :     if (u32(myRank_) != root_) { // 非root节点不需要后拷贝
     116            0 :         return HcclResult::HCCL_SUCCESS;
     117              :     }
     118              : 
     119              :     // 后拷贝数据量
     120            0 :     u64 postCopyDataSize = sliceInfoVec.back().back().size + sliceInfoVec.back().back().offset;
     121              :     // 后拷贝数据在 main buffer 上的偏移
     122            0 :     u64 postCopyOffset = mainBufferBaseOffset_;
     123            0 :     HCCL_INFO("[InsTempGatherNHR][PostCopy] mainBufferType[%d], postCopyOffset[%llu], postCopyDataSize[%llu]",
     124              :         mainBufferType_, postCopyOffset, postCopyDataSize);
     125              : 
     126              :     // 通信后数据全部在 scratch 上,如果是单算子模式, 并且是最后一步算子,需要将数据从 scratch 拷贝到 userOut
     127            0 :     if (tempFuncs.isBottom && opMode_ == OpMode::OPBASE) {
     128            0 :         HCCL_INFO("[InsTempGatherNHR][PostCopy] Opbase && isBottom, copy from outBuff to userOut");
     129            0 :         CHK_RET(LocalCopySlices(tempInsQues[0], tempFuncs.usrData.scratchOutSlices, tempFuncs.usrData.usrOutSlices));
     130              :     } else {
     131            0 :         if (buffInfo_.outBuffType == mainBufferType_ && buffInfo_.outBuffBaseOff == postCopyOffset) {
     132              :             // 如果 mainBuffer 就是 OutBuffer,不需要拷贝
     133            0 :             HCCL_INFO("[InsTempGatherNHR][PostCopy] outBuff is same as scratchBuff, no need post copy");
     134              :         } else {
     135            0 :             HCCL_INFO("[InsTempGatherNHR][PostCopy] , copy from scratchBuff to outBuff");
     136            0 :             DataSlice srcSlice  = DataSlice(mainBufferType_, postCopyOffset, postCopyDataSize);
     137            0 :             DataSlice dstSlice  = DataSlice(buffInfo_.outBuffType, buffInfo_.outBuffBaseOff, postCopyDataSize);
     138            0 :             CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
     139              :         }
     140              : 
     141              :         // 图模式或者单算子模式下非第一个算子,需要将数据从 scratch 拷贝到 outBuff
     142            0 :         HCCL_INFO("[InsTempGatherNHR][PreCopy] not first op, not seq comb, copy from inBuff to outBuff");
     143            0 :         DataSlice srcSlice  = DataSlice(mainBufferType_, postCopyOffset, postCopyDataSize);
     144            0 :         DataSlice dstSlice  = DataSlice(buffInfo_.outBuffType, buffInfo_.outBuffBaseOff, postCopyDataSize);
     145            0 :         CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
     146              :     }
     147            0 :     return HcclResult::HCCL_SUCCESS;
     148              : }
     149              : 
     150            0 : HcclResult InsTempGatherNHR::Run(const TempFuncs &tempFuncs, const RankSliceInfo &sliceInfoVec,
     151              :                                           const BuffInfo &buffInfo, const ResLinks &tempLinks,
     152              :                                           std::vector<InsQuePtr> &tempInsQues)
     153              : {
     154            0 :     HCCL_INFO("[InsTempGatherNHR] Run start");
     155              :     // 初始化参数
     156            0 :     opMode_              = tempFuncs.opMode;
     157            0 :     enableCounterNotify_ = tempFuncs.enableCounterNotify;
     158            0 :     buffInfo_            = buffInfo;
     159            0 :     queNum_ = tempVTopo_.size();
     160            0 :     CHK_PRT_RET(queNum_ != tempInsQues.size(),
     161              :                 HCCL_ERROR("[CollAlgFactory] [InsTempGatherNHR] Rank [%d], requiredQue Error.", myRank_),
     162              :                 HcclResult::HCCL_E_INTERNAL);
     163              : 
     164              :     // Gather NHR 算子在通信过程中需要使用 scratch, 主要的通信过程也是在scratch上进行的
     165            0 :     mainBufferType_ = buffInfo_.scratBuffType;
     166            0 :     mainBufferBaseOffset_ = buffInfo_.scratchBuffBaseOff;
     167              : 
     168            0 :     HCCL_INFO("[InsTempGatherNHR Run]RankID:[%d], root:[%u], isForepart:[%d], isBottom:[%d]", myRank_, root_, tempFuncs.isForepart, tempFuncs.isBottom);
     169              : 
     170              :     // 前拷贝
     171            0 :     PreCopy(tempFuncs, sliceInfoVec, tempInsQues);
     172              : 
     173            0 :     std::vector<AicpuNHRStepInfo> nhrSteps;
     174            0 :     GetGatherStepInfo(nhrSteps);
     175              : 
     176            0 :     for (auto &nhrstep : nhrSteps) {
     177            0 :         CHK_PRT_RET(BatchTxRx(nhrstep, tempLinks, tempInsQues[0], sliceInfoVec),
     178              :                 HCCL_ERROR("[InsTempGatherNHR] BatchTxRx failed"),
     179              :                 HcclResult::HCCL_E_INTERNAL);
     180              :     }
     181              : 
     182              :     // 后拷贝
     183            0 :     PostCopy(tempFuncs, sliceInfoVec, tempInsQues);
     184            0 :     return HcclResult::HCCL_SUCCESS;
     185            0 : }
     186              : 
     187              : // Send multiple DataSlices
     188            0 : HcclResult InsTempGatherNHR::BatchTxRx(AicpuNHRStepInfo &stepInfo, const ResLinks &tempLinks, InsQuePtr &queue,
     189              :     const RankSliceInfo &sliceInfoVec)
     190              : {
     191              :     // 只有Tx,使用send指令
     192            0 :     if (stepInfo.txSliceIdxs.size() > 0 && stepInfo.rxSliceIdxs.size() == 0) {
     193            0 :         BatchSend(stepInfo, tempLinks, queue, sliceInfoVec, mainBufferType_, mainBufferBaseOffset_);
     194              :     }
     195              :     // 只有Rx,使用recv指令
     196            0 :     else if (stepInfo.txSliceIdxs.size() == 0 && stepInfo.rxSliceIdxs.size() > 0) {
     197            0 :         BatchRecv(stepInfo, tempLinks, queue, sliceInfoVec, mainBufferType_, mainBufferBaseOffset_);
     198              :     }
     199              :     // 既有Tx又有Rx,使用SendRecv指令
     200            0 :     else if (stepInfo.txSliceIdxs.size() > 0 && stepInfo.rxSliceIdxs.size() > 0) {
     201            0 :         BatchSR(stepInfo, tempLinks, queue, sliceInfoVec, mainBufferType_, mainBufferBaseOffset_);
     202              :     }
     203            0 :     return HcclResult::HCCL_SUCCESS;
     204              : }
     205              : 
     206            0 : HcclResult InsTempGatherNHR::BatchSend(AicpuNHRStepInfo &stepInfo, const ResLinks &tempLinks, InsQuePtr &queue,
     207              :     const RankSliceInfo &sliceInfoVec, BufferType memType, u32 memOffset) const
     208              : {
     209            0 :     CHK_PRT_RET(tempLinks.count(stepInfo.toRank) == 0 ,
     210              :         HCCL_ERROR("[InsTempGatherNHR][BatchSend] rank [%u] not found in links map", stepInfo.toRank),
     211              :         HcclResult::HCCL_E_INTERNAL);
     212              : 
     213            0 :     const LinkData &linkSend = tempLinks.at(stepInfo.toRank)[0];
     214            0 :     std::vector<DataSlice> txSlices;
     215            0 :     for (u32 i = 0; i < stepInfo.txSliceIdxs.size(); i++) {
     216            0 :         u32 txId = stepInfo.txSliceIdxs[i];
     217            0 :         DataSlice txSrcDstSlice = DataSlice( memType, memOffset + sliceInfoVec[txId][0].offset, sliceInfoVec[txId][0].size );
     218            0 :         txSlices.push_back(txSrcDstSlice);
     219              :     }
     220            0 :     SlicesList txSlicesList(txSlices, txSlices);
     221            0 :     DataInfo sendData(linkSend, txSlicesList);
     222            0 :     CHK_PRT_RET(Send(sendData, queue), HCCL_ERROR("[InsTempGatherNHR] BatchSend failed"),
     223              :         HcclResult::HCCL_E_INTERNAL);
     224            0 :     return HcclResult::HCCL_SUCCESS;
     225            0 : }
     226              : 
     227            0 : HcclResult InsTempGatherNHR::BatchRecv(AicpuNHRStepInfo &stepInfo, const ResLinks &tempLinks, InsQuePtr &queue,
     228              :     const RankSliceInfo &sliceInfoVec, BufferType memType, u32 memOffset) const
     229              : {
     230            0 :     CHK_PRT_RET(tempLinks.count(stepInfo.fromRank) == 0 ,
     231              :         HCCL_ERROR("[InsTempGatherNHR][BatchRecv] rank [%u] not found in links map", stepInfo.fromRank),
     232              :         HcclResult::HCCL_E_INTERNAL);
     233              : 
     234            0 :     const LinkData &linkRecv = tempLinks.at(stepInfo.fromRank)[0];
     235            0 :     std::vector<DataSlice> rxSlices;
     236            0 :     for (u32 i = 0; i < stepInfo.rxSliceIdxs.size(); i++) {
     237            0 :         u32 rxId = stepInfo.rxSliceIdxs[i];
     238            0 :         DataSlice rxSrcDstSlice = DataSlice( memType, memOffset + sliceInfoVec[rxId][0].offset, sliceInfoVec[rxId][0].size );
     239            0 :         rxSlices.push_back(rxSrcDstSlice);
     240              :     }
     241            0 :     SlicesList rxSlicesList(rxSlices, rxSlices);
     242            0 :     DataInfo recvData(linkRecv, rxSlicesList);
     243            0 :     CHK_PRT_RET(Recv(recvData, queue), HCCL_ERROR("[InsTempGatherNHR] BatchTxRx Recv failed"),
     244              :         HcclResult::HCCL_E_INTERNAL);
     245            0 :     return HcclResult::HCCL_SUCCESS;
     246            0 : }
     247              : 
     248            0 : HcclResult InsTempGatherNHR::BatchSR(AicpuNHRStepInfo &stepInfo, const ResLinks &tempLinks, InsQuePtr &queue,
     249              :     const RankSliceInfo &sliceInfoVec, BufferType memType, u32 memOffset)const
     250              : {
     251            0 :     CHK_PRT_RET(tempLinks.count(stepInfo.toRank) == 0 ,
     252              :         HCCL_ERROR("[InsTempGatherNHR][BatchSR] rank [%u] not found in links map", stepInfo.toRank),
     253              :         HcclResult::HCCL_E_INTERNAL);
     254            0 :     const LinkData &linkSend = tempLinks.at(stepInfo.toRank)[0];
     255            0 :     CHK_PRT_RET(tempLinks.count(stepInfo.fromRank) == 0 ,
     256              :         HCCL_ERROR("[InsTempGatherNHR][BatchSR] rank [%u] not found in links map", stepInfo.fromRank),
     257              :         HcclResult::HCCL_E_INTERNAL);
     258            0 :     const LinkData &linkRecv = tempLinks.at(stepInfo.fromRank)[0];
     259            0 :     TxRxLinks linkSendRecv = {linkSend, linkRecv};
     260              : 
     261            0 :     std::vector<DataSlice> txSlices;
     262            0 :     for (u32 i = 0; i < stepInfo.txSliceIdxs.size(); i++) {
     263            0 :         u32 txId = stepInfo.txSliceIdxs[i];
     264            0 :         DataSlice txSrcDstSlice = DataSlice( memType, memOffset + sliceInfoVec[txId][0].offset, sliceInfoVec[txId][0].size );
     265            0 :         txSlices.push_back(txSrcDstSlice);
     266              :     }
     267            0 :     SlicesList txSlicesList(txSlices, txSlices);
     268            0 :     std::vector<DataSlice> rxSlices;
     269            0 :     for (u32 i = 0; i < stepInfo.rxSliceIdxs.size(); i++) {
     270            0 :         u32 rxId = stepInfo.rxSliceIdxs[i];
     271            0 :         DataSlice rxSrcDstSlice = DataSlice( memType, memOffset + sliceInfoVec[rxId][0].offset, sliceInfoVec[rxId][0].size );
     272            0 :         rxSlices.push_back(rxSrcDstSlice);
     273              :     }
     274            0 :     SlicesList rxSlicesList(rxSlices, rxSlices);
     275            0 :     TxRxSlicesList txRxSlicesList(txSlicesList, rxSlicesList);
     276            0 :     SendRecvInfo sendRecvInfo(linkSendRecv, txRxSlicesList);
     277            0 :     CHK_PRT_RET(SendRecv(sendRecvInfo, queue, 0, true, dmaMode_), HCCL_ERROR("[InsTempGatherNHR] BatchTxRx SendRecv failed"),
     278              :         HcclResult::HCCL_E_INTERNAL);
     279            0 :     return HcclResult::HCCL_SUCCESS;
     280            0 : }
     281              : 
     282              : // NHR每步的算法描述原理函数
     283            0 : HcclResult InsTempGatherNHR::GetScatterStepInfo(u32 step, u32 nSteps, AicpuNHRStepInfo &stepInfo) const
     284              : {
     285            0 :     u32 rankSize = tempRankSize_;
     286            0 :     stepInfo.txSliceIdxs.clear();
     287            0 :     stepInfo.rxSliceIdxs.clear();
     288            0 :     stepInfo.nSlices = 0;
     289            0 :     stepInfo.toRank = rankSize;
     290            0 :     stepInfo.fromRank = rankSize;
     291            0 :     stepInfo.step = step;
     292            0 :     stepInfo.myRank = myRank_;
     293              : 
     294            0 :     u32 deltaRoot = (root_ + rankSize - myRank_) % rankSize;
     295            0 :     u32 deltaRankPair = 1 << step;
     296              : 
     297              :     // 数据份数和数据编号增量
     298            0 :     u32 nSlices = (rankSize - 1 + (1 << step)) / (1 << (step + 1));
     299            0 :     u32 deltaSliceIndex = 1 << (step + 1);
     300              : 
     301              :     // 判断是否是2的幂
     302            0 :     u32 nRanks = 0; // 本步需要进行收/发的rank数
     303            0 :     bool isPerfect = (rankSize & (rankSize - 1)) == 0;
     304            0 :     if (!isPerfect && step == nSteps - 1) {
     305            0 :         nRanks = rankSize - deltaRankPair;
     306              :     } else {
     307            0 :         nRanks = deltaRankPair;
     308              :     }
     309              : 
     310            0 :     if (deltaRoot < nRanks) { // 需要发
     311            0 :         u32 sendTo = (myRank_ + rankSize - deltaRankPair) % rankSize;
     312            0 :         u32 txSliceIdx = sendTo;
     313            0 :         for (u32 i = 0; i < nSlices; i++) {
     314            0 :             u32 targetTxSliceIdx = txSliceIdx;
     315            0 :             stepInfo.txSliceIdxs.push_back(targetTxSliceIdx);
     316            0 :             txSliceIdx = (txSliceIdx + rankSize - deltaSliceIndex) % rankSize;
     317              :         }
     318              : 
     319            0 :         stepInfo.toRank = sendTo;
     320            0 :         stepInfo.nSlices = nSlices;
     321            0 :     } else if (deltaRoot >= deltaRankPair && deltaRoot < nRanks + deltaRankPair) { // 需要收
     322            0 :         u32 recvFrom = (myRank_ + deltaRankPair) % rankSize;
     323            0 :         u32 rxSliceIdx = myRank_;
     324            0 :         for (u32 i = 0; i < nSlices; i++) {
     325            0 :             u32 targetRxSliceIdx = rxSliceIdx;
     326            0 :             stepInfo.rxSliceIdxs.push_back(targetRxSliceIdx);
     327            0 :             rxSliceIdx = (rxSliceIdx + rankSize - deltaSliceIndex) % rankSize;
     328              :         }
     329              : 
     330            0 :         stepInfo.fromRank = recvFrom;
     331            0 :         stepInfo.nSlices = nSlices;
     332              :     }
     333            0 :     return HcclResult::HCCL_SUCCESS;
     334              : }
     335              : 
     336            0 : HcclResult InsTempGatherNHR::GetGatherStepInfo(std::vector<AicpuNHRStepInfo> &nhrSteps) const
     337              : {
     338            0 :     nhrSteps.clear();
     339            0 :     u32 nSteps = GetNHRStepNum(tempRankSize_);
     340            0 :     nhrSteps.resize(nSteps);
     341            0 :     for (u32 step = 0; step < nSteps; step++) {
     342              :         // 复用 Scatter NHR 的计算方法,只不过要把步骤顺序和收发端反过来
     343            0 :         u32 stepIdx = nSteps - step - 1;
     344            0 :         GetScatterStepInfo(step, nSteps, nhrSteps[stepIdx]);
     345            0 :         nhrSteps[stepIdx].step = step;
     346            0 :         u32 tmp = nhrSteps[stepIdx].toRank;
     347            0 :         nhrSteps[stepIdx].toRank = nhrSteps[stepIdx].fromRank;
     348            0 :         nhrSteps[stepIdx].fromRank = tmp;
     349            0 :         nhrSteps[stepIdx].txSliceIdxs.swap(nhrSteps[stepIdx].rxSliceIdxs);
     350              :     }
     351            0 :     return HcclResult::HCCL_SUCCESS;
     352              : }
     353              : 
     354              : 
     355              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1