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

Generated by: LCOV version 2.0-1