LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_template/prim_alg_template - temp_all_gather_mesh.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 141 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 14 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              : 
      13              : #include "temp_all_gather_mesh.h"
      14              : 
      15              : namespace Hccl {
      16            0 : TempAllGatherMesh::TempAllGatherMesh(
      17              :     const RankId virtualRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
      18            0 :     const std::map<RankId, u32>& tempVirtRankMap)
      19            0 :     : AlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
      20            0 : {}
      21              : 
      22            0 : TempAllGatherMesh::~TempAllGatherMesh() {}
      23              : 
      24            0 : HcclResult TempAllGatherMesh::CalcRes(AlgTempResReq& tempResReq)
      25              : {
      26            0 :     tempResReq.queNum = tempVTopo_[0].size() - 1;
      27              : 
      28            0 :     CHK_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
      29            0 :     return HcclResult::HCCL_SUCCESS;
      30              : }
      31              : 
      32            0 : HcclResult TempAllGatherMesh::CalcResDetour(const RankGraph* rankGraph, AlgTempResReq& tempResReq)
      33              : {
      34              :     u32 myAlgRank;
      35            0 :     CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
      36              : 
      37            0 :     linkNumBtwPeers_ = GetLinkNum(rankGraph, myRank_, tempVTopo_[0][(myAlgRank + 1) % tempRankSize_]);
      38            0 :     if (linkNumBtwPeers_ == 1) {
      39            0 :         HCCL_INFO(
      40              :             "[CollAlgFactory] [TempAllGatherMesh] [WARNING] Rank [%d], linkNum between rank [%d] and rank [%d] "
      41              :             "equals 1, not able to detour",
      42              :             myRank_, myRank_, tempVTopo_[0][(myAlgRank + 1) % tempRankSize_]);
      43            0 :         enableDetour_ = false;
      44              :     } else {
      45            0 :         enableDetour_ = true;
      46              :     }
      47              : 
      48            0 :     queNumPerNeighbor_ = (linkNumBtwPeers_ + 1) >> 1;
      49            0 :     tempResReq.queNum = (tempVTopo_[0].size() - 1) * queNumPerNeighbor_;
      50              : 
      51            0 :     CHK_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
      52            0 :     return HcclResult::HCCL_SUCCESS;
      53              : }
      54              : 
      55            0 : HcclResult TempAllGatherMesh::CalcResDetour(ConnectedLinkMgr* linkMgr, AlgTempResReq& tempResReq)
      56              : {
      57              :     u32 myAlgRank;
      58            0 :     CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
      59              : 
      60            0 :     linkNumBtwPeers_ = (linkMgr->GetLinks(tempVTopo_[0][(myAlgRank + 1) % tempRankSize_])).size();
      61              : 
      62            0 :     enableDetour_ = (linkNumBtwPeers_ == 1) ? false : true;
      63              : 
      64            0 :     queNumPerNeighbor_ = (linkNumBtwPeers_ + 1) >> 1;
      65            0 :     tempResReq.queNum = (tempVTopo_[0].size() - 1) * queNumPerNeighbor_;
      66              : 
      67            0 :     CHK_RET(CalcResLinksMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
      68            0 :     return HcclResult::HCCL_SUCCESS;
      69              : }
      70              : 
      71              : /*
      72              : dataSize / (rankSize) --> chunkSize
      73              : dataSize / (rankSize * dimNum) --> sliceSize
      74              : 
      75              : SliceInfoVecforConcurrMesh: [1st chunk: [1st Slice, 2nd Slice], 2nd chunk: [1st Slice, 2nd Slice], ...]
      76              : */
      77              : HcclResult
      78            0 : TempAllGatherMesh::CalcSliceInfo(const AllignInfo& allignInfo, const u64 dataSize, RankSliceInfo& sliceInfoVec)
      79              : {
      80            0 :     std::vector<SliceInfo> tmp(1);
      81            0 :     sliceInfoVec.resize(tempRankSize_, tmp);
      82              : 
      83            0 :     CHK_RET(CalcRsAgSliceInfoMesh(myRank_, tempRankSize_, allignInfo, dataSize, sliceInfoVec));
      84              : 
      85            0 :     return HcclResult::HCCL_SUCCESS;
      86            0 : }
      87              : 
      88            0 : HcclResult TempAllGatherMesh::GenPrimQue(
      89              :     const TempFuncs& tempFuncs, const RankSliceInfo& sliceInfoVec, const BuffInfo& buffInfo, const ResLinks& tempLinks,
      90              :     std::vector<PrimQuePtr>& tempPrimQues)
      91              : {
      92            0 :     opMode_ = tempFuncs.opMode;
      93            0 :     enableCounterNotify_ = tempFuncs.enableCounterNotify;
      94            0 :     buffInfo_ = buffInfo;
      95              : 
      96            0 :     auto linkIter = tempLinks.begin();
      97            0 :     linkNumBtwPeers_ = linkIter->second.size();
      98            0 :     HCCL_INFO(
      99              :         "[CollAlgFactory] [TempAllGatherMesh] Rank [%d], linkNumBtwPeers equals to [%u].", myRank_, linkNumBtwPeers_);
     100            0 :     queNumPerNeighbor_ = (linkNumBtwPeers_ + 1) >> 1;
     101            0 :     HCCL_INFO(
     102              :         "[CollAlgFactory] [TempAllGatherMesh] Rank [%d], queNumPerNeighbor equals to [%u].", myRank_,
     103              :         queNumPerNeighbor_);
     104            0 :     enableDetour_ = (linkNumBtwPeers_ == 1) ? false : true;
     105              : 
     106            0 :     majorQueNum_ = tempVTopo_[0].size() - 1;
     107            0 :     CHK_PRT_RET(
     108              :         majorQueNum_ * queNumPerNeighbor_ != tempPrimQues.size(),
     109              :         HCCL_ERROR(
     110              :             "[CollAlgFactory] [TempAllGatherMesh] Rank [%d], requiredQueNum [%u] not equals to templateQueNum [%u].",
     111              :             myRank_, majorQueNum_ * queNumPerNeighbor_, tempPrimQues.size()),
     112              :         HcclResult::HCCL_E_INTERNAL);
     113              : 
     114              :     // queue arrangement
     115            0 :     std::vector<PrimQuePtr> mainPrimQues;
     116            0 :     for (u32 queIdx = 0; queIdx < majorQueNum_; queIdx++) {
     117            0 :         mainPrimQues.push_back(tempPrimQues[queIdx * queNumPerNeighbor_]);
     118              :     }
     119              : 
     120              :     // Local Copy from Input to Scratch Buffer for OPBASE
     121            0 :     if ((opMode_ == OpMode::OPBASE) && tempFuncs.isForepart && !tempFuncs.forAllReduce) {
     122            0 :         CHK_RET(PreCopyOpbase(tempFuncs.usrData, mainPrimQues));
     123              :     }
     124              : 
     125              :     // Local Copy from Input to Output Buffer for OFFLOAD
     126            0 :     if ((opMode_ == OpMode::OFFLOAD) && (!tempFuncs.forAlgSeqComb)) {
     127            0 :         CHK_RET(PreCopyOffload(sliceInfoVec, tempFuncs.forAllReduce, mainPrimQues));
     128              :     }
     129              : 
     130              :     // semaphore sync
     131            0 :     if (majorQueNum_ > 1) {
     132            0 :         CHK_RET(PreSyncInterQueues(mainPrimQues));
     133              :     }
     134              : 
     135              :     // locate myRank in tempVTopo -> algRank
     136              :     u32 myAlgRank;
     137            0 :     CHK_RET(GetAlgRank(myRank_, tempVTopo_[0], myAlgRank));
     138              : 
     139              :     // run Mesh
     140            0 :     CHK_PRT_RET(
     141              :         RunMesh(myAlgRank, tempVTopo_[0], sliceInfoVec, tempLinks, tempPrimQues) != HcclResult::HCCL_SUCCESS,
     142              :         HCCL_ERROR("[CollAlgFactory] [TempAllGatherMesh] Rank [%d], unable to run the mesh algorithm.", myRank_),
     143              :         HcclResult::HCCL_E_INTERNAL);
     144              : 
     145              :     // semaphore sync
     146            0 :     if (majorQueNum_ > 1) {
     147            0 :         CHK_RET(PostSyncInterQueues(mainPrimQues));
     148              :     }
     149              : 
     150              :     // LocalCopy: from scratch to output for opbase
     151            0 :     if ((opMode_ == OpMode::OPBASE) && tempFuncs.isBottom) {
     152            0 :         CHK_RET(PostCopyOpbase(tempFuncs.usrData, mainPrimQues));
     153              :     }
     154              : 
     155            0 :     return HcclResult::HCCL_SUCCESS;
     156            0 : }
     157              : 
     158            0 : HcclResult TempAllGatherMesh::RunMesh(
     159              :     const u32 myAlgRank, const std::vector<RankId>& vTopo, const RankSliceInfo& sliceInfoVec, const ResLinks& tempLinks,
     160              :     std::vector<PrimQuePtr>& tempPrimQues)
     161              : {
     162            0 :     for (u32 queIdx = 0; queIdx < vTopo.size() - 1; queIdx++) {
     163              :         // find neighbors -> virtualRank
     164            0 :         RankId neighborRank = vTopo[(myAlgRank + 1 + queIdx) % tempRankSize_];
     165              : 
     166            0 :         u32 recvChunkIdx = tempVirtRankMap_[neighborRank];
     167            0 :         u32 sendChunkIdx = tempVirtRankMap_[myRank_];
     168              : 
     169              :         // queue assignment
     170            0 :         if (enableDetour_) {
     171            0 :             std::vector<PrimQuePtr> detourPrimQues;
     172            0 :             for (u32 detourIdx = 0; detourIdx < queNumPerNeighbor_; detourIdx++) {
     173            0 :                 detourPrimQues.push_back(tempPrimQues[queIdx * queNumPerNeighbor_ + detourIdx]);
     174              :             }
     175              : 
     176            0 :             CHK_RET(RunIndividualPeerDetour(
     177              :                 neighborRank, sliceInfoVec[sendChunkIdx][0], sliceInfoVec[recvChunkIdx][0], tempLinks, detourPrimQues));
     178            0 :         } else {
     179            0 :             PrimQuePtr currQue = tempPrimQues[queIdx];
     180            0 :             LinkData neighborLinkData = tempLinks.at(neighborRank)[0];
     181            0 :             CHK_RET(RunIndividualPeer(
     182              :                 neighborRank, neighborLinkData, sliceInfoVec[sendChunkIdx][0], sliceInfoVec[recvChunkIdx][0], currQue));
     183            0 :         }
     184              :     }
     185              : 
     186            0 :     return HcclResult::HCCL_SUCCESS;
     187              : }
     188              : 
     189            0 : HcclResult TempAllGatherMesh::RunIndividualPeerDetour(
     190              :     const RankId neighborRank, const SliceInfo& sendSlice, const SliceInfo& recvSlice, const ResLinks& tempLinks,
     191              :     std::vector<PrimQuePtr>& detourPrimQues)
     192              : {
     193            0 :     CHK_RET(PreSyncInterQueues(detourPrimQues));
     194              : 
     195            0 :     u32 dataSizePerVolume = DataTypeSizeGet(dataType_);
     196            0 :     u64 unitRecvSize = RoundUp(recvSlice.size, queNumPerNeighbor_ * dataSizePerVolume) * dataSizePerVolume;
     197            0 :     u64 resRecvSize = recvSlice.size;
     198            0 :     u64 currRecvOff = recvSlice.offset + buffInfo_.outBuffBaseOff;
     199              : 
     200            0 :     u64 unitSendSize = RoundUp(sendSlice.size, queNumPerNeighbor_ * dataSizePerVolume) * dataSizePerVolume;
     201            0 :     u64 resSendSize = sendSlice.size;
     202            0 :     u64 currSendOff = sendSlice.offset + buffInfo_.outBuffBaseOff;
     203              : 
     204            0 :     std::vector<std::vector<LinkDataIterator>> sendRecvLinks;
     205            0 :     CHK_RET(GetSendRecvLinks(neighborRank, tempLinks, sendRecvLinks));
     206              : 
     207            0 :     for (u32 detourIdx = 0; detourIdx < queNumPerNeighbor_; detourIdx++) {
     208            0 :         u64 currRecvSize = resRecvSize > unitRecvSize ? unitRecvSize : resRecvSize;
     209            0 :         u64 currSendSize = resSendSize > unitSendSize ? unitSendSize : resSendSize;
     210            0 :         SliceInfo currSendSlice = {currSendOff, currSendSize};
     211            0 :         SliceInfo currRecvSlice = {currRecvOff, currRecvSize};
     212              : 
     213              :         std::unique_ptr<PrimGroup> primGroup = RunSendRecv(
     214            0 :             neighborRank, (*sendRecvLinks[detourIdx][0]), (*sendRecvLinks[detourIdx][1]), currSendSlice, currRecvSlice);
     215              : 
     216            0 :         detourPrimQues[detourIdx]->Append(std::move(primGroup));
     217              : 
     218            0 :         resRecvSize -= currRecvSize;
     219            0 :         resSendSize -= currSendSize;
     220            0 :         currRecvOff += currRecvSize;
     221            0 :         currSendOff += currSendSize;
     222            0 :     }
     223              : 
     224            0 :     CHK_RET(PostSyncInterQueues(detourPrimQues));
     225            0 :     return HcclResult::HCCL_SUCCESS;
     226            0 : }
     227              : 
     228            0 : HcclResult TempAllGatherMesh::GetSendRecvLinks(
     229              :     const RankId neighborRank, const ResLinks& tempLinks,
     230              :     std::vector<std::vector<LinkDataIterator>>& sendRecvLinks) const
     231              : {
     232            0 :     CHK_PRT_RET(
     233              :         ((queNumPerNeighbor_ != NUM_TWO) || (tempRankSize_ != NUM_TWO)),
     234              :         HCCL_ERROR(
     235              :             "[CollAlgFactory] [TempAllGatherMesh] Rank [%d], detouring is supported only in 2P Mesh in 4P topo.",
     236              :             myRank_),
     237              :         HcclResult::HCCL_E_INTERNAL);
     238              : 
     239            0 :     std::vector<LinkDataIterator> tmpLinks(NUM_TWO);
     240            0 :     sendRecvLinks.resize(queNumPerNeighbor_, tmpLinks);
     241              : 
     242            0 :     CHK_PRT_RET(
     243              :         GetDetourSendRecvLinksIn4P(myRank_, neighborRank, tempLinks, sendRecvLinks),
     244              :         HCCL_ERROR(
     245              :             "[InsCollAlgFactory] [TempAllGatherMesh] Rank [%d], get send recv links in 2P Mesh in 4P topo.", myRank_),
     246              :         HcclResult::HCCL_E_INTERNAL);
     247            0 :     return HcclResult::HCCL_SUCCESS;
     248            0 : }
     249              : 
     250            0 : HcclResult TempAllGatherMesh::RunIndividualPeer(
     251              :     const RankId neighborRank, const LinkData& neighborLinkData, const SliceInfo& sendSlice, const SliceInfo& recvSlice,
     252              :     PrimQuePtr currQue)
     253              : {
     254            0 :     SliceInfo currSendSlice = {sendSlice.offset + buffInfo_.outBuffBaseOff, sendSlice.size};
     255            0 :     SliceInfo currRecvSlice = {recvSlice.offset + buffInfo_.outBuffBaseOff, recvSlice.size};
     256              : 
     257              :     std::unique_ptr<PrimGroup> primGroup
     258            0 :         = RunSendRecv(neighborRank, neighborLinkData, neighborLinkData, currSendSlice, currRecvSlice);
     259            0 :     currQue->Append(std::move(primGroup));
     260            0 :     return HcclResult::HCCL_SUCCESS;
     261            0 : }
     262              : 
     263            0 : std::unique_ptr<PrimGroup> TempAllGatherMesh::RunSendRecv(
     264              :     const RankId neighborRank, const LinkData& sendLinkData, const LinkData& recvLinkData,
     265              :     const SliceInfo& currSendSlice, const SliceInfo& currRecvSlice) const
     266              : {
     267              :     // PrimGroup
     268            0 :     std::unique_ptr<PrimGroup> primGroup = std::make_unique<PrimGroup>();
     269              : 
     270              :     // Recv
     271            0 :     DataSlice recvRemSlice = DataSlice(buffInfo_.outBuffType, currRecvSlice.offset, currRecvSlice.size);
     272            0 :     DataSlice recvLocSlice = DataSlice(buffInfo_.outBuffType, currRecvSlice.offset, currRecvSlice.size);
     273              :     std::unique_ptr<Primitive> primRecv
     274            0 :         = std::make_unique<PrimRecv>(neighborRank, recvLinkData, recvLocSlice, recvRemSlice, dmaMode_);
     275              : 
     276            0 :     primGroup->Append(std::move(primRecv));
     277              : 
     278              :     // Send
     279            0 :     DataSlice sendLocSlice = DataSlice(buffInfo_.outBuffType, currSendSlice.offset, currSendSlice.size);
     280            0 :     DataSlice sendRemSlice = DataSlice(buffInfo_.outBuffType, currSendSlice.offset, currSendSlice.size);
     281              :     std::unique_ptr<Primitive> primSend
     282            0 :         = std::make_unique<PrimSend>(neighborRank, sendLinkData, sendLocSlice, sendRemSlice, dmaMode_);
     283              : 
     284            0 :     primGroup->Append(std::move(primSend));
     285              : 
     286            0 :     return primGroup;
     287            0 : }
     288              : 
     289            0 : HcclResult TempAllGatherMesh::PreCopyOffload(
     290              :     const RankSliceInfo& sliceInfoVec, const bool forAllReduce, std::vector<PrimQuePtr>& tempPrimQues)
     291              : {
     292            0 :     u64 srcOffset = forAllReduce ? sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset : 0;
     293            0 :     u64 srcSize = sliceInfoVec[tempVirtRankMap_[myRank_]][0].size;
     294            0 :     u64 dstOffset = sliceInfoVec[tempVirtRankMap_[myRank_]][0].offset;
     295            0 :     DataSlice srcSlice = DataSlice(buffInfo_.inBuffType, srcOffset + buffInfo_.inBuffBaseOff, srcSize);
     296            0 :     DataSlice dstSlice = DataSlice(buffInfo_.outBuffType, dstOffset + buffInfo_.outBuffBaseOff, srcSize);
     297            0 :     std::unique_ptr<Primitive> primLocalCopy = std::make_unique<PrimLocalCopy>(srcSlice, dstSlice);
     298            0 :     tempPrimQues[0]->Append(std::move(primLocalCopy));
     299              : 
     300            0 :     return HcclResult::HCCL_SUCCESS;
     301            0 : }
     302              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1