LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_all_gather - all_gather_nhr_v1.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 105 0
Test Date: 2026-07-28 12:11:00 Functions: 0.0 % 6 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 "all_gather_nhr_v1.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15            0 : AllGatherNHRV1::AllGatherNHRV1(const HcclDispatcher dispatcher) : NHRV1Base(dispatcher)
      16              : {
      17            0 : }
      18              : 
      19            0 : AllGatherNHRV1::~AllGatherNHRV1()
      20              : {
      21            0 : }
      22              : 
      23              : // 服务器间allgather的入口函数
      24            0 : HcclResult AllGatherNHRV1::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
      25              : {
      26            0 :     CHK_SMART_PTR_NULL(dispatcher_);
      27            0 :     CHK_PTR_NULL(stream_.ptr());
      28            0 :     HCCL_INFO("[AllGatherNHRV1] run_async rank[%u] ranksize[%u] inputMem[%p] outputMem[%p] count[%llu]", \
      29              :               rank, rankSize, inputMem_.ptr(), outputMem_.ptr(), count_);
      30              : 
      31              :     // 判断rank_size == 1
      32            0 :     if (rankSize == 1) {
      33            0 :         if (inputMem_ != outputMem_) {
      34            0 :             CHK_RET(HcclD2DMemcpyAsync(dispatcher_, outputMem_, inputMem_, stream_));
      35              :         }
      36            0 :         return HCCL_SUCCESS;
      37              :     }
      38              : 
      39            0 :     CHK_PRT_RET(links.size() < rankSize, HCCL_ERROR("[AllGatherNHRV1][RunAsync]rank[%u] linkSize is less than rankSize",
      40              :         rank), HCCL_E_INTERNAL);
      41              : 
      42            0 :     u32 unitSize = DataUnitSize(dataType_);
      43            0 :     CHK_PRT_RET(unitSize == 0, HCCL_ERROR("[AllGatherNHRV1][RunAsync]unitSize is zero"), HCCL_E_INTERNAL);
      44              : 
      45              :     // 处理和检查Slices
      46            0 :     if (slices_.size() != 0) {
      47            0 :         HCCL_WARNING("[AllGatherNHRV1][RunAsync]AllGatherNHRV1 not supported passing in parameter slice_, "\
      48              :             "otherwise will be cleared");
      49            0 :         slices_.clear();
      50              :     }
      51            0 :     std::vector<Slice> inputSlices(slices_);
      52            0 :     if (slices_.size() == 0) {
      53            0 :         slices_.resize(rankSize);
      54            0 :         inputSlices.resize(rankSize);
      55            0 :         u64 sliceSize = count_ * unitSize;
      56            0 :         HCCL_DEBUG("[AllGatherNHRV1][RunAsync]sliceSize is %llu, rankSize is %u", sliceSize, rankSize);
      57            0 :         for (u32 i = 0; i < rankSize; i++) {
      58            0 :             slices_[i].size = sliceSize;
      59            0 :             slices_[i].offset = sliceSize * i;
      60            0 :             inputSlices[i].size = sliceSize;
      61            0 :             inputSlices[i].offset = (inputMem_.size() < outputMem_.size()) ? 0 : (sliceSize * i);
      62            0 :             HCCL_DEBUG("rank[%u], slices[%u].offset=%llu, slices[%u].size=%llu", \
      63              :                 rank, i, slices_[i].offset, i, slices_[i].size);
      64              :         }
      65              :     }
      66              : 
      67              :     // 双buffer下, 先将input拷贝到output的合适位置
      68            0 :     if (inputMem_ != outputMem_) {
      69            0 :         DeviceMem dst = outputMem_.range(slices_[rank].offset, slices_[rank].size);
      70            0 :         DeviceMem src = inputMem_.range(inputSlices[rank].offset, inputSlices[rank].size);
      71            0 :         CHK_RET(HcclD2DMemcpyAsync(dispatcher_, dst, src, stream_));
      72            0 :     }
      73              : 
      74              :     HcclResult ret;
      75              :     // 获取通信关系
      76            0 :     RingInfo info = GetRingInfo(rankSize);
      77              : 
      78              :     // 水平方向做ring
      79            0 :     ret = RunAllGatherOnHorizontal(rank, links, info);
      80            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[AllGatherNHRV1][RunAsync]rank[%u] count[%llu] failed in "\
      81              :         "RunAllGatherOnHorizontal step", rank, count_), ret);
      82              : 
      83              :     // 垂直方向做ring
      84            0 :     ret = RunAllGatherOnVertical(rank, links, info);
      85            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[AllGatherNHRV1][RunAsync]rank[%u] count[%llu] failed in "\
      86              :         "RunAllGatherOnVertical step", rank, count_), ret);
      87              : 
      88            0 :     HCCL_INFO("[AllGatherNHRV1] finished: rank[%u]", rank);
      89            0 :     return HCCL_SUCCESS;
      90            0 : }
      91              : 
      92            0 : HcclResult AllGatherNHRV1::RunAllGatherOnHorizontal(u32 rank, const std::vector<LINK> &links, const RingInfo &info)
      93              : {
      94            0 :     u32 ringRank = info.GetHIndex(rank);            // 查找自己位于第几列,也即处于Ring中的第几个rank
      95            0 :     u32 ringSize = info.GetHSizeByRank(rank);       // 查找自己所处的行长度,也即Ring的大小
      96            0 :     u32 vIndex = info.GetVIndex(rank);              // 查找自己位于第几行
      97              : 
      98              :     // 收集本列各rank号,构建新的links、slices数组
      99            0 :     std::vector<Slice> hSlices;
     100            0 :     std::vector<LINK> hLinks;
     101            0 :     for (u32 hIdx = 0; hIdx < ringSize; hIdx++) {
     102            0 :         u32 oldRank = info.GetRank(vIndex, hIdx);
     103            0 :         CHK_PRT_RET(oldRank >= links.size(), HCCL_ERROR("[AllGatherNHRV1] rank[%u] out of range, "\
     104              :             "oldRank=%u, links.size=%u", rank, oldRank, links.size()), HCCL_E_INTERNAL);
     105            0 :         hSlices.push_back(slices_[oldRank]);
     106            0 :         hLinks.push_back(links[oldRank]);
     107              :     }
     108              : 
     109              :     // 长度不足2,直接跳过
     110            0 :     if (hLinks.size() < 2) {
     111            0 :         return HCCL_SUCCESS;
     112              :     }
     113              : 
     114            0 :     std::unique_ptr<AlgTemplateBase> tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(
     115            0 :         TemplateType::TEMPLATE_ALL_GATHER_RING, dispatcher_);
     116            0 :     CHK_SMART_PTR_NULL(tempAlg);
     117            0 :     HCCL_INFO("rank[%u] tempAlg AllGathering inputMem[%p] outputMem[%p] mem_size[%llu] "\
     118              :         "count[%llu] planeID:[%d]", rank, inputMem_.ptr(), outputMem_.ptr(), inputMem_.size(),
     119              :         count_, profilerInput_.planeID);
     120              : 
     121              :     // 判断是否关闭AllGather的barrier
     122            0 :     if (!barrierSwitchOn_) {
     123            0 :         tempAlg->CloseBarrier();
     124              :     }
     125              : 
     126              :     // 调用AllGather ring的算法执行
     127            0 :     CHK_RET(tempAlg->Prepare(outputMem_, outputMem_, outputMem_, count_, dataType_, stream_,
     128              :         reductionOp_, root_, hSlices, baseOffset_));
     129              : 
     130            0 :     CHK_RET(tempAlg->RegisterProfiler(
     131              :         profilerInput_.planeID, profilerInput_.stage, profilerInput_.step, stream_));
     132              : 
     133            0 :     HCCL_DEBUG("[AllGatherNHRV1][Horizontal] rank[%u], ringRank=%u, ringSize=%u", rank, ringRank, ringSize);
     134            0 :     return tempAlg->RunAsync(ringRank, ringSize, hLinks);
     135            0 : }
     136              : 
     137            0 : HcclResult AllGatherNHRV1::RunAllGatherOnVertical(u32 rank, const std::vector<LINK> &links, const RingInfo &info)
     138              : {
     139            0 :     u32 hIndex = info.GetHIndex(rank); // 查找自己位于第几列
     140              : 
     141            0 :     u32 hIndexForRing = (hIndex < info.GetRowSize()) ? hIndex : info.GetVIndex(rank); // 属于第几个垂直Ring
     142            0 :     u32 vSizeForRing = info.GetVSizeByHIndex(hIndexForRing); // 所属垂直Ring的大小
     143              : 
     144              :     // 收集本列各rank号,构建新的links、slices数组
     145            0 :     std::vector<LINK> vLinks;
     146            0 :     std::vector<Slice> vSlices;
     147            0 :     for (u32 vIdx = 0; vIdx < vSizeForRing; vIdx++) {
     148            0 :         u32 oldLRank = info.GetRank(vIdx, hIndexForRing);
     149            0 :         CHK_PRT_RET(oldLRank >= links.size(), HCCL_ERROR("[AllGatherNHRV1] rank[%u] out of range, "\
     150              :             "oldLRank=%u, links.size=%u", rank, oldLRank, links.size()), HCCL_E_INTERNAL);
     151            0 :         vLinks.push_back(links[oldLRank]);
     152            0 :         Slice slice;
     153            0 :         slice.size = slices_[vIdx].size * info.GetHSizeByVIndex(vIdx);
     154            0 :         u32 oldSRank = info.GetRank(vIdx, 0);
     155            0 :         CHK_PRT_RET(oldSRank >= links.size(), HCCL_ERROR("[AllGatherNHRV1] rank[%u] out of range, "\
     156              :             "oldSRank=%u, links.size=%u", rank, oldSRank, links.size()), HCCL_E_INTERNAL);
     157            0 :         slice.offset = slices_[oldSRank].offset;
     158            0 :         vSlices.push_back(slice);
     159              :     }
     160              : 
     161              :     // -- 可能还涉及跳跃的一个链接,比如8节点
     162              :     // ---- 0   1   2
     163              :     // ---- 3   4   5
     164              :     // ---- 6   7
     165              :     // -- 两个垂直Ring分别是{0,3,6,2}和{1,4,7,5},而不是{0,3,6}和{1,4,7}
     166            0 :     if (info.GetHSizeByVIndex(hIndexForRing) > info.GetRowSize()) {
     167            0 :         u32 oldLRank = info.GetRank(hIndexForRing, info.GetSqrtRankSize());
     168            0 :         CHK_PRT_RET(oldLRank >= links.size(), HCCL_ERROR("[AllGatherNHRV1] rank[%u] out of range, "\
     169              :             "oldLRank=%u, links.size=%u", rank, oldLRank, links.size()), HCCL_E_INTERNAL);
     170            0 :         vLinks.push_back(links[oldLRank]);
     171            0 :         Slice slice;
     172            0 :         slice.offset = 0;
     173            0 :         slice.size = 0;
     174            0 :         vSlices.push_back(slice);
     175              :     }
     176              : 
     177              :     // 长度不足2,直接跳过
     178            0 :     if (vLinks.size() < 2) {
     179            0 :         return HCCL_SUCCESS;
     180              :     }
     181              : 
     182            0 :     std::unique_ptr<AlgTemplateBase> tempAlg = AlgTemplateRegistry::Instance().GetAlgTemplate(
     183            0 :         TemplateType::TEMPLATE_ALL_GATHER_RING, dispatcher_);
     184            0 :     CHK_SMART_PTR_NULL(tempAlg);
     185            0 :     HCCL_INFO("rank[%u] tempAlg AllGathering inputMem[%p] outputMem[%p] mem_size[%llu] "\
     186              :         "count[%llu] planeID:[%d]", rank, inputMem_.ptr(), outputMem_.ptr(), inputMem_.size(),
     187              :         count_, profilerInput_.planeID);
     188              :     // 判断是否关闭allgather的barrier
     189            0 :     if (!barrierSwitchOn_) {
     190            0 :         tempAlg->CloseBarrier();
     191              :     }
     192              :     // 调用allgather ring的算法执行
     193            0 :     CHK_RET(tempAlg->Prepare(outputMem_, outputMem_, outputMem_, count_, dataType_, stream_,
     194              :         reductionOp_, root_, vSlices, baseOffset_));
     195              : 
     196            0 :     CHK_RET(tempAlg->RegisterProfiler(
     197              :         profilerInput_.planeID, profilerInput_.stage, profilerInput_.step, stream_));
     198              : 
     199              :     // 计算在垂直Ring中的rank号
     200            0 :     u32 subRank = (hIndex == hIndexForRing) ? info.GetVIndex(rank) : vSizeForRing;
     201              : 
     202            0 :     HCCL_DEBUG("[AllGatherNHR][Vertical] rank[%u], subRank=%u, ringSize=%u", rank, subRank, vLinks.size());
     203            0 :     return tempAlg->RunAsync(subRank, vLinks.size(), vLinks);
     204            0 : }
     205              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_ALL_GATHER_NHRV1, AllGatherNHRV1);
     206              : } // namespace hccl
     207              : 
        

Generated by: LCOV version 2.0-1