LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_executor/ins_alg_executor/send_recv - ins_batchSendRecv_executor.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 359 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 29 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 "ins_coll_alg_registry.h"
      14              : #include "ins_batchSendRecv_executor.h"
      15              : #include "alg_data_trans_wrapper.h"
      16              : 
      17              : using namespace std;
      18              : 
      19              : namespace Hccl {
      20              : 
      21              : template <typename AlgTopoMatch>
      22            0 : InsBatchSendRecvExecutor<AlgTopoMatch>::InsBatchSendRecvExecutor() : InsCollAlgBase()
      23            0 : {}
      24              : 
      25              : template <typename AlgTopoMatch>
      26            0 : InsBatchSendRecvExecutor<AlgTopoMatch>::~InsBatchSendRecvExecutor()
      27            0 : {}
      28              : 
      29              : template <typename AlgTopoMatch>
      30            0 : void InsBatchSendRecvExecutor<AlgTopoMatch>::SetRmaDataBufferMgr(const RmtDataBufferMgr* rmaDataBufferMgr)
      31              : {
      32            0 :     rmaDataBufferMgr_ = const_cast<RmtDataBufferMgr*>(rmaDataBufferMgr);
      33            0 :     return;
      34              : }
      35              : 
      36              : template <typename AlgTopoMatch>
      37            0 : void InsBatchSendRecvExecutor<AlgTopoMatch>::SetOp(const CollAlgOperator& op)
      38              : {
      39            0 :     op_ = op;
      40            0 :     HcclSendRecvItem* itemPtr = reinterpret_cast<HcclSendRecvItem*>(op.batchSendRecvDataDes.sendRecvItemsPtr);
      41            0 :     u32 itemNum = op.batchSendRecvDataDes.itemNum;
      42            0 :     if (itemPtr == nullptr) {
      43            0 :         THROW<NullPtrException>(StringFormat("itemPtr is null!"));
      44              :     }
      45            0 :     commTargetUserRankSet_.clear();
      46            0 :     for (u32 i = 0; i < itemNum; i++) {
      47            0 :         commTargetUserRankSet_.insert((itemPtr + i)->remoteRank);
      48            0 :         HCCL_DEBUG(
      49              :             "[InsBatchSendRecvExecutor][ParseParam] insert remoteUserRank[%u] to Set ", (itemPtr + i)->remoteRank);
      50              :     }
      51            0 :     HCCL_DEBUG("[SetOp]commTargetUserRankSet_ size[%zu]", commTargetUserRankSet_.size());
      52            0 : }
      53              : 
      54              : template <typename AlgTopoMatch>
      55            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::InitParams(const CollAlgOperator& op, const CollAlgParams& params)
      56              : {
      57            0 :     opMode_ = params.opMode;
      58            0 :     maxTmpMemSize_ = params.maxTmpMemSize;
      59            0 :     CHK_PRT_RET(
      60              :         (maxTmpMemSize_ == 0), HCCL_ERROR("[InitParams] maxTmpMemSize equals to zero for OPBASE."),
      61              :         HcclResult::HCCL_E_PARA);
      62            0 :     HcclSendRecvItem* itemPtr = reinterpret_cast<HcclSendRecvItem*>(op.batchSendRecvDataDes.sendRecvItemsPtr);
      63            0 :     u32 itemNum = op.batchSendRecvDataDes.itemNum;
      64            0 :     CHK_PTR_NULL(itemPtr);
      65            0 :     commTargetUserRankSet_.clear();
      66            0 :     for (u32 i = 0; i < itemNum; i++) {
      67            0 :         commTargetUserRankSet_.insert((itemPtr + i)->remoteRank);
      68            0 :         HCCL_DEBUG(
      69              :             "[InsBatchSendRecvExecutor][ParseParam] insert remoteUserRank[%u] to Set ", (itemPtr + i)->remoteRank);
      70              :     }
      71            0 :     HCCL_DEBUG("[InitParams]commTargetUserRankSet_ size[%zu]", commTargetUserRankSet_.size());
      72            0 :     return HcclResult::HCCL_SUCCESS;
      73              : }
      74              : 
      75              : template <typename AlgTopoMatch>
      76            0 : bool InsBatchSendRecvExecutor<AlgTopoMatch>::SortSendItems(HcclSendRecvItem* a, HcclSendRecvItem* b) const
      77              : {
      78            0 :     u32 aFlag = (a->remoteRank <= static_cast<uint32_t>(myRank_)) ? (a->remoteRank + rankSize_) : a->remoteRank;
      79            0 :     u32 bFlag = (b->remoteRank <= static_cast<uint32_t>(myRank_)) ? (b->remoteRank + rankSize_) : b->remoteRank;
      80            0 :     if (aFlag > bFlag) {
      81            0 :         return true;
      82            0 :     } else if (aFlag < bFlag) {
      83            0 :         return false;
      84              :     }
      85            0 :     return a->count > b->count;
      86              : }
      87              : 
      88              : template <typename AlgTopoMatch>
      89            0 : bool InsBatchSendRecvExecutor<AlgTopoMatch>::SortRecvItems(HcclSendRecvItem* a, HcclSendRecvItem* b) const
      90              : {
      91            0 :     u32 aFlag = (a->remoteRank < static_cast<uint32_t>(myRank_)) ? (a->remoteRank + rankSize_) : a->remoteRank;
      92            0 :     u32 bFlag = (b->remoteRank < static_cast<uint32_t>(myRank_)) ? (b->remoteRank + rankSize_) : b->remoteRank;
      93            0 :     if (aFlag > bFlag) {
      94            0 :         return false;
      95            0 :     } else if (aFlag < bFlag) {
      96            0 :         return true;
      97              :     }
      98            0 :     return a->count > b->count;
      99              : }
     100              : 
     101              : template <typename AlgTopoMatch>
     102            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::GetPairWiseList(HcclSendRecvItem* sendRecvInfo, u32 itemNum)
     103              : {
     104            0 :     HCCL_INFO("[InsBatchSendRecvExecutor][GetPairWiseList] Start sort the batchSendRecv tasklist.");
     105            0 :     CHK_PTR_NULL(sendRecvInfo);
     106              : 
     107            0 :     for (u32 i = 0; i < itemNum; i++) {
     108            0 :         HCCL_INFO(
     109              :             "[InsBatchSendRecvExecutor][GetPairWiseList] index is %u, itemNum is %u,"
     110              :             "localRankID is %d, remoteRank is %u, sendRecvType is %u, rankSize is %u.",
     111              :             i, itemNum, myRank_, sendRecvInfo->remoteRank, static_cast<u32>(sendRecvInfo->sendRecvType), rankSize_);
     112            0 :         CHK_PTR_NULL(sendRecvInfo->buf);
     113              : 
     114            0 :         if (sendRecvInfo->sendRecvType == HcclSendRecvType::HCCL_SEND) {
     115            0 :             sendDeque_.push_back(sendRecvInfo);
     116            0 :         } else if (sendRecvInfo->sendRecvType == HcclSendRecvType::HCCL_RECV) {
     117            0 :             recvDeque_.push_back(sendRecvInfo);
     118              :         } else {
     119            0 :             HCCL_ERROR(
     120              :                 "[InsBatchSendRecvExecutor][GetPairWiseList] sendRecvType wrong sendrecvType is %d, "
     121              :                 "rankID is %d, remoteRank is %u.",
     122              :                 sendRecvInfo->sendRecvType, myRank_, sendRecvInfo->remoteRank);
     123            0 :             return HcclResult::HCCL_E_PARA;
     124              :         }
     125            0 :         sendRecvInfo++;
     126              :     }
     127              : 
     128              :     /* 此处的排序逻辑(pair-wise算法):
     129              :         1.sendDeque元素顺序是:先放remoteRank号小于等于root rank的第一个任务,依次减小(循环索引)直至放完
     130              :         2.recvDeque元素顺序是:先放remoteRank号大于等于root rank的第一个任务,依次增大(循环索引)直至放完
     131              :         如果有rank间重复send/recv场景,按照收发数据从大到小排序
     132              :     */
     133            0 :     auto sendCompare = [this](HcclSendRecvItem* a, HcclSendRecvItem* b) {
     134            0 :         return this->SortSendItems(a, b);
     135              :     };
     136              : 
     137            0 :     auto recvCompare = [this](HcclSendRecvItem* a, HcclSendRecvItem* b) {
     138            0 :         return this->SortRecvItems(a, b);
     139              :     };
     140              : 
     141            0 :     std::stable_sort(sendDeque_.begin(), sendDeque_.end(), sendCompare);
     142            0 :     std::stable_sort(recvDeque_.begin(), recvDeque_.end(), recvCompare);
     143              : 
     144              :     // 筛选自收发任务
     145            0 :     while ((!sendDeque_.empty() && sendDeque_.front()->remoteRank == static_cast<uint32_t>(myRank_))
     146            0 :            && (!recvDeque_.empty() && recvDeque_.front()->remoteRank == static_cast<uint32_t>(myRank_))) {
     147            0 :         sendToSelfDeque_.push_back(sendDeque_.front());
     148            0 :         recvFromSelfDeque_.push_back(recvDeque_.front());
     149            0 :         sendDeque_.pop_front();
     150            0 :         recvDeque_.pop_front();
     151              :     }
     152              :     // 自收发任务按照收发长度大小排序
     153            0 :     auto selfDequeCompare = [this](HcclSendRecvItem* a, HcclSendRecvItem* b) {
     154            0 :         return a->count > b->count;
     155              :     };
     156              : 
     157            0 :     std::stable_sort(sendToSelfDeque_.begin(), sendToSelfDeque_.end(), selfDequeCompare);
     158            0 :     std::stable_sort(recvFromSelfDeque_.begin(), recvFromSelfDeque_.end(), selfDequeCompare);
     159              : 
     160              :     // 如果自发自收任务没有完全匹配
     161            0 :     if ((!sendDeque_.empty() && sendDeque_.front()->remoteRank == static_cast<uint32_t>(myRank_))
     162            0 :         || (!recvDeque_.empty() && recvDeque_.front()->remoteRank == static_cast<uint32_t>(myRank_))) {
     163            0 :         HCCL_ERROR("[CollBatchSendRecvExecutor] SendTask and Recv Task to rank itself do not match,"
     164              :                    "please check the task list.");
     165            0 :         return HcclResult::HCCL_E_PARA;
     166              :     }
     167            0 :     HCCL_INFO("[CollBatchSendRecvExecutor][GetPairWiseList] End sort the batchSendRecv tasklist.");
     168            0 :     return HcclResult::HCCL_SUCCESS;
     169              : }
     170              : 
     171              : template <typename AlgTopoMatch>
     172            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::ProcessSelfSendRecvTasks(InsQuePtr& queue)
     173              : {
     174            0 :     while (!sendToSelfDeque_.empty() && !recvFromSelfDeque_.empty()) {
     175            0 :         if (sendToSelfDeque_.front()->count == recvFromSelfDeque_.front()->count
     176            0 :             && sendToSelfDeque_.front()->dataType == recvFromSelfDeque_.front()->dataType) {
     177            0 :             HcclDataType hccldataTypeSelf = sendToSelfDeque_.front()->dataType;
     178            0 :             DataType dataTypeSelf = HcclDataTypeToDataType(hccldataTypeSelf);
     179            0 :             u64 dataSize = sendToSelfDeque_.front()->count * DataTypeSizeGet(dataTypeSelf);
     180              : 
     181              :             // 搬运本卡到本卡的数据 使用扩展InsLocalCopyExtend接口
     182            0 :             DataBuffer inputBuffer(reinterpret_cast<uintptr_t>(sendToSelfDeque_.front()->buf), dataSize);
     183            0 :             DataBuffer outputBuffer(reinterpret_cast<uintptr_t>(recvFromSelfDeque_.front()->buf), dataSize);
     184            0 :             HCCL_DEBUG(
     185              :                 "inputBuffer[%llu], outputBuffer[%llu], dataSize[%llu]", inputBuffer.GetAddr(), outputBuffer.GetAddr(),
     186              :                 dataSize);
     187            0 :             queue->Append(std::make_unique<InsLocalCopyExtend>(inputBuffer, outputBuffer)); // localcopy
     188              : 
     189            0 :             sendToSelfDeque_.pop_front();
     190            0 :             recvFromSelfDeque_.pop_front();
     191            0 :         } else {
     192            0 :             HCCL_ERROR("[HcclBatchSendRecv] Send task and recv task to self : count or dataType do not equal, please"
     193              :                        "check the task list.");
     194            0 :             return HCCL_E_PARA;
     195              :         }
     196              :     }
     197            0 :     return HcclResult::HCCL_SUCCESS;
     198              : }
     199              : 
     200              : template <typename AlgTopoMatch>
     201            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::ProcessSendRecv(
     202              :     const CollAlgOperator& op, InsQuePtr& queue, u32 remoteRank, std::vector<SendRecvSlice>& sendRemoteSlices,
     203              :     std::vector<SendRecvSlice>& recvRemoteSlices, LinkData& link) const
     204              : {
     205            0 :     HCCL_INFO("[InsBatchSendRecvExecutor][ProcessSendRecv] Start to with rank[%u].", remoteRank);
     206            0 :     u32 maxSendRecvStep = std::max(sendRemoteSlices.size(), recvRemoteSlices.size());
     207            0 :     HCCL_DEBUG("[InsBatchSendRecvExecutor][ProcessSendRecv] maxSendRecvStep[%u].", maxSendRecvStep);
     208              : 
     209            0 :     CHK_PTR_NULL(op.scratchMem);
     210            0 :     uint64_t scratchBufferAddr = op.scratchMem->GetAddr();
     211              : 
     212              :     // 当前是write的逻辑,整理一套read的逻辑出来
     213            0 :     if (dmaMode_ == DmaMode::GET) {
     214            0 :         for (u32 step = 0; step < maxSendRecvStep; step++) {
     215            0 :             if (step < sendRemoteSlices.size()) {
     216              :                 // 先做localCopy local copy: usrin->cclin
     217            0 :                 DataBuffer inputBuffer(sendRemoteSlices[step].addr_, sendRemoteSlices[step].size_);
     218            0 :                 DataBuffer inScratchSlice(
     219            0 :                     scratchBufferAddr + (remoteRank % rankSize_) * maxRoundTransferSize_, sendRemoteSlices[step].size_);
     220            0 :                 HCCL_DEBUG(
     221              :                     "scratchBufferAddr[%llu], offset[%llu], dataSize[%llu]", scratchBufferAddr,
     222              :                     (remoteRank % rankSize_) * maxRoundTransferSize_, sendRemoteSlices[step].size_);
     223              : 
     224            0 :                 queue->Append(std::make_unique<InsLocalCopyExtend>(
     225              :                     inputBuffer, inScratchSlice)); // 这里还没做DMA消减,可以到时看下性能再优化
     226              :                 // 然后通知对端来读
     227            0 :                 queue->Append(std::make_unique<InsPostReady>(static_cast<RankId>(remoteRank), link));
     228            0 :             }
     229              : 
     230            0 :             if (step < recvRemoteSlices.size()) {
     231            0 :                 CHK_RET(ProcessRecvDataSlice(queue, recvRemoteSlices[step], remoteRank, scratchBufferAddr, link));
     232              :             }
     233              : 
     234            0 :             if (step < sendRemoteSlices.size()) {
     235            0 :                 queue->Append(std::make_unique<InsWaitFin>(static_cast<RankId>(remoteRank), link));
     236              :             }
     237              :         }
     238              : 
     239            0 :         return HcclResult::HCCL_SUCCESS;
     240              :     }
     241              : 
     242            0 :     for (u32 step = 0; step < maxSendRecvStep; step++) {
     243            0 :         if (step < recvRemoteSlices.size()) {
     244              :             // tell sendRank ready to write
     245            0 :             queue->Append(std::make_unique<InsPostReady>(static_cast<RankId>(remoteRank), link));
     246              :         }
     247            0 :         if (step < sendRemoteSlices.size()) {
     248            0 :             CHK_RET(ProcessSendDataSlice(queue, sendRemoteSlices[step], remoteRank, scratchBufferAddr, link));
     249              :         }
     250            0 :         if (step < recvRemoteSlices.size()) {
     251              :             // wait sendRank write done
     252            0 :             queue->Append(std::make_unique<InsWaitFin>(static_cast<RankId>(remoteRank), link));
     253              :             // local copy
     254            0 :             CHK_RET(CopyRecvDataSliceToUsrOut(queue, recvRemoteSlices[step], remoteRank, scratchBufferAddr));
     255              :         }
     256              :     }
     257            0 :     return HcclResult::HCCL_SUCCESS;
     258              : }
     259              : 
     260              : template <typename AlgTopoMatch>
     261            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::RunLoopSendRecv(
     262              :     const CollAlgOperator& op, std::vector<InsQuePtr>& queues, InsTempAllGatherMesh1D& tempAlg)
     263              : {
     264              :     // pre sync
     265            0 :     CHK_RET(tempAlg.PreSyncInterQueues(queues));
     266              : 
     267              :     // sendrecv options
     268            0 :     u32 queIdx = 1;
     269            0 :     for (const u32& remoteRank : commTargetUserRankSet_) {
     270            0 :         HCCL_INFO("[InsBatchSendRecvExecutor][RunLoopSendRecv] remoteRank[%u].", remoteRank);
     271            0 :         if (remoteRank == static_cast<uint32_t>(myRank_)) {
     272            0 :             continue;
     273              :         }
     274            0 :         if (queIdx >= queues.size()) {
     275            0 :             HCCL_ERROR(
     276              :                 "[InsBatchSendRecvExecutor][RunLoopSendRecv] queIdx[%u] is bigger than queues size[%u].", queIdx,
     277              :                 queues.size());
     278            0 :             return HCCL_E_PARA;
     279              :         }
     280            0 :         auto sendIt = SendSliceMapByRemoteRank_.find(remoteRank);
     281            0 :         auto recvIt = RecvSliceMapByRemoteRank_.find(remoteRank);
     282            0 :         if (sendIt == SendSliceMapByRemoteRank_.end() && recvIt == RecvSliceMapByRemoteRank_.end()) {
     283            0 :             continue;
     284              :         }
     285            0 :         LinkData link = tempResLinks_.at(remoteRank)[0];
     286            0 :         if (sendIt != SendSliceMapByRemoteRank_.end() && recvIt != RecvSliceMapByRemoteRank_.end()) {
     287            0 :             CHK_RET(ProcessSendRecv(
     288              :                 op, queues[queIdx], remoteRank, SendSliceMapByRemoteRank_[remoteRank],
     289              :                 RecvSliceMapByRemoteRank_[remoteRank], link));
     290            0 :         } else if (sendIt != SendSliceMapByRemoteRank_.end()) {
     291            0 :             std::vector<SendRecvSlice> empty;
     292            0 :             CHK_RET(
     293              :                 ProcessSendRecv(op, queues[queIdx], remoteRank, SendSliceMapByRemoteRank_[remoteRank], empty, link));
     294            0 :         } else if (recvIt != RecvSliceMapByRemoteRank_.end()) {
     295            0 :             std::vector<SendRecvSlice> empty;
     296            0 :             CHK_RET(
     297              :                 ProcessSendRecv(op, queues[queIdx], remoteRank, empty, RecvSliceMapByRemoteRank_[remoteRank], link));
     298            0 :         }
     299            0 :         queIdx++;
     300              :     }
     301              : 
     302              :     // post sync
     303            0 :     CHK_RET(tempAlg.PostSyncInterQueues(queues));
     304              : 
     305            0 :     return HcclResult::HCCL_SUCCESS;
     306              : }
     307              : 
     308              : template <typename AlgTopoMatch>
     309            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::GenSendSlicesMapRank()
     310              : {
     311              :     // 遍历 sendDataSlices_,将每个元素根据其 remoteRank 放入相应的 vector 中
     312            0 :     for (const auto& slice : sendDataSilces_) {
     313              :         // 获取 remoteRank
     314            0 :         int remoteRank = slice.remoteRank_;
     315              : 
     316              :         // 将当前 slice 放入对应的 vector 中
     317            0 :         SendSliceMapByRemoteRank_[remoteRank].emplace_back(slice);
     318              :     }
     319            0 :     return HcclResult::HCCL_SUCCESS;
     320              : }
     321              : 
     322              : template <typename AlgTopoMatch>
     323            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcSendSlices(u64 maxRoundTransferSize)
     324              : {
     325            0 :     while (!sendDeque_.empty()) {
     326            0 :         HcclSendRecvItem* sendRecvItem = sendDeque_.front();
     327            0 :         HCCL_INFO(
     328              :             "[InsBatchSendRecvExecutor][CalcSendSlices] remoteRank[%u], buf[%p], count[%llu],"
     329              :             "dataType[%u], sendRecvType[%d].",
     330              :             sendRecvItem->remoteRank, sendRecvItem->buf, sendRecvItem->count, sendRecvItem->dataType,
     331              :             sendRecvItem->sendRecvType);
     332            0 :         u8* curInputPtr = static_cast<u8*>(sendRecvItem->buf);
     333            0 :         CHK_PTR_NULL(curInputPtr);
     334              : 
     335            0 :         HcclDataType hccldataTypeSend = sendRecvItem->dataType;
     336            0 :         DataType dataTypeSend = HcclDataTypeToDataType(hccldataTypeSend);
     337            0 :         u32 unitSize = DataTypeSizeGet(dataTypeSend);
     338              : 
     339            0 :         u64 resDataSize = sendRecvItem->count * unitSize;
     340            0 :         u64 curOffset = 0;
     341              : 
     342            0 :         while (resDataSize > 0) {
     343              :             // 判断本轮需搬运的数据量
     344            0 :             u64 transferSize = resDataSize > maxRoundTransferSize ? maxRoundTransferSize : resDataSize;
     345            0 :             curInputPtr = static_cast<u8*>(sendRecvItem->buf) + curOffset;
     346            0 :             sendDataSilces_.emplace_back(
     347            0 :                 reinterpret_cast<uintptr_t>(curInputPtr), transferSize, sendRecvItem->remoteRank);
     348            0 :             HCCL_DEBUG(
     349              :                 "[InsBatchSendRecvExecutor][CalcSendSlices] slice curOffset[%llu], slice size[%llu] curInputPtr [%p].",
     350              :                 curOffset, transferSize, curInputPtr);
     351            0 :             curOffset += transferSize;
     352            0 :             resDataSize -= transferSize;
     353              :         }
     354            0 :         sendDeque_.pop_front();
     355              :     }
     356            0 :     return HcclResult::HCCL_SUCCESS;
     357              : }
     358              : 
     359              : template <typename AlgTopoMatch>
     360            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::GenRecvSlicesMapRank()
     361              : {
     362              :     // 遍历 recvDataSilces_, 将每个元素根据其 remoteRank 放入相应的 vector 中
     363            0 :     for (const auto& slice : recvDataSilces_) {
     364              :         // 获取 remoteRank
     365            0 :         int remoteRank = slice.remoteRank_;
     366              : 
     367              :         // 将当前 slice 放入对应的 vector 中
     368            0 :         RecvSliceMapByRemoteRank_[remoteRank].emplace_back(slice);
     369              :     }
     370            0 :     return HcclResult::HCCL_SUCCESS;
     371              : }
     372              : 
     373              : template <typename AlgTopoMatch>
     374            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcRecvSlices(u64 maxRoundTransferSize)
     375              : {
     376            0 :     while (!recvDeque_.empty()) {
     377            0 :         HcclSendRecvItem* sendRecvItem = recvDeque_.front();
     378            0 :         HCCL_INFO(
     379              :             "[InsBatchSendRecvExecutor][CalcSendSlices] remoteRank[%u], buf[%p], count[%llu],"
     380              :             "dataType[%u], sendRecvType[%d].",
     381              :             sendRecvItem->remoteRank, sendRecvItem->buf, sendRecvItem->count, sendRecvItem->dataType,
     382              :             sendRecvItem->sendRecvType);
     383            0 :         u8* curInputPtr = static_cast<u8*>(sendRecvItem->buf);
     384            0 :         CHK_PTR_NULL(curInputPtr);
     385              : 
     386            0 :         HcclDataType hccldataTypeRecv = sendRecvItem->dataType;
     387            0 :         DataType dataTypeRecv = HcclDataTypeToDataType(hccldataTypeRecv);
     388            0 :         u32 unitSize = DataTypeSizeGet(dataTypeRecv);
     389              : 
     390            0 :         u64 resDataSize = sendRecvItem->count * unitSize;
     391            0 :         u64 curOffset = 0;
     392              : 
     393            0 :         while (resDataSize > 0) {
     394              :             // 判断本轮需搬运的数据量
     395            0 :             u64 transferSize = resDataSize > maxRoundTransferSize ? maxRoundTransferSize : resDataSize;
     396            0 :             curInputPtr = static_cast<u8*>(sendRecvItem->buf) + curOffset;
     397            0 :             recvDataSilces_.emplace_back(
     398            0 :                 reinterpret_cast<uintptr_t>(curInputPtr), transferSize, sendRecvItem->remoteRank);
     399            0 :             HCCL_DEBUG(
     400              :                 "[InsBatchSendRecvExecutor][CalcRecvSlices] slice curOffset[%llu], slice size[%llu], curInputPtr [%p].",
     401              :                 curOffset, transferSize, curInputPtr);
     402            0 :             curOffset += transferSize;
     403            0 :             resDataSize -= transferSize;
     404              :         }
     405              : 
     406            0 :         recvDeque_.pop_front();
     407              :     }
     408            0 :     return HcclResult::HCCL_SUCCESS;
     409              : }
     410              : 
     411              : template <typename AlgTopoMatch>
     412            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::ProcessRecvDataSlice(
     413              :     InsQuePtr& queue, SendRecvSlice& recvRemoteSlice, u32 remoteRank, uint64_t scratchBufferAddr, LinkData& link) const
     414              : {
     415              :     // 从远端读
     416            0 :     queue->Append(std::make_unique<InsWaitReady>(static_cast<RankId>(remoteRank), link));
     417              : 
     418              :     // 获取远端内存地址, 获取的是scratch的基起始地址
     419            0 :     DataBuffer remoteBuffer = rmaDataBufferMgr_->GetBuffer(link, BufferType::SCRATCH);
     420            0 :     uint64_t remoteBufferAddr = remoteBuffer.GetAddr();
     421            0 :     DataBuffer srcScratchSlice(remoteBufferAddr + (myRank_ % rankSize_) * maxRoundTransferSize_, recvRemoteSlice.size_);
     422              : 
     423              :     // 准备数据偏移
     424            0 :     u64 offsetOfRemoteScratchBase
     425            0 :         = maxRoundTransferSize_ * rankSize_ + maxRoundTransferSize_ * (remoteRank % rankSize_);
     426            0 :     DataBuffer dstScratchSlice(scratchBufferAddr + offsetOfRemoteScratchBase, recvRemoteSlice.size_);
     427            0 :     HCCL_DEBUG(
     428              :         "[InsBatchSendRecvExecutor][ProcessRecvDataSlice] myRank[%d] recv Size[%llu], remoteBuffer[%llu], "
     429              :         "remoteUserRank[%u].",
     430              :         myRank_, recvRemoteSlice.size_, remoteBufferAddr, remoteRank);
     431              : 
     432              :     // Recv
     433            0 :     queue->Append(
     434            0 :         std::make_unique<InsReadExtend>(static_cast<RankId>(remoteRank), link, dstScratchSlice, srcScratchSlice));
     435              : 
     436            0 :     queue->Append(std::make_unique<InsPostFin>(static_cast<RankId>(remoteRank), link));
     437              : 
     438              :     // 最后把数据拷贝回自己的output
     439            0 :     CHK_RET(CopyRecvDataSliceToUsrOut(queue, recvRemoteSlice, remoteRank, scratchBufferAddr));
     440              : 
     441            0 :     return HcclResult::HCCL_SUCCESS;
     442            0 : }
     443              : 
     444              : template <typename AlgTopoMatch>
     445            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::ProcessSendDataSlice(
     446              :     InsQuePtr& queue, SendRecvSlice& sendRemoteSlice, u32 remoteRank, uint64_t scratchBufferAddr, LinkData& link) const
     447              : {
     448              :     // local copy: usrin->cclin
     449            0 :     DataBuffer inputBuffer(sendRemoteSlice.addr_, sendRemoteSlice.size_);
     450            0 :     DataBuffer inScratchSlice(
     451            0 :         scratchBufferAddr + (remoteRank % rankSize_) * maxRoundTransferSize_, sendRemoteSlice.size_);
     452            0 :     HCCL_DEBUG(
     453              :         "scratchBufferAddr[%llu], offset[%llu], dataSize[%llu]", scratchBufferAddr,
     454              :         (remoteRank % rankSize_) * maxRoundTransferSize_, sendRemoteSlice.size_);
     455              : 
     456            0 :     queue->Append(std::make_unique<InsLocalCopyExtend>(inputBuffer, inScratchSlice));
     457              : 
     458            0 :     CHK_RET(SendRun(inScratchSlice, remoteRank, queue, link));
     459              : 
     460            0 :     return HcclResult::HCCL_SUCCESS;
     461            0 : }
     462              : 
     463              : template <typename AlgTopoMatch>
     464            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CopyRecvDataSliceToUsrOut(
     465              :     InsQuePtr& queue, SendRecvSlice& slice, u32 remoteRank, uint64_t scratchBufferAddr) const
     466              : {
     467              :     // local copy : cclout->usrout
     468            0 :     DataBuffer outScratchSlice(
     469            0 :         scratchBufferAddr + (remoteRank % rankSize_ + rankSize_) * maxRoundTransferSize_, slice.size_);
     470              : 
     471            0 :     DataBuffer outputBuffer(slice.addr_, slice.size_);
     472            0 :     HCCL_DEBUG(
     473              :         "[InsBatchSendRecvExecutor][CopyRecvDataSliceToUsrOut] scratchMem Addr[%llu] localcopy"
     474              :         "size[%llu] to outputBuffer[%llu].",
     475              :         outScratchSlice.GetAddr(), slice.size_, outputBuffer.GetAddr());
     476            0 :     queue->Append(std::make_unique<InsLocalCopyExtend>(outScratchSlice, outputBuffer));
     477              : 
     478            0 :     return HcclResult::HCCL_SUCCESS;
     479            0 : }
     480              : 
     481              : template <typename AlgTopoMatch>
     482            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::SendRun(
     483              :     DataBuffer& execBufferSlice, u32 remoteUserRank, InsQuePtr& queue, LinkData& link) const
     484              : {
     485            0 :     if (execBufferSlice.GetSize() == 0) {
     486            0 :         HCCL_ERROR("[InsBatchSendRecvExecutor][SendRun] SendRun input is null");
     487            0 :         return HCCL_E_PTR;
     488              :     }
     489              : 
     490            0 :     u64 sendSize = execBufferSlice.GetSize();
     491              : 
     492              :     // 准备数据偏移
     493            0 :     u64 offsetOfRemoteScratchBase = maxRoundTransferSize_ * rankSize_ + maxRoundTransferSize_ * (myRank_ % rankSize_);
     494              : 
     495              :     // 获取远端内存地址, 获取的是scratch的基起始地址
     496            0 :     DataBuffer remoteBuffer = rmaDataBufferMgr_->GetBuffer(link, BufferType::SCRATCH);
     497            0 :     uint64_t remoteBufferAddr = remoteBuffer.GetAddr();
     498            0 :     DataBuffer sendRemoteBuffer(remoteBufferAddr + offsetOfRemoteScratchBase, sendSize);
     499            0 :     HCCL_DEBUG(
     500              :         "[InsBatchSendRecvExecutor][SendRun] myRank[%d] send Size[%llu], remoteBuffer[%llu], remoteUserRank[%u].",
     501              :         myRank_, sendSize, remoteBuffer.GetAddr(), remoteUserRank);
     502              : 
     503              :     // wait recvRank ready
     504            0 :     queue->Append(std::make_unique<InsWaitReady>(static_cast<RankId>(remoteUserRank), link));
     505              : 
     506              :     // Send
     507            0 :     queue->Append(std::make_unique<InsWriteWithFinExtend>(
     508            0 :         static_cast<RankId>(remoteUserRank), link, execBufferSlice, sendRemoteBuffer));
     509              : 
     510            0 :     return HcclResult::HCCL_SUCCESS;
     511            0 : }
     512              : 
     513              : // 算子执行ccu接口
     514              : template <typename AlgTopoMatch>
     515            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::Orchestrate(
     516              :     const RankGraph* rankGraph, const CollAlgOperator& op, const CollAlgParams& params, InsQuePtr insQue)
     517              : {
     518              :     (void)rankGraph;
     519              :     (void)op;
     520              :     (void)params;
     521              :     (void)insQue;
     522              : 
     523            0 :     return HcclResult::HCCL_E_NOT_SUPPORT;
     524              : }
     525              : 
     526              : // 算子执行aicpu接口
     527              : template <typename AlgTopoMatch>
     528            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::Orchestrate(
     529              :     const AlgTopoInfo& topoInfo, const CollAlgOperator& op, const CollAlgParams& params, ConnectedLinkMgr* linkMgr,
     530              :     InsQuePtr insQue)
     531              : {
     532            0 :     HCCL_INFO("[InsBatchSendRecvExecutor][Orchestrate] Begin to Generate Instruction Queue for BatchSendRecv.");
     533              :     // init and check params
     534            0 :     CHK_RET(Init(op, params, insQue));
     535              : 
     536            0 :     CHK_PRT_RET(
     537              :         topoInfo.vTopo.size() == 0, HCCL_ERROR("[InsBatchSendRecvExecutor] Rank[%d], vTopo size is zero.", myRank_),
     538              :         HcclResult::HCCL_E_PARA);
     539              : 
     540            0 :     CHK_PRT_RET(
     541              :         topoInfo.virtRankMap.size() == 0,
     542              :         HCCL_ERROR("[InsBatchSendRecvExecutor] Rank[%d], virtRankMap size is zero.", myRank_), HcclResult::HCCL_E_PARA);
     543              : 
     544            0 :     CHK_PRT_RET(
     545              :         rankSize_ == 1, HCCL_ERROR("BatchSendRecv Executor orchestrate failed, do not support single rank."),
     546              :         HcclResult::HCCL_E_PARA);
     547              : 
     548            0 :     virtRankMap_ = topoInfo.virtRankMap[0];
     549            0 :     vTopo_ = topoInfo.vTopo[0];
     550              : 
     551            0 :     InsTempAllGatherMesh1D tempAlg(myRank_, rankSize_, topoInfo.vTopo[0], topoInfo.virtRankMap[0]);
     552              : 
     553              :     // calculate required insQues and prepare queue
     554            0 :     AlgTempResReq tempResReq;
     555            0 :     CHK_RET(CalcRes(tempResReq));
     556              : 
     557            0 :     CHK_RET(InitQueue(tempResReq.queNum, requiredQue_));
     558            0 :     HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], requiredQue Num [%u].", myRank_, tempResReq.queNum);
     559              : 
     560            0 :     CHK_PTR_NULL(linkMgr);
     561            0 :     CHK_RET(PrepResLinks(myRank_, tempResReq.links, linkMgr, tempResLinks_));
     562              : 
     563            0 :     if (tempAlg.IsPcieLink(tempResLinks_)) {
     564            0 :         dmaMode_ = DmaMode::GET;
     565              :     }
     566              : 
     567              :     // cclbuffer
     568            0 :     buffInfo_.inBuffType = BufferType::SCRATCH;
     569            0 :     buffInfo_.outBuffType = BufferType::SCRATCH;
     570            0 :     buffInfo_.inBuffBaseOff = 0;
     571            0 :     buffInfo_.outBuffBaseOff = maxTmpMemSize_ / 2; // 占据scratch memory的后半部分,除以2
     572              : 
     573              :     // batchsendrecv实现
     574            0 :     CHK_RET(GetPairWiseList(
     575              :         static_cast<HcclSendRecvItem*>(op.batchSendRecvDataDes.sendRecvItemsPtr), op.batchSendRecvDataDes.itemNum));
     576            0 :     CHK_RET(ProcessSelfSendRecvTasks(requiredQue_[0]));
     577              : 
     578              :     // 当需要多轮搬运时,需保证一次数据的搬运量需为单个数据size的整数倍
     579            0 :     u64 maxRoundTransferSize = params.maxTmpMemSize / MULTIPLY_TWO / rankSize_; // scratch分成2*ranksize份
     580            0 :     maxRoundTransferSize_ = maxRoundTransferSize;
     581            0 :     HCCL_DEBUG("[InsBatchSendRecvExecutor][Orchestrate] Max scratch buffer size [%u].", params.maxTmpMemSize);
     582              : 
     583            0 :     CHK_RET(CalcSendSlices(maxRoundTransferSize));
     584            0 :     CHK_RET(GenSendSlicesMapRank());
     585              : 
     586            0 :     CHK_RET(CalcRecvSlices(maxRoundTransferSize));
     587            0 :     CHK_RET(GenRecvSlicesMapRank());
     588              : 
     589              :     // aicpu mode
     590            0 :     CHK_RET(RunLoopSendRecv(op, requiredQue_, tempAlg));
     591              : 
     592            0 :     return HcclResult::HCCL_SUCCESS;
     593            0 : }
     594              : 
     595              : template <typename AlgTopoMatch>
     596            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcResLinksPartialMesh(
     597              :     const RankId myRank, const std::vector<std::vector<RankId>>& tempVTopo, const u32 linkNumBtwPeers,
     598              :     AlgTempResReq& tempResReq)
     599              : {
     600              :     u32 myAlgRank;
     601            0 :     u32 partialRankSize = commTargetUserRankSet_.size() + 1;
     602              : 
     603            0 :     if (tempVTopo.size() < 1) {
     604            0 :         HCCL_ERROR("[InsBatchSendRecvExecutor][CalcResLinksPartialMesh] Rank[%d], tempVTopo size is zero.", myRank);
     605            0 :         return HCCL_E_PARA;
     606              :     }
     607            0 :     for (u32 i = 0; i < tempVTopo.size(); i++) { // 遍历level0的2个平面
     608            0 :         CHK_RET(GetAlgRank(myRank, tempVTopo[i], myAlgRank));
     609            0 :         for (u32 queIdx = 0; queIdx < tempResReq.queNum; queIdx++) {
     610              :             // find neighbors : virtualRank
     611            0 :             u32 remoteAlgRank = (myAlgRank + 1 + queIdx + partialRankSize) % partialRankSize;
     612            0 :             if (remoteAlgRank >= tempVTopo[i].size()) {
     613            0 :                 continue;
     614              :             }
     615            0 :             RankId neighborRank = tempVTopo[i][remoteAlgRank];
     616            0 :             HCCL_DEBUG("tempVTopo[%u] index[%u] value[%d]", i, remoteAlgRank, neighborRank);
     617            0 :             auto rankInRankSet = std::find(
     618            0 :                 commTargetUserRankSet_.begin(), commTargetUserRankSet_.end(), static_cast<u32>(neighborRank));
     619            0 :             if (rankInRankSet != commTargetUserRankSet_.end() && neighborRank != myRank) {
     620              :                 // LinkNum
     621            0 :                 tempResReq.links[neighborRank] = linkNumBtwPeers;
     622            0 :                 HCCL_DEBUG("myRank[%d] neighborRank[%d] links is [%u]", myRank, neighborRank, linkNumBtwPeers);
     623              :             }
     624              :         }
     625              :     }
     626              : 
     627            0 :     return HcclResult::HCCL_SUCCESS;
     628              : }
     629              : 
     630              : template <typename AlgTopoMatch>
     631            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcRes(AlgTempResReq& tempResReq)
     632              : {
     633            0 :     InsTempAllGatherMesh1D tempAlg(myRank_, rankSize_, vTopo_, virtRankMap_);
     634            0 :     tempResReq.queNum = commTargetUserRankSet_.size() + 1; // 使用n条从流
     635            0 :     tempResReq.streamNum = tempResReq.queNum;
     636            0 :     tempResReq.queNotifys = tempAlg.CreateMasterSlaveQueNotifiesRequest(tempResReq.queNum);
     637              : 
     638            0 :     QId centerQ = 0;
     639            0 :     tempResReq.localWaitGroupCntNotify.emplace_back(centerQ, 0);
     640            0 :     tempResReq.localBcastPostCntNotify.emplace_back(centerQ, 0);
     641              : 
     642            0 :     CHK_RET(CalcResLinksPartialMesh(myRank_, vTopo_, 1, tempResReq));
     643            0 :     HCCL_DEBUG(
     644              :         "[InsBatchSendRecvExecutor][CalcRes] Rank[%d] vTopoSize[%lu] requiredQue Num[%u].", myRank_, vTopo_[0].size(),
     645              :         tempResReq.queNum);
     646            0 :     return HcclResult::HCCL_SUCCESS;
     647            0 : }
     648              : 
     649              : template <typename AlgTopoMatch>
     650            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcResOffload(
     651              :     const RankGraph* rankGraph, const u64& dataSize, CollOffloadOpResReq& resReq)
     652              : {
     653              :     (void)dataSize;
     654            0 :     resReq.requiredScratchMemSize = 0;
     655              :     // Topo Match
     656            0 :     AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
     657            0 :     CHK_RET(topoMatch.SetTargetRanks(commTargetUserRankSet_));
     658            0 :     CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
     659              : 
     660              :     // calculate required insQues and prepare queue
     661            0 :     AlgTempResReq tempResReq;
     662            0 :     if (enableDetour_) {
     663            0 :         HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
     664            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     665              :     } else {
     666            0 :         HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
     667            0 :         CHK_RET(CalcRes(tempResReq));
     668              :     }
     669              : 
     670            0 :     resReq.requiredSubQueNum = commTargetUserRankSet_.size();
     671              : 
     672            0 :     return HcclResult::HCCL_SUCCESS;
     673            0 : }
     674              : 
     675              : template <typename AlgTopoMatch>
     676            0 : HcclResult InsBatchSendRecvExecutor<AlgTopoMatch>::CalcRes(const RankGraph* rankGraph, CollAlgResReq& algResReq)
     677              : {
     678              :     // Topo Match
     679            0 :     AlgTopoMatch topoMatch(myRank_, rankSize_, rankGraph, devType_);
     680            0 :     CHK_RET(topoMatch.SetTargetRanks(commTargetUserRankSet_));
     681            0 :     CHK_RET(topoMatch.MatchTopo(vTopo_, virtRanks_, virtRankMap_));
     682              : 
     683            0 :     algResReq.topoInfo.UpdateSingleLevelTopo(virtRanks_, virtRankMap_, vTopo_);
     684              : 
     685            0 :     for (u32 i = 0; i < vTopo_.size(); i++) {        // 遍历level0
     686            0 :         for (u32 j = 0; j < vTopo_[i].size(); j++) { // 遍历平面内的所有rank
     687            0 :             HCCL_DEBUG(
     688              :                 "[InsBatchSendRecvExecutor][CalcResLinksPartialMesh] vTopo_[%u][%u] is [%d].", i, j, vTopo_[i][j]);
     689              :         }
     690              :     }
     691            0 :     HCCL_DEBUG(
     692              :         "[InsBatchSendRecvExecutor][CalcRes]topoInfo.virtRanks[%zu], topoInfo.virtRankMap[%zu],"
     693              :         "topoInfo.vTopo[%zu]",
     694              :         algResReq.topoInfo.virtRanks.size(), algResReq.topoInfo.virtRankMap.size(), algResReq.topoInfo.vTopo.size());
     695              : 
     696              :     // calculate required insQues and prepare queue
     697            0 :     AlgTempResReq tempResReq;
     698            0 :     if (enableDetour_) {
     699            0 :         HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], CalcRes with detouring enabled.", myRank_);
     700            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     701              :     } else {
     702            0 :         HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], CalcRes with detouring disabled.", myRank_);
     703            0 :         CHK_RET(CalcRes(tempResReq));
     704              :     }
     705              : 
     706            0 :     algResReq.primQueueNum = tempResReq.streamNum;
     707            0 :     algResReq.queueNotifys = tempResReq.queNotifys;
     708            0 :     HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], requiredQueNum [%u].", myRank_, algResReq.primQueueNum);
     709              : 
     710            0 :     CHK_RET(CalcLinkInfo(myRank_, rankGraph, tempResReq.links, algResReq.levelRankPairs));
     711            0 :     CHK_RET(CalcResLinks(myRank_, rankGraph, linkPriority_, tempResReq.links, algResReq.links));
     712            0 :     HCCL_DEBUG("[InsBatchSendRecvExecutor] Rank[%d], algResReq.links size[%zu].", myRank_, algResReq.links.size());
     713              : 
     714            0 :     return HcclResult::HCCL_SUCCESS;
     715            0 : }
     716              : 
     717              : // 注册
     718              : INS_REGISTER_IMPL_BY_TOPO(OpType::BATCHSENDRECV, InsBatchSendRecv, InsBatchSendRecvExecutor, TopoMatchPartialMesh);
     719              : 
     720              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1