LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_scatter - scatter_double_ring_direct.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 192 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 15 0

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "scatter_double_ring_direct.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15              : 
      16              : constexpr u32 RANK_SIZE_THREE = 3;
      17              : 
      18            0 : ScatterDoubleRingDirect::ScatterDoubleRingDirect(const HcclDispatcher dispatcher) : AlgTemplateBase(dispatcher) {}
      19              : 
      20            0 : ScatterDoubleRingDirect::~ScatterDoubleRingDirect() {}
      21              : 
      22            0 : HcclResult ScatterDoubleRingDirect::Prepare(
      23              :     HcomCollOpInfo* opInfo, const u32 userRank, const u32 subRingRank, std::vector<Stream>& subStreams,
      24              :     const std::vector<std::shared_ptr<LocalNotify>>& mainSignals,
      25              :     const std::vector<std::shared_ptr<LocalNotify>>& subSignals, const std::vector<std::vector<u32>>& ringsOrders,
      26              :     const std::vector<std::vector<Slice>>& multiRingSlices, const std::vector<std::vector<Slice>>& userMemInputSlices)
      27              : {
      28            0 :     opInfo_ = opInfo;
      29            0 :     userRank_ = userRank;
      30            0 :     subRingRank_ = subRingRank;
      31            0 :     subStreams_ = subStreams;
      32            0 :     mainSignals_ = mainSignals;
      33            0 :     subSignals_ = subSignals;
      34            0 :     ringsOrders_ = ringsOrders;
      35            0 :     multiRingSlices_ = multiRingSlices;
      36            0 :     userMemInputSlices_ = userMemInputSlices;
      37            0 :     return HCCL_SUCCESS;
      38              : }
      39              : 
      40              : // reduce scatter ring direct算法的函数入口
      41            0 : HcclResult ScatterDoubleRingDirect::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
      42              : {
      43              :     // 基本的检查
      44            0 :     CHK_RET(CheckParameters(rank, rankSize, links));
      45              : 
      46              :     // 判断rank_size == 1
      47            0 :     if (rankSize == 1) {
      48            0 :         CHK_RET(MemcpyByOneRank());
      49            0 :         return HCCL_SUCCESS;
      50              :     }
      51              :     // 收集邻居信息
      52            0 :     CHK_RET(GetInitializedNeighborLinks(rank, rankSize, links));
      53              : 
      54              :     // 运行scatter, ring算法
      55            0 :     CHK_RET(RunScatter(rank, rankSize));
      56            0 :     CHK_RET(LaunchTaskExtend(dispatcher_, stream_, subStreams_));
      57              : 
      58            0 :     HCCL_INFO("ScatterDoubleRingDirect finished: rank[%u]", rank);
      59            0 :     return HCCL_SUCCESS;
      60              : }
      61              : 
      62            0 : HcclResult ScatterDoubleRingDirect::CheckParameters(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
      63              : {
      64            0 :     CHK_PTR_NULL(opInfo_);
      65            0 :     CHK_RET(CheckConcurrentDirectParameters(rank, rankSize, links));
      66              :     // 判断ranksize大小
      67            0 :     CHK_PRT_RET(
      68              :         rankSize < 1, HCCL_ERROR("[ScatterDoubleRingDirect] rankSize size[%u] is less than 1", rankSize), HCCL_E_PARA);
      69              :     // 判断subStreams数量是否正确
      70            0 :     if (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
      71            0 :         CHK_PRT_RET(
      72              :             subStreams_.size() != 1,
      73              :             HCCL_ERROR("[ScatterDoubleRingDirect] subStreams size[%u] must equal to 1", subStreams_.size()),
      74              :             HCCL_E_PARA);
      75              :     } else {
      76            0 :         CHK_PRT_RET(
      77              :             subStreams_.size() != DOUBLE_RING_STREAM_NUM,
      78              :             HCCL_ERROR("[ScatterDoubleRingDirect] subStreams size[%u] must equal to 3", subStreams_.size()),
      79              :             HCCL_E_PARA);
      80              :     }
      81            0 :     for (auto& s : subStreams_) {
      82            0 :         CHK_PTR_NULL(s.ptr());
      83              :     }
      84              :     // 判断mainSignals数量是否正确
      85            0 :     CHK_PRT_RET(
      86              :         mainSignals_.size() < 1,
      87              :         HCCL_ERROR("[ScatterDoubleRingDirect] mainSignals size[%u] is less than 1", mainSignals_.size()), HCCL_E_PARA);
      88              :     // 判断subSignals数量是否正确
      89            0 :     CHK_PRT_RET(
      90              :         subSignals_.size() < 1,
      91              :         HCCL_ERROR("[ScatterDoubleRingDirect] subSignals size[%u] is less than 1", subSignals_.size()), HCCL_E_PARA);
      92              :     // 判断ringsOrder size, multiRingSlices size, userMemInputSlices size是否正确
      93            0 :     if (ringsOrders_.size() != DOUBLE_RING_NUM || multiRingSlices_.size() != DOUBLE_RING_NUM
      94            0 :         || userMemInputSlices_.size() != DOUBLE_RING_NUM) {
      95            0 :         HCCL_ERROR(
      96              :             "[ScatterDoubleRingDirect] ringsOrder size[%u], multiRingSlices size[%u], userMemInputSlices"
      97              :             "size[%u] must equal to 2",
      98              :             ringsOrders_.size(), multiRingSlices_.size(), userMemInputSlices_.size());
      99            0 :         return HCCL_E_PARA;
     100              :     }
     101              :     // 判断ringsOrder数量是否正确
     102            0 :     for (u32 ringIndex = 0; ringIndex < ringsOrders_.size(); ringIndex++) {
     103            0 :         CHK_PRT_RET(
     104              :             ringsOrders_[ringIndex].size() != rankSize,
     105              :             HCCL_ERROR(
     106              :                 "[ScatterDoubleRingDirect] ringsOrders[%u] size[%u] must equal to rank size[%u]", ringIndex,
     107              :                 ringsOrders_[ringIndex].size(), rankSize),
     108              :             HCCL_E_PARA);
     109              :     }
     110              :     // 判断multiRingSlices数量是否正确
     111            0 :     for (u32 ringIndex = 0; ringIndex < multiRingSlices_.size(); ringIndex++) {
     112            0 :         CHK_PRT_RET(
     113              :             multiRingSlices_[ringIndex].size() != rankSize,
     114              :             HCCL_ERROR(
     115              :                 "[ScatterDoubleRingDirect] multiRingSlices[%u] size[%u] must equal to rank size[%u]", ringIndex,
     116              :                 multiRingSlices_[ringIndex].size(), rankSize),
     117              :             HCCL_E_PARA);
     118              :     }
     119              :     // 判断userMemInputSlices数量是否正确
     120            0 :     for (u32 ringIndex = 0; ringIndex < userMemInputSlices_.size(); ringIndex++) {
     121            0 :         CHK_PRT_RET(
     122              :             userMemInputSlices_[ringIndex].size() != rankSize,
     123              :             HCCL_ERROR(
     124              :                 "[ScatterDoubleRingDirect] userMemInputSlices_[%u] size[%u] must equal to rank size[%u]", ringIndex,
     125              :                 userMemInputSlices_[ringIndex].size(), rankSize),
     126              :             HCCL_E_PARA);
     127              :     }
     128            0 :     HCCL_INFO("ScatterDoubleRingDirect CheckParameters success");
     129            0 :     return HCCL_SUCCESS;
     130              : }
     131              : 
     132            0 : HcclResult ScatterDoubleRingDirect::MemcpyByOneRank()
     133              : {
     134            0 :     for (u32 ringIndex = 0; ringIndex < multiRingSlices_.size(); ringIndex++) {
     135            0 :         const Slice& srcSlice = userMemInputSlices_[ringIndex][0];
     136            0 :         const Slice& dstSlice = multiRingSlices_[ringIndex][0];
     137            0 :         DeviceMem src = DeviceMem::create(static_cast<u8*>(opInfo_->inputAddr) + srcSlice.offset, srcSlice.size);
     138            0 :         DeviceMem dst;
     139            0 :         if (opInfo_->outputAddr != nullptr) {
     140              :             // opInfo_->outputAddr != nullptr指示要将输出发送至user output
     141            0 :             u64 stepOffset = multiRingSlices_[ringIndex][ringsOrders_[ringIndex][0]].offset;
     142            0 :             HCCL_DEBUG(
     143              :                 "Memcpy operation: stream[main], rank[%u] starts to rcv offset[%llu], size[%llu] at userMemOut_",
     144              :                 userRank_, stepOffset, dstSlice.size);
     145            0 :             dst = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + stepOffset, dstSlice.size);
     146              :         } else {
     147              :             // opInfo_->outputAddr == nullptr指示要将输出发送至CCL buffer
     148            0 :             HCCL_DEBUG(
     149              :                 "Memcpy operation: stream[main], rank[%u] starts to rcv offset[%llu], size[%llu] at outputMem_",
     150              :                 userRank_, dstSlice.offset, dstSlice.size);
     151            0 :             dst = outputMem_.range(dstSlice.offset, dstSlice.size);
     152              :         }
     153            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, stream_));
     154            0 :     }
     155            0 :     return HCCL_SUCCESS;
     156              : }
     157              : 
     158              : HcclResult
     159            0 : ScatterDoubleRingDirect::GetInitializedNeighborLinks(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
     160              : {
     161              :     // 收集左邻居信息
     162            0 :     leftLink_ = links[(rank + rankSize - 1) % rankSize];
     163            0 :     CHK_SMART_PTR_NULL(leftLink_);
     164              : 
     165              :     // 收集右邻居信息
     166            0 :     rightLink_ = links[(rank + 1) % rankSize];
     167            0 :     CHK_SMART_PTR_NULL(rightLink_);
     168            0 :     HCCL_INFO("ScatterDoubleRingDirect finished to GetInitializedNeighborLinks");
     169            0 :     return HCCL_SUCCESS;
     170              : }
     171              : 
     172            0 : HcclResult ScatterDoubleRingDirect::RunInitStep(const u32 rank, const u32 rankSize)
     173              : {
     174            0 :     if (rank != root_) {
     175            0 :         return HCCL_SUCCESS;
     176              :     }
     177            0 :     for (u32 ringIndex = 0; ringIndex < multiRingSlices_.size(); ringIndex++) {
     178            0 :         u32 initSlice0Idx = 0;
     179            0 :         if (ringIndex == 0) {
     180            0 :             initSlice0Idx = (rank + rankSize - 1) % rankSize;
     181              :         } else {
     182            0 :             initSlice0Idx = (subRingRank_ + rankSize - 1) % rankSize;
     183              :         }
     184            0 :         const Slice& srcInitSlice0 = userMemInputSlices_[ringIndex][initSlice0Idx];
     185              :         DeviceMem srcInit
     186            0 :             = DeviceMem::create(static_cast<u8*>(opInfo_->inputAddr) + srcInitSlice0.offset, srcInitSlice0.size);
     187            0 :         const Slice& dstInitSlice0 = multiRingSlices_[ringIndex][initSlice0Idx];
     188            0 :         DeviceMem dstInit = inputMem_.range(dstInitSlice0.offset, dstInitSlice0.size);
     189            0 :         HCCL_DEBUG(
     190              :             "Memcpy operation: step[-1] stream[sub] src rank[%u] starts to copy(rcv) offset[%llu], size[%llu] "
     191              :             "on userMemInput to offset[%llu], size[%llu] on CCL",
     192              :             userRank_, srcInitSlice0.offset, srcInitSlice0.size, dstInitSlice0.offset, dstInitSlice0.size);
     193            0 :         if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
     194            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstInit, srcInit, stream_));
     195              :         }
     196            0 :     }
     197              :     // 第-1步,片内将部分数据从userIn搬到cclIn
     198            0 :     return HCCL_SUCCESS;
     199              : }
     200              : 
     201            0 : HcclResult ScatterDoubleRingDirect::RunAllStreams(
     202              :     const u32 rank, const u32 step, const u32 rankSize, RxMemoryInfo& mainRxMem, RxMemoryInfo& subRxMem,
     203              :     DeviceMem& mainLocalSrcMem, DeviceMem& mainLocalDstMem, DeviceMem& subLocalSrcMem, DeviceMem& subLocalDstMem)
     204              : {
     205              :     (void)step;
     206              :     (void)rankSize;
     207            0 :     Stream mainStream = stream_;
     208            0 :     LINK mainPreLink = rightLink_;
     209            0 :     LINK mainNextLink = leftLink_;
     210            0 :     Stream subStream = subStreams_[0];
     211            0 :     LINK subPreLink = leftLink_;
     212            0 :     LINK subNextLink = rightLink_;
     213              : 
     214              :     // 唤醒所有环的主流做跨片同步
     215            0 :     CHK_RET(LocalNotify::Post(stream_, dispatcher_, subSignals_[0], profilerInput_.stage));
     216            0 :     CHK_RET(LocalNotify::Wait(subStreams_[0], dispatcher_, subSignals_[0], profilerInput_.stage));
     217              : 
     218            0 :     CHK_RET(mainNextLink->TxAck(mainStream));
     219            0 :     CHK_RET(subNextLink->TxAck(subStream));
     220              : 
     221            0 :     CHK_RET(mainPreLink->RxAck(mainStream));
     222            0 :     CHK_RET(subPreLink->RxAck(subStream));
     223              : 
     224              :     // 回到主流
     225            0 :     CHK_RET(LocalNotify::Post(subStreams_[0], dispatcher_, mainSignals_[0], profilerInput_.stage));
     226            0 :     CHK_RET(LocalNotify::Wait(stream_, dispatcher_, mainSignals_[0], profilerInput_.stage));
     227              : 
     228              :     // 主流唤醒所有流做跨片拷贝和片内拷贝
     229            0 :     CHK_RET(MainRecordSub());
     230              : 
     231              :     // 小数据量减少冗余通信,
     232            0 :     const u64 SMALL_DATASIZE = 4 * 1024 * 1024;
     233            0 :     bool isLargeCount = opInfo_->count * SIZE_TABLE[opInfo_->dataType] > SMALL_DATASIZE;
     234            0 :     if (isLargeCount || (step + 1 >= (root_ + rankSize - rank) % rankSize)) {
     235            0 :         CHK_RET(RxAsyncMemcpy(mainRxMem, mainStream, mainPreLink));
     236              :     }
     237            0 :     if (isLargeCount || (step + 1 >= (rank + rankSize - root_) % rankSize)) {
     238            0 :         CHK_RET(RxAsyncMemcpy(subRxMem, subStream, subPreLink));
     239              :     }
     240              : 
     241              :     // 本地拷贝
     242            0 :     if (rank == root_ && GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OPS_KERNEL_INFO_LIB) {
     243            0 :         if (mainLocalDstMem != mainLocalSrcMem) {
     244            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, mainLocalDstMem, mainLocalSrcMem, subStreams_[1]));
     245              :         }
     246            0 :         if (subLocalDstMem != subLocalSrcMem) {
     247            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, subLocalDstMem, subLocalSrcMem, subStreams_[2]));
     248              :         }
     249              :     }
     250              : 
     251            0 :     CHK_RET(mainPreLink->TxDataSignal(mainStream));
     252            0 :     CHK_RET(subPreLink->TxDataSignal(subStream));
     253              : 
     254            0 :     CHK_RET(mainNextLink->RxDataSignal(mainStream));
     255            0 :     CHK_RET(subNextLink->RxDataSignal(subStream));
     256              : 
     257            0 :     CHK_RET(MainWaitSub());
     258            0 :     return HCCL_SUCCESS;
     259            0 : }
     260              : 
     261            0 : HcclResult ScatterDoubleRingDirect::RxAsyncMemcpy(RxMemoryInfo& mem, Stream& stream, LINK& link)
     262              : {
     263            0 :     CHK_PTR_NULL(mem.dst);
     264            0 :     void* srcMemPtr = nullptr;
     265            0 :     CHK_RET(link->GetRemoteMem(mem.srcMemType, &srcMemPtr));
     266              : 
     267            0 :     DeviceMem srcDevMem(static_cast<s8*>(srcMemPtr) + mem.srcOffset, mem.len);
     268            0 :     DeviceMem dstDevMem(static_cast<s8*>(mem.dst), mem.len);
     269            0 :     CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dstDevMem, srcDevMem, stream, link->GetRemoteRank(), link->GetLinkType()));
     270            0 :     return HCCL_SUCCESS;
     271            0 : }
     272              : 
     273            0 : HcclResult ScatterDoubleRingDirect::PrepareDeviceMems(
     274              :     const u32 rank, const u32 step, const u32 ringIndex, const u32 rankSize, const u32 subSliceIdx,
     275              :     const u32 rxSliceIdx, RxMemoryInfo& rxMem, DeviceMem& localSrcMem, DeviceMem& localDstMem)
     276              : {
     277            0 :     const Slice& subSlice = userMemInputSlices_[ringIndex][subSliceIdx];
     278            0 :     const Slice& cclSlice = multiRingSlices_[ringIndex][subSliceIdx];
     279            0 :     const Slice& rxSlice = multiRingSlices_[ringIndex][rxSliceIdx];
     280              : 
     281            0 :     u64 lastStepOffset = multiRingSlices_[ringIndex][ringsOrders_[ringIndex][0]].offset;
     282              : 
     283            0 :     DeviceMem dst;
     284            0 :     if (step == rankSize - DMA_REDUCE_TWO_OFFSET && opInfo_->outputAddr != nullptr) {
     285            0 :         HCCL_DEBUG(
     286              :             "MemcpyAsync operation: step[%u] stream[main], dst rank[%u] starts to rcv offset[%llu], "
     287              :             "size[%llu] at userMemOut_",
     288              :             step, userRank_, lastStepOffset, rxSlice.size);
     289            0 :         dst = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + lastStepOffset, rxSlice.size);
     290              :     } else {
     291            0 :         HCCL_DEBUG(
     292              :             "MemcpyAsync operation: step[%u] stream[main], dst rank[%u] starts to rcv offset[%llu], "
     293              :             "size[%llu] at inputMem_",
     294              :             step, userRank_, rxSlice.offset, rxSlice.size);
     295            0 :         dst = inputMem_.range(rxSlice.offset, rxSlice.size);
     296              :     }
     297            0 :     rxMem = RxMemoryInfo{UserMemType::INPUT_MEM, rxSlice.offset + baseOffset_, dst.ptr(), rxSlice.size};
     298              : 
     299            0 :     if (rank == root_) {
     300              :         // root节点参与通信,避免片内拷贝带宽过高过分抢占HBM带宽导致其他节点读取数据时性能下降
     301            0 :         u32 rxSliceIdxForRoot = (rxSliceIdx + DMA_REDUCE_TWO_OFFSET) % rankSize;
     302            0 :         Slice rxSliceForRoot = multiRingSlices_[ringIndex][rxSliceIdxForRoot];
     303            0 :         if ((rankSize < RANK_SIZE_THREE && step == 0) || (inputMem_.ptr() == opInfo_->inputAddr))
     304            0 :             rxSliceForRoot.size = 0;
     305            0 :         dst = inputMem_.range(rxSliceForRoot.offset, rxSliceForRoot.size);
     306              :         rxMem
     307            0 :             = RxMemoryInfo{UserMemType::INPUT_MEM, rxSliceForRoot.offset + baseOffset_, dst.ptr(), rxSliceForRoot.size};
     308            0 :         HCCL_DEBUG(
     309              :             "Memcpy operation: step[%u] stream[sub], src rank[%u] starts to send offset[%llu], size[%llu] "
     310              :             "from userMemIn_",
     311              :             step, userRank_, subSlice.offset, subSlice.size);
     312            0 :         localSrcMem = DeviceMem::create(static_cast<u8*>(opInfo_->inputAddr) + subSlice.offset, subSlice.size);
     313            0 :         if (step == rankSize - DMA_REDUCE_TWO_OFFSET && opInfo_->outputAddr != nullptr) {
     314            0 :             HCCL_DEBUG(
     315              :                 "Memcpy operation: step[%u] stream[sub], dst rank[%u] starts to rcv offset[%llu], size[%llu] "
     316              :                 "to userMemOut_",
     317              :                 step, userRank_, lastStepOffset, subSlice.size);
     318            0 :             localDstMem = DeviceMem::create(static_cast<u8*>(opInfo_->outputAddr) + lastStepOffset, subSlice.size);
     319              :         } else {
     320            0 :             HCCL_DEBUG(
     321              :                 "Memcpy operation: step[%u] stream[sub], dst rank[%u] starts to rcv offset[%llu], size[%llu] "
     322              :                 "to inputMem_",
     323              :                 step, userRank_, cclSlice.offset, cclSlice.size);
     324            0 :             localDstMem = inputMem_.range(cclSlice.offset, cclSlice.size);
     325              :         }
     326              :     }
     327            0 :     return HCCL_SUCCESS;
     328            0 : }
     329              : 
     330            0 : HcclResult ScatterDoubleRingDirect::RunScatter(const u32 rank, const u32 rankSize)
     331              : {
     332            0 :     HCCL_INFO("ScatterDoubleRingDirect starts, the input param rank[%u]", rank);
     333              : 
     334            0 :     CHK_RET(RunInitStep(rank, rankSize));
     335              : 
     336              :     // 例如rank[0,1,2,3]中,rank0的rxSliceIdx = 2,txSliceIdx = 3, subSliceIdx = 1
     337            0 :     u32 subSliceIdx = (rank + rankSize - DMA_REDUCE_TWO_OFFSET) % rankSize;
     338            0 :     u32 mainSliceIdx = (subRingRank_ + rankSize - DMA_REDUCE_TWO_OFFSET) % rankSize;
     339              : 
     340            0 :     for (u32 step = 0; step < rankSize - 1; step++) {
     341              :         RxMemoryInfo rxMemSub;
     342            0 :         DeviceMem localSrcMemSub;
     343            0 :         DeviceMem localDstMemSub;
     344            0 :         CHK_RET(PrepareDeviceMems(
     345              :             rank, step, ALIGNED_SUB_RING_INDEX, rankSize, subSliceIdx, subSliceIdx, rxMemSub, localSrcMemSub,
     346              :             localDstMemSub));
     347              :         RxMemoryInfo rxMemMain;
     348            0 :         DeviceMem localSrcMemMain;
     349            0 :         DeviceMem localDstMemMain;
     350            0 :         CHK_RET(PrepareDeviceMems(
     351              :             rank, step, ALIGNED_MAIN_RING_INDEX, rankSize, mainSliceIdx, mainSliceIdx, rxMemMain, localSrcMemMain,
     352              :             localDstMemMain));
     353              : 
     354            0 :         CHK_RET(RunAllStreams(
     355              :             rank, step, rankSize, rxMemMain, rxMemSub, localSrcMemMain, localDstMemMain, localSrcMemSub,
     356              :             localDstMemSub));
     357              : 
     358              :         // 更新索引
     359            0 :         mainSliceIdx = (mainSliceIdx + rankSize - 1) % rankSize;
     360            0 :         subSliceIdx = (subSliceIdx + rankSize - 1) % rankSize;
     361            0 :     }
     362            0 :     HCCL_INFO("ScatterDoubleRingDirect finished to RunScatter");
     363            0 :     return HCCL_SUCCESS;
     364              : }
     365              : 
     366              : // 主流通知从流干活, 从流等待主流
     367            0 : HcclResult ScatterDoubleRingDirect::MainRecordSub()
     368              : {
     369            0 :     for (u32 signalIndex = 0; signalIndex < subSignals_.size(); signalIndex++) {
     370            0 :         CHK_RET(LocalNotify::Post(stream_, dispatcher_, subSignals_[signalIndex], profilerInput_.stage));
     371              :     }
     372            0 :     for (u32 signalIndex = 0; signalIndex < subSignals_.size(); signalIndex++) {
     373            0 :         CHK_RET(
     374              :             LocalNotify::Wait(subStreams_[signalIndex], dispatcher_, subSignals_[signalIndex], profilerInput_.stage));
     375              :     }
     376            0 :     for (u32 signalIndex = 0; signalIndex < subSignals_.size(); signalIndex++) {
     377            0 :         CHK_RET(ExecEmptyTask(inputMem_, outputMem_, subStreams_[signalIndex], dispatcher_));
     378              :     }
     379            0 :     CHK_RET(ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     380            0 :     return HCCL_SUCCESS;
     381              : }
     382              : 
     383              : // 主流等待从流, 从流告诉主流活干完了
     384            0 : HcclResult ScatterDoubleRingDirect::MainWaitSub()
     385              : {
     386            0 :     for (u32 signalIndex = 0; signalIndex < mainSignals_.size(); signalIndex++) {
     387            0 :         CHK_RET(LocalNotify::Wait(stream_, dispatcher_, mainSignals_[signalIndex], profilerInput_.stage));
     388              :     }
     389            0 :     for (u32 signalIndex = 0; signalIndex < mainSignals_.size(); signalIndex++) {
     390            0 :         CHK_RET(
     391              :             LocalNotify::Post(subStreams_[signalIndex], dispatcher_, mainSignals_[signalIndex], profilerInput_.stage));
     392              :     }
     393            0 :     for (u32 signalIndex = 0; signalIndex < mainSignals_.size(); signalIndex++) {
     394            0 :         CHK_RET(ExecEmptyTask(inputMem_, outputMem_, subStreams_[signalIndex], dispatcher_));
     395              :     }
     396            0 :     CHK_RET(ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     397            0 :     return HCCL_SUCCESS;
     398              : }
     399              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_SCATTER_DOUBLE_RING_DIRECT, ScatterDoubleRingDirect);
     400              : } // namespace hccl
        

Generated by: LCOV version 2.0-1