LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_reduce_scatter - reduce_scatter_mesh_atomic.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 11.3 % 106 12
Test Date: 2026-07-28 12:11:00 Functions: 57.1 % 7 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 "reduce_scatter_mesh_atomic.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15              : using namespace std;
      16              : 
      17            1 : ReduceScatterMeshAtomic::ReduceScatterMeshAtomic(const HcclDispatcher dispatcher)
      18            1 :     : AlgTemplateBase(dispatcher)
      19            1 : {}
      20              : 
      21            2 : ReduceScatterMeshAtomic::~ReduceScatterMeshAtomic() {}
      22              : 
      23            1 : HcclResult ReduceScatterMeshAtomic::Prepare(DeviceMem &inputMem, DeviceMem &outputMem, DeviceMem &scratchMem,
      24              :                                             const u64 count, const HcclDataType dataType, const Stream &stream,
      25              :                                             const HcclReduceOp reductionOp, const u32 root,
      26              :                                             const std::vector<Slice> &slices, const u64 baseOffset,
      27              :                                             const u64 reduceAttrBitMap, std::vector<Stream> &meshStreams,
      28              :                                             std::vector<std::shared_ptr<LocalNotify>> &meshSignal,
      29              :                                             std::vector<std::shared_ptr<LocalNotify>> &meshSignalAux,
      30              :                                             u32 userRank, const HcomCollOpInfo *opInfo)
      31              : {
      32            1 :     reduceAttr_ = reduceAttrBitMap;
      33            1 :     userRank_ = userRank;
      34            1 :     meshStreams_ = meshStreams;
      35            1 :     meshSignalPtr_ = &meshSignal;
      36            1 :     meshSignalAuxPtr_ = &meshSignalAux;
      37              :     (void)opInfo;
      38            4 :     return AlgTemplateBase::Prepare(inputMem, outputMem, scratchMem, count, dataType, stream, reductionOp,
      39            2 :         root, slices, baseOffset);
      40              : }
      41              : 
      42            0 : HcclResult ReduceScatterMeshAtomic::RunReduceScatter(const std::vector<LINK> &links)
      43              : {
      44              :     // 拼接所有stream
      45            0 :     vector<Stream> streamVct;
      46            0 :     streamVct.reserve(localRankSize_ - 1); // 有ranksize-1个对端,每个对端对应一条stream
      47            0 :     streamVct.push_back(stream_);          // 增加主stream
      48            0 :     streamVct.insert(streamVct.end(), meshStreams_.begin(), meshStreams_.end()); // 增加从stream
      49              : 
      50              :     // 每个stream只负责一个对端的交互
      51            0 :     for (u32 streamIndex = 0; streamIndex < localRankSize_ - 1; streamIndex++) {
      52            0 :         u32 remoteRank = (streamIndex + localRank_ + 1) % localRankSize_;
      53            0 :         const LINK &dstLink = links[remoteRank];
      54            0 :         Stream &stream = streamVct[streamIndex];
      55              : 
      56            0 :         CHK_RET(dstLink->TxAck(stream));
      57            0 :         CHK_RET(dstLink->RxAck(stream));
      58              :     }
      59              : 
      60            0 :     for (u32 streamIndex = 0; streamIndex < localRankSize_ - 1; streamIndex++) {
      61            0 :         u32 remoteRank = (streamIndex + localRank_ + 1) % localRankSize_;
      62            0 :         const LINK &dstLink = links[remoteRank];
      63            0 :         Stream &stream = streamVct[streamIndex];
      64            0 :         profilerInput_.streamID = stream.id();
      65            0 :         profilerInput_.planeID = streamIndex - 1;
      66            0 :         profilerInput_.step = HCCL_EXEC_STEP_NOT_SET;
      67              : 
      68            0 :         Slice &rxSlice = slices_[localRank_];
      69            0 :         if (streamIndex == 0) {
      70            0 :             for (u32 signalIndex = 0; signalIndex < localRankSize_ - 2; signalIndex++) { // rankSize-2: stream num
      71            0 :                 CHK_RET(LocalNotify::Wait(stream, dispatcher_, (*meshSignalPtr_)[signalIndex], profilerInput_.stage));
      72              :             }
      73            0 :             for (u32 signalIndex = 0; signalIndex < localRankSize_ - 2; signalIndex++) { // rankSize-2: stream num
      74            0 :                 CHK_RET(LocalNotify::Post(stream, dispatcher_, (*meshSignalAuxPtr_)[signalIndex],
      75              :                     profilerInput_.stage));
      76              :             }
      77              :         } else {
      78            0 :             u32 signalIndex = streamIndex - 1;
      79            0 :             CHK_RET(LocalNotify::Post(stream, dispatcher_, (*meshSignalPtr_)[signalIndex],
      80              :                 profilerInput_.stage));
      81            0 :             CHK_RET(LocalNotify::Wait(stream, dispatcher_, (*meshSignalAuxPtr_)[signalIndex], profilerInput_.stage));
      82              :         }
      83              : 
      84            0 :         HCCL_DEBUG(
      85              :             "ReduceScatterMeshAtomic RX rank[%u] inputMemSize[%llu], rxSlice.offset[%llu], rxSlice.size[%llu] "
      86              :             "baseOffset_[%llu]",
      87              :             localRank_, inputMem_.size(), rxSlice.offset, rxSlice.size, baseOffset_);
      88            0 :         DeviceMem dstMem = inputMem_.range(rxSlice.offset, rxSlice.size);
      89            0 :         void *remoteMem = nullptr;
      90            0 :         CHK_RET(dstLink->GetRemoteMem(UserMemType::INPUT_MEM, &remoteMem));
      91            0 :         CHK_RET(HcclReduceAsync(dispatcher_, static_cast<s8 *>(remoteMem) + baseOffset_ + rxSlice.offset,
      92              :             dstMem.size() / SIZE_TABLE[dataType_], dataType_, reductionOp_, stream,
      93              :             dstMem.ptr(), dstLink->GetRemoteRank(), dstLink->GetLinkType(), INLINE_REDUCE_BIT));
      94              : 
      95            0 :         CHK_RET(dstLink->TxDataSignal(stream));
      96            0 :         CHK_RET(dstLink->RxDataSignal(stream));
      97            0 :     }
      98              :     // 添加空task,保证执行时不乱序
      99            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, streamVct[0], dispatcher_));
     100            0 :     return HCCL_SUCCESS;
     101            0 : }
     102              : 
     103            0 : HcclResult ReduceScatterMeshAtomic::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
     104              : {
     105            0 :     CHK_SMART_PTR_NULL(dispatcher_);
     106            0 :     CHK_PTR_NULL(stream_.ptr());
     107            0 :     HCCL_INFO("ReduceScatterMeshAtomic run: rank[%u] totalrank[%u] inputMem[%p] outputMem[%p] count[%llu]", rank,
     108              :         rankSize, inputMem_.ptr(), outputMem_.ptr(), count_);
     109              : 
     110            0 :     localRank_ = rank;
     111            0 :     localRankSize_ = rankSize;
     112              : 
     113            0 :     if (localRankSize_ == 1) {
     114            0 :         if (inputMem_ != outputMem_) {
     115            0 :             return HcclD2DMemcpyAsync(dispatcher_, outputMem_, inputMem_, stream_);
     116              :         }
     117            0 :         return HCCL_SUCCESS;
     118              :     }
     119              : 
     120            0 :     if (links.size() < rankSize) {
     121            0 :         HCCL_ERROR("[ReduceScatterMeshAtomic][RunAsync]rank[%u] linksize[%zu] error", rank, links.size());
     122            0 :         return HCCL_E_INTERNAL;
     123              :     }
     124            0 :     CHK_RET(MemSlice());
     125              : 
     126            0 :     for (u32 streamIndex = 0; streamIndex < rankSize - 2; streamIndex++) { // rankSize-2: stream num
     127            0 :         HCCL_DEBUG("rank[%u] streamindex[%u] wait signalaux[%p]",
     128              :             rank, streamIndex, (*meshSignalAuxPtr_)[streamIndex]->ptr());
     129            0 :         CHK_RET(LocalNotify::Wait(meshStreams_[streamIndex], dispatcher_, (*meshSignalAuxPtr_)[streamIndex],
     130              :             profilerInput_.stage));
     131              :     }
     132            0 :     for (u32 streamIndex = 0; streamIndex < rankSize - 2; streamIndex++) { // rankSize-2: stream num
     133            0 :         CHK_RET(LocalNotify::Post(stream_, dispatcher_, (*meshSignalAuxPtr_)[streamIndex],
     134              :             profilerInput_.stage));
     135              :     }
     136              : 
     137            0 :     CHK_RET(RunReduceScatter(links));
     138              : 
     139            0 :     for (u32 streamIndex = 0; streamIndex < rankSize - 2; streamIndex++) { // rankSize - 2 stream num
     140            0 :         HCCL_DEBUG("rank[%u] streamindex[%u] wait signal[%p] ",
     141              :             rank, streamIndex, (*meshSignalPtr_)[streamIndex]->ptr());
     142            0 :         CHK_RET(LocalNotify::Wait(stream_, dispatcher_, (*meshSignalPtr_)[streamIndex], profilerInput_.stage));
     143            0 :         CHK_RET(LocalNotify::Post(meshStreams_[streamIndex], dispatcher_, (*meshSignalPtr_)[streamIndex],
     144              :             profilerInput_.stage));
     145              :     }
     146              : 
     147              :     // 添加空task,保证执行时不乱序
     148            0 :     CHK_RET(AlgTemplateBase::ExecEmptyTask(inputMem_, outputMem_, stream_, dispatcher_));
     149              : 
     150            0 :     if (inputMem_ != outputMem_) {
     151            0 :         DeviceMem src = inputMem_.range(slices_[localRank_].offset, slices_[localRank_].size);
     152            0 :         HCCL_DEBUG("rank[%u] copy result from to output[%p] offset[%llu] size[%llu] ", localRank_, outputMem_.ptr(),
     153              :             slices_[localRank_].offset, slices_[localRank_].size);
     154            0 :         HcclResult ret = HcclD2DMemcpyAsync(dispatcher_, outputMem_, src, stream_);
     155            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     156              :             HCCL_ERROR("[ReduceScatterMeshAtomic][RunAsync]rank[%u] memcpy async from mem[%p] "
     157              :             "to ouputmem[%p] failed",
     158              :             rank, src.ptr(), outputMem_.ptr()),
     159              :             ret);
     160            0 :     }
     161              : 
     162            0 :     HCCL_INFO("ReduceScatterMeshAtomic finished: rank[%u]", rank);
     163            0 :     return HCCL_SUCCESS;
     164              : }
     165              : 
     166            0 : HcclResult ReduceScatterMeshAtomic::MemSlice()
     167              : {
     168            0 :     u32 unitSize = SIZE_TABLE[dataType_];
     169            0 :     if (unitSize == 0) {
     170            0 :         HCCL_ERROR("[ReduceScatterMeshAtomic][RunAsync]rank[%u] unit data size is zero", localRank_);
     171            0 :         return HCCL_E_INTERNAL;
     172              :     }
     173              : 
     174            0 :     if (HcclCheckLogLevel(DLOG_DEBUG)) {
     175            0 :         for (size_t i = 0; i < slices_.size(); i++) {
     176            0 :             HCCL_DEBUG("[ReduceScatterMeshAtomic] rank[%u] index[%zu] size[%llu] offset[%llu]", localRank_, i,
     177              :                 slices_[i].size, slices_[i].offset);
     178              :         }
     179            0 :         HCCL_DEBUG("[ReduceScatterMeshAtomic] localRankSize[%u]", localRankSize_);
     180              :     }
     181              : 
     182            0 :     if (slices_.size() == 0) {
     183            0 :         slices_.resize(localRankSize_);
     184            0 :         u64 sliceSize = count_ * unitSize;
     185            0 :         for (u32 i = 0; i < localRankSize_; i++) {
     186            0 :             slices_[i].size = sliceSize;
     187            0 :             slices_[i].offset = (i * sliceSize);
     188              :         }
     189              :     }
     190              : 
     191            0 :     scratchSlices_.resize(localRankSize_);
     192            0 :     for (u32 i = 0; i < localRankSize_; i++) {
     193            0 :         scratchSlices_[i].size = slices_[i].size;
     194            0 :         scratchSlices_[i].offset = (scratchMem_.size() < inputMem_.size()) ? 0 : slices_[i].offset;
     195              :     }
     196              : 
     197            0 :     if (HcclCheckLogLevel(DLOG_DEBUG)) {
     198            0 :         for (size_t i = 0; i < slices_.size(); i++) {
     199            0 :             HCCL_DEBUG("ReduceScatterMeshAtomic rank[%u] index[%zu] " \
     200              :                 "size[%llu] offset[%llu] scratch_size[%llu] scratch_offset[%llu]",
     201              :                 localRank_, i, slices_[i].size, slices_[i].offset, scratchSlices_[i].size, scratchSlices_[i].offset);
     202              :         }
     203              :     }
     204              : 
     205            0 :     return HCCL_SUCCESS;
     206              : }
     207              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_REDUCESCATTER_MESH_ATOMIC, ReduceScatterMeshAtomic);
     208              : }
        

Generated by: LCOV version 2.0-1