LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_broadcast - bcast_recursive_halvingdoubling.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 236 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 12 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 "bcast_recursive_halvingdoubling.h"
      12              : #include <cmath>
      13              : #include "alg_template_register.h"
      14              : 
      15              : namespace hccl {
      16            0 : BcastRecursiveHalvingDoubling::BcastRecursiveHalvingDoubling(const HcclDispatcher dispatcher)
      17              :     : RecursiveHalvingDoublingBase(dispatcher),
      18            0 :       hasData_(false)
      19            0 : {}
      20              : 
      21            0 : BcastRecursiveHalvingDoubling::~BcastRecursiveHalvingDoubling() {}
      22              : 
      23              : // recursiveHD broadcast算法主入口
      24            0 : HcclResult BcastRecursiveHalvingDoubling::RunAsync(
      25              :     const u32 rank, const u32 rankSize, const std::vector<std::shared_ptr<Transport>>& links)
      26              : {
      27            0 :     CHK_SMART_PTR_NULL(dispatcher_);
      28            0 :     CHK_PTR_NULL(stream_.ptr());
      29            0 :     CHK_PRT_RET(
      30              :         !inputMem_, HCCL_ERROR("[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] run_async inputmem is null", rank),
      31              :         HCCL_E_PTR);
      32              : 
      33            0 :     HCCL_INFO(
      34              :         "BcastRecursiveHalvingDoubling run: rank[%u] rootRank[%u] totalrank[%u]"
      35              :         " inputMem[%p] outputMem[%p] count[%llu]",
      36              :         rank, root_, rankSize, inputMem_.ptr(), outputMem_.ptr(), count_);
      37              : 
      38            0 :     if (rankSize == 1) {
      39            0 :         return HCCL_SUCCESS;
      40              :     }
      41              : 
      42            0 :     if (rank == root_) {
      43            0 :         hasData_ = true;
      44              :     }
      45              : 
      46            0 :     CHK_PRT_RET(
      47              :         links.size() < rankSize,
      48              :         HCCL_ERROR(
      49              :             "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] linksize[%llu] is less than rankSize[%u]", rank,
      50              :             links.size(), rankSize),
      51              :         HCCL_E_INTERNAL);
      52              : 
      53              :     // 计算recursive算法第一部分相关参数
      54            0 :     HcclResult ret = CalcPartOneSizeAndBlockSize(rankSize);
      55            0 :     CHK_PRT_RET(
      56              :         ret != HCCL_SUCCESS,
      57              :         HCCL_ERROR(
      58              :             "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] Calculate "
      59              :             "Par1Size[%u] And BlockSize[%u] Failed! rankSize[%u]",
      60              :             rank, part1Size_, blockSize_, rankSize),
      61              :         ret);
      62              : 
      63            0 :     HCCL_DEBUG("rank[%u] BroadcastInBlock... blockSize_[%u], part1Size_[%u]", rank, blockSize_, part1Size_);
      64              : 
      65              :     // 先进行block内部的bcast
      66            0 :     CHK_RET(BroadcastInBlock(rank, links));
      67              : 
      68            0 :     HCCL_DEBUG("rank[%u] BroadcastOutOfBlock", rank);
      69              : 
      70            0 :     if (rank < part1Size_ && (rank % 2 == 0)) { // 模2是否为0判断rank奇偶性
      71            0 :         CHK_RET(EvenNumberRankProcess(rank, links));
      72            0 :     } else if (rank < part1Size_ && (rank % 2 == 1)) { // 模2是否为1判断rank奇偶性
      73            0 :         CHK_RET(OddNumberRankProcess(rank, links));
      74              :     }
      75              : 
      76            0 :     HCCL_INFO("BcastRecursiveHalvingDoubling finished: rank[%u] finished", rank);
      77            0 :     return HCCL_SUCCESS;
      78              : }
      79              : 
      80              : HcclResult
      81            0 : BcastRecursiveHalvingDoubling::ReceiveData(const u32 destRank, const std::vector<std::shared_ptr<Transport>>& links)
      82              : {
      83            0 :     if (destRank < links.size()) {
      84            0 :         if (links[destRank] == nullptr) {
      85            0 :             HCCL_ERROR(
      86              :                 "[Receive][Data]errNo[0x%016llx] links[destRank[%u]] ptr is NULL, return HCCL_E_PTR",
      87              :                 HCCL_ERROR_CODE(HCCL_E_PTR), destRank);
      88            0 :             return HCCL_E_PTR;
      89              :         }
      90            0 :         HcclResult ret = links[destRank]->TxAck(stream_);
      91            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Receive][Data]tx ack to dstrank[%u] failed", destRank), ret);
      92            0 :         ret = links[destRank]->RxAck(stream_);
      93            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Receive][Data]rx ack to dstrank[%u] failed", destRank), ret);
      94              : 
      95            0 :         u64 dataBytes = count_ * DataUnitSize(dataType_);
      96            0 :         DeviceMem rcvMem = inputMem_.range(baseOffset_, dataBytes);
      97            0 :         HCCL_DEBUG(
      98              :             "rx async from dstrank[%u] with rcvMem[%p] inputmem's offset[%llu] size[%llu]", destRank, rcvMem.ptr(),
      99              :             baseOffset_, dataBytes);
     100              : 
     101            0 :         ret = ExecuteRxSync(links[destRank], UserMemType::INPUT_MEM, baseOffset_, rcvMem.ptr(), dataBytes, stream_);
     102            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Receive][Data]rx sync from rank[%u] failed", destRank), ret);
     103            0 :     }
     104            0 :     return HCCL_SUCCESS;
     105              : }
     106              : 
     107              : HcclResult
     108            0 : BcastRecursiveHalvingDoubling::SendData(const u32 destRank, const std::vector<std::shared_ptr<Transport>>& links)
     109              : {
     110            0 :     if (destRank < links.size()) {
     111            0 :         if (links[destRank] == nullptr) {
     112            0 :             HCCL_ERROR(
     113              :                 "[Send][Data]errNo[0x%016llx] links[destRank[%u]] ptr is NULL, return HCCL_E_PTR",
     114              :                 HCCL_ERROR_CODE(HCCL_E_PTR), destRank);
     115            0 :             return HCCL_E_PTR;
     116              :         }
     117            0 :         HcclResult ret = links[destRank]->TxAck(stream_);
     118            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Send][Data]tx ack from rank[%u] failed", destRank), ret);
     119            0 :         ret = links[destRank]->RxAck(stream_);
     120            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Send][Data]rx ack from rank[%u] failed", destRank), ret);
     121              : 
     122            0 :         u64 dataBytes = count_ * DataUnitSize(dataType_);
     123            0 :         DeviceMem sendMem = inputMem_.range(baseOffset_, dataBytes);
     124            0 :         HCCL_DEBUG(
     125              :             "tx async to dstrank[%u] from sendMem[%p] inputmem's offset[%llu] size[%llu]", destRank, sendMem.ptr(),
     126              :             baseOffset_, dataBytes);
     127              : 
     128            0 :         ret = ExecuteTxSync(links[destRank], UserMemType::INPUT_MEM, baseOffset_, sendMem.ptr(), dataBytes, stream_);
     129            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Send][Data]tx sync to rank[%u] failed", destRank), ret);
     130            0 :     }
     131            0 :     return HCCL_SUCCESS;
     132              : }
     133              : 
     134            0 : u32 BcastRecursiveHalvingDoubling::GetRankIndexReal(const u32 rankInBlock) const
     135              : {
     136            0 :     u32 res = 0;
     137              :     /* 如果根节点在第一部分的偶数位置或其他部分 */
     138            0 :     if ((root_ < part1Size_ && (root_ % 2) == 0) || root_ >= part1Size_) { // 模2判断奇偶性
     139            0 :         if (rankInBlock < part1Size_ / 2) {                                // 除2计算block内part1的rank范围
     140            0 :             res = rankInBlock * 2;                                         // 乘2计算block内part1的rank范围
     141            0 :             return res;
     142              :         } else {
     143            0 :             res = part1Size_ / 2 + rankInBlock; // 除2加rankInBlock计算真实的rank值
     144            0 :             return res;
     145              :         }
     146              :     } else {
     147            0 :         if (rankInBlock < part1Size_ / 2) { // 除2计算block内part1的rank范围
     148            0 :             res = rankInBlock * 2 + 1;      // 乘2加1计算计算真实的rank值
     149            0 :             return res;
     150              :         } else {
     151            0 :             res = part1Size_ / 2 + rankInBlock; // 除2加rankInBlock计算真实的rank值
     152            0 :             return res;
     153              :         }
     154              :     }
     155              : }
     156              : 
     157            0 : u32 BcastRecursiveHalvingDoubling::GetRankIndexInBlock(const u32 rank) const
     158              : {
     159              :     // root在第一部分,并且root是偶数rank,或者root在第二部分
     160            0 :     if ((root_ < part1Size_ && (root_ % 2) == 0) || root_ >= part1Size_) { // 模2判断奇偶性
     161              :         // rank在第一部分,并且本rank是偶数rank,除以2就为在block内的index
     162            0 :         if (rank < part1Size_ && rank % 2 == 0) {        // 模2判断奇偶性
     163            0 :             return rank / 2;                             // 除2计算block内rank值
     164            0 :         } else if (rank < part1Size_ && rank % 2 == 1) { // 模2判断奇偶性,奇数的话不在block内
     165            0 :             return INVALID_VALUE_RANKID;
     166              :         } else {
     167            0 :             return rank - part1Size_ / 2; // 除2计算block内part1的rank范围
     168              :         }
     169              :     } else {                                      // root在第一部分属于奇数rank
     170            0 :         if (rank < part1Size_ && rank % 2 == 0) { // 模2判断奇偶性,偶数rank不在block内
     171            0 :             return INVALID_VALUE_RANKID;
     172            0 :         } else if (rank < part1Size_ && rank % 2 == 1) { // 模2判断奇偶性,为奇计算block内rank号
     173            0 :             return (rank - 1) / 2;                       // 通过减1再除2得到block内rank号
     174              :         } else {
     175            0 :             return rank - part1Size_ / 2; // 除2计算block内part1的rank范围
     176              :         }
     177              :     }
     178              : }
     179              : 
     180              : HcclResult
     181            0 : BcastRecursiveHalvingDoubling::BroadcastInBlock(const u32 rank, const std::vector<std::shared_ptr<Transport>>& links)
     182              : {
     183            0 :     u32 rankInBlock = GetRankIndexInBlock(rank);
     184            0 :     if (rankInBlock == INVALID_VALUE_RANKID) { // 非block内的节点,不做操作
     185            0 :         return HCCL_SUCCESS;
     186              :     }
     187              : 
     188            0 :     u32 rootInBlock = GetRankIndexInBlock(root_);
     189            0 :     for (u32 i = 0; i < round_; i++) {
     190            0 :         u32 peerRankBitmask = 1 << (round_ - i - 1); // 进入此条件,round必然不小于1
     191            0 :         u32 peerRankInBlock = rankInBlock ^ peerRankBitmask;
     192            0 :         u32 andOprand = (1 << (round_ - i - 1)) - 1;
     193            0 :         u32 peerRankReal = GetRankIndexReal(peerRankInBlock);
     194              : 
     195            0 :         HcclResult ret = HCCL_SUCCESS;
     196              :         // 本rank在第round轮需要接收数据
     197            0 :         if (((rankInBlock & andOprand) == (rootInBlock & andOprand)) && (rank != root_) && !hasData_) {
     198            0 :             HCCL_DEBUG(
     199              :                 "rank[%u] receive memsize[%llu] from rank[%u] in round[%u]", rank, DataUnitSize(dataType_) * count_,
     200              :                 peerRankReal, i);
     201            0 :             ret = ReceiveData(peerRankReal, links);
     202            0 :             CHK_PRT_RET(
     203              :                 ret != HCCL_SUCCESS,
     204              :                 HCCL_ERROR(
     205              :                     "[BcastRecursiveHalvingDoubling][BroadcastInBlock]rank[%u] "
     206              :                     "Receive Data from rank[%u] failed.",
     207              :                     rank, peerRankReal),
     208              :                 ret);
     209            0 :             hasData_ = true;
     210            0 :             if (peerRankReal < links.size()) {
     211            0 :                 ret = links[peerRankReal]->RxWaitDone(stream_);
     212            0 :                 CHK_PRT_RET(
     213              :                     ret != HCCL_SUCCESS,
     214              :                     HCCL_ERROR("[BcastRecursiveHalvingDoubling][BroadcastInBlock]RxWaitDone failed"), ret);
     215              :             }
     216            0 :             continue;
     217              :         }
     218              : 
     219              :         // 需要向目的rank发送数据,前提是收到数据后(root 节点每轮都发)
     220            0 :         if (hasData_) {
     221            0 :             HCCL_DEBUG(
     222              :                 "rank[%u] send mem[%llu] to rank[%u] in round:%u", rank, DataUnitSize(dataType_) * count_, peerRankReal,
     223              :                 i);
     224            0 :             ret = SendData(peerRankReal, links);
     225            0 :             CHK_PRT_RET(
     226              :                 ret != HCCL_SUCCESS,
     227              :                 HCCL_ERROR(
     228              :                     "[BcastRecursiveHalvingDoubling][BroadcastInBlock]rank[%u] Send "
     229              :                     "Data to rank[%u] failed.",
     230              :                     rank, peerRankReal),
     231              :                 ret);
     232              :         }
     233            0 :         if (peerRankReal < links.size()) {
     234            0 :             ret = links[peerRankReal]->TxWaitDone(stream_);
     235            0 :             CHK_PRT_RET(
     236              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[BcastRecursiveHalvingDoubling][BroadcastInBlock]TxWaitDone failed"),
     237              :                 ret);
     238              :         }
     239              :     }
     240            0 :     return HCCL_SUCCESS;
     241              : }
     242              : 
     243            0 : HcclResult BcastRecursiveHalvingDoubling::EvenNumberRankProcess(
     244              :     const u32 rank, const std::vector<std::shared_ptr<Transport>>& links)
     245              : {
     246              :     HcclResult ret;
     247            0 :     if (root_ % 2 == 0 || root_ >= part1Size_) { // 模2是否为0判断rank_奇偶性
     248            0 :         HCCL_DEBUG(
     249              :             "rank[%u] stream[%p] send memsize[%llu] to rank[%u]", rank, stream_.ptr(), DataUnitSize(dataType_) * count_,
     250              :             rank + 1);
     251              :         // 该rank需要向第一部分的后续奇数rank发送数据
     252            0 :         ret = SendData(rank + 1, links);
     253            0 :         CHK_PRT_RET(
     254              :             ret != HCCL_SUCCESS,
     255              :             HCCL_ERROR(
     256              :                 "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] stream[%p] Send data to "
     257              :                 "Rank[%u] failed",
     258              :                 rank, stream_.ptr(), rank + 1),
     259              :             ret);
     260            0 :         if (rank + 1 < links.size()) {
     261            0 :             ret = links[rank + 1]->TxWaitDone(stream_);
     262            0 :             CHK_PRT_RET(
     263              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[BcastRecursiveHalvingDoubling][RunAsync]TxWaitDone failed"), ret);
     264              :         }
     265              :     } else {
     266            0 :         HCCL_DEBUG(
     267              :             "rank[%u] stream[%p] receive memsize[%llu] from rank[%u]", rank, stream_.ptr(),
     268              :             DataUnitSize(dataType_) * count_, rank + 1);
     269              : 
     270              :         // root为奇数,本rank为偶数,需要从邻接的奇数rank接收数据
     271            0 :         ret = ReceiveData(rank + 1, links);
     272            0 :         CHK_PRT_RET(
     273              :             ret != HCCL_SUCCESS,
     274              :             HCCL_ERROR(
     275              :                 "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] stream[%p] Receive data "
     276              :                 "from Rank[%u] failed",
     277              :                 rank, stream_.ptr(), rank + 1),
     278              :             ret);
     279            0 :         if (rank + 1 < links.size()) {
     280            0 :             ret = links[rank + 1]->RxWaitDone(stream_);
     281            0 :             CHK_PRT_RET(
     282              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[BcastRecursiveHalvingDoubling][RunAsync]RxWaitDone failed"), ret);
     283              :         }
     284              :     }
     285            0 :     return HCCL_SUCCESS;
     286              : }
     287              : 
     288            0 : HcclResult BcastRecursiveHalvingDoubling::OddNumberRankProcess(
     289              :     const u32 rank, const std::vector<std::shared_ptr<Transport>>& links)
     290              : {
     291              :     HcclResult ret;
     292            0 :     if (root_ % 2 == 0 || root_ >= part1Size_) { // 模2是否为0判断rank_奇偶性
     293            0 :         HCCL_DEBUG(
     294              :             "rank[%u] stream[%p] receive memsize[%llu] from rank[%u]", rank, stream_.ptr(),
     295              :             DataUnitSize(dataType_) * count_, rank - 1);
     296              : 
     297              :         // root是偶数节点,rank从前面邻接的偶数节点接收数据
     298            0 :         ret = ReceiveData(rank - 1, links);
     299            0 :         CHK_PRT_RET(
     300              :             ret != HCCL_SUCCESS,
     301              :             HCCL_ERROR(
     302              :                 "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] stream[%p] Receive data "
     303              :                 "from Rank[%u] failed",
     304              :                 rank, stream_.ptr(), rank - 1),
     305              :             ret);
     306            0 :         if (rank - 1 < links.size()) {
     307            0 :             ret = links[rank - 1]->RxWaitDone(stream_);
     308            0 :             CHK_PRT_RET(
     309              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[BcastRecursiveHalvingDoubling][RunAsync]RxWaitDone failed"), ret);
     310              :         }
     311              :     } else {
     312            0 :         HCCL_DEBUG(
     313              :             "rank[%u] stream[%p] send memsize[%llu] to rank[%u]", rank, stream_.ptr(), DataUnitSize(dataType_) * count_,
     314              :             rank - 1);
     315            0 :         ret = SendData(rank - 1, links);
     316            0 :         CHK_PRT_RET(
     317              :             ret != HCCL_SUCCESS,
     318              :             HCCL_ERROR(
     319              :                 "[BcastRecursiveHalvingDoubling][RunAsync]rank[%u] stream[%p] Send data to "
     320              :                 "Rank[%u] failed",
     321              :                 rank, stream_.ptr(), rank - 1),
     322              :             ret);
     323            0 :         if (rank - 1 < links.size()) {
     324            0 :             ret = links[rank - 1]->TxWaitDone(stream_);
     325            0 :             CHK_PRT_RET(
     326              :                 ret != HCCL_SUCCESS, HCCL_ERROR("[BcastRecursiveHalvingDoubling][RunAsync]TxWaitDone failed"), ret);
     327              :         }
     328              :     }
     329            0 :     return HCCL_SUCCESS;
     330              : }
     331            0 : HcclResult BcastRecursiveHalvingDoubling::GetNslbAdjInfo(
     332              :     const u32 rank, const u32 rankSize, const std::vector<LINK>& links, AdjInfo& nslbAdjInfo)
     333              : {
     334            0 :     u32 nslbRound = 0;
     335            0 :     u32 base = 1;
     336            0 :     const u32 minExponent = 1;
     337            0 :     while ((base << nslbRound) <= rankSize) {
     338            0 :         nslbRound++;
     339              :     }
     340            0 :     if (nslbRound >= minExponent) {
     341            0 :         nslbRound = nslbRound - minExponent;
     342              :     }
     343            0 :     u32 nslbBlockSize = base << nslbRound;
     344              :     // 获取第一部分:rank数减block数乘2
     345            0 :     u32 nslbPart1Size = (rankSize - nslbBlockSize) * NSLBDP_BCAST_MOLD2;
     346              : 
     347            0 :     u32 rankInBlock = 0;
     348            0 :     if (rank < nslbPart1Size && (rank % NSLBDP_BCAST_MOLD2) == 0) {
     349            0 :         rankInBlock = rank / NSLBDP_BCAST_MOLD2; // 直接除以2即为本rank的在block内的排序
     350              :     } else {
     351              :         rankInBlock
     352            0 :             = rank - nslbPart1Size / NSLBDP_BCAST_MOLD2; // 通过rank减去part1除2的大小即不处于第一部分的block内rank号
     353              :     }
     354              :     // 2的次幂场景下处理流程
     355            0 :     if (nslbPart1Size == 0) {
     356            0 :         u32 stepNum = 0;
     357            0 :         while ((rankSize >> (stepNum + 1)) != 0) {
     358            0 :             stepNum++;
     359              :         }
     360            0 :         bool begin = false;
     361            0 :         if (rank == 0) {
     362            0 :             begin = true;
     363              :         }
     364            0 :         for (u32 step = 0; step < stepNum; step++) {
     365            0 :             u32 peerRankBitmask = 1 << (stepNum - step - 1); // 进入此条件,round必然不小于1
     366            0 :             u32 peerRankInBlock = rankInBlock ^ peerRankBitmask;
     367            0 :             u32 andOprand = (1 << (stepNum - step - 1)) - 1;
     368              : 
     369              :             // 本rank在第round轮需要接收数据
     370            0 :             if (((rankInBlock & andOprand) == 0) && (rank != 0) && !begin) {
     371            0 :                 begin = true;
     372            0 :                 continue;
     373              :             }
     374            0 :             if (begin) {
     375            0 :                 NslbDpAdjInfo adjInfoStep = {};
     376            0 :                 u32 remoteuserRank = links[peerRankInBlock]->GetRemoteRank();
     377            0 :                 adjInfoStep.dstLocalRankId = remoteuserRank;
     378            0 :                 adjInfoStep.phaseId = step + 1;
     379            0 :                 adjInfoStep.rev = 0;
     380            0 :                 nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     381              :             }
     382              :         }
     383            0 :         nslbAdjInfo.dstRankNum = nslbAdjInfo.nsAdjInfo.size();
     384            0 :         return HCCL_SUCCESS;
     385              :     }
     386              :     // 非2的次幂场景下,被合并部分的奇数rank处理流程
     387            0 :     if (rank < nslbPart1Size && rank % NSLBDP_BCAST_MOLD2 == 1) {
     388            0 :         u32 peerRank = rank - 1;
     389            0 :         if (peerRank < links.size()) {
     390            0 :             NslbDpAdjInfo adjInfoStep = {};
     391            0 :             adjInfoStep.dstLocalRankId = links[peerRank]->GetRemoteRank();
     392            0 :             adjInfoStep.phaseId = 1;
     393            0 :             adjInfoStep.rev = 0;
     394            0 :             HCCL_INFO("AllGatherHDR-nslb: peerRank[%u]", peerRank);
     395            0 :             nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     396            0 :             nslbAdjInfo.dstRankNum = 1;
     397              :         }
     398            0 :         return HCCL_SUCCESS;
     399              :     }
     400              : 
     401            0 :     std::vector<LINK> subLinks;
     402            0 :     std::vector<LINK>::const_iterator iter = links.begin();
     403            0 :     subLinks.resize(nslbBlockSize);
     404            0 :     for (u32 i = 0; i < rankSize; i++) {
     405            0 :         if (i < nslbPart1Size
     406            0 :             && (i % NSLBDP_BCAST_MOLD2) == 1) { // 模2余1代表当前rank在part1的奇数位置上,不参与block内的建链
     407            0 :             continue;
     408            0 :         } else if (i < nslbPart1Size && (i % NSLBDP_BCAST_MOLD2) == 0) { // 模2余0代表当前rank在part1的偶数位置上
     409            0 :             std::vector<LINK>::const_iterator niter = std::next(iter, i);
     410            0 :             if (niter != links.end()) {
     411            0 :                 subLinks[i / NSLBDP_BCAST_MOLD2] = *niter;
     412              :             }
     413            0 :         } else {
     414            0 :             std::vector<LINK>::const_iterator niter = std::next(iter, i);
     415            0 :             if (niter != links.end()) {
     416            0 :                 subLinks[i - nslbPart1Size / NSLBDP_BCAST_MOLD2] = *niter;
     417              :             }
     418              :         }
     419              :     }
     420            0 :     u32 stepNum = 0;
     421            0 :     while ((nslbBlockSize >> (stepNum + 1)) != 0) {
     422            0 :         stepNum++;
     423              :     }
     424              :     // 映射完成后针对以新的通信域进行邻接表获取
     425            0 :     u32 begin = 1;
     426            0 :     for (u32 step = 0; step < stepNum; step++) {
     427            0 :         u32 peerRankBitmask = 1 << (stepNum - step - 1);
     428            0 :         u32 peerRank = rankInBlock ^ peerRankBitmask;
     429            0 :         NslbDpAdjInfo adjInfoStep = {};
     430            0 :         if (subLinks[peerRank] == nullptr) {
     431            0 :             continue;
     432              :         }
     433            0 :         u32 remoteuserRank = subLinks[peerRank]->GetRemoteRank();
     434            0 :         adjInfoStep.dstLocalRankId = remoteuserRank;
     435            0 :         adjInfoStep.phaseId = step + begin + 1;
     436            0 :         adjInfoStep.rev = 0;
     437            0 :         nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     438              :     }
     439            0 :     nslbAdjInfo.dstRankNum = nslbAdjInfo.nsAdjInfo.size();
     440            0 :     HCCL_DEBUG("[BcastRecursiveHalvingDoubling]dstRankNum is %u", nslbAdjInfo.dstRankNum);
     441              : 
     442            0 :     if (nslbAdjInfo.nsAdjInfo.size() == 0) {
     443            0 :         return HCCL_SUCCESS;
     444              :     }
     445              :     // 上面处理完成后,紧接着处理合并部分的偶数rank同步到奇数rank增加phaseId
     446            0 :     if (rank < nslbPart1Size && rank % NSLBDP_BCAST_MOLD2 == 0) {
     447            0 :         u32 peerRank = rank + 1;
     448            0 :         uint16_t phaseSize = nslbAdjInfo.nsAdjInfo.size();
     449            0 :         if (peerRank < links.size()) {
     450            0 :             NslbDpAdjInfo adjInfoStep = {};
     451            0 :             adjInfoStep.dstLocalRankId = links[peerRank]->GetRemoteRank();
     452            0 :             adjInfoStep.phaseId = nslbAdjInfo.nsAdjInfo[phaseSize - 1].phaseId + 1;
     453            0 :             adjInfoStep.rev = 0;
     454            0 :             HCCL_INFO("Scatter-nslb: peerRank[%u]", peerRank);
     455            0 :             nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     456            0 :             nslbAdjInfo.dstRankNum = nslbAdjInfo.nsAdjInfo.size();
     457              :         }
     458            0 :         return HCCL_SUCCESS;
     459              :     }
     460            0 :     return HCCL_SUCCESS;
     461            0 : }
     462              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_BROADCAST_RECURSIVE_HD, BcastRecursiveHalvingDoubling);
     463              : } // namespace hccl
        

Generated by: LCOV version 2.0-1