LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/impl/operator - broadcast_operator.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 33.7 % 169 57
Test Date: 2026-07-28 12:11:00 Functions: 50.0 % 10 5

            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 "broadcast_operator.h"
      12              : #include "device_capacity.h"
      13              : #include "coll_alg_op_registry.h"
      14              : 
      15              : namespace hccl {
      16              : constexpr u64 AIV_MAX_DATASIZE = 4ULL * 1024 * 1024 * 1024;
      17              : 
      18            1 : BroadCastOperator::BroadCastOperator(AlgConfigurator* algConfigurator, CCLBufferManager &cclBufferManager,
      19            1 :     HcclDispatcher dispatcher, std::unique_ptr<TopoMatcher> &topoMatcher)
      20            1 :     : CollAlgOperator(algConfigurator, cclBufferManager, dispatcher, topoMatcher, HcclCMDType::HCCL_CMD_BROADCAST)
      21              : {
      22              :     // 由于bcast暂不支持server间ring,需继续使用HD或NHR
      23            1 :     if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR) &&
      24            0 :         !(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR_V1) &&
      25            0 :         !(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING) &&
      26            0 :         !(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB)) {
      27            0 :         algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_HD;
      28            0 :         HCCL_WARNING("[BroadCastOperator][BroadCastOperator] do not support ring in AlgoLevel1 yet, reset algType=HD.");
      29              :     }
      30            1 : }
      31            2 : BroadCastOperator::~BroadCastOperator()
      32              : {
      33            2 : }
      34              : 
      35            1 : HcclResult BroadCastOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName,
      36              :                                         std::string& newTag)
      37              : {
      38              :     HcclResult ret;
      39            1 :     isAivMode_ = false;
      40            1 :     if (isDiffDeviceType_) {
      41            0 :         ret = SelectAlgforMix(param, algName);
      42            1 :     } else if (Is310P3Common(isHaveCpuRank_, deviceType_)) {
      43            0 :         ret = SelectAlgfor310P3(param, algName);
      44            1 :     } else if (Is310PDevice() && topoType_ == TopoType::TOPO_TYPE_2P_MESH) {
      45            0 :         ret = SelectAlgfor310P(param, algName);
      46            1 :     } else if (deviceType_ == DevType::DEV_TYPE_910) {
      47            0 :         ret = SelectAlgfor910A(param, algName);
      48            1 :     } else if (deviceType_ == DevType::DEV_TYPE_910B) {
      49            0 :         ret = SelectAlgfor910B(param, algName);
      50            1 :     } else if (deviceType_ == DevType::DEV_TYPE_910_93) {
      51            1 :         ret = SelectAlgfor91093(param, algName);
      52              :     } else {
      53            0 :         HCCL_ERROR("BroadCastOperator[SelectAlg] device type[%d] is out of range for selector.", deviceType_);
      54            0 :         return HCCL_E_NOT_SUPPORT;
      55              :     }
      56            1 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
      57              :         HCCL_ERROR("[BroadCastSelector][SelectAlg]tag[%s], broadcast failed, return[%d]", tag.c_str(), ret), ret);
      58              : 
      59            1 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
      60            1 :         newTag = tag;
      61            0 :     } else if (isAivMode_ || (Is310P3Common(isHaveCpuRank_, deviceType_) &&
      62            0 :                             (algType_.algoLevel1 != AlgTypeLevel1::ALG_LEVEL1_HD))) {
      63            0 :         newTag = tag + algName;
      64            0 :     } else if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD || algType_.algoLevel2 == AlgTypeLevel2::ALG_LEVEL2_HD) {
      65            0 :         newTag = tag + algName;
      66            0 :         std::string appendTag = "";
      67            0 :         u32 serverNumPerSuperPod = superPodNum_ == 0 ? moduleNum_ : moduleNum_ / superPodNum_;
      68            0 :         if (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_HD) {
      69            0 :             u32 part1Size = FACTOR_TWO * (serverNumPerSuperPod - (1 << static_cast<u32>(log2(serverNumPerSuperPod))));
      70            0 :             u32 rootId = param.root / deviceNumPerAggregation_ % serverNumPerSuperPod;
      71            0 :             appendTag += "L1_" + std::to_string((rootId >= part1Size) || ((rootId % FACTOR_TWO) == 0));
      72              :         }
      73            0 :         if (algType_.algoLevel2 == AlgTypeLevel2::ALG_LEVEL2_HD) {
      74            0 :             u32 part1Size = FACTOR_TWO * (superPodNum_ - (1 << static_cast<u32>(log2(superPodNum_))));
      75            0 :             u32 rootId = param.root / deviceNumPerAggregation_ / serverNumPerSuperPod;
      76            0 :             appendTag += (appendTag.empty() ? "L2_" : "_L2_") + std::to_string((rootId >= part1Size) || ((rootId % FACTOR_TWO) == 0));
      77              :         }
      78            0 :         HCCL_DEBUG("[BroadCastOperator][SelectAlg]tag is [%s]", tag);
      79            0 :         newTag = newTag + '_' + appendTag;
      80            0 :         if (GetExternalInputHcclEnableEntryLog() && param.opBaseAtraceInfo != nullptr) {
      81            0 :             CHK_RET(param.opBaseAtraceInfo->SavealgtypeTraceInfo(appendTag, param.tag));
      82              :         }
      83            0 :     } else {
      84            0 :         AlgTypeLevel1 algType1 = algType_.algoLevel1;
      85            0 :         auto level1Iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algType1);
      86            0 :         CHK_PRT_RET(level1Iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(), HCCL_ERROR("level1: algType1[%u] is invalid.",
      87              :             algType1), HCCL_E_INTERNAL);
      88            0 :         newTag = tag + level1Iter->second + algName;
      89              :     }
      90            1 :     HCCL_DEBUG("[%s] SelectAlg for newTag", __func__);
      91            1 :     newTag += (param.aicpuUnfoldMode ? "_device" : "_host");
      92            1 :     return ret;
      93              : }
      94              : 
      95            0 : HcclResult BroadCastOperator::SelectAlgforMix(const OpParam& param, std::string& algName)
      96              : {
      97              :     (void) param;
      98            0 :     if (gcdDeviceNumPerAggregation_ > 1) {
      99            0 :         algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
     100            0 :         HCCL_WARNING("[BroadCastOperator][SelectAlgforMix] only support NHR in AlgoLevel1 yet, "\
     101              :             "default is algType=NHR.");
     102            0 :         algName = "BroadCastMixExecutor";
     103              :     } else {
     104            0 :         algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_RING;
     105            0 :         HCCL_WARNING("[BroadCastOperator][SelectAlgforMix] only support ring in AlgoComm yet, "\
     106              :             "default is algType=ring.");
     107            0 :         algName = "BroadCastComm";
     108              :     }
     109              : 
     110            0 :     HCCL_INFO("[SelectAlgforMix] broadcast SelectAlgforMix is algName [%s]", algName.c_str());
     111            0 :     return HCCL_SUCCESS;
     112              : }
     113              : 
     114            0 : HcclResult BroadCastOperator::SelectAlgfor310P3(const OpParam& param, std::string& algName)
     115              : {
     116              :     (void) param;
     117            0 :     algName = "BroadCastCommFor310P";
     118            0 :     HCCL_INFO("[SelectAlgfor310P3] broadcast SelectAlgfor310P3 is algName [%s]", algName.c_str());
     119            0 :     return HCCL_SUCCESS;
     120              : }
     121              : 
     122            0 : HcclResult BroadCastOperator::SelectAlgfor310P(const OpParam& param, std::string& algName)
     123              : {
     124            0 :     algName = "BroadcastPlusBroadcast";
     125            0 :     HCCL_INFO("[SelectAlgfor310P] broadcast SelectAlgfor310P is algName [%s]", algName.c_str());
     126            0 :     return HCCL_SUCCESS;
     127              : }
     128              : 
     129            0 : HcclResult BroadCastOperator::SelectAlgfor910A(const OpParam& param, std::string& algName)
     130              : {
     131              :     (void) param;
     132            0 :     bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_4P_MESH || topoType_ == TopoType::TOPO_TYPE_2P_MESH;
     133            0 :     bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING || topoType_ == TopoType::TOPO_TYPE_8P_RING;
     134              : 
     135            0 :     if (isMeshTopo) {
     136            0 :         algName = "BroadCastMeshExecutor";
     137            0 :     } else if (topoType_ == TopoType::TOPO_TYPE_4P_RING) {
     138            0 :         algName = "BroadCast4pRingExecutor";
     139            0 :     } else if (isRingTopo) {
     140            0 :         algName = "BroadCastRingExecutor";
     141              :     } else {
     142            0 :         algName = "BroadCastComm";
     143              :     }
     144            0 :     HCCL_INFO("[SelectAlgfor910A] broadcast SelectAlgfor910A is algName [%s]", algName.c_str());
     145            0 :     return HCCL_SUCCESS;
     146              : }
     147              : 
     148            0 : HcclResult BroadCastOperator::SelectAlgfor910B(const OpParam& param, std::string& algName)
     149              : {
     150            0 :     bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH ||
     151            0 :         topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
     152            0 :     bool isRingTopo = topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING || topoType_ == TopoType::TOPO_TYPE_8P_RING;
     153            0 :     bool isOpbase = (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
     154              :     
     155              :     // 暂只支持单算子模式
     156            0 :     const u64 commInputSize = cclBufferManager_.GetInCCLbufferSize();
     157            0 :     const u64 commOutputSize = cclBufferManager_.GetOutCCLbufferSize();
     158            0 :     u64 dataSize = param.DataDes.count * SIZE_TABLE[param.DataDes.dataType];
     159            0 :     bool isCCLBufferGE16M = commInputSize >= HCCL_MID_COUNT_16_MB && commOutputSize >= HCCL_MID_COUNT_16_MB;
     160            0 :     isAivMode_ = topoMatcher_->GetAivModeConfig() && isSingleMeshAggregation_ && isOpbase && isCCLBufferGE16M &&
     161            0 :                      IsSupportAIVCopy(param.DataDes.dataType) && dataSize <= AIV_MAX_DATASIZE;
     162            0 :     if (isAivMode_) {
     163            0 :         algName = "BroadcastMeshAivExecutor";
     164            0 :     } else if (isMeshTopo) {
     165            0 :         algName = "BroadCastMeshExecutor";
     166            0 :     } else if (topoType_ == TopoType::TOPO_TYPE_4P_RING) {
     167            0 :         algName = "BroadCast4pRingExecutor";
     168            0 :     } else if (isRingTopo) {
     169            0 :         algName = "BroadCastRingExecutor";
     170              :     } else {
     171            0 :         algName = "BroadCastComm";
     172              :     }
     173            0 :     HCCL_INFO("[SelectAlgfor910B] broadcast SelectAlgfor910B is algName [%s]", algName.c_str());
     174            0 :     return HCCL_SUCCESS;
     175              : }
     176              : 
     177            1 : HcclResult BroadCastOperator::SelectAlgfor91093(const OpParam& param, std::string& algName)
     178              : {
     179              :     // level 1重定向为NHR, 因scatter && broadcast只支持nhr/nb
     180            1 :     if (!(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NHR) &&
     181            0 :         !(algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_NB)) {
     182            0 :         algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
     183            0 :         HCCL_WARNING("[BroadCastOperator][BroadCastOperator] do not support ring in AlgoLevel1 yet, reset algType=NHR.");
     184              :     }
     185              : 
     186            1 :     u32 unitSize = SIZE_TABLE[param.DataDes.dataType];
     187            1 :     u64 dataSize = param.DataDes.count * unitSize; // 单位:字节
     188            1 :     if (dataSize >= cclBufferManager_.GetInCCLbufferSize()) {
     189            1 :         HCCL_WARNING("The current inCCLbufferSize is [%llu] bytes, change the HCCL_BUFFSIZE environment variable "\
     190              :             "to be greater than the current data volume[%llu] bytes to improve the performance of the 91093 environment.",
     191              :             cclBufferManager_.GetInCCLbufferSize(), dataSize);
     192              :     }
     193              : 
     194            1 :     const u64 commInputSize = cclBufferManager_.GetInCCLbufferSize();
     195            1 :     const u64 commOutputSize = cclBufferManager_.GetOutCCLbufferSize();
     196            1 :     bool isCCLBufferGE16M = commInputSize >= HCCL_MID_COUNT_16_MB && commOutputSize >= HCCL_MID_COUNT_16_MB;
     197            1 :     bool isOpbase = (GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
     198              : 
     199            1 :     bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
     200            1 :     bool hasEnoughCCLBuffer = isSingleMeshAggregation_ && isOpbase && isCCLBufferGE16M && dataSize <= AIV_MAX_DATASIZE;
     201            1 :     bool hasSmallDataOrOnlyAiv = !isOpbase && (isOnlyAiv || dataSize <= HCCL_MID_COUNT_16_MB);
     202            1 :     bool isSatisfyDataSize = (userRankSize_ <= DEVICE_EIGHT && dataSize <= HCCL_SMALL_COUNT_512_KB ) ||
     203            0 :                              (userRankSize_ > DEVICE_EIGHT && dataSize <= HCCL_SMALL_COUNT_1_MB);
     204              : 
     205            1 :     bool isAivSingleNode = serverNum_ == 1 && (hasEnoughCCLBuffer || hasSmallDataOrOnlyAiv);
     206            0 :     bool isAivCrossNode  = (superPodNum_ == 1) && (serverNum_ > 1) && !GetExternalInputInterHccsDisable()
     207            1 :         && ((isOpbase && isCCLBufferGE16M && isSatisfyDataSize) || hasSmallDataOrOnlyAiv);
     208              :     
     209            1 :     isAivMode_ = topoMatcher_->GetAivModeConfig()
     210            1 :             && IsSupportAIVCopy(param.DataDes.dataType)
     211            2 :             && (isAivSingleNode || isAivCrossNode);
     212              : 
     213            1 :     bool smallCountOptimSingleServer =
     214            2 :         (serverNum_ == 1) &&
     215            1 :         ((workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) ||
     216            1 :         (workflowMode_ != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE && !param.aicpuUnfoldMode)) &&
     217            2 :         (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO) &&
     218            0 :         (param.DataDes.count * SIZE_TABLE[param.DataDes.dataType] <= HCCL_SMALL_COUNT_512_KB * userRankSize_);
     219            1 :     bool smallCountOptimMultiServer =
     220            1 :         (deviceNumPerAggregation_ > HCCL_DEVICE_NUM_TWO) && (serverNum_ != 1) && (superPodNum_ == 1) &&
     221            0 :         (param.DataDes.count * SIZE_TABLE[param.DataDes.dataType] <= HCCL_SMALL_COUNT_1_MB * deviceNumPerAggregation_);
     222            1 :     bool is2Pod2ServerTopo = (superPodNum_ == 2 && serverNum_ == 2);// 针对 A3背靠背机型
     223            1 :     bool smallCountOptimMultiPod = (superPodNum_ > 1 || (GetExternalInputInterHccsDisable() && serverNum_ > 1)) && !is2Pod2ServerTopo &&
     224            2 :         (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_16_KB * deviceNumPerAggregation_) && !retryEnable_; // 涉及ROCE平面
     225            0 :     bool isBack2BackFor91093 = is2Pod2ServerTopo && (workflowMode_ == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) &&
     226            1 :         (param.DataDes.count * unitSize <= HCCL_SMALL_COUNT_16_KB * deviceNumPerAggregation_) && !retryEnable_; 
     227            1 :     if (isAivMode_) {
     228            1 :         if(isAivSingleNode) {
     229            1 :             algName = "BroadcastMeshAivExecutor";
     230              :         } else {
     231            0 :             algName = "BroadcastMeshAivFor91093Executor";
     232              :         }
     233            0 :     } else if (multiModuleDiffDeviceNumMode_ || multiSuperPodDiffServerNumMode_) {
     234            0 :         algName = "BroadCastComm";
     235            0 :     } else if (smallCountOptimMultiServer || smallCountOptimMultiPod) {
     236            0 :         algName = "BroadCastComm";
     237            0 :         algType_.algoLevel1 = AlgTypeLevel1::ALG_LEVEL1_NHR;
     238            0 :     } else if (isBack2BackFor91093) {
     239            0 :         algName = "BroadcastMidCountFor91093Executor";
     240            0 :     } else if (smallCountOptimSingleServer) {
     241            0 :         algName = "BroadCastSmallCountExecutor";
     242            0 :     } else if (param.supportZeroCopy &&
     243            0 :         (topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING || param.DataDes.count * unitSize > HCCL_MID_COUNT_16_MB * serverNum_)) {
     244            0 :         algName = "BroadCastRingZerocopyExecutor";
     245            0 :     } else if (topoType_ == TopoType::TOPO_TYPE_NP_SINGLE_RING || topoType_ == TopoType::TOPO_TYPE_NP_DOUBLE_RING) {
     246            0 :         algName = "BroadCastRingFor91093Executor";
     247              :     } else {
     248            0 :         algName = "BroadCastComm";
     249              :     }
     250            1 :     HCCL_INFO("[SelectAlgfor91093] broadcast SelectAlgfor91093 is algName [%s]", algName.c_str());
     251            1 :     return HCCL_SUCCESS;
     252              : }
     253              : 
     254              : REGISTER_OP(HcclCMDType::HCCL_CMD_BROADCAST, Broadcast, BroadCastOperator);
     255              : } // namespace hccl
        

Generated by: LCOV version 2.0-1