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

Generated by: LCOV version 2.0-1