LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_template/ins_alg_template - ins_temp_reduce_scatter_nhr.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 252 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 17 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_reduce_scatter_nhr.h"
      12              : #include "log.h"
      13              : #include "alg_data_trans_wrapper.h"
      14              : 
      15              : namespace Hccl {
      16            0 : InsTempReduceScatterNHR::InsTempReduceScatterNHR(
      17              :     const RankId virtualRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
      18            0 :     const std::map<RankId, u32>& tempVirtRankMap)
      19            0 :     : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
      20            0 : {}
      21              : 
      22            0 : InsTempReduceScatterNHR::~InsTempReduceScatterNHR() {}
      23              : 
      24            0 : HcclResult InsTempReduceScatterNHR::CalcRes(AlgTempResReq& tempResReq)
      25              : {
      26            0 :     CHK_PRT_RET(
      27              :         CalcResLinksNHR(myRank_, tempRankSize_, tempVTopo_, tempResReq) != HcclResult::HCCL_SUCCESS,
      28              :         HCCL_ERROR("[CollAlgFactory] [InsTempReduceScatterNHR] Rank [%d], resLinks calculation error!", myRank_),
      29              :         HcclResult::HCCL_E_INTERNAL);
      30            0 :     auto& linkReq = tempResReq.links;
      31            0 :     u32 pathNum = 0;
      32            0 :     for (auto resReqIter = linkReq.begin(); resReqIter != linkReq.end(); resReqIter++) {
      33            0 :         auto remoteRank = resReqIter->first;
      34            0 :         if (rank2PathNumMap_.find(remoteRank) == rank2PathNumMap_.end() || rank2PathNumMap_[remoteRank] == 0) {
      35            0 :             HCCL_ERROR("[InsTempReduceScatterNHR] No path to remoteRank[%d]", remoteRank);
      36            0 :             return HcclResult::HCCL_E_INTERNAL;
      37              :         }
      38            0 :         if (pathNum == 0) {
      39            0 :             pathNum = rank2PathNumMap_[remoteRank];
      40            0 :         } else if (rank2PathNumMap_[remoteRank] != pathNum) {
      41            0 :             HCCL_ERROR(
      42              :                 "[InsTempReduceScatterNHR] Inconsistency pathNum to remoteRanks, Previous consistent pathNum=[%u], "
      43              :                 "mismatched "
      44              :                 "remoteRank=[%d], pathNum=[%u]",
      45              :                 pathNum, remoteRank, rank2PathNumMap_[remoteRank]);
      46            0 :             return HcclResult::HCCL_E_INTERNAL;
      47              :         }
      48            0 :         resReqIter->second = pathNum;
      49              :     }
      50              :     // NHR 需要的 que Num 为 1 * pathNum
      51            0 :     tempResReq.queNum = pathNum;
      52            0 :     tempResReq.streamNum = tempResReq.queNum;
      53            0 :     tempResReq.queNotifys = CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
      54            0 :     return HcclResult::HCCL_SUCCESS;
      55              : }
      56              : 
      57              : /*
      58              : dataSize / (rankSize) --> chunkSize
      59              : dataSize / (rankSize * queNum) --> sliceSize
      60              : 
      61              : SliceInfoVecforNHR: [1st chunk: [1st Slice, 2nd Slice, ...], 2nd chunk: [1st Slice, 2nd Slice, ...], ...]
      62              : */
      63              : HcclResult
      64            0 : InsTempReduceScatterNHR::CalcSliceInfo(const AllignInfo& allignInfo, const u64 dataSize, RankSliceInfo& sliceInfoVec)
      65              : {
      66            0 :     std::vector<SliceInfo> tmp(tempVTopo_.size());
      67            0 :     sliceInfoVec.resize(tempRankSize_, tmp);
      68            0 :     CHK_RET(CalcRsAgSliceInfoNHR(myRank_, tempRankSize_, allignInfo, dataSize, sliceInfoVec));
      69              : 
      70            0 :     return HcclResult::HCCL_SUCCESS;
      71            0 : }
      72              : 
      73            0 : HcclResult InsTempReduceScatterNHR::Run(
      74              :     const TempFuncs& tempFuncs, const RankSliceInfo& sliceInfoVec, const BuffInfo& buffInfo, const ResLinks& tempLinks,
      75              :     std::vector<InsQuePtr>& tempInsQues)
      76              : {
      77            0 :     if (IsPcieLink(tempLinks)) {
      78            0 :         dmaMode_ = DmaMode::GET;
      79              :     }
      80            0 :     opMode_ = tempFuncs.opMode;
      81            0 :     enableCounterNotify_ = tempFuncs.enableCounterNotify;
      82            0 :     buffInfo_ = buffInfo;
      83            0 :     queNum_ = tempVTopo_.size();
      84            0 :     CHK_PRT_RET(
      85              :         queNum_ != tempInsQues.size(),
      86              :         HCCL_ERROR("[CollAlgFactory] [InsTempReduceScatterNHR] Rank [%d], requiredQue Error.", myRank_),
      87              :         HcclResult::HCCL_E_INTERNAL);
      88            0 :     CHK_RET(PreCopy(tempFuncs, sliceInfoVec, tempInsQues));
      89            0 :     CHK_RET(RunReduceScatter(sliceInfoVec, tempLinks, tempInsQues));
      90            0 :     CHK_RET(PostCopy(tempFuncs, sliceInfoVec, tempInsQues));
      91            0 :     return HcclResult::HCCL_SUCCESS;
      92              : }
      93              : 
      94            0 : HcclResult InsTempReduceScatterNHR::PreCopy(
      95              :     const TempFuncs& tempFuncs, const RankSliceInfo& sliceInfoVec, std::vector<InsQuePtr>& tempInsQues)
      96              : {
      97              :     (void)sliceInfoVec;
      98              :     // 通信前需要将所有的数据统一拷贝到 inBuff 上的对应位置。
      99            0 :     if (tempFuncs.isForepart && opMode_ == OpMode::OPBASE) {
     100              :         // 单算子模式下,第一个算子,需要将数据从 userIn 拷贝到 inBuff
     101            0 :         HCCL_INFO("[InsTempReduceScatterNHR][PreCopy] Opbase Forepart, copy from userIn to outBuff");
     102            0 :         CHK_RET(MultiSliceLocalCopy(tempInsQues[0], tempFuncs.usrData.usrInSlices, tempFuncs.usrData.scratchInSlices));
     103              :     } else {
     104              :         // 图模式或者单算子模式下非第一个算子,数据已经在 inbuff 上了,不需要拷贝
     105            0 :         HCCL_INFO("[InsTempReduceScatterNHR][PreCopy] not forpat and opbse, skip precopy");
     106              :     }
     107            0 :     return HcclResult::HCCL_SUCCESS;
     108              : }
     109              : 
     110            0 : HcclResult InsTempReduceScatterNHR::PostCopy(
     111              :     const TempFuncs& tempFuncs, const RankSliceInfo& sliceInfoVec, std::vector<InsQuePtr>& tempInsQues)
     112              : {
     113              :     // 通信结束之后,数据都在 inbuff 上,需要搬运到对应的输出位置。
     114            0 :     if (tempFuncs.isBottom && opMode_ == OpMode::OPBASE) {
     115              :         // 如果是单算子模式, 并且是最后一步算子,需要将数据从 inBuff 拷贝到 userOut
     116              :         // 是否需要将数据搬运到 OutBuff 上再搬运到 UserOut 上??
     117            0 :         HCCL_INFO("[InsTempReduceScatterNHR][PostCopy] Opbase Bottom, copy from outBuff to userOut");
     118            0 :         CHK_RET(
     119              :             MultiSliceLocalCopy(tempInsQues[0], tempFuncs.usrData.scratchOutSlices, tempFuncs.usrData.usrOutSlices));
     120            0 :     } else if (tempFuncs.forAllReduce) {
     121              :         // 如果是 forAllReduce 算子的前半部分需要将数据从 inBuff 拷贝到 outBuff 并且加上本rank的偏移
     122            0 :         if (buffInfo_.inBuffType != buffInfo_.outBuffType || buffInfo_.inBuffBaseOff != buffInfo_.outBuffBaseOff) {
     123            0 :             HCCL_INFO("[InsTempReduceScatterNHR][PostCopy] forAllReduce, copy from inBuff to outBuff");
     124            0 :             u64 size = sliceInfoVec[tempVirtRankMap_[myRank_]][0].size;
     125            0 :             u64 srcOffset = sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset;
     126            0 :             u64 dstOffset = sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset;
     127            0 :             DataSlice srcSlice = DataSlice(buffInfo_.inBuffType, srcOffset + buffInfo_.inBuffBaseOff, size);
     128            0 :             DataSlice dstSlice = DataSlice(buffInfo_.outBuffType, dstOffset + buffInfo_.outBuffBaseOff, size);
     129            0 :             CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
     130              :         } else {
     131            0 :             HCCL_INFO("[InsTempReduceScatterNHR][PostCopy] forAllReduce, inBuff same as outBuff, skip copy");
     132              :         }
     133              :     } else {
     134              :         // 如果是图模式,或者单算子模式但不是最后一步算子需要将数据从 inBuff 拷贝到 outBuff 顶头放
     135            0 :         u64 size = sliceInfoVec[tempVirtRankMap_[myRank_]][0].size;
     136            0 :         u64 srcOffset = sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset + buffInfo_.inBuffBaseOff;
     137            0 :         u64 dstOffset = buffInfo_.outBuffBaseOff;
     138            0 :         if (buffInfo_.inBuffType == buffInfo_.outBuffType && srcOffset == dstOffset) {
     139            0 :             HCCL_INFO(
     140              :                 "[InsTempReduceScatterNHR][PostCopy] not forpat and opbse, inBuffType same as outBuffType, skip copy");
     141              :         } else {
     142            0 :             HCCL_INFO("[InsTempReduceScatterNHR][PostCopy] not forpat and opbse, copy from outBuff to userOut");
     143            0 :             DataSlice srcSlice = DataSlice(buffInfo_.inBuffType, srcOffset, size);
     144            0 :             DataSlice dstSlice = DataSlice(buffInfo_.outBuffType, dstOffset, size);
     145            0 :             CHK_RET(LocalCopy(tempInsQues[0], srcSlice, dstSlice));
     146              :         }
     147              :     }
     148            0 :     return HcclResult::HCCL_SUCCESS;
     149              : }
     150              : 
     151            0 : HcclResult InsTempReduceScatterNHR::MultiSliceLocalCopy(
     152              :     InsQuePtr& insQue, const std::vector<DataSlice>& srcList, const std::vector<DataSlice>& dstList) const
     153              : {
     154            0 :     CHK_PRT_RET(
     155              :         srcList.size() != dstList.size(),
     156              :         HCCL_ERROR(
     157              :             "[InsTempReduceScatterNHR] [LocalCopy] Rank [%d], srcList size[%llu] and "
     158              :             "dstList size[%llu] not same.",
     159              :             myRank_, srcList.size(), dstList.size()),
     160              :         HcclResult::HCCL_E_INTERNAL);
     161            0 :     CHK_RET(LocalCopySlices(insQue, srcList, dstList));
     162            0 :     return HcclResult::HCCL_SUCCESS;
     163              : }
     164              : 
     165            0 : HcclResult InsTempReduceScatterNHR::RunReduceScatter(
     166              :     const RankSliceInfo& sliceInfoVec, const ResLinks& tempLinks, std::vector<InsQuePtr>& tempInsQues)
     167              : {
     168            0 :     std::vector<AicpuNHRStepInfo> stepInfoList;
     169            0 :     GetStepInfoList(stepInfoList);
     170            0 :     for (auto& stepInfo : stepInfoList) {
     171            0 :         HCCL_DEBUG(
     172              :             "[InsTempReduceScatterNHR][RunReduceScatter] step[%u], myRank[%u], toRank[%u], fromRank[%u], nSlices[%u].",
     173              :             stepInfo.step, stepInfo.myRank, stepInfo.toRank, stepInfo.fromRank, stepInfo.nSlices);
     174              : 
     175            0 :         const std::vector<LinkData>& linkRecv = tempLinks.at(GetRankFromMap(stepInfo.fromRank));
     176            0 :         const std::vector<LinkData>& linkSend = tempLinks.at(GetRankFromMap(stepInfo.toRank));
     177            0 :         std::vector<DataSlice> txSlices;
     178            0 :         std::vector<DataSlice> rxSlices;
     179              : 
     180              :         // 在 inBuff 上进行 ReduceScatter 操作
     181            0 :         for (u32 i = 0; i < stepInfo.nSlices; i++) {
     182            0 :             u64 txOffset = sliceInfoVec[stepInfo.txSliceIdxs[i]][0].offset + buffInfo_.inBuffBaseOff;
     183            0 :             u64 txSize = sliceInfoVec[stepInfo.txSliceIdxs[i]][0].size;
     184            0 :             u64 rxOffset = sliceInfoVec[stepInfo.rxSliceIdxs[i]][0].offset + buffInfo_.inBuffBaseOff;
     185            0 :             u64 rxSize = sliceInfoVec[stepInfo.rxSliceIdxs[i]][0].size;
     186            0 :             DataSlice txSlice = DataSlice(buffInfo_.inBuffType, txOffset, txSize);
     187            0 :             DataSlice rxSlice = DataSlice(buffInfo_.inBuffType, rxOffset, rxSize);
     188            0 :             txSlices.push_back(txSlice);
     189            0 :             rxSlices.push_back(rxSlice);
     190              :         }
     191              :         SendRecvReduceInfo sendRecvReduceInfo{
     192            0 :             {linkSend[0], linkRecv[0]}, {{txSlices, txSlices}, {rxSlices, rxSlices}}, dataType_, redOp_};
     193            0 :         CHK_PRT_RET(
     194              :             SendRecvReduce(sendRecvReduceInfo, tempInsQues[0], 0, true, dmaMode_),
     195              :             HCCL_ERROR("[InsTempReduceScatterNHR] RunReduceScatter SendRecvReduce failed"),
     196              :             HcclResult::HCCL_E_INTERNAL);
     197            0 :     }
     198            0 :     return HcclResult::HCCL_SUCCESS;
     199            0 : }
     200              : 
     201            0 : HcclResult InsTempReduceScatterNHR::GenExtIns(
     202              :     const TempFuncs& tempFuncs, const TemplateDataParams& tempAlgParams, const ResLinks& tempLinks,
     203              :     std::vector<InsQuePtr>& tempInsQues)
     204              : {
     205            0 :     HCCL_INFO("[InsTempReduceScatterNHR] GenExtIns start");
     206            0 :     if (IsPcieLink(tempLinks)) {
     207            0 :         dmaMode_ = DmaMode::GET;
     208              :     }
     209            0 :     opMode_ = tempFuncs.opMode;
     210            0 :     enableCounterNotify_ = tempFuncs.enableCounterNotify;
     211            0 :     tempAlgParams_ = tempAlgParams;
     212            0 :     tempLinks_ = tempLinks;
     213            0 :     buffInfo_ = tempAlgParams_.buffInfo;
     214              : 
     215            0 :     uint32_t linkNum = tempLinks.begin()->second.size();
     216              :     // 流的数量不能少于linkNum
     217            0 :     CHK_PRT_RET(
     218              :         linkNum > tempInsQues.size(),
     219              :         HCCL_ERROR("[CollAlgFactory] [InsTempAllReduceNHR] Rank [%d], requiredQue Error.", myRank_),
     220              :         HcclResult::HCCL_E_INTERNAL);
     221              : 
     222            0 :     std::vector<float> dataSplitRate(linkNum);
     223            0 :     CHK_RET(CalcDataSplitRateForLinks(tempLinks.begin()->second, dataSplitRate));
     224              :     // 将一个RankSliceInfo,拆分成linkNum 个RankSliceInfo
     225            0 :     u64 typeSize = DataTypeSizeGet(dataType_);
     226            0 :     u64 dataCnt = tempAlgParams.sliceSize / typeSize;
     227            0 :     std::vector<RankSliceInfo> sliceInfoVecForAllLinks(linkNum);
     228            0 :     u64 linkSliceOffset = 0;
     229            0 :     for (u32 linkIdx = 0; linkIdx < linkNum; linkIdx++) {
     230            0 :         processSize_.emplace_back();
     231            0 :         linkSliceOffsetVec_.emplace_back();
     232            0 :         HCCL_INFO("[InsTempAllReduceNHR] linkIdx =%u", linkIdx);
     233            0 :         if (linkIdx != linkNum - 1) {
     234            0 :             processSize_[linkIdx] = static_cast<u64>(static_cast<float>(dataCnt) * dataSplitRate[linkIdx]) * typeSize;
     235              :         } else {
     236            0 :             processSize_[linkIdx] = tempAlgParams.sliceSize - linkSliceOffset;
     237              :         }
     238            0 :         linkSliceOffsetVec_[linkIdx] = linkSliceOffset;
     239            0 :         linkSliceOffset += processSize_[linkIdx];
     240              :     }
     241              : 
     242            0 :     u32 mainQueIdx = 0;
     243              :     // 流间前同步,主流通知从流,只有一个流则不做任何事
     244            0 :     CHK_RET(PreSyncQues(tempInsQues, mainQueIdx));
     245              : 
     246            0 :     for (uint32_t linkIdx = 0; linkIdx < linkNum; linkIdx++) {
     247            0 :         CHK_RET(LocalDataCopy(tempInsQues, tempFuncs, linkIdx));
     248              : 
     249            0 :         if (tempRankSize_ <= 1) {
     250            0 :             CHK_RET(PostLocalCopy(tempInsQues, linkIdx)); // input->scratch
     251            0 :             return HcclResult::HCCL_SUCCESS;
     252              :         }
     253              : 
     254            0 :         CHK_RET(RunNHR(tempInsQues, linkIdx));
     255            0 :         CHK_RET(PostLocalCopy(tempInsQues, linkIdx));
     256              :     }
     257            0 :     CHK_RET(PostSyncQues(tempInsQues, mainQueIdx));
     258            0 :     return HcclResult::HCCL_SUCCESS;
     259            0 : }
     260              : 
     261              : HcclResult
     262            0 : InsTempReduceScatterNHR::LocalDataCopy(std::vector<InsQuePtr>& tempInsQues, const TempFuncs& tempFuncs, u32 linkIdx)
     263              : {
     264            0 :     CHK_PRT_RET(tempInsQues.empty(), HCCL_ERROR("[RS-NHR][LocalDataCopy] empty queue"), HcclResult::HCCL_E_INTERNAL);
     265            0 :     InsQuePtr q = tempInsQues[linkIdx];
     266              :     u64 inBaseOff;
     267              :     u64 inOff;
     268            0 :     const u64 rptNum = std::max<u64>(1, tempAlgParams_.repeatNum);
     269            0 :     for (u32 localRandId = 0; localRandId < tempRankSize_; ++localRandId) {
     270            0 :         for (u64 rpt = 0; rpt < rptNum; ++rpt) {
     271            0 :             if (tempFuncs.isBottom) { // 后nhr 前一半数据
     272            0 :                 inBaseOff = tempAlgParams_.buffInfo.inBuffBaseOff + rpt * tempAlgParams_.inputRepeatStride;
     273            0 :                 inOff = inBaseOff + localRandId * tempAlgParams_.inputSliceStride + linkSliceOffsetVec_[linkIdx];
     274              :             } else { // 前nhr,后一半数据
     275            0 :                 inBaseOff = tempAlgParams_.buffInfo.inBuffBaseOff + localRandId * tempAlgParams_.inputRepeatStride;
     276            0 :                 inOff = inBaseOff + rpt * tempAlgParams_.inputSliceStride + linkSliceOffsetVec_[linkIdx];
     277              :             }
     278            0 :             const u64 scratchBase
     279            0 :                 = tempAlgParams_.buffInfo.scratchBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
     280            0 :             const u64 scOff = scratchBase + localRandId * tempAlgParams_.sliceSize + linkSliceOffsetVec_[linkIdx];
     281              :             // 如果源地址和目标地址相同,则不需要做拷贝
     282            0 :             if (tempAlgParams_.buffInfo.inBuffType != tempAlgParams_.buffInfo.scratBuffType || inOff != scOff) {
     283            0 :                 DataSlice src(tempAlgParams_.buffInfo.inBuffType, inOff, processSize_[linkIdx]);
     284            0 :                 DataSlice dst(tempAlgParams_.buffInfo.scratBuffType, scOff, processSize_[linkIdx]);
     285            0 :                 auto ins = std::make_unique<InsLocalCopy>(src, dst);
     286            0 :                 q->Append(std::move(ins));
     287            0 :             }
     288              :         }
     289              :     }
     290            0 :     return HcclResult::HCCL_SUCCESS;
     291            0 : }
     292              : 
     293            0 : HcclResult InsTempReduceScatterNHR::PostLocalCopy(std::vector<InsQuePtr>& tempInsQues, u32 linkIdx)
     294              : {
     295            0 :     CHK_PRT_RET(tempInsQues.empty(), HCCL_ERROR("[RS-NHR][PostLocalCopy] empty queue"), HcclResult::HCCL_E_INTERNAL);
     296              : 
     297            0 :     const u32 myAlgIdx = tempVirtRankMap_.at(myRank_);
     298            0 :     InsQuePtr q = tempInsQues[linkIdx];
     299              : 
     300            0 :     const u64 rptNum = std::max<u64>(1, tempAlgParams_.repeatNum);
     301            0 :     for (u64 rpt = 0; rpt < rptNum; ++rpt) {
     302            0 :         const u64 outBaseOff = tempAlgParams_.buffInfo.outBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
     303            0 :         const u64 scratchBase = tempAlgParams_.buffInfo.scratchBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
     304              : 
     305            0 :         const u64 scOff = scratchBase + tempAlgParams_.sliceSize * myAlgIdx + linkSliceOffsetVec_[linkIdx];
     306            0 :         const u64 outOff = outBaseOff + linkSliceOffsetVec_[linkIdx];
     307            0 :         DataSlice src(tempAlgParams_.buffInfo.scratBuffType, scOff, processSize_[linkIdx]);
     308            0 :         DataSlice dst(tempAlgParams_.buffInfo.outBuffType, outOff, processSize_[linkIdx]);
     309            0 :         if (tempAlgParams_.buffInfo.scratBuffType != tempAlgParams_.buffInfo.outBuffType || scOff != outOff) {
     310            0 :             auto ins = std::make_unique<InsLocalCopy>(src, dst);
     311            0 :             q->Append(std::move(ins));
     312            0 :         }
     313              :     }
     314            0 :     return HcclResult::HCCL_SUCCESS;
     315            0 : }
     316              : 
     317            0 : HcclResult InsTempReduceScatterNHR::RunNHR(std::vector<InsQuePtr>& tempInsQues, u32 linkIdx)
     318              : {
     319            0 :     CHK_PRT_RET(tempInsQues.empty(), HCCL_ERROR("[RS-NHR][RunNHR] empty queue"), HcclResult::HCCL_E_INTERNAL);
     320              : 
     321            0 :     if (tempRankSize_ <= 1)
     322            0 :         return HcclResult::HCCL_SUCCESS;
     323              : 
     324            0 :     InsQuePtr q = tempInsQues[linkIdx];
     325              : 
     326              :     // 步进参数
     327            0 :     const u64 rptNum = std::max<u64>(1, tempAlgParams_.repeatNum);
     328              : 
     329              :     // 预计算步骤列表(算法序)
     330            0 :     std::vector<AicpuNHRStepInfo> steps;
     331            0 :     CHK_RET(GetStepInfoList(steps));
     332            0 :     for (u32 s = 0; s < steps.size(); ++s) {
     333            0 :         const auto& st = steps[s];
     334              : 
     335            0 :         const RankId recvFromRank = GetRankFromMap(st.fromRank);
     336            0 :         const RankId sendToRank = GetRankFromMap(st.toRank);
     337            0 :         CHK_PRT_RET(
     338              :             recvFromRank == static_cast<RankId>(-1) || sendToRank == static_cast<RankId>(-1),
     339              :             HCCL_ERROR("[RS-NHR][RunNHR] rank map failed: from[%u] to[%u]", st.fromRank, st.toRank),
     340              :             HcclResult::HCCL_E_INTERNAL);
     341              : 
     342            0 :         auto itRecv = tempLinks_.find(recvFromRank);
     343            0 :         auto itSend = tempLinks_.find(sendToRank);
     344            0 :         CHK_PRT_RET(
     345              :             itRecv == tempLinks_.end() || itRecv->second.empty() || itSend == tempLinks_.end()
     346              :                 || itSend->second.empty(),
     347              :             HCCL_ERROR("[RS-NHR][RunNHR] link missing: recvFrom=%d sendTo=%d", recvFromRank, sendToRank),
     348              :             HcclResult::HCCL_E_INTERNAL);
     349              : 
     350            0 :         const LinkData& linkRecv = itRecv->second[linkIdx];
     351            0 :         const LinkData& linkSend = itSend->second[linkIdx];
     352              : 
     353            0 :         std::vector<DataSlice> txSlices;
     354            0 :         std::vector<DataSlice> rxSlices;
     355            0 :         txSlices.reserve(st.nSlices);
     356            0 :         rxSlices.reserve(st.nSlices);
     357            0 :         for (u64 rpt = 0; rpt < rptNum; ++rpt) {
     358            0 :             const u64 scratchBase
     359            0 :                 = tempAlgParams_.buffInfo.scratchBuffBaseOff + rpt * tempAlgParams_.outputRepeatStride;
     360              : 
     361              :             // RS:在 SCRATCH 上进行规约交换
     362            0 :             for (u32 i = 0; i < st.nSlices; ++i) {
     363            0 :                 const u32 txIdx = st.txSliceIdxs[i]; // 算法序
     364            0 :                 const u32 rxIdx = st.rxSliceIdxs[i];
     365            0 :                 const u64 txScOff = scratchBase + tempAlgParams_.sliceSize * txIdx + linkSliceOffsetVec_[linkIdx];
     366            0 :                 const u64 rxScOff = scratchBase + tempAlgParams_.sliceSize * rxIdx + linkSliceOffsetVec_[linkIdx];
     367            0 :                 txSlices.emplace_back(tempAlgParams_.buffInfo.scratBuffType, txScOff, processSize_[linkIdx]);
     368            0 :                 rxSlices.emplace_back(tempAlgParams_.buffInfo.scratBuffType, rxScOff, processSize_[linkIdx]);
     369              :             }
     370              :         }
     371            0 :         SendRecvReduceInfo info{{linkSend, linkRecv}, {{txSlices, txSlices}, {rxSlices, rxSlices}}, dataType_, redOp_};
     372              : 
     373            0 :         CHK_PRT_RET(
     374              :             SendRecvReduce(info, tempInsQues[linkIdx], 0, true, dmaMode_),
     375              :             HCCL_ERROR("[RS-NHR][RunNHR] SendRecvReduce failed (step=%u)", st.step), HcclResult::HCCL_E_INTERNAL);
     376            0 :     }
     377              : 
     378            0 :     return HcclResult::HCCL_SUCCESS;
     379            0 : }
     380              : 
     381              : //  计算每轮收发的对端以及slice编号
     382            0 : HcclResult InsTempReduceScatterNHR::GetStepInfoList(std::vector<AicpuNHRStepInfo>& stepInfoList)
     383              : {
     384              :     // 将本 rank 号转换成算法使用的索引号
     385            0 :     u32 rankIdx = tempVirtRankMap_[myRank_];
     386            0 :     stepInfoList.clear();
     387              : 
     388            0 :     u32 nSteps = GetNHRStepNum(tempRankSize_);
     389            0 :     stepInfoList.resize(nSteps);
     390            0 :     for (u32 step = 0; step < nSteps; step++) {
     391              :         // 计算通信对象
     392            0 :         u32 deltaRank = 1 << step;
     393            0 :         u32 sendTo = (rankIdx + tempRankSize_ - deltaRank) % tempRankSize_;
     394            0 :         u32 recvFrom = (rankIdx + deltaRank) % tempRankSize_;
     395              : 
     396              :         // 数据份数和数据编号增量
     397            0 :         u32 nSlices = (tempRankSize_ - 1 + (1 << step)) / (1 << (step + 1));
     398            0 :         u32 deltaSliceIndex = 1 << (step + 1);
     399            0 :         u32 txSliceIdx = sendTo;
     400            0 :         u32 rxSliceIdx = rankIdx;
     401              : 
     402            0 :         AicpuNHRStepInfo& currStepInfo = stepInfoList[step];
     403            0 :         currStepInfo.step = step;
     404            0 :         currStepInfo.myRank = rankIdx;
     405            0 :         currStepInfo.nSlices = nSlices;
     406            0 :         currStepInfo.toRank = sendTo;
     407            0 :         currStepInfo.fromRank = recvFrom;
     408              : 
     409              :         // 计算本rank在每轮收/发中的slice编号
     410            0 :         currStepInfo.txSliceIdxs.reserve(nSlices);
     411            0 :         currStepInfo.rxSliceIdxs.reserve(nSlices);
     412            0 :         for (u32 i = 0; i < nSlices; i++) {
     413            0 :             currStepInfo.txSliceIdxs.push_back(txSliceIdx);
     414            0 :             currStepInfo.rxSliceIdxs.push_back(rxSliceIdx);
     415            0 :             HCCL_DEBUG(
     416              :                 "[InsTempReduceScatterNHR][GetStepInfoList] i[%u] txSliceIdx[%u] rxSliceIdx[%u]", i, txSliceIdx,
     417              :                 rxSliceIdx);
     418            0 :             txSliceIdx = (txSliceIdx + tempRankSize_ - deltaSliceIndex) % tempRankSize_;
     419            0 :             rxSliceIdx = (rxSliceIdx + tempRankSize_ - deltaSliceIndex) % tempRankSize_;
     420              :         }
     421              :     }
     422            0 :     return HcclResult::HCCL_SUCCESS;
     423              : }
     424              : 
     425            0 : RankId InsTempReduceScatterNHR::GetRankFromMap(const u32 rankIdx)
     426              : {
     427            0 :     HCCL_INFO("[InsTempReduceScatterNHR] GetRankFromMap");
     428            0 :     RankId rank = -1;
     429            0 :     for (auto& pair : tempVirtRankMap_) {
     430            0 :         if (pair.second == rankIdx) {
     431            0 :             rank = pair.first;
     432            0 :             break;
     433              :         }
     434              :     }
     435            0 :     return rank;
     436              : }
     437              : 
     438            0 : HcclResult InsTempReduceScatterNHR::GetScratchBufferInfo(const uint64_t scratchBufferSize, DataType dataType) const
     439              : {
     440              :     (void)scratchBufferSize;
     441              :     (void)dataType;
     442            0 :     return HcclResult::HCCL_SUCCESS;
     443              : }
     444              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1