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

Generated by: LCOV version 2.0-1