LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_all_gather - aligned_all_gather_double_ring.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 4.3 % 257 11
Test Date: 2026-08-18 17:47:01 Functions: 19.0 % 21 4

            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 "aligned_all_gather_double_ring.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15           34 : AlignedAllGatherDoubleRing::AlignedAllGatherDoubleRing(const HcclDispatcher dispatcher) : AlgTemplateBase(dispatcher) {}
      16              : 
      17           68 : AlignedAllGatherDoubleRing::~AlignedAllGatherDoubleRing() {}
      18              : 
      19           34 : HcclResult AlignedAllGatherDoubleRing::Prepare(
      20              :     HcomCollOpInfo* opInfo, const u32 userRank, std::vector<Stream>& subStreams,
      21              :     std::vector<std::shared_ptr<LocalNotify>>& mainSignals, std::vector<std::shared_ptr<LocalNotify>>& subSignals,
      22              :     const std::vector<std::vector<u32>>& ringsOrders,
      23              :     const std::vector<std::vector<Slice>>& userMemOutputSlicesOfDoubleRing)
      24              : {
      25           34 :     opInfo_ = opInfo;
      26           34 :     userRank_ = userRank;
      27           34 :     subStreams_ = subStreams;
      28           34 :     mainSignals_ = mainSignals;
      29           34 :     subSignals_ = subSignals;
      30           34 :     ringsOrders_ = ringsOrders;
      31           34 :     userMemOutputSlicesOfDoubleRing_ = userMemOutputSlicesOfDoubleRing;
      32           34 :     return HCCL_SUCCESS;
      33              : }
      34              : 
      35              : // 服务器间allgather的入口函数
      36            0 : HcclResult AlignedAllGatherDoubleRing::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
      37              : {
      38              :     // 基本的检查
      39            0 :     CHK_RET(CheckParameters(rank, rankSize, links));
      40              : 
      41            0 :     if (rankSize == 1) {
      42            0 :         CHK_RET(OneRankMemcpy());
      43            0 :         return HCCL_SUCCESS;
      44              :     }
      45              :     // 收集邻居信息
      46            0 :     CHK_RET(GetInitializedNeighborLinks(rank, rankSize, links));
      47              : 
      48              :     // 填充slice_
      49            0 :     CHK_RET(SetSlices(rank, rankSize));
      50              : 
      51            0 :     HCCL_DEBUG("[AlignedAllGatherDoubleRing]RunAsync begins");
      52              : 
      53              :     // 运行all-gather, ring算法
      54            0 :     CHK_RET(RunAllGather(rank, rankSize));
      55              : 
      56            0 :     if (barrierSwitchOn_) {
      57              :         // 执行barrier,保证数据收发完成
      58            0 :         CHK_RET(ExecuteBarrier(leftLink_, rightLink_));
      59              :     }
      60              : 
      61            0 :     CHK_RET(LaunchTaskExtend(dispatcher_, stream_, subStreams_));
      62              : 
      63            0 :     HCCL_INFO("AlignedAllGatherDoubleRing finished: rank[%u] end", rank);
      64            0 :     return HCCL_SUCCESS;
      65              : }
      66              : 
      67              : HcclResult
      68            0 : AlignedAllGatherDoubleRing::CheckParameters(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
      69              : {
      70            0 :     CHK_PTR_NULL(opInfo_);
      71            0 :     CHK_RET(CheckConcurrentDirectParameters(rank, rankSize, links));
      72              :     // 判断subStreams数量是否正确
      73            0 :     CHK_PRT_RET(
      74              :         subStreams_.size() < 1,
      75              :         HCCL_ERROR("[AlignedAllGatherDoubleRing] subStreams size[%u] is less than 1", subStreams_.size()), HCCL_E_PARA);
      76            0 :     for (auto& s : subStreams_) {
      77            0 :         CHK_PTR_NULL(s.ptr());
      78              :     }
      79              :     // 判断mainSignals数量是否正确
      80            0 :     CHK_PRT_RET(
      81              :         mainSignals_.size() < 1,
      82              :         HCCL_ERROR("[AlignedAllGatherDoubleRing] mainSignals size[%u] is less than 1", mainSignals_.size()),
      83              :         HCCL_E_PARA);
      84              :     // 判断subSignals数量是否正确
      85            0 :     CHK_PRT_RET(
      86              :         subSignals_.size() < 1,
      87              :         HCCL_ERROR("[AlignedAllGatherDoubleRing] subSignals size[%u] is less than 1", subSignals_.size()), HCCL_E_PARA);
      88              :     // 判断ringsOrder数量是否正确
      89            0 :     for (u32 ringIndex = 0; ringIndex < ringsOrders_.size(); ringIndex++) {
      90            0 :         CHK_PRT_RET(
      91              :             ringsOrders_[ringIndex].size() % rankSize != 0,
      92              :             HCCL_ERROR(
      93              :                 "[AlignedAllGatherDoubleRing] ringsOrders[%u] size[%u] can not be divided by rank size[%u]", ringIndex,
      94              :                 ringsOrders_[ringIndex].size(), rankSize),
      95              :             HCCL_E_PARA);
      96              :     }
      97              :     // 判断userMemOutputSlices数量是否正确
      98            0 :     for (u32 ringIndex = 0; ringIndex < userMemOutputSlicesOfDoubleRing_.size(); ringIndex++) {
      99            0 :         CHK_PRT_RET(
     100              :             userMemOutputSlicesOfDoubleRing_[ringIndex].size() % rankSize != 0,
     101              :             HCCL_ERROR(
     102              :                 "[AlignedAllGatherDoubleRing] userMemOutputSlicesOfDoubleRing[%u] size[%u] can not be divided by rank "
     103              :                 "size[%u]",
     104              :                 ringIndex, userMemOutputSlicesOfDoubleRing_[ringIndex].size(), rankSize),
     105              :             HCCL_E_PARA);
     106              :     }
     107            0 :     u32 mainSliceSize = multRingsSlices_[ALIGNED_MAIN_RING_INDEX].size() / rankSize;
     108            0 :     u32 subSliceSize = multRingsSlices_[ALIGNED_SUB_RING_INDEX].size() / rankSize;
     109            0 :     CHK_PRT_RET(
     110              :         mainSliceSize != subSliceSize,
     111              :         HCCL_ERROR(
     112              :             "[AlignedAllGatherDoubleRing] mainSliceSize[%u] is not equal to subSliceSize[%u].", mainSliceSize,
     113              :             subSliceSize),
     114              :         HCCL_E_PARA);
     115            0 :     HCCL_INFO("AlignedAllGatherDoubleRing finished to CheckParameters");
     116            0 :     return HCCL_SUCCESS;
     117              : }
     118              : 
     119            0 : HcclResult AlignedAllGatherDoubleRing::OneRankMemcpy()
     120              : {
     121            0 :     CHK_RET(MainRecordSub()); // 主流通知从流开始通信
     122            0 :     CHK_RET(SubWaitMain());   // 从流等待主流通知
     123            0 :     for (u32 ringIndex = 0; ringIndex < multRingsSlices_.size(); ringIndex++) {
     124            0 :         for (u32 sliceIdx = 0; sliceIdx < multRingsSlices_[ringIndex].size(); sliceIdx++) {
     125            0 :             const Slice& srcSlice = multRingsSlices_[ringIndex][sliceIdx];
     126            0 :             const Slice& dstSlice = userMemOutputSlicesOfDoubleRing_[ringIndex][sliceIdx];
     127            0 :             DeviceMem src;
     128            0 :             DeviceMem dst = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + dstSlice.offset, dstSlice.size);
     129            0 :             if (opInfo_->inputAddr != nullptr) {
     130              :                 // opInfo_->inputAddr != nullptr指示要从user input获取输入
     131            0 :                 u64 stepOffset = multRingsSlices_[ringIndex][ringsOrders_[ringIndex][0]].offset;
     132            0 :                 HCCL_DEBUG(
     133              :                     "Memcpy operation: stream[main], rank[%u] starts to copy offset[%llu], size[%llu] at userInput",
     134              :                     userRank_, stepOffset, srcSlice.size);
     135            0 :                 src = DeviceMem::create(static_cast<u8*>(opInfo_->inputAddr) + stepOffset, srcSlice.size);
     136              :             } else {
     137              :                 // opInfo_->inputAddr == nullptr指示要从CCL buffer获取输入
     138            0 :                 HCCL_DEBUG(
     139              :                     "Memcpy operation: stream[main], rank[%u] starts to copy offset[%llu], size[%llu] at inputMem_",
     140              :                     userRank_, srcSlice.offset, srcSlice.size);
     141            0 :                 src = inputMem_.range(srcSlice.offset, srcSlice.size);
     142              :             }
     143            0 :             if (ringIndex == 1) {
     144            0 :                 CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, stream_));
     145              :             } else {
     146            0 :                 CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, subStreams_[0]));
     147              :             }
     148            0 :         }
     149              :     }
     150            0 :     CHK_RET(SubRecordMain()); // 从流通知主流通信完成
     151            0 :     CHK_RET(MainWaitSub());   // 主流等待从流通知
     152            0 :     return HCCL_SUCCESS;
     153              : }
     154              : 
     155            0 : HcclResult AlignedAllGatherDoubleRing::GetInitializedNeighborLinks(
     156              :     const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
     157              : {
     158              :     // 收集左邻居信息
     159            0 :     leftLink_ = links[(rank + rankSize - 1) % rankSize];
     160            0 :     CHK_SMART_PTR_NULL(leftLink_);
     161              : 
     162              :     // 收集右邻居信息
     163            0 :     rightLink_ = links[(rank + 1) % rankSize];
     164            0 :     CHK_SMART_PTR_NULL(rightLink_);
     165            0 :     HCCL_INFO("AlignedAllGatherDoubleRing finished to GetInitializedNeighborLinks");
     166            0 :     return HCCL_SUCCESS;
     167              : }
     168              : 
     169            0 : HcclResult AlignedAllGatherDoubleRing::SetSlices(const u32 rank, const u32 rankSize)
     170              : {
     171            0 :     for (u32 ringIndex = 0; ringIndex < multRingsSlices_.size(); ringIndex++) {
     172            0 :         if (multRingsSlices_[ringIndex].size() == 0) {
     173            0 :             multRingsSlices_[ringIndex].resize(rankSize);
     174              : 
     175            0 :             u64 sliceSize = count_ * DataUnitSize(dataType_);
     176            0 :             for (u32 i = 0; i < rankSize; i++) {
     177            0 :                 multRingsSlices_[ringIndex][i].size = sliceSize;
     178            0 :                 multRingsSlices_[ringIndex][i].offset = sliceSize * i;
     179            0 :                 HCCL_DEBUG(
     180              :                     "multRingsSlices_[%u], rank[%u], slices[%u].offset=%llu, slices[%u].size=[%llu]", ringIndex, rank,
     181              :                     i, multRingsSlices_[ringIndex][i].offset, i, multRingsSlices_[ringIndex][i].size);
     182              :             }
     183              :         }
     184            0 :         for (u32 i = 0; i < multRingsSlices_[ringIndex].size(); i++) {
     185            0 :             HCCL_DEBUG(
     186              :                 "[AlignedAllGatherDoubleRing][SetSlices] multRingsSlices_[%u], rank[%u], slices[%u].offset=[%llu], "
     187              :                 "slices[%u].size=[%llu]",
     188              :                 ringIndex, rank, i, multRingsSlices_[ringIndex][i].offset, i, multRingsSlices_[ringIndex][i].size);
     189              :         }
     190              :     }
     191            0 :     HCCL_INFO("AlignedAllGatherDoubleRing finished to SetSlices");
     192            0 :     return HCCL_SUCCESS;
     193              : }
     194              : 
     195            0 : HcclResult AlignedAllGatherDoubleRing::RunInitStep(const u32 rank, const u32 rankSize)
     196              : {
     197            0 :     for (u32 ringIndex = 0; ringIndex < multRingsSlices_.size(); ringIndex++) {
     198              :         // 第一步搬到userMemIn_的offset, 不同的ring环offset不一样
     199              :         u64 firstStepOffset;
     200            0 :         if (ringIndex == 0) {
     201            0 :             firstStepOffset = multRingsSlices_[ringIndex][ringsOrders_[ringIndex][0]].offset;
     202              :         } else {
     203            0 :             const auto& prevRingSlice = multRingsSlices_[ringIndex - 1][ringsOrders_[ringIndex - 1][rank]];
     204            0 :             const auto& slice = multRingsSlices_[ringIndex][ringsOrders_[ringIndex][rank]];
     205            0 :             firstStepOffset = slice.offset - prevRingSlice.offset;
     206              :         }
     207              :         // 第-1步,片内将部分数据从userIn搬到cclIn
     208            0 :         DeviceMem srcInit;
     209            0 :         DeviceMem dstInit;
     210              :         u32 initSliceIdx;
     211            0 :         if (ringIndex == 0) {
     212            0 :             initSliceIdx = rank;
     213              :         } else {
     214            0 :             initSliceIdx = (rankSize - rank) % rankSize;
     215              :         }
     216            0 :         u32 sliceSize = multRingsSlices_[ringIndex].size() / rankSize;
     217            0 :         for (u32 sliceIdx = 0; sliceIdx < sliceSize; sliceIdx++) {
     218            0 :             Slice initSlice = multRingsSlices_[ringIndex][initSliceIdx * sliceSize + sliceIdx];
     219              :             // 需要+userMemIn_的offset
     220            0 :             if (opInfo_->inputAddr != nullptr) {
     221              :                 // AllGather算子调用AlignedAllGatherDoubleRing场景
     222            0 :                 HCCL_DEBUG(
     223              :                     "Memcpy operation: step[-1] stream[main] src rank[%u] starts to copy(rcv) offset[%llu], "
     224              :                     "size[%llu] on userMemOutput to offset[%llu], size[%llu] on CCL",
     225              :                     userRank_, firstStepOffset, initSlice.size, initSlice.offset, initSlice.size);
     226            0 :                 srcInit = DeviceMem::create(static_cast<u8*>(opInfo_->inputAddr) + firstStepOffset, initSlice.size);
     227              :             } else {
     228              :                 // AllReduce算子调用AlignedAllGatherDoubleRing场景
     229            0 :                 HCCL_DEBUG(
     230              :                     "Memcpy operation: step[-1] stream[main] src rank[%u] starts to copy(rcv) offset[%llu], "
     231              :                     "size[%llu] on CCL to offset[%llu], size[%llu] on CCL",
     232              :                     userRank_, initSlice.offset, initSlice.size, initSlice.offset, initSlice.size);
     233            0 :                 srcInit = inputMem_.range(initSlice.offset, initSlice.size);
     234              :             }
     235            0 :             dstInit = outputMem_.range(initSlice.offset, initSlice.size);
     236              :             // 若src与dst一样,则不需要搬运
     237            0 :             if (srcInit == dstInit) {
     238            0 :                 continue;
     239              :             }
     240            0 :             if (ringIndex == 1) {
     241            0 :                 CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstInit, srcInit, stream_));
     242              :             } else {
     243            0 :                 CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstInit, srcInit, subStreams_[0]));
     244              :             }
     245              :         }
     246            0 :     }
     247            0 :     return HCCL_SUCCESS;
     248              : }
     249              : 
     250              : HcclResult
     251            0 : AlignedAllGatherDoubleRing::PrepareRunMainStream(u32 ringIndex, Stream& stream, LINK& preLink, LINK& nextLink)
     252              : {
     253            0 :     HCCL_DEBUG("AlignedAllGatherDoubleRing PrepareRunMainStream start");
     254            0 :     if (ringIndex == 1) {
     255            0 :         stream = stream_;
     256            0 :         preLink = rightLink_;
     257            0 :         nextLink = leftLink_;
     258              :     } else {
     259            0 :         stream = subStreams_[0];
     260            0 :         preLink = leftLink_;
     261            0 :         nextLink = rightLink_;
     262              :     }
     263            0 :     HCCL_DEBUG("AlignedAllGatherDoubleRing PrepareRunMainStream end");
     264            0 :     return HCCL_SUCCESS;
     265              : }
     266              : 
     267            0 : HcclResult AlignedAllGatherDoubleRing::RunAllStreams(
     268              :     const u32 step, const u32 rankSize, const std::vector<TxMemoryInfo>& mainTxMems,
     269              :     std::vector<RxMemoryInfo>& mainRxMems, const std::vector<TxMemoryInfo>& subTxMems,
     270              :     std::vector<RxMemoryInfo>& subRxMems, std::vector<DeviceMem>& mainLocalSrcMems,
     271              :     std::vector<DeviceMem>& mainLocalDstMems, std::vector<DeviceMem>& subLocalSrcMems,
     272              :     std::vector<DeviceMem>& subLocalDstMems)
     273              : {
     274              :     (void)mainTxMems;
     275              :     (void)subTxMems;
     276            0 :     Stream mainStream;
     277            0 :     LINK mainPreLink;
     278            0 :     LINK mainNextLink;
     279            0 :     Stream subStream;
     280            0 :     LINK subPreLink;
     281            0 :     LINK subNextLink;
     282            0 :     CHK_RET(PrepareRunMainStream(ALIGNED_MAIN_RING_INDEX, mainStream, mainPreLink, mainNextLink));
     283            0 :     CHK_RET(PrepareRunMainStream(ALIGNED_SUB_RING_INDEX, subStream, subPreLink, subNextLink));
     284              : 
     285            0 :     CHK_RET(mainNextLink->TxAck(mainStream));
     286            0 :     CHK_RET(subNextLink->TxAck(subStream));
     287              : 
     288            0 :     CHK_RET(mainPreLink->RxAck(mainStream));
     289            0 :     CHK_RET(subPreLink->RxAck(subStream));
     290            0 :     u32 sliceSize = multRingsSlices_[ALIGNED_MAIN_RING_INDEX].size() / rankSize;
     291            0 :     for (u32 memIdx = 0; memIdx < sliceSize; memIdx++) {
     292            0 :         CHK_RET(RxAsyncMemcpy(step, ALIGNED_SUB_RING_INDEX, subRxMems[memIdx], subStream, subPreLink));
     293            0 :         CHK_RET(LocalMemcpy(ALIGNED_MAIN_RING_INDEX, mainLocalSrcMems[memIdx], mainLocalDstMems[memIdx]));
     294            0 :         CHK_RET(LocalMemcpy(ALIGNED_SUB_RING_INDEX, subLocalSrcMems[memIdx], subLocalDstMems[memIdx]));
     295            0 :         CHK_RET(RxAsyncMemcpy(step, ALIGNED_MAIN_RING_INDEX, mainRxMems[memIdx], mainStream, mainPreLink));
     296              :     }
     297            0 :     CHK_RET(mainPreLink->TxDataSignal(mainStream));
     298            0 :     CHK_RET(subPreLink->TxDataSignal(subStream));
     299              : 
     300            0 :     CHK_RET(mainNextLink->RxDataSignal(mainStream));
     301            0 :     CHK_RET(subNextLink->RxDataSignal(subStream));
     302            0 :     return HCCL_SUCCESS;
     303            0 : }
     304              : 
     305            0 : HcclResult AlignedAllGatherDoubleRing::RxAsyncMemcpy(
     306              :     const u32 step, const u32 ringIndex, RxMemoryInfo& mem, Stream& stream, LINK& link)
     307              : {
     308              :     (void)step;
     309              :     // PreSync
     310            0 :     if (ringIndex == 1) {
     311            0 :         CHK_RET(MainWaitSub());
     312            0 :         CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     313            0 :         CHK_RET(MainRecordSub());
     314              :     } else {
     315            0 :         CHK_RET(LocalNotify::Post(subStreams_[0], dispatcher_, mainSignals_[0], profilerInput_.stage));
     316            0 :         CHK_RET(LocalNotify::Wait(subStreams_[0], dispatcher_, subSignals_[0], profilerInput_.stage));
     317              :     }
     318            0 :     CHK_PTR_NULL(mem.dst);
     319            0 :     void* srcMemPtr = nullptr;
     320            0 :     CHK_RET(link->GetRemoteMem(mem.srcMemType, &srcMemPtr));
     321              : 
     322            0 :     DeviceMem srcDevMem(static_cast<s8*>(srcMemPtr) + mem.srcOffset, mem.len);
     323            0 :     DeviceMem dstDevMem(static_cast<s8*>(mem.dst), mem.len);
     324            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstDevMem, srcDevMem, stream, link->GetRemoteRank(), link->GetLinkType()));
     325            0 :     return HCCL_SUCCESS;
     326            0 : }
     327              : 
     328            0 : HcclResult AlignedAllGatherDoubleRing::LocalMemcpy(const u32 ringIndex, DeviceMem& localSrcMem, DeviceMem& localDstMem)
     329              : {
     330              :     // 校验流数
     331            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
     332            0 :         CHK_RET(LocalNotify::Post(
     333              :             subStreams_[ringIndex + 1], dispatcher_, mainSignals_[ringIndex + 1], profilerInput_.stage));
     334            0 :         CHK_RET(LocalNotify::Wait(
     335              :             subStreams_[ringIndex + 1], dispatcher_, subSignals_[ringIndex + 1], profilerInput_.stage));
     336            0 :         if (localSrcMem != localDstMem) {
     337            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, localDstMem, localSrcMem, subStreams_[ringIndex + 1]));
     338              :         }
     339              :     }
     340            0 :     return HCCL_SUCCESS;
     341              : }
     342              : 
     343            0 : HcclResult AlignedAllGatherDoubleRing::PrepareDeviceMems(
     344              :     const u32 step, const u32 ringIndex, const u32 rankSize, const u32 txSliceIdx, const u32 rxSliceIdx,
     345              :     std::vector<TxMemoryInfo>& txMems, std::vector<RxMemoryInfo>& rxMems, std::vector<DeviceMem>& localSrcMems,
     346              :     std::vector<DeviceMem>& localDstMems)
     347              : {
     348            0 :     u32 sliceSize = multRingsSlices_[ringIndex].size() / rankSize;
     349            0 :     for (u32 sliceIdx = 0; sliceIdx < sliceSize; sliceIdx++) {
     350            0 :         const Slice& rxSlice = multRingsSlices_[ringIndex][rxSliceIdx * sliceSize + sliceIdx];
     351            0 :         const Slice& mainSlice = userMemOutputSlicesOfDoubleRing_[ringIndex][rxSliceIdx * sliceSize + sliceIdx];
     352            0 :         const Slice& txSlice = multRingsSlices_[ringIndex][txSliceIdx * sliceSize + sliceIdx];
     353            0 :         const Slice& subSlice = userMemOutputSlicesOfDoubleRing_[ringIndex][txSliceIdx * sliceSize + sliceIdx];
     354              :         // PrepareTxRxMems
     355            0 :         DeviceMem src = outputMem_.range(txSlice.offset, txSlice.size);
     356            0 :         HCCL_DEBUG("tx srcMem[%p] range[%llu] size[%llu] ", src.ptr(), txSlice.offset, txSlice.size);
     357            0 :         txMems.emplace_back(
     358            0 :             TxMemoryInfo{UserMemType::OUTPUT_MEM, txSlice.offset + baseOffset_, src.ptr(), txSlice.size});
     359            0 :         DeviceMem dst;
     360            0 :         if (step == rankSize - DMA_REDUCE_TWO_OFFSET) {
     361            0 :             HCCL_DEBUG(
     362              :                 "DMAReduce(sdma) MemcpyAsync operation: step[%u] stream[main], dst rank[%u] starts to rcv "
     363              :                 "offset[%llu] size[%llu] at userMemOutput_",
     364              :                 step, userRank_, mainSlice.offset, mainSlice.size);
     365            0 :             dst = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + mainSlice.offset, mainSlice.size);
     366              :         } else {
     367            0 :             HCCL_DEBUG(
     368              :                 "MemcpyAsync operation: step[%u] stream[main], dst rank[%u] starts to rcv offset[%llu] size[%llu] "
     369              :                 "at outputMem_",
     370              :                 step, userRank_, rxSlice.offset, rxSlice.size);
     371            0 :             dst = outputMem_.range(rxSlice.offset, rxSlice.size);
     372              :         }
     373            0 :         rxMems.emplace_back(
     374            0 :             RxMemoryInfo{UserMemType::OUTPUT_MEM, rxSlice.offset + baseOffset_, dst.ptr(), rxSlice.size});
     375              :         // PrepareLocalCopyDeviceMems
     376              :         // 从流
     377            0 :         src = outputMem_.range(txSlice.offset, txSlice.size);
     378            0 :         dst = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + subSlice.offset, subSlice.size);
     379            0 :         HCCL_DEBUG(
     380              :             "Memcpy operation: step[%u] stream[sub], src rank[%u] starts to send offset[%llu] size[%llu], "
     381              :             "dst rank starts to rcv offset[%llu] size[%llu] at userMemOutput_",
     382              :             step, userRank_, subSlice.offset, subSlice.size, txSlice.offset, txSlice.size);
     383            0 :         localSrcMems.emplace_back(src);
     384            0 :         localDstMems.emplace_back(dst);
     385            0 :     }
     386            0 :     return HCCL_SUCCESS;
     387              : }
     388              : 
     389            0 : HcclResult AlignedAllGatherDoubleRing::RunAllGather(const u32 rank, const u32 rankSize)
     390              : {
     391            0 :     HCCL_INFO("AlignedAllGatherDoubleRing starts, the input param rank[%u]", rank);
     392            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
     393              :         // 主环主流通知从环主流开始通信
     394            0 :         CHK_RET(LocalNotify::Post(stream_, dispatcher_, subSignals_[0], profilerInput_.stage));
     395              :         // 从环主流等待主环主流通知
     396            0 :         CHK_RET(LocalNotify::Wait(subStreams_[0], dispatcher_, subSignals_[0], profilerInput_.stage));
     397            0 :         CHK_RET(RunInitStep(rank, rankSize));
     398            0 :         CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     399            0 :         CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, subStreams_[0], dispatcher_));
     400              :         // 从流通知主流通信完成
     401            0 :         CHK_RET(LocalNotify::Post(subStreams_[0], dispatcher_, mainSignals_[0], profilerInput_.stage));
     402              :         // 主流等待从流通知
     403            0 :         CHK_RET(LocalNotify::Wait(stream_, dispatcher_, mainSignals_[0], profilerInput_.stage));
     404              :     }
     405              :     // 主环主流通知从环主流开始通信
     406            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     407            0 :     CHK_RET(MainRecordSub());
     408              :     // 从环主流等待主环主流通知
     409            0 :     CHK_RET(SubWaitMain());
     410            0 :     u32 txSliceIdxSub = rank;
     411            0 :     u32 rxSliceIdxSub = (rank + rankSize - 1) % rankSize;
     412            0 :     u32 txSliceIdxMain = (rankSize - rank) % rankSize;
     413            0 :     u32 rxSliceIdxMain = (rankSize - rank - 1 + rankSize) % rankSize;
     414              :     // 空拷贝用于主从流任务并发
     415            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     416            0 :     CHK_RET(ExecEmptyTasks());
     417            0 :     for (u32 step = 0; step < rankSize - 1; step++) {
     418            0 :         std::vector<TxMemoryInfo> txMemsSub;
     419            0 :         std::vector<RxMemoryInfo> rxMemsSub;
     420            0 :         std::vector<DeviceMem> localSrcMemsSub;
     421            0 :         std::vector<DeviceMem> localDstMemsSub;
     422            0 :         CHK_RET(PrepareDeviceMems(
     423              :             step, ALIGNED_SUB_RING_INDEX, rankSize, txSliceIdxSub, rxSliceIdxSub, txMemsSub, rxMemsSub, localSrcMemsSub,
     424              :             localDstMemsSub));
     425            0 :         std::vector<TxMemoryInfo> txMemsMain;
     426            0 :         std::vector<RxMemoryInfo> rxMemsMain;
     427            0 :         std::vector<DeviceMem> localSrcMemsMain;
     428            0 :         std::vector<DeviceMem> localDstMemsMain;
     429            0 :         CHK_RET(PrepareDeviceMems(
     430              :             step, ALIGNED_MAIN_RING_INDEX, rankSize, txSliceIdxMain, rxSliceIdxMain, txMemsMain, rxMemsMain,
     431              :             localSrcMemsMain, localDstMemsMain));
     432            0 :         CHK_RET(RunAllStreams(
     433              :             step, rankSize, txMemsMain, rxMemsMain, txMemsSub, rxMemsSub, localSrcMemsMain, localDstMemsMain,
     434              :             localSrcMemsSub, localDstMemsSub));
     435              : 
     436              :         // 更新索引
     437            0 :         txSliceIdxSub = (txSliceIdxSub + rankSize - 1) % rankSize;
     438            0 :         rxSliceIdxSub = (rxSliceIdxSub + rankSize - 1) % rankSize;
     439            0 :         txSliceIdxMain = (txSliceIdxMain + rankSize - 1) % rankSize;
     440            0 :         rxSliceIdxMain = (rxSliceIdxMain + rankSize - 1) % rankSize;
     441            0 :     }
     442              :     // 从环主流通知主环主流通信完成
     443            0 :     CHK_RET(SubRecordMain());
     444              :     // 主环主流等待从环主流通知
     445            0 :     CHK_RET(MainWaitSub());
     446            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     447            0 :     HCCL_INFO("AlignedAllGatherDoubleRing finished to RunAllGather");
     448            0 :     return HCCL_SUCCESS;
     449              : }
     450              : 
     451            0 : HcclResult AlignedAllGatherDoubleRing::ExecEmptyTasks()
     452              : {
     453            0 :     for (u32 signalIndex = 0; signalIndex < subStreams_.size(); signalIndex++) {
     454            0 :         CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, subStreams_[signalIndex], dispatcher_));
     455              :     }
     456            0 :     return HCCL_SUCCESS;
     457              : }
     458              : 
     459              : // 主流通知从流干活
     460            0 : HcclResult AlignedAllGatherDoubleRing::MainRecordSub()
     461              : {
     462            0 :     for (u32 signalIndex = 0; signalIndex < subSignals_.size(); signalIndex++) {
     463            0 :         CHK_RET(LocalNotify::Post(stream_, dispatcher_, subSignals_[signalIndex], profilerInput_.stage));
     464              :     }
     465            0 :     return HCCL_SUCCESS;
     466              : }
     467              : // 从流等待主流
     468            0 : HcclResult AlignedAllGatherDoubleRing::SubWaitMain()
     469              : {
     470            0 :     for (u32 streamIndex = 0; streamIndex < subSignals_.size(); streamIndex++) {
     471            0 :         CHK_RET(
     472              :             LocalNotify::Wait(subStreams_[streamIndex], dispatcher_, subSignals_[streamIndex], profilerInput_.stage));
     473              :     }
     474            0 :     return HCCL_SUCCESS;
     475              : }
     476              : // 主流等待从流
     477            0 : HcclResult AlignedAllGatherDoubleRing::MainWaitSub()
     478              : {
     479            0 :     for (u32 signalIndex = 0; signalIndex < mainSignals_.size(); signalIndex++) {
     480            0 :         CHK_RET(LocalNotify::Wait(stream_, dispatcher_, mainSignals_[signalIndex], profilerInput_.stage));
     481              :     }
     482            0 :     return HCCL_SUCCESS;
     483              : }
     484              : // 从流告诉主流活干完了
     485            0 : HcclResult AlignedAllGatherDoubleRing::SubRecordMain()
     486              : {
     487            0 :     for (u32 streamIndex = 0; streamIndex < mainSignals_.size(); streamIndex++) {
     488            0 :         CHK_RET(
     489              :             LocalNotify::Post(subStreams_[streamIndex], dispatcher_, mainSignals_[streamIndex], profilerInput_.stage));
     490              :     }
     491            0 :     return HCCL_SUCCESS;
     492              : }
     493              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_ALIGNED_ALL_GATHER_DOUBLE_RING, AlignedAllGatherDoubleRing);
     494              : } // namespace hccl
        

Generated by: LCOV version 2.0-1