LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_all_reduce - all_reduce_nhr_v1.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 163 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 14 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 "alg_template_register.h"
      12              : #include "all_reduce_nhr_v1.h"
      13              : 
      14              : namespace hccl {
      15            0 : AllReduceNHRV1::AllReduceNHRV1(const HcclDispatcher dispatcher) : NHRV1Base(dispatcher) {}
      16              : 
      17            0 : AllReduceNHRV1::~AllReduceNHRV1() {}
      18              : 
      19            0 : HcclResult AllReduceNHRV1::Prepare(u64 reduceAttrBitMap, [[maybe_unused]] HcomCollOpInfo* opInfo)
      20              : {
      21            0 :     reduceAttr_ = reduceAttrBitMap;
      22            0 :     return HCCL_SUCCESS;
      23              : }
      24              : 
      25              : HcclResult
      26            0 : AllReduceNHRV1::RunAsync(const u32 rank, const u32 rankSize, const std::vector<std::shared_ptr<Transport>>& links)
      27              : {
      28            0 :     CHK_RET(PrepareRunAsync(rank, rankSize, links));
      29            0 :     CHK_PRT_RET(
      30              :         rankSize == 1, HCCL_INFO("[AllReduceNHRV1][RunAsync] rankSize[%u], do nothing.", rankSize), HCCL_SUCCESS);
      31              : 
      32            0 :     HcclResult ret = HCCL_SUCCESS;
      33              :     // 获取通信关系
      34            0 :     RingInfo info = GetRingInfo(rankSize);
      35              :     // 水平方向做broken reducescatter ring
      36              : 
      37            0 :     ret = RunReduceScatterOnHorizontal(rank, links, info);
      38            0 :     CHK_PRT_RET(
      39              :         ret != HCCL_SUCCESS,
      40              :         HCCL_ERROR(
      41              :             "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
      42              :             "RunReduceScatterOnHorizontal step",
      43              :             rank, count_),
      44              :         ret);
      45              : 
      46              :     // 垂直方向做allreduce ring
      47            0 :     ret = RunAllReduceOnVertical(rank, links, info);
      48            0 :     CHK_PRT_RET(
      49              :         ret != HCCL_SUCCESS,
      50              :         HCCL_ERROR(
      51              :             "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
      52              :             "RunAllReduceOnVertical step",
      53              :             rank, count_),
      54              :         ret);
      55              : 
      56              :     // 水平方向做broken allgather ring
      57            0 :     ret = RunAllGatherOnHorizontal(rank, links, info);
      58            0 :     CHK_PRT_RET(
      59              :         ret != HCCL_SUCCESS,
      60              :         HCCL_ERROR(
      61              :             "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
      62              :             "RunAllGatherOnHorizontal step",
      63              :             rank, count_),
      64              :         ret);
      65              : 
      66            0 :     HCCL_INFO("AllReduceNHRV1 finished: rank[%u]", rank);
      67            0 :     return HCCL_SUCCESS;
      68            0 : }
      69              : 
      70              : HcclResult
      71            0 : AllReduceNHRV1::RunAsyncStaged(const u32 rank, const u32 rankSize, const std::vector<LINK>& links, RunStage stage)
      72              : {
      73            0 :     CHK_PRT_RET(
      74              :         rankSize == 1 && stage != RunStage::RUN_PREPARE,
      75              :         HCCL_INFO("[AllReduceNHRV1][RunAsyncStaged] rankSize[%u], stage[%d], do nothing.", rankSize, stage),
      76              :         HCCL_SUCCESS);
      77              :     // 获取通信关系
      78            0 :     RingInfo info = GetRingInfo(rankSize);
      79              : 
      80            0 :     HcclResult ret = HCCL_SUCCESS;
      81            0 :     switch (stage) {
      82            0 :         case RunStage::RUN_PREPARE:
      83            0 :             ret = PrepareRunAsync(rank, rankSize, links);
      84            0 :             CHK_PRT_RET(
      85              :                 ret != HCCL_SUCCESS,
      86              :                 HCCL_ERROR(
      87              :                     "[AllReduceNHRV1][RunAsyncStaged]rank[%u] count[%llu] failed in PrepareRunAsync step", rank,
      88              :                     count_),
      89              :                 ret);
      90            0 :             break;
      91            0 :         case RunStage::RUN_REDUCE_SCATTER:
      92              :             // 水平方向做broken reducescatter ring
      93            0 :             ret = RunReduceScatterOnHorizontal(rank, links, info);
      94            0 :             CHK_PRT_RET(
      95              :                 ret != HCCL_SUCCESS,
      96              :                 HCCL_ERROR(
      97              :                     "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
      98              :                     "RunReduceScatterOnHorizontal step",
      99              :                     rank, count_),
     100              :                 ret);
     101            0 :             break;
     102            0 :         case RunStage::RUN_ALLREDUCE:
     103              :             // 垂直方向做allreduce ring
     104            0 :             ret = RunAllReduceOnVertical(rank, links, info);
     105            0 :             CHK_PRT_RET(
     106              :                 ret != HCCL_SUCCESS,
     107              :                 HCCL_ERROR(
     108              :                     "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
     109              :                     "RunAllReduceOnVertical step",
     110              :                     rank, count_),
     111              :                 ret);
     112            0 :             break;
     113            0 :         case RunStage::RUN_ALLGATHER:
     114              :             // 水平方向做broken allgather ring
     115            0 :             ret = RunAllGatherOnHorizontal(rank, links, info);
     116            0 :             CHK_PRT_RET(
     117              :                 ret != HCCL_SUCCESS,
     118              :                 HCCL_ERROR(
     119              :                     "[AllReduceNHRV1][RunAsync]rank[%u] count[%llu] failed in "
     120              :                     "RunAllGatherOnHorizontal step",
     121              :                     rank, count_),
     122              :                 ret);
     123            0 :             break;
     124            0 :         default:
     125            0 :             HCCL_ERROR("[AllReduceNHRV1][RunAsyncStaged]stage[%d]is not support", stage);
     126            0 :             return HCCL_E_NOT_SUPPORT;
     127              :     }
     128            0 :     HCCL_INFO("AllReduceNHRV1 RunAsyncStaged stage[%d] finished: rank[%u] ranksize[%u]", stage, rank, rankSize);
     129            0 :     return HCCL_SUCCESS;
     130            0 : }
     131              : 
     132            0 : HcclResult AllReduceNHRV1::PrepareRunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK>& links)
     133              : {
     134            0 :     HcclResult ret = HCCL_SUCCESS;
     135            0 :     CHK_SMART_PTR_NULL(dispatcher_);
     136            0 :     CHK_PTR_NULL(stream_.ptr());
     137            0 :     CHK_PRT_RET(
     138              :         !outputMem_ || !inputMem_,
     139              :         HCCL_ERROR("[AllReduceNHRV1][RunAsync]rank[%u] run_async inputmem or outputmem is null", rank), HCCL_E_PTR);
     140              : 
     141            0 :     HCCL_INFO(
     142              :         "AllReduceNHRV1 run: rank[%u] ranksize[%u] inputMem[%p] outputMem[%p] count[%llu]", rank, rankSize,
     143              :         inputMem_.ptr(), outputMem_.ptr(), count_);
     144              : 
     145            0 :     CHK_PRT_RET(
     146              :         links.size() < rankSize,
     147              :         HCCL_ERROR(
     148              :             "[AllReduceNHRV1][RunAsync]rank[%u] linksize[%llu] is less "
     149              :             "than rankSize[%u]",
     150              :             rank, links.size(), rankSize),
     151              :         HCCL_E_INTERNAL);
     152              : 
     153              :     // 如果ranksize为1, inline reduce和普通跨片reduce操作一致,从input->output
     154            0 :     if (rankSize == 1) {
     155            0 :         if (inputMem_ != outputMem_) {
     156            0 :             ret = HcclD2DMemcpyAsync(dispatcher_, outputMem_, inputMem_, stream_);
     157            0 :             CHK_PRT_RET(
     158              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[AllReduceNHRV1][RunAsync]rank[%u] memcpy async failed", rank), ret);
     159              :         }
     160            0 :         return ret;
     161              :     }
     162              : 
     163              :     // 检查、并清空slices_
     164            0 :     if (slices_.size() != 0) {
     165            0 :         HCCL_WARNING("[AllReduceNHRV1][RunAsync]AllReduceNHRV1 not supported passing in parameter slice_, "
     166              :                      "otherwise will be cleared");
     167            0 :         slices_.clear();
     168              :     }
     169            0 :     return HCCL_SUCCESS;
     170              : }
     171              : 
     172            0 : HcclResult AllReduceNHRV1::CalcHSlicesAndLinks(
     173              :     const u32 rank, const std::vector<LINK>& links, const RingInfo& info, std::vector<LINK>& hLinks,
     174              :     std::vector<Slice>& hSlices)
     175              : {
     176            0 :     u32 ringSize = info.GetHSizeByRank(rank); // 查找自己所处的行长度,也即Ring的大小
     177            0 :     u32 vIndex = info.GetVIndex(rank);        // 查找自己位于第几行
     178              : 
     179              :     // 计算水平方向每个rank结果上的offset和size
     180            0 :     u64 sliceSizeCalculated = (count_ + (info.GetRowSize() - 1)) / info.GetRowSize() * DataUnitSize(dataType_);
     181            0 :     u64 totalSize = count_ * DataUnitSize(dataType_);
     182            0 :     u64 residueSize = totalSize;
     183            0 :     u64 sliceSizeAligned = AlgTemplateBase::RoundUpWithDivisor(sliceSizeCalculated, HCCL_MIN_SLICE_ALIGN);
     184              : 
     185              :     // 水平方向都为broken ring,故最后一列有可能不需要参与计算,此时size为0
     186            0 :     for (u32 hIdx = 0; hIdx < ringSize; hIdx++) {
     187            0 :         u32 oldRank = info.GetRank(vIndex, hIdx);
     188              : 
     189            0 :         CHK_PRT_RET(
     190              :             oldRank >= links.size(),
     191              :             HCCL_ERROR(
     192              :                 "[AllReduceNHRV1] rank[%u] out of range, "
     193              :                 "oldRank=%u, links.size=%u",
     194              :                 rank, oldRank, links.size()),
     195              :             HCCL_E_INTERNAL);
     196            0 :         hLinks.push_back(links[oldRank]);
     197            0 :         Slice slice;
     198            0 :         if (info.GetVSizeByHIndex(hIdx) == info.GetVSizeByHIndex(0)) {
     199            0 :             slice.size = (residueSize > sliceSizeAligned) ? sliceSizeAligned : residueSize;
     200            0 :             slice.offset = totalSize - residueSize;
     201            0 :             residueSize -= slice.size;
     202              :         } else {
     203            0 :             slice.size = 0;
     204            0 :             slice.offset = 0;
     205              :         }
     206            0 :         HCCL_DEBUG(
     207              :             "[AllReduceNHRV1][CalcHSlicesAndLinks] rank[%u], slices[%u].offset=%llu, slices[%u].size=%llu", rank, hIdx,
     208              :             slice.offset, hIdx, slice.size);
     209            0 :         hSlices.push_back(slice);
     210              :     }
     211            0 :     return HCCL_SUCCESS;
     212              : }
     213              : 
     214            0 : HcclResult AllReduceNHRV1::CalcVSlicesAndLinks(
     215              :     const u32 rank, const std::vector<LINK>& links, const RingInfo& info, std::vector<LINK>& vLinks,
     216              :     std::vector<Slice>& vSlices)
     217              : {
     218            0 :     u32 ringSize = info.GetVSizeByRank(rank); // 查找自己所处的列长度,也即Ring的大小
     219            0 :     u32 hIndex = info.GetHIndex(rank);        // 查找自己位于第几列
     220              : 
     221            0 :     std::vector<Slice> hSlices;
     222            0 :     std::vector<LINK> hLinks;
     223            0 :     CHK_RET(CalcHSlicesAndLinks(rank, links, info, hLinks, hSlices));
     224              : 
     225              :     // 计算垂直方向每个rank结果上的offset和size
     226              :     u64 sliceSizeCalculated
     227            0 :         = (hSlices[hIndex].size / DataUnitSize(dataType_) + (ringSize - 1)) / ringSize * DataUnitSize(dataType_);
     228            0 :     u64 totalSize = hSlices[hIndex].size;
     229            0 :     u64 residueSize = totalSize;
     230            0 :     u64 sliceSizeAligned = AlgTemplateBase::RoundUpWithDivisor(sliceSizeCalculated, HCCL_MIN_SLICE_ALIGN);
     231              : 
     232            0 :     for (u32 vIdx = 0; vIdx < ringSize; vIdx++) {
     233            0 :         u32 oldRank = info.GetRank(vIdx, hIndex);
     234            0 :         CHK_PRT_RET(
     235              :             oldRank >= links.size(),
     236              :             HCCL_ERROR(
     237              :                 "[AllReduceNHRV1] rank[%u] out of range, "
     238              :                 "oldRank=%u, links.size=%u",
     239              :                 rank, oldRank, links.size()),
     240              :             HCCL_E_INTERNAL);
     241            0 :         vLinks.push_back(links[oldRank]);
     242            0 :         Slice slice;
     243            0 :         slice.size = (residueSize > sliceSizeAligned) ? sliceSizeAligned : residueSize;
     244            0 :         slice.offset = hSlices[hIndex].offset + totalSize - residueSize;
     245            0 :         residueSize -= slice.size;
     246            0 :         HCCL_DEBUG(
     247              :             "[AllReduceNHRV1][CalcVSlicesAndLinks] rank[%u], slices[%u].offset=%llu, slices[%u].size=%llu", rank, vIdx,
     248              :             slice.offset, vIdx, slice.size);
     249            0 :         vSlices.push_back(slice);
     250              :     }
     251            0 :     return HCCL_SUCCESS;
     252            0 : }
     253              : 
     254              : HcclResult
     255            0 : AllReduceNHRV1::RunReduceScatterOnHorizontal(const u32 rank, const std::vector<LINK>& links, const RingInfo& info)
     256              : {
     257            0 :     u32 ringRank = info.GetHIndex(rank); // 查找自己位于第几列,也即处于Ring中的第几个rank
     258              : 
     259              :     // 计算reducescatter每个rank结果上的offset和size
     260            0 :     std::vector<Slice> hSlices;
     261            0 :     std::vector<LINK> hLinks;
     262            0 :     CHK_RET(CalcHSlicesAndLinks(rank, links, info, hLinks, hSlices));
     263              : 
     264              :     // 长度不足2,直接跳过
     265            0 :     if (hLinks.size() < 2) {
     266            0 :         return HCCL_SUCCESS;
     267              :     }
     268              : 
     269            0 :     HCCL_DEBUG("[AllReduceNHRV1][ReduceScatter-H] rank[%u] ringRank=%u, ringSize=%u", rank, ringRank, hLinks.size());
     270            0 :     return RunReduceScatterBrokenRing(ringRank, hLinks, hSlices);
     271            0 : }
     272              : 
     273            0 : HcclResult AllReduceNHRV1::RunAllReduceOnVertical(const u32 rank, const std::vector<LINK>& links, const RingInfo& info)
     274              : {
     275            0 :     u32 ringRank = info.GetVIndex(rank);      // 查找自己位于第几行,也即处于Ring中的第几个rank
     276            0 :     u32 ringSize = info.GetVSizeByRank(rank); // 查找自己所处的列长度,也即Ring的大小
     277              :     // 若最后一列不完整,则不做allreduce操作直接返回success
     278            0 :     if (ringSize < info.GetVSizeByHIndex(0)) {
     279            0 :         return HCCL_SUCCESS;
     280              :     }
     281              :     // 计算allreduce 阶段每个rank结果上的offset和size
     282            0 :     std::vector<Slice> vSlices;
     283            0 :     std::vector<LINK> vLinks;
     284            0 :     CHK_RET(CalcVSlicesAndLinks(rank, links, info, vLinks, vSlices));
     285              : 
     286            0 :     std::unique_ptr<AlgTemplateBase> tempAlg;
     287            0 :     tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_ALL_REDUCE_RING, dispatcher_);
     288            0 :     CHK_SMART_PTR_NULL(tempAlg);
     289            0 :     CHK_RET(tempAlg->Prepare(reduceAttr_));
     290              : 
     291              :     // 判断是否关闭allreduce的barrier
     292            0 :     if (!barrierSwitchOn_) {
     293            0 :         tempAlg->CloseBarrier();
     294              :     }
     295              : 
     296            0 :     CHK_RET(tempAlg->Prepare(
     297              :         inputMem_, outputMem_, outputMem_, count_, dataType_, stream_, reductionOp_, root_, vSlices, baseOffset_));
     298              : 
     299            0 :     CHK_RET(tempAlg->RegisterProfiler(profilerInput_.planeID, profilerInput_.stage, profilerInput_.step, stream_));
     300              : 
     301            0 :     HCCL_DEBUG("[AllReduceNHRV1][AllReduce-V] rank[%u] ringRank=%u, ringSize=%u", rank, ringRank, ringSize);
     302            0 :     return tempAlg->RunAsync(ringRank, ringSize, vLinks);
     303            0 : }
     304              : 
     305              : HcclResult
     306            0 : AllReduceNHRV1::RunAllGatherOnHorizontal(const u32 rank, const std::vector<LINK>& links, const RingInfo& info)
     307              : {
     308            0 :     u32 ringRank = info.GetHIndex(rank); // 查找自己位于第几列,也即处于Ring中的第几个rank
     309              : 
     310              :     // 计算allgather阶段每个rank结果上的offset和size
     311            0 :     std::vector<Slice> hSlices;
     312            0 :     std::vector<LINK> hLinks;
     313            0 :     CHK_RET(CalcHSlicesAndLinks(rank, links, info, hLinks, hSlices));
     314              : 
     315              :     // 长度不足2,直接跳过
     316            0 :     if (hLinks.size() < 2)
     317            0 :         return HCCL_SUCCESS;
     318              : 
     319            0 :     HCCL_DEBUG("[AllReduceNHRV1][AllGather-H] rank[%u] ringRank=%u, ringSize=%u", rank, ringRank, hLinks.size());
     320            0 :     return RunAllGatherBrokenRing(ringRank, hLinks, hSlices);
     321            0 : }
     322              : 
     323            0 : HcclResult AllReduceNHRV1::RunReduceScatterBrokenRing(
     324              :     const u32 rank, const std::vector<LINK>& links, const std::vector<Slice>& slices)
     325              : {
     326              :     std::unique_ptr<AlgTemplateBase> tempAlg
     327            0 :         = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_REDUCESCATTER_RING, dispatcher_);
     328            0 :     CHK_SMART_PTR_NULL(tempAlg);
     329            0 :     CHK_RET(tempAlg->Prepare(reduceAttr_));
     330              : 
     331              :     // 判断是否关闭reducescatter的barrier
     332            0 :     if (!barrierSwitchOn_) {
     333            0 :         tempAlg->CloseBarrier();
     334              :     }
     335              : 
     336              :     // 调用reducescatter ring的算法执行
     337            0 :     CHK_RET(tempAlg->Prepare(
     338              :         inputMem_, inputMem_, outputMem_, count_, dataType_, stream_, reductionOp_, root_, slices, baseOffset_));
     339              : 
     340            0 :     CHK_RET(tempAlg->RegisterProfiler(profilerInput_.planeID, profilerInput_.stage, profilerInput_.step, stream_));
     341              : 
     342            0 :     return tempAlg->RunAsync(rank, links.size(), links);
     343            0 : }
     344              : 
     345              : HcclResult
     346            0 : AllReduceNHRV1::RunAllGatherBrokenRing(const u32 rank, const std::vector<LINK>& links, const std::vector<Slice>& slices)
     347              : {
     348              :     std::unique_ptr<AlgTemplateBase> tempAlg
     349            0 :         = AlgTemplateRegistry::Instance().GetAlgTemplate(TemplateType::TEMPLATE_ALL_GATHER_RING, dispatcher_);
     350            0 :     CHK_SMART_PTR_NULL(tempAlg);
     351              :     // 判断是否关闭allgather的barrier
     352            0 :     if (!barrierSwitchOn_) {
     353            0 :         tempAlg->CloseBarrier();
     354              :     }
     355              : 
     356              :     // 调用allgather ring的算法执行
     357            0 :     CHK_RET(tempAlg->Prepare(
     358              :         outputMem_, outputMem_, outputMem_, count_, dataType_, stream_, reductionOp_, root_, slices, baseOffset_));
     359              : 
     360            0 :     CHK_RET(tempAlg->RegisterProfiler(profilerInput_.planeID, profilerInput_.stage, profilerInput_.step, stream_));
     361              : 
     362            0 :     return tempAlg->RunAsync(rank, links.size(), links);
     363            0 : }
     364              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_ALL_REDUCE_NHR_V1, AllReduceNHRV1);
     365              : } // namespace hccl
        

Generated by: LCOV version 2.0-1