LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/impl/operator - coll_alg_operator.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 37.3 % 614 229
Test Date: 2026-08-17 10:19:35 Functions: 56.9 % 51 29

            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 <cmath>
      12              : #include <algorithm>
      13              : #include "device_capacity.h"
      14              : #include "coll_executor_base.h"
      15              : #include "coll_alg_exec_registry.h"
      16              : #include "coll_alg_operator.h"
      17              : 
      18              : namespace hccl {
      19              : using namespace std;
      20              : constexpr float GB2B = 1024 * 1024 * 1024;
      21              : constexpr float SECOND2MICROSECOND = 1000000;
      22              : constexpr float RHD_FACTOR_TWO = 2.0;
      23              : constexpr float RHD_FACTOR_ONE = 1.0;
      24              : constexpr float DOUBLE_SUB_HCCLCMD = 2.0; // The hcclCMD can be considered as combination of two hcclCMDs.
      25              : constexpr float COPY_TIME_IN_RHD = 1.0;
      26              : constexpr double NHR_FACTOR_TWO = 2.0;
      27              : constexpr double NHR_FACTOR_THREE = 3.0;
      28              : constexpr double NHR_FACTOR_FOUR = 4.0;
      29              : constexpr double NHR_SUB_TWO = 2.0;
      30              : constexpr float LATENCY = 60;                // 静态时延 60 us;
      31              : constexpr u64 PIPELINE_MIN_SIZE = 32 * 1024; // 当数据量大于等于32KB时,reduce_scatter和all_gather使能pipeline模式
      32              : constexpr u64 PIPELINE_ALLREDUCE_MIN_SIZE = 1024 * 1024; // 当数据量大于等于1MB时,allreduce使能pipeline模式
      33              : constexpr u64 PIPELINE_MIN_SIZE_NO_LITE = 2 * 1024 * 1024; // 如不支持RDMALite,当数据量大于等于2MB时,使能pipeline模式
      34              : constexpr u64 HCCL_FFTS_CAPACITY = 65535; // FFTS+子图最大容量
      35              : constexpr u32 AHC_MIN_SUBGROUP_SPLIT_DIVISOR = 2;
      36              : constexpr u32 AHC_LEVEL0_GROUP_SIZE_THRESHOLD = 3;
      37              : constexpr u32 SERVER_COUNT_THRESHOLD_FOR_MULTI_DETER_PIPELINE = 2;
      38              : constexpr u32 MIN_STRICT_RANK_NUM = 3;
      39              : 
      40           87 : CollAlgOperator::CollAlgOperator(
      41              :     AlgConfigurator* algConfigurator, CCLBufferManager& cclBufferManager, HcclDispatcher dispatcher,
      42           87 :     std::unique_ptr<TopoMatcher>& topoMatcher, HcclCMDType opType)
      43           84 :     : algConfigurator_(algConfigurator),
      44           84 :       cclBufferManager_(cclBufferManager),
      45           80 :       dispatcher_(dispatcher),
      46           80 :       topoMatcher_(topoMatcher),
      47          559 :       workflowMode_(GetWorkflowMode())
      48              : {
      49           75 :     SetTopoAttr(algConfigurator_);
      50           78 :     SetAlgoAttr(algConfigurator_);
      51           94 :     algConfigurator->GetAlgTypeDirect(algType_, opType);
      52           74 :     algConfigurator->GetAlgoLevel1DefaultSwitch(isAlgoLevel1Default_, opType);
      53           73 :     algConfigurator->GetTopoType(topoType_);
      54           73 : }
      55              : 
      56              : HcclResult
      57            0 : CollAlgOperator::SelectAlg(const std::string& tag, const OpParam& param, std::string& algName, std::string& newTag)
      58              : {
      59            0 :     return HCCL_SUCCESS;
      60              : }
      61              : 
      62           30 : HcclResult CollAlgOperator::SelectAlg(
      63              :     const std::string& tag, const OpParam& param, std::string& algName, std::string& newTag, const ResourceLimit& limit)
      64              : {
      65           30 :     return SelectAlg(tag, param, algName, newTag);
      66              : }
      67              : 
      68            1 : HcclResult CollAlgOperator::GetAivExecParam(
      69              :     std::string& algName, const OpParam& param, AlgResourceResponse& algRes, AivSuperKernelArgs& args)
      70              : {
      71            1 :     if (executor_.get() == nullptr) {
      72            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
      73            0 :         CHK_PRT_RET(
      74              :             executor_.get() == nullptr,
      75              :             HCCL_ERROR("[CollAlgOperator][GetAivExecParam]Fail to find executor for algName[%s]", algName.c_str()),
      76              :             HCCL_E_PARA);
      77              :     }
      78            1 :     return executor_->GetAivExecParam(param, algRes, args);
      79              : }
      80              : 
      81              : HcclResult
      82            1 : CollAlgOperator::CalNumBlocks(std::string& algName, const OpParam& param, u32& numBlocks, int32_t aivCoreLimit)
      83              : {
      84            1 :     if (executor_.get() == nullptr) {
      85            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
      86            0 :         CHK_PRT_RET(
      87              :             executor_.get() == nullptr,
      88              :             HCCL_ERROR("[CollAlgOperator][CalNumBlocks]Fail to find executor for algName[%s]", algName.c_str()),
      89              :             HCCL_E_PARA);
      90            0 :         CHK_RET(SetExecutorAttr(param));
      91              :     }
      92              : 
      93            1 :     if (aivCoreLimit != 0) {
      94            1 :         CHK_RET(executor_->SetNumBlocks(aivCoreLimit));
      95              :     }
      96              : 
      97            1 :     if (param.opType == HcclCMDType::HCCL_CMD_ALLTOALL) {
      98            0 :         return executor_->CalNumBlocks(
      99            0 :             numBlocks, userRankSize_, param.All2AllDataDes.sendCount * SIZE_TABLE[param.All2AllDataDes.sendType],
     100            0 :             param.opType);
     101            1 :     } else if (
     102            1 :         param.opType == HcclCMDType::HCCL_CMD_ALLREDUCE || param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER
     103            0 :         || param.opType == HcclCMDType::HCCL_CMD_ALLGATHER || param.opType == HcclCMDType::HCCL_CMD_BROADCAST) {
     104            1 :         return executor_->CalNumBlocks(
     105            1 :             numBlocks, userRankSize_, param.DataDes.count * SIZE_TABLE[param.DataDes.dataType], param.opType);
     106              :     } else {
     107            0 :         return executor_->CalNumBlocks(numBlocks, userRankSize_);
     108              :     }
     109              :     return HCCL_SUCCESS;
     110              : }
     111              : 
     112            0 : HcclResult CollAlgOperator::GetOpExpansionStr(const OpParam& param, const AlgDesc& algDesc, std::string& opExpansionStr)
     113              : {
     114            0 :     if (algDesc.isAivMode) {
     115            0 :         opExpansionStr = "AIV";
     116            0 :     } else if (param.aicpuUnfoldMode) {
     117            0 :         opExpansionStr = "AI_CPU";
     118            0 :     } else if (static_cast<bool>(topoMatcher_->GetExternalInputHcclEnableFfts())) {
     119            0 :         opExpansionStr = "HOST";
     120              :     } else {
     121            0 :         opExpansionStr = "HOST_TS";
     122              :     }
     123            0 :     return HCCL_SUCCESS;
     124              : }
     125              : 
     126           60 : HcclResult CollAlgOperator::SelectAlg(
     127              :     const std::string& tag, const OpParam& param, const ResourceLimit& limit, std::string& algName, AlgDesc& algDesc,
     128              :     std::string& newTag)
     129              : {
     130           60 :     bool isOnlyAiv = topoMatcher_->GetIsOnlyAivConfig();
     131           62 :     bool supportOnlyAiv
     132           54 :         = (param.opType == HcclCMDType::HCCL_CMD_ALLGATHER || param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER
     133           28 :            || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLV || param.opType == HcclCMDType::HCCL_CMD_ALLTOALLVC
     134          116 :            || param.opType == HcclCMDType::HCCL_CMD_ALLTOALL || param.opType == HcclCMDType::HCCL_CMD_ALLREDUCE);
     135           62 :     CHK_PRT_RET(
     136              :         isOnlyAiv && !supportOnlyAiv,
     137              :         HCCL_ERROR(
     138              :             "[CollAlgOperator][SelectAlg] opType[%s] currently do not support aivonly",
     139              :             GetCMDTypeEnumStr(param.opType).c_str()),
     140              :         HCCL_E_NOT_SUPPORT);
     141           62 :     CHK_PRT_RET(
     142              :         isOnlyAiv && userRankSize_ == 1 && supportOnlyAiv,
     143              :         HCCL_ERROR("[CollAlgOperator][SelectAlg] aivonly not support, please ensure rankNum is greater than one"),
     144              :         HCCL_E_NOT_SUPPORT);
     145              : 
     146              :     // 兼容老接口
     147           62 :     if (limit.ifLimit) {
     148           62 :         CHK_RET(SelectAlg(tag, param, algName, newTag, limit));
     149              :     } else {
     150            0 :         CHK_RET(SelectAlg(tag, param, algName, newTag));
     151              :     }
     152              : 
     153              :     // 非AIV算法提前返回, 采用兜底Executor
     154           76 :     if (algName.empty()) {
     155            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec("SendExecutor", dispatcher_, topoMatcher_);
     156            0 :         CHK_PRT_RET(
     157              :             executor_.get() == nullptr,
     158              :             HCCL_ERROR("[CollAlgOperator][SelectAlg]Fail to find executor for algName[DefaultExecutor]"), HCCL_E_PARA);
     159              :     } else {
     160              :         // 校验控核
     161           75 :         if (limit.ifLimit && deviceType_ == DevType::DEV_TYPE_910_93 && topoMatcher_->GetAivModeConfig()) {
     162            0 :             CHK_RET(SelectAlgFor91093WithCoreLimit(param, limit, algName));
     163              :         }
     164              : 
     165              :         // 从对应executor获取算法描述
     166           74 :         if (executor_.get() == nullptr) {
     167           72 :             executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     168           73 :             CHK_PRT_RET(
     169              :                 executor_.get() == nullptr,
     170              :                 HCCL_ERROR("[CollAlgOperator][SelectAlg]Fail to find executor for algName[%s]", algName.c_str()),
     171              :                 HCCL_E_PARA);
     172           71 :             CHK_RET(SetExecutorAttr(param));
     173              :         }
     174              :     }
     175              : 
     176           72 :     bool isLastSelect = algDesc.isLastSelect;
     177           72 :     algDesc = executor_->GetAlgDesc();
     178              :     // 打印维测日志
     179           69 :     if (UNLIKELY(GetDebugConfig() & HCCL_ALG) && isLastSelect) {
     180              :         // 获取展开模式,转换成字符串
     181            0 :         std::string opExpansionStr;
     182            0 :         CHK_RET(GetOpExpansionStr(param, algDesc, opExpansionStr));
     183              :         // 尝试获取确定性属性(如果Executor有声明自己是否为确定性)
     184            0 :         std::string appendStr = "";
     185            0 :         if (algDesc.deterministic >= 0) {
     186            0 :             appendStr += "deterministic[" + std::to_string(algDesc.deterministic) + "]";
     187              :         }
     188              :         // 打印关键维测内容
     189            0 :         bool isOpBase = GetWorkflowMode() == HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE;
     190            0 :         HCCL_CONFIG_INFO(
     191              :             HCCL_ALG,
     192              :             "[%s] newTag[%s] algName[%s] userRank[%u] topoType[%d] algType[%s] "
     193              :             "userRankSize[%u] level0Size[%u] moduleNum_[%u] level2Size[%u] ",
     194              :             __func__, newTag.c_str(), algName.c_str(), userRank_, topoType_, AlgTypeToStr(algDesc.algType).c_str(),
     195              :             userRankSize_, deviceNumPerAggregation_, moduleNum_, superPodNum_);
     196            0 :         HCCL_CONFIG_INFO(
     197              :             HCCL_ALG,
     198              :             "[%s] newTag[%s] "
     199              :             "opExpansionMode[%s] isZeroCopy[%u] retryEnable[%u] isOpBase[%u] isCapture[%u] aivCoreLimit[%u] %s.",
     200              :             __func__, newTag.c_str(), opExpansionStr.c_str(), algDesc.isZeroCopy, retryEnable_, isOpBase,
     201              :             param.isCapture, limit.aivCoreLimit, appendStr.c_str());
     202            0 :     }
     203           72 :     return HCCL_SUCCESS;
     204              : }
     205              : 
     206              : HcclResult
     207            0 : CollAlgOperator::SelectAlgFor91093WithCoreLimit(const OpParam& param, const ResourceLimit& limit, std::string& algName)
     208              : {
     209            0 :     if (executor_.get() == nullptr) {
     210            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     211            0 :         CHK_PRT_RET(
     212              :             executor_.get() == nullptr,
     213              :             HCCL_ERROR(
     214              :                 "[CollAlgOperator][SelectAlgFor91093WithCoreLimit]Fail to find executor for algName[%s]",
     215              :                 algName.c_str()),
     216              :             HCCL_E_PARA);
     217            0 :         CHK_RET(SetExecutorAttr(param));
     218              :     }
     219              : 
     220            0 :     CHK_RET(SetNumBlocks(limit.aivCoreLimit));
     221              : 
     222            0 :     std::string reSelName;
     223            0 :     switch (param.opType) {
     224            0 :         case HcclCMDType::HCCL_CMD_ALLREDUCE:
     225            0 :             reSelName = "AllReduceMeshAivFor91093Executor";
     226            0 :             break;
     227            0 :         case HcclCMDType::HCCL_CMD_ALLGATHER:
     228            0 :             reSelName = "AllGatherMeshAivFor91093Executor";
     229            0 :             break;
     230            0 :         case HcclCMDType::HCCL_CMD_REDUCE_SCATTER:
     231            0 :             reSelName = "ReduceScatterMeshAivFor91093Executor";
     232            0 :             break;
     233            0 :         case HcclCMDType::HCCL_CMD_ALLTOALLV:
     234              :         case HcclCMDType::HCCL_CMD_ALLTOALL:
     235              :         case HcclCMDType::HCCL_CMD_ALLTOALLVC:
     236            0 :             reSelName = "AlltoAllMeshAivFor91093Executor";
     237            0 :             break;
     238            0 :         default:
     239            0 :             break;
     240              :     }
     241              : 
     242              :     u32 numBlocks;
     243            0 :     HcclResult ret = CalNumBlocks(algName, param, numBlocks);
     244            0 :     if (ret != HCCL_SUCCESS) {
     245            0 :         CHK_PRT_RET(
     246              :             reSelName.empty() || reSelName == algName,
     247              :             HCCL_ERROR(
     248              :                 "[CollAlgOperator][SelectAlgFor91093WithCoreLimit]Fail to check CalNumBlocks for algName[%s]",
     249              :                 algName.c_str()),
     250              :             HCCL_E_PARA);
     251              : 
     252            0 :         algName = reSelName;
     253            0 :         executor_ = nullptr;
     254            0 :         HCCL_INFO("[CollAlgOperator][SelectAlgFor91093WithCoreLimit]Re select to algName[%s]", reSelName.c_str());
     255              :     }
     256              : 
     257            0 :     return HCCL_SUCCESS;
     258            0 : }
     259              : 
     260              : HcclResult
     261           70 : CollAlgOperator::CalcResRequest(const std::string& algName, const OpParam& param, AlgResourceRequest& resourceRequest)
     262              : {
     263           70 :     if (executor_.get() == nullptr) {
     264            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     265            0 :         CHK_PRT_RET(
     266              :             executor_.get() == nullptr,
     267              :             HCCL_ERROR("[CollAlgOperator][CalcResRequest]Fail to find executor for algName[%s]", algName.c_str()),
     268              :             HCCL_E_PARA);
     269            0 :         CHK_RET(SetExecutorAttr(param));
     270              :     }
     271           69 :     return executor_->CalcResRequest(param, resourceRequest);
     272              : }
     273              : 
     274           24 : HcclResult CollAlgOperator::Orchestrate(const std::string& algName, OpParam& param, AlgResourceResponse& algResource)
     275              : {
     276           24 :     HCCL_INFO("[CollAlgOperator][Orchestrate]algName[%s]", algName.c_str());
     277           24 :     if (executor_.get() == nullptr) {
     278            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     279            0 :         CHK_PRT_RET(
     280              :             executor_.get() == nullptr,
     281              :             HCCL_ERROR("[CollAlgOperator][Orchestrate]Fail to find executor for algName[%s]", algName.c_str()),
     282              :             HCCL_E_PARA);
     283            0 :         CHK_RET(SetExecutorAttr(param));
     284              :     }
     285           24 :     executor_->SetAivClearEnable(aivClearEnable_);
     286           24 :     executor_->SetAlgOpContext(algOpContext_);
     287           24 :     executor_->SetOpCounter(opCounter_);
     288           24 :     return executor_->Orchestrate(param, algResource);
     289              : }
     290              : 
     291            0 : HcclResult CollAlgOperator::GetAdjInfo(
     292              :     const std::string& algName, OpParam& param, AlgResourceResponse& algResource, AdjInfo& nslbAdjInfo)
     293              : {
     294            0 :     if (executor_.get() == nullptr) {
     295            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     296            0 :         CHK_PRT_RET(
     297              :             executor_.get() == nullptr,
     298              :             HCCL_ERROR("[CollAlgOperator][Orchestrate]Fail to find executor for algName[%s]", algName.c_str()),
     299              :             HCCL_E_PARA);
     300            0 :         CHK_RET(SetExecutorAttr(param));
     301              :     }
     302              : 
     303            0 :     return executor_->GetAdjInfo(algResource, nslbAdjInfo);
     304              : }
     305              : 
     306           25 : HcclResult CollAlgOperator::PrepareCommInfoToDevice(const std::string& algName, AlgResourceResponse& algResource)
     307              : {
     308           25 :     if (executor_.get() == nullptr) {
     309            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     310            0 :         CHK_PRT_RET(
     311              :             executor_.get() == nullptr,
     312              :             HCCL_ERROR(
     313              :                 "[CollAlgOperator][PrepareCommInfoToDevice]Fail to find executor for algName[%s]", algName.c_str()),
     314              :             HCCL_E_PARA);
     315              :     }
     316           25 :     return executor_->PrepareCommInfoToDevice(algResource);
     317              : }
     318              : 
     319            0 : HcclResult CollAlgOperator::CalcIncreLinkRequest(
     320              :     const std::string& algName, const OpParam& param, std::set<u32>& ranksHasLinked,
     321              :     AlgResourceRequest& resourceRequest, bool& needIncreLink)
     322              : {
     323            0 :     if (executor_.get() == nullptr) {
     324            0 :         executor_ = CollAlgExecRegistry::Instance().GetAlgExec(algName, dispatcher_, topoMatcher_);
     325            0 :         CHK_PRT_RET(
     326              :             executor_.get() == nullptr,
     327              :             HCCL_ERROR("[CollAlgOperator][CalcIncreLinkRequest]Fail to find executor for algName[%s]", algName.c_str()),
     328              :             HCCL_E_PARA);
     329              :     }
     330            0 :     return executor_->CalcIncreLinkRequest(param, ranksHasLinked, resourceRequest, needIncreLink);
     331              : }
     332              : 
     333           77 : void CollAlgOperator::SetTopoAttr(AlgConfigurator* algConfigurator)
     334              : {
     335           77 :     const HcclTopoAttr& topoAttr = algConfigurator->GetTopoAttr();
     336           78 :     serverNum_ = topoAttr.serverNum;
     337           78 :     moduleNum_ = topoAttr.moduleNum;
     338           78 :     superPodNum_ = topoAttr.superPodNum;
     339           78 :     deviceNumPerServer_ = topoAttr.deviceNumPerServer;
     340           78 :     deviceNumPerAggregation_ = topoAttr.deviceNumPerAggregation;
     341           78 :     multiModuleDiffDeviceNumMode_ = topoAttr.multiModuleDiffDeviceNumMode;
     342           78 :     multiSuperPodDiffServerNumMode_ = topoAttr.multiSuperPodDiffServerNumMode;
     343           78 :     multiSuperPodDiffDeviceNumMode_ = topoAttr.multiSuperPodDiffDeviceNumMode;
     344           78 :     isDiffDeviceType_ = topoAttr.isDiffDeviceType;
     345           78 :     gcdDeviceNumPerAggregation_ = topoAttr.gcdDeviceNumPerAggregation;
     346              : 
     347           78 :     meshAggregationRankSize_ = topoAttr.meshAggregationRankSize;
     348           78 :     isDiffDeviceModule_ = topoAttr.isDiffDeviceModule;
     349           78 :     isSingleMeshAggregation_ = topoAttr.isSingleMeshAggregation;
     350           78 :     isAllRankSamePlane_ = topoAttr.isAllRankSamePlane;
     351           78 :     is310PDuoCard_ = topoAttr.is310PDuoCard;
     352           78 :     isCommon310P3DUO_ = topoAttr.isCommon310P3DUO;
     353           78 :     hccsPortNum_ = topoAttr.hccsPortNum;
     354              : 
     355           78 :     userRank_ = topoAttr.userRank;
     356           78 :     realUserRank_ = topoAttr.realUserRank;
     357           78 :     userRankSize_ = topoAttr.userRankSize;
     358              : 
     359           78 :     devicePhyId_ = topoAttr.devicePhyId;
     360           78 :     deviceLogicId_ = topoAttr.deviceLogicId;
     361           78 :     deviceType_ = topoAttr.deviceType;
     362              : 
     363           78 :     nicList_ = topoAttr.nicList;
     364           78 :     pairLinkCounter_ = topoAttr.pairLinkCounter;
     365           78 :     isSupportRdmaLite_ = topoAttr.isSupportRdmaLite;
     366           78 :     isSupportHccsAndSio_ = topoAttr.isSupportHccsAndSio;
     367           78 :     useSuperPodMode_ = topoAttr.useSuperPodMode;
     368           78 :     isARSDoubleRing_ = topoAttr.isARSDoubleRing;
     369           78 :     return;
     370              : }
     371              : 
     372           80 : void CollAlgOperator::SetAlgoAttr(AlgConfigurator* algConfigurator)
     373              : {
     374           80 :     const HcclAlgoAttr& algoAttr = algConfigurator->GetAlgoAttr();
     375           80 :     isHaveCpuRank_ = algoAttr.isHaveCpuRank;
     376           80 :     inlineReduceSwitchOn_ = algoAttr.inlineReduceSwitchOn;
     377           80 :     identifier_ = algoAttr.identifier;
     378           93 :     return;
     379              : }
     380              : 
     381           66 : HcclResult CollAlgOperator::SetExecutorAttr(const OpParam& param)
     382              : {
     383           66 :     CHK_RET(executor_->SetAlgType(algType_));
     384           64 :     CHK_RET(executor_->SetCCLInBuffer(cclBufferManager_.GetInCCLbufferSize()));
     385              : 
     386           65 :     if (param.opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER) {
     387           31 :         bool isSupportSDMAReduce = false;
     388           31 :         if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     389              :             isSupportSDMAReduce
     390           13 :                 = IsSupportSDMAReduce(param.inputPtr, param.outputPtr, param.DataDes.dataType, param.reduceType);
     391              :         } else {
     392           17 :             isSupportSDMAReduce = IsSupportSDMAReduce(
     393           17 :                 cclBufferManager_.GetInCCLbuffer().ptr(), cclBufferManager_.GetOutCCLbuffer().ptr(),
     394           17 :                 param.DataDes.dataType, param.reduceType);
     395              :         }
     396           30 :         CHK_RET(executor_->SetIsSupportSDMAReduce(isSupportSDMAReduce));
     397              :     }
     398           66 :     return HCCL_SUCCESS;
     399              : }
     400              : 
     401            0 : std::string CollAlgOperator::GenerateNewTagByAlgTypeLevel1(std::string tag, std::string algTypeLevel1Tag) const
     402              : {
     403            0 :     if (algTypeLevel1Tag == "") {
     404            0 :         return tag;
     405              :     } else {
     406            0 :         return tag + "_" + algTypeLevel1Tag;
     407              :     }
     408              : }
     409              : 
     410            0 : HcclResult CollAlgOperator::AppendTag(const AlgTypeLevel1& algTypeLevel1, std::string& tag)
     411              : {
     412            0 :     switch (algTypeLevel1) {
     413            0 :         case AlgTypeLevel1::ALG_LEVEL1_RING:
     414            0 :             tag = "ALG_LEVEL1_RING";
     415            0 :             break;
     416            0 :         case AlgTypeLevel1::ALG_LEVEL1_HD:
     417            0 :             tag = "ALG_LEVEL1_HD";
     418            0 :             break;
     419            0 :         case AlgTypeLevel1::ALG_LEVEL1_NHR:
     420            0 :             tag = "ALG_LEVEL1_NHR";
     421            0 :             break;
     422            0 :         case AlgTypeLevel1::ALG_LEVEL1_PIPELINE:
     423            0 :             tag = "ALG_LEVEL1_PIPELINE";
     424            0 :             break;
     425            0 :         default:
     426            0 :             HCCL_WARNING("[CollAlgOperator][AppendTag] The algTypeLevel1 %d is not supported.", algTypeLevel1);
     427            0 :             break;
     428              :     }
     429            0 :     return HCCL_SUCCESS;
     430              : }
     431              : 
     432           14 : HcclResult CollAlgOperator::AutoSelectAlgTypeLevel1(
     433              :     HcclCMDType hcclCMDType, u64 countSize, u64 cclBufferSize, std::string& algTypeLevel1Tag, bool isInlineReduce,
     434              :     bool isRdmaReduce, bool isAivMode)
     435              : {
     436           14 :     if (isSingleMeshAggregation_) {
     437           14 :         HCCL_INFO(
     438              :             "[AutoSelectAlgTypeLevel1] there are %u server(%u module) in level1, no need to choose algo.", serverNum_,
     439              :             moduleNum_);
     440           18 :         return HCCL_SUCCESS;
     441              :     }
     442              : 
     443              :     // auto algo selection process
     444            0 :     if (isAlgoLevel1Default_) {
     445              :         // parse algType_ and get algTypeLevel1 and algTypeLevel0
     446            0 :         auto originalAlgTypeLevel0 = algType_.algoLevel0;
     447              :         // set algTypeLevel1
     448              :         AlgTypeLevel1 algTypeLevel1;
     449            0 :         CHK_RET(GetDefaultAlgoLevel1V2(
     450              :             hcclCMDType, countSize, cclBufferSize, algTypeLevel1, isInlineReduce, isRdmaReduce, isAivMode));
     451            0 :         auto iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algTypeLevel1);
     452            0 :         CHK_PRT_RET(
     453              :             iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(),
     454              :             HCCL_ERROR("[AutoSelectAlgTypeLevel1] level1: algType[%u] is invalid.", algTypeLevel1), HCCL_E_INTERNAL);
     455            0 :         HCCL_INFO(
     456              :             "[AutoSelectAlgTypeLevel1] there are %u server(%u module) in level1, using %s algo", serverNum_, moduleNum_,
     457              :             iter->second.c_str());
     458            0 :         algType_.algoLevel0 = originalAlgTypeLevel0;
     459            0 :         algType_.algoLevel1 = algTypeLevel1;
     460              :         // tag 增加所选的算法
     461            0 :         AppendTag(algTypeLevel1, algTypeLevel1Tag);
     462              :     }
     463            0 :     return HCCL_SUCCESS;
     464              : }
     465              : 
     466            0 : HcclResult CollAlgOperator::SelectAlgoForComm(
     467              :     HcclCMDType hcclCMDType, float delay, u64 curSize, float bandWidth, AlgTypeLevel1& algType)
     468              : {
     469              :     // 从map中查找对应的计算函数
     470            0 :     auto it = selectFuncMap_.find(hcclCMDType);
     471            0 :     if (it == selectFuncMap_.end()) {
     472            0 :         HCCL_ERROR("[Get][AlgTypeLevel1] The hcclCMDType %d is not supported.", hcclCMDType);
     473            0 :         return HCCL_E_NOT_SUPPORT;
     474              :     }
     475            0 :     return (it->second)(delay, curSize, bandWidth, algType);
     476              : }
     477              : 
     478              : // 保守估计Pipeline算法所需context数量
     479            0 : u32 CollAlgOperator::CalcContextNumForPipeline(HcclCMDType hcclCMDType)
     480              : {
     481              :     bool isDeterPipeline
     482            0 :         = topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_ENABLE
     483            0 :           && (hcclCMDType == HcclCMDType::HCCL_CMD_ALLREDUCE || hcclCMDType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER);
     484            0 :     const u32 stepNum = moduleNum_;                                       // 通信步数
     485            0 :     const u32 hccsContextNumPerStep = 5 * (deviceNumPerAggregation_ - 1); // SDMA跨片每步所需context数
     486            0 :     const u32 roceContextNumPerStep = 7;                                  // RDMA每步所需context数
     487            0 :     const u32 copyContextNumPerStep = 1;                                  // SDMA片内每步所需context数
     488            0 :     const u32 localReduceNumPerStep = isDeterPipeline ? (deviceNumPerAggregation_ - 1) : 0;
     489            0 :     const u32 contextNumPerStep
     490            0 :         = hccsContextNumPerStep + roceContextNumPerStep + copyContextNumPerStep + localReduceNumPerStep; // 小计
     491            0 :     const u32 barrierContextNum = 4; // 通信结束时barrier操作所需context数
     492              : 
     493            0 :     switch (hcclCMDType) {
     494            0 :         case HcclCMDType::HCCL_CMD_ALLREDUCE:      // fall-through
     495              :         case HcclCMDType::HCCL_CMD_REDUCE_SCATTER: // fall-through
     496              :         case HcclCMDType::HCCL_CMD_ALLGATHER:
     497              :         case HcclCMDType::HCCL_CMD_ALLGATHER_V: {
     498            0 :             const u32 copyContextNum = 1; // 通信首尾所需context数量
     499            0 :             u32 contextNum = stepNum * contextNumPerStep + barrierContextNum + copyContextNum;
     500            0 :             if (hcclCMDType == HcclCMDType::HCCL_CMD_ALLREDUCE) {
     501            0 :                 contextNum += contextNum;
     502              :             }
     503            0 :             if (isDeterPipeline) {
     504            0 :                 contextNum += stepNum - 1; // 最后的local reduce
     505              :             }
     506            0 :             return contextNum;
     507              :         }
     508            0 :         case HcclCMDType::HCCL_CMD_ALLTOALLV:  // fall-through
     509              :         case HcclCMDType::HCCL_CMD_ALLTOALLVC: // fall-through
     510              :         case HcclCMDType::HCCL_CMD_ALLTOALL: {
     511            0 :             const u32 copyContextNum = 1 + moduleNum_; // 通信首尾所需context数量
     512            0 :             return stepNum * contextNumPerStep + barrierContextNum + copyContextNum;
     513              :         }
     514            0 :         default:
     515            0 :             return 0;
     516              :     }
     517              : }
     518              : 
     519            0 : HcclResult CollAlgOperator::GetDefaultAlgoLevel1V2(
     520              :     HcclCMDType hcclCMDType, u64 curSize, u64 cclBufferSize, AlgTypeLevel1& algType, bool isInlineReduce,
     521              :     bool isRdmaReduce, bool isAivMode)
     522              : {
     523              :     // pipeline mode is deployed,where there is multi-sever multi-device(insever) now,
     524              :     // since RDMA is not reduced by normal serial orchestration of tasks.
     525              :     // So pipeline mode is more dominant than normal serial orchestration now.
     526            0 :     auto originalAlgTypeLevel0 = algType_.algoLevel0;
     527              :     bool disdeterniminsticWithInlineReduce
     528            0 :         = isInlineReduce && isRdmaReduce && topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE;
     529              :     bool deterniminsticWithInlineReduce
     530            0 :         = isInlineReduce && isRdmaReduce && topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_ENABLE;
     531              : 
     532              :     // 对于不支持Rdma Lite的场景,下发性能较差,RS和AG需要一个很大的数据量(AR的一半)才能掩盖下发时间
     533            0 :     u64 pipelineMinSize = (isSupportRdmaLite_) ? (PIPELINE_MIN_SIZE) : (PIPELINE_MIN_SIZE_NO_LITE);
     534            0 :     if (((hcclCMDType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER && disdeterniminsticWithInlineReduce)
     535            0 :          || hcclCMDType == HcclCMDType::HCCL_CMD_ALLGATHER || hcclCMDType == HcclCMDType::HCCL_CMD_ALLGATHER_V)
     536            0 :         && deviceNumPerAggregation_ != 1 && curSize >= pipelineMinSize && IsAlgTypeLevel0Mesh(originalAlgTypeLevel0)
     537            0 :         && CalcContextNumForPipeline(hcclCMDType) <= HCCL_FFTS_CAPACITY) {
     538            0 :         algType = AlgTypeLevel1::ALG_LEVEL1_PIPELINE;
     539            0 :         return HCCL_SUCCESS;
     540              :     }
     541            0 :     if (hcclCMDType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER && deterniminsticWithInlineReduce
     542            0 :         && deviceNumPerAggregation_ > 1 && curSize >= pipelineMinSize && IsAlgTypeLevel0Mesh(originalAlgTypeLevel0)
     543            0 :         && CalcContextNumForPipeline(hcclCMDType) <= HCCL_FFTS_CAPACITY && moduleNum_ > 1
     544            0 :         && curSize >= HCCL_SMALL_COUNT_256_KB) {
     545            0 :         algType = AlgTypeLevel1::ALG_LEVEL1_PIPELINE;
     546            0 :         return HCCL_SUCCESS;
     547              :     }
     548              : 
     549              :     // 对于不支持Rdma Lite的场景,下发性能较差,AllReduce需要一个较大的数据量才能掩盖下发时间
     550            0 :     pipelineMinSize = (isSupportRdmaLite_) ? (PIPELINE_ALLREDUCE_MIN_SIZE) : (PIPELINE_MIN_SIZE_NO_LITE);
     551            0 :     if (hcclCMDType == HcclCMDType::HCCL_CMD_ALLREDUCE) {
     552              :         // 计算每个slice的大小
     553            0 :         u64 allreduceCurSize = 0;
     554            0 :         allreduceCurSize = curSize / (moduleNum_ * deviceNumPerAggregation_);
     555            0 :         if (disdeterniminsticWithInlineReduce && deviceNumPerAggregation_ != 1 && allreduceCurSize >= pipelineMinSize
     556            0 :             && !isAivMode && IsAlgTypeLevel0Mesh(originalAlgTypeLevel0)
     557            0 :             && CalcContextNumForPipeline(hcclCMDType) <= HCCL_FFTS_CAPACITY) {
     558            0 :             algType = AlgTypeLevel1::ALG_LEVEL1_PIPELINE;
     559            0 :             return HCCL_SUCCESS;
     560              :         }
     561            0 :         if (deterniminsticWithInlineReduce && deviceNumPerAggregation_ > 1 && allreduceCurSize >= HCCL_SMALL_COUNT_1_MB
     562            0 :             && !isAivMode && IsAlgTypeLevel0Mesh(originalAlgTypeLevel0)
     563            0 :             && CalcContextNumForPipeline(hcclCMDType) <= HCCL_FFTS_CAPACITY) {
     564            0 :             algType = AlgTypeLevel1::ALG_LEVEL1_PIPELINE;
     565            0 :             return HCCL_SUCCESS;
     566              :         }
     567              :     }
     568            0 :     u64 dataSizePerLoop = curSize > cclBufferSize ? cclBufferSize : curSize;
     569            0 :     float delay = LATENCY; // 静态时延 60 us;
     570              :     float bandWidth;
     571            0 :     CHK_RET(GetBandWidthPerNPU(1, userRankSize_, deviceNumPerAggregation_, bandWidth)); // 单位:GB/s
     572            0 :     bandWidth = bandWidth * GB2B;                                                       // 单位:B/s
     573            0 :     CHK_RET(SelectAlgoForComm(hcclCMDType, delay, dataSizePerLoop, bandWidth, algType));
     574            0 :     return HCCL_SUCCESS;
     575              : }
     576              : 
     577              : HcclResult
     578            0 : CollAlgOperator::SelectAlgoTypeForReduceScatter(float delay, u64 recvCurSize, float bandWidth, AlgTypeLevel1& algType)
     579              : {
     580            0 :     auto steps = moduleNum_ - 1;
     581              :     // theoretical time cost of Ring
     582            0 :     double ringCost
     583            0 :         = static_cast<double>(steps) * delay
     584            0 :           + static_cast<double>(steps) / moduleNum_ * recvCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     585              : 
     586              :     // theoretical time cost of NHR
     587            0 :     double nhrCost = ceil(log2(moduleNum_)) * delay
     588            0 :                      + static_cast<double>(moduleNum_ - 1) / moduleNum_ * recvCurSize * userRankSize_ / bandWidth
     589            0 :                            * SECOND2MICROSECOND;
     590              : 
     591              :     // compare costs between NHR and Ring, if same cost, Ring > NHR > HD
     592            0 :     algType = (nhrCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_NHR : AlgTypeLevel1::ALG_LEVEL1_RING;
     593            0 :     double interMinCost = min(nhrCost, ringCost);
     594              : 
     595              :     // theoretical time cost of HD/RHD
     596            0 :     double hdCost = 0.0;
     597            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     598              :         // theoretical time cost of HD
     599              :         hdCost
     600            0 :             = log2(moduleNum_) * delay
     601            0 :               + static_cast<double>(steps) / moduleNum_ * recvCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     602              :     } else {
     603              :         // theoretical time cost of Recursive HD,
     604              :         // the (RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ is equal to 1 + (moduleNum_ -1) / moduleNum_
     605            0 :         hdCost = ceil(log2(moduleNum_)) * delay
     606            0 :                  + static_cast<double>(RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ * recvCurSize
     607            0 :                        * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     608              :     }
     609              : 
     610              :     // compare cost among NHR, HD and Ring
     611            0 :     algType = (hdCost < interMinCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : algType;
     612            0 :     return HCCL_SUCCESS;
     613              : }
     614              : 
     615              : HcclResult
     616            0 : CollAlgOperator::SelectAlgoTypeForAllGather(float delay, u64 sendCurSize, float bandWidth, AlgTypeLevel1& algType)
     617              : {
     618            0 :     auto steps = moduleNum_ - 1;
     619              :     // theoretical time cost of Ring
     620            0 :     double ringCost
     621            0 :         = static_cast<double>(steps) * delay
     622            0 :           + static_cast<double>(steps) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     623              : 
     624              :     // theoretical time cost of NHR
     625            0 :     double nhrCost = ceil(log2(moduleNum_)) * delay
     626            0 :                      + static_cast<double>(moduleNum_ - 1) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth
     627            0 :                            * SECOND2MICROSECOND;
     628              : 
     629              :     // compare costs between NHR and Ring, if same cost, Ring > NHR > HD
     630            0 :     algType = (nhrCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_NHR : AlgTypeLevel1::ALG_LEVEL1_RING;
     631            0 :     double interMinCost = min(nhrCost, ringCost);
     632              : 
     633              :     // theoretical time cost of HD/RHD
     634            0 :     double hdCost = 0.0;
     635            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     636              :         // theoretical time cost of HD
     637              :         hdCost
     638            0 :             = log2(moduleNum_) * delay
     639            0 :               + static_cast<double>(steps) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     640              :     } else {
     641              :         // theoretical time cost of Recursive HD
     642              :         // the (RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ is equal to 1 + (moduleNum_ -1) / moduleNum_
     643            0 :         hdCost = ceil(log2(moduleNum_)) * delay
     644            0 :                  + static_cast<double>(RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ * sendCurSize
     645            0 :                        * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     646              :     }
     647              : 
     648              :     // compare cost among NHR, HD and Ring
     649            0 :     algType = (hdCost < interMinCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : algType;
     650            0 :     return HCCL_SUCCESS;
     651              : }
     652              : 
     653              : HcclResult
     654            0 : CollAlgOperator::SelectAlgoTypeForAllGatherV(float delay, u64 sendCurSize, float bandWidth, AlgTypeLevel1& algType)
     655              : {
     656            0 :     auto steps = moduleNum_ - 1;
     657              :     // theoretical time cost of Ring
     658            0 :     double ringCost
     659            0 :         = static_cast<double>(steps) * delay
     660            0 :           + static_cast<double>(steps) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     661              : 
     662            0 :     HCCL_DEBUG("[%s] CollAlgOperator for SelectAlgoTypeForAllGatherV", __func__);
     663              :     // theoretical time cost of NHR
     664            0 :     double nhrCost = ceil(log2(moduleNum_)) * delay
     665            0 :                      + static_cast<double>(moduleNum_ - 1) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth
     666            0 :                            * SECOND2MICROSECOND;
     667              : 
     668              :     // compare costs between NHR and Ring, if same cost, Ring > NHR > HD
     669            0 :     algType = (nhrCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_NHR : AlgTypeLevel1::ALG_LEVEL1_RING;
     670              : 
     671            0 :     return HCCL_SUCCESS;
     672              : }
     673              : 
     674              : HcclResult
     675            0 : CollAlgOperator::SelectAlgoTypeForGather(float delay, u64 sendCurSize, float bandWidth, AlgTypeLevel1& algType)
     676              : {
     677            0 :     auto steps = moduleNum_ - 1;
     678              :     // theoretical time cost of Ring
     679            0 :     double ringCost
     680            0 :         = static_cast<double>(steps) * delay
     681            0 :           + static_cast<double>(steps) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     682            0 :     double hdCost = 0.0;
     683            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     684              :         // theoretical time cost of HD
     685              :         hdCost
     686            0 :             = log2(moduleNum_) * delay
     687            0 :               + static_cast<double>(steps) / moduleNum_ * sendCurSize * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     688              :     } else {
     689              :         // theoretical time cost of Recursive HD
     690              :         // the (RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ is equal to 1 + (moduleNum_ -1) / moduleNum_
     691            0 :         hdCost = ceil(log2(moduleNum_)) * delay
     692            0 :                  + static_cast<double>(RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ * sendCurSize
     693            0 :                        * userRankSize_ / bandWidth * SECOND2MICROSECOND;
     694              :     }
     695            0 :     algType = (hdCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : AlgTypeLevel1::ALG_LEVEL1_RING;
     696            0 :     return HCCL_SUCCESS;
     697              : }
     698              : 
     699              : HcclResult
     700            0 : CollAlgOperator::SelectAlgoTypeForAllReduce(float delay, u64 curSize, float bandWidth, AlgTypeLevel1& algType)
     701              : {
     702            0 :     auto steps = moduleNum_ - 1;
     703              :     // theoretical time cost of Ring
     704            0 :     double ringCost = DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) * delay
     705            0 :                       + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize
     706            0 :                             / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     707              : 
     708              :     // theoretical time cost of NHR
     709            0 :     double nhrCost = NHR_FACTOR_TWO * ceil(log2(moduleNum_)) * delay
     710            0 :                      + NHR_FACTOR_TWO * static_cast<double>(moduleNum_ - 1) / moduleNum_ * curSize
     711            0 :                            / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     712              : 
     713              :     // compare costs between NHR and Ring, if same cost, Ring > NHR > HD
     714            0 :     algType = (nhrCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_NHR : AlgTypeLevel1::ALG_LEVEL1_RING;
     715            0 :     double interMinCost = min(nhrCost, ringCost);
     716              : 
     717              :     // theoretical time cost of HD/RHD
     718            0 :     double hdCost = 0.0;
     719            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     720              :         // theoretical time cost of HD
     721            0 :         hdCost = DOUBLE_SUB_HCCLCMD * log2(moduleNum_) * delay
     722            0 :                  + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize / deviceNumPerAggregation_
     723            0 :                        / bandWidth * SECOND2MICROSECOND;
     724              :     } else {
     725              :         // theoretical time cost of Recursive HD
     726              :         // the (RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_ is equal to 1 + (moduleNum_ -1) / moduleNum_
     727            0 :         hdCost = DOUBLE_SUB_HCCLCMD * ceil(log2(moduleNum_)) * delay
     728            0 :                  + DOUBLE_SUB_HCCLCMD * static_cast<double>(RHD_FACTOR_TWO * moduleNum_ - RHD_FACTOR_ONE) / moduleNum_
     729            0 :                        * curSize / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     730              :     }
     731              : 
     732              :     // compare cost among NHR, HD and Ring
     733            0 :     algType = (hdCost < interMinCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : algType;
     734            0 :     return HCCL_SUCCESS;
     735              : }
     736              : 
     737              : HcclResult
     738            0 : CollAlgOperator::SelectAlgoTypeForBroadcast(float delay, u64 curSize, float bandWidth, AlgTypeLevel1& algType)
     739              : {
     740            0 :     auto steps = moduleNum_ - 1;
     741              :     // theoretical time cost of Ring
     742            0 :     double ringCost = DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) * delay
     743            0 :                       + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize
     744            0 :                             / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     745            0 :     double hdCost = 0.0;
     746            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     747              :         // theoretical time cost of HD
     748            0 :         hdCost = DOUBLE_SUB_HCCLCMD * log2(moduleNum_) * delay
     749            0 :                  + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize / deviceNumPerAggregation_
     750            0 :                        / bandWidth * SECOND2MICROSECOND;
     751              :     } else {
     752              :         // theoretical time cost of Recursive HD
     753              :         // rhd-broadcast = scatter + allgather + copy
     754            0 :         hdCost = (COPY_TIME_IN_RHD + DOUBLE_SUB_HCCLCMD * floor(log2(moduleNum_))) * delay
     755            0 :                  + (COPY_TIME_IN_RHD + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_) * curSize
     756            0 :                        / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     757              :     }
     758            0 :     algType = (hdCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : AlgTypeLevel1::ALG_LEVEL1_RING;
     759            0 :     return HCCL_SUCCESS;
     760              : }
     761              : 
     762            0 : HcclResult CollAlgOperator::SelectAlgoTypeForReduce(float delay, u64 curSize, float bandWidth, AlgTypeLevel1& algType)
     763              : {
     764            0 :     HCCL_DEBUG("[CollAlgOperator]SelectAlgoTypeForReduce start");
     765            0 :     auto steps = moduleNum_ - 1;
     766              :     // theoretical time cost of Ring
     767            0 :     double ringCost = DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) * delay
     768            0 :                       + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize
     769            0 :                             / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     770            0 :     double hdCost = 0.0;
     771            0 :     if ((moduleNum_ & (moduleNum_ - 1)) == 0) {
     772              :         // theoretical time cost of HD
     773            0 :         hdCost = DOUBLE_SUB_HCCLCMD * log2(moduleNum_) * delay
     774            0 :                  + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_ * curSize / deviceNumPerAggregation_
     775            0 :                        / bandWidth * SECOND2MICROSECOND;
     776              :     } else {
     777              :         // theoretical time cost of Recursive HD
     778              :         // rhd-broadcast = reducescatter + gather + copy
     779            0 :         hdCost = (COPY_TIME_IN_RHD + DOUBLE_SUB_HCCLCMD * floor(log2(moduleNum_))) * delay
     780            0 :                  + (COPY_TIME_IN_RHD + DOUBLE_SUB_HCCLCMD * static_cast<double>(steps) / moduleNum_) * curSize
     781            0 :                        / deviceNumPerAggregation_ / bandWidth * SECOND2MICROSECOND;
     782              :     }
     783            0 :     algType = (hdCost < ringCost) ? AlgTypeLevel1::ALG_LEVEL1_HD : AlgTypeLevel1::ALG_LEVEL1_RING;
     784            0 :     return HCCL_SUCCESS;
     785              : }
     786              : 
     787           24 : AlgType CollAlgOperator::GetAlgType() { return algType_; }
     788              : 
     789            2 : bool CollAlgOperator::Is2U2PInfer()
     790              : {
     791              :     return (
     792            0 :         (deviceNumPerAggregation_ == HCCL_DEVICE_NUM_TWO) && (serverNum_ == 1)
     793            0 :         && (deviceType_ == DevType::DEV_TYPE_910B) && (meshAggregationRankSize_ == HCCL_DEVICE_NUM_TWO)
     794            2 :         && (pairLinkCounter_[static_cast<u32>(LinkTypeInServer::HCCS_TYPE)] == 0));
     795              : }
     796              : 
     797           24 : bool CollAlgOperator::Is910BSingleMesh()
     798              : {
     799            1 :     bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH
     800           25 :                       || topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
     801              : 
     802              :     bool isSingleMesh
     803           24 :         = (deviceType_ == DevType::DEV_TYPE_910B) && (isMeshTopo || Is2U2PInfer()) && (userRankSize_ != 1);
     804           24 :     return isSingleMesh;
     805              : }
     806              : 
     807            1 : bool CollAlgOperator::NeedCreateSingleMeshPlane(const bool isInlineReduce)
     808              : {
     809              :     // 910B 图模式非确定计算,inlineReduce使能,MESH拓扑场景下,创建一个mesh平面
     810            1 :     bool meshSinglePlane = Is910BSingleMesh() && topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_DISABLE
     811            1 :                            && isInlineReduce && (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE);
     812              : 
     813            1 :     return meshSinglePlane;
     814              : }
     815              : 
     816           23 : bool CollAlgOperator::SingleMeshInlineReduce(void* inputPtr, void* outputPtr, HcclDataType dataType, HcclReduceOp op)
     817              : {
     818           23 :     bool isInlineReduce = IsSupportSDMAReduce(inputPtr, outputPtr, dataType, op);
     819           22 :     bool singleMeshInlineReduce = Is910BSingleMesh() && isInlineReduce && isSingleMeshAggregation_;
     820           21 :     return singleMeshInlineReduce;
     821              : }
     822              : 
     823            2 : bool CollAlgOperator::IsMultiMeshInlineReduce(void* inputPtr, void* outputPtr, HcclDataType dataType, HcclReduceOp op)
     824              : {
     825            0 :     bool isMeshTopo = topoType_ == TopoType::TOPO_TYPE_NP_MESH || topoType_ == TopoType::TOPO_TYPE_4P_MESH
     826            2 :                       || topoType_ == TopoType::TOPO_TYPE_2P_MESH || topoType_ == TopoType::TOPO_TYPE_1P_MESH;
     827              : 
     828            2 :     bool isInlineReduce = IsSupportSDMAReduce(inputPtr, outputPtr, dataType, op);
     829            3 :     bool isRdmaReduce = IsSupportRDMAReduce(dataType, op);
     830            3 :     bool multiMeshInlineReduce = (deviceType_ == DevType::DEV_TYPE_910B) && isMeshTopo && isInlineReduce && isRdmaReduce
     831            6 :                                  && (!isSingleMeshAggregation_);
     832            3 :     return multiMeshInlineReduce;
     833              : }
     834              : 
     835            0 : void CollAlgOperator::SetLegacyHcclImpl(std::unique_ptr<hcclImpl>& impl)
     836              : {
     837            0 :     hcclImpl_ = impl.get();
     838            0 :     return;
     839              : }
     840              : 
     841            8 : HcclResult CollAlgOperator::SetRetryEnable(bool retryEnable)
     842              : {
     843            8 :     retryEnable_ = retryEnable;
     844            8 :     return HCCL_SUCCESS;
     845              : }
     846              : 
     847            7 : HcclResult CollAlgOperator::SetAivClearEnable(bool aivClearEnable)
     848              : {
     849            7 :     aivClearEnable_ = aivClearEnable;
     850            7 :     return HCCL_SUCCESS;
     851              : }
     852              : 
     853            0 : HcclResult CollAlgOperator::SetAlgOpContext(AlgOpContext algOpContext)
     854              : {
     855            0 :     algOpContext_ = algOpContext;
     856            0 :     return HCCL_SUCCESS;
     857              : }
     858              : 
     859           29 : bool CollAlgOperator::SupportRetryWithInplaceCheck(
     860              :     const HcclCMDType& opType, OpParam& param, std::string& algName, u8& isInplaceStatus,
     861              :     InplaceSupportRetryStatus& inPlaceSupportRetryStatus)
     862              : {
     863              :     // 不支持inplace的通信算子重执行
     864           29 :     if (IsHcclOpInplace(opType, param, userRank_, userRankSize_, isInplaceStatus)) {
     865           13 :         void* commInputPtr = nullptr;
     866           13 :         u64 commInputSize = 0;
     867           21 :         CHK_RET(cclBufferManager_.GetInCCLbuffer(commInputPtr, commInputSize));
     868           13 :         if (!FitRetryConditionforInPlaceOp(
     869           13 :                 opType, param, algName, commInputSize, userRankSize_, retryEnable_, inPlaceSupportRetryStatus)) {
     870            8 :             HCCL_DEBUG(
     871              :                 "[CollAlgOperator][OpRetry][AICPU]hccl aicpu can not retry, opType[%s], inputPtr[%p], "
     872              :                 "outputPtr[%p].",
     873              :                 GetCMDTypeEnumStr(opType).c_str(), param.inputPtr, param.outputPtr);
     874            8 :             return false;
     875              :         }
     876              :     }
     877              :     // true 存在两种情况:
     878              :     // 1. 非inplace场景
     879              :     // 2. 是inplace但同时符合retry条件的场景
     880           21 :     return true;
     881              : }
     882              : 
     883           21 : HcclResult CollAlgOperator::GetNumBlocks(u32& numBlocks)
     884              : {
     885           21 :     CHK_SMART_PTR_NULL(executor_);
     886           21 :     return executor_->GetNumBlocks(numBlocks);
     887              : }
     888              : 
     889            5 : HcclResult CollAlgOperator::SetNumBlocks(const u32& numBlocks)
     890              : {
     891            5 :     CHK_SMART_PTR_NULL(executor_);
     892            5 :     return executor_->SetNumBlocks(numBlocks);
     893              : }
     894              : 
     895            2 : HcclResult CollAlgOperator::GetCache(HcclCacheInfo& cacheInfo)
     896              : {
     897            2 :     CHK_SMART_PTR_NULL(executor_);
     898            2 :     return executor_->GetCache(cacheInfo);
     899              : }
     900              : 
     901           24 : HcclResult CollAlgOperator::SetOpCounter(const OpCounterInfo& opCounter)
     902              : {
     903           24 :     opCounter_ = opCounter;
     904           24 :     return HCCL_SUCCESS;
     905              : }
     906              : 
     907            0 : HcclResult CollAlgOperator::SetRmaInfo(void* rmaInfo)
     908              : {
     909            0 :     CHK_SMART_PTR_NULL(executor_);
     910            0 :     CHK_PTR_NULL(rmaInfo);
     911            0 :     return executor_->SetRmaInfo(rmaInfo);
     912              : }
     913              : 
     914            9 : HcclResult CollAlgOperator::SelectAlgforAHC(u64 dataSize, AHCOpType ahcOpType)
     915              : {
     916            9 :     if (multiModuleDiffDeviceNumMode_) {
     917            0 :         return HCCL_SUCCESS;
     918              :     }
     919              : 
     920            9 :     bool isAHCWholeConfig
     921            9 :         = (algType_.algoLevel0 == AlgTypeLevel0::ALG_LEVEL0_RESERVED
     922            9 :            && (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC
     923            0 :                || algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE));
     924              : 
     925            9 :     CommPlane ahcSubGroupLevel = COMM_LEVEL1_AHC;
     926            9 :     if (isAHCWholeConfig) {
     927            0 :         if (deviceType_ != DevType::DEV_TYPE_910_93) {
     928            0 :             ahcSubGroupLevel = COMM_COMBINE;
     929              :         } else {
     930            0 :             ahcSubGroupLevel = COMM_COMBINE_ORDER;
     931              :         }
     932            9 :     } else if (deviceType_ != DevType::DEV_TYPE_910_93) {
     933            0 :         HCCL_DEBUG("[AHCAlgSelect] hccl algorithm: 910B not support level1 ahc, return ERROR.");
     934            0 :         return HCCL_E_PARA;
     935              :     }
     936              : 
     937            9 :     HCCL_INFO(
     938              :         "[SelectAlgforAHC] ahcOpType[%u] isAHCWholeConfig[%u] AHClevel[%u] algType_[%u] deviceType_[%u]", ahcOpType,
     939              :         isAHCWholeConfig, ahcSubGroupLevel, algType_.algoLevel1, deviceType_);
     940              : 
     941              :     AlgTypeLevel1 algTypeLevel1;
     942              : 
     943            9 :     std::vector<std::vector<std::vector<u32>>> globalSubGroups;
     944            9 :     std::map<AHCConcOpType, TemplateType> ahcAlgOption;
     945            9 :     CHK_RET(topoMatcher_->GetGlobalSubGroups(ahcSubGroupLevel, globalSubGroups));
     946            9 :     topoMatcher_->GetAHCAlgOption(ahcAlgOption);
     947              : 
     948            9 :     AHCAlgSelectParam ahcAlgSelectParam;
     949            9 :     ahcAlgSelectParam.opType = ahcOpType;
     950            9 :     ahcAlgSelectParam.dataSize = dataSize;
     951              : 
     952              :     // AHC 封装算法选择逻辑
     953            9 :     CHK_RET(AHCAlgSelect(algTypeLevel1, globalSubGroups, ahcAlgOption, ahcAlgSelectParam));
     954              : 
     955            9 :     topoMatcher_->SetAHCAlgOption(ahcAlgOption);
     956              : 
     957            9 :     auto iter = HCCL_ALGO_LEVEL1_NAME_MAP.find(algTypeLevel1);
     958            9 :     CHK_PRT_RET(
     959              :         iter == HCCL_ALGO_LEVEL1_NAME_MAP.end(),
     960              :         HCCL_ERROR("[AHCAlgSelect] level1: algType_[%u] is invalid.", algTypeLevel1), HCCL_E_INTERNAL);
     961              : 
     962              :     // 支持 AHC 自适应调节为 BROKE 类型
     963            9 :     if (algType_.algoLevel1 != algTypeLevel1 && algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_AHC) {
     964            8 :         algType_.algoLevel1 = algTypeLevel1;
     965              :     }
     966              : 
     967            9 :     HCCL_INFO(
     968              :         "[AHCAlgSelect] hccl algorithm: there are %u server(%u module) in level1, using %s algo", serverNum_,
     969              :         moduleNum_, iter->second.c_str());
     970              : 
     971            9 :     return HCCL_SUCCESS;
     972            9 : }
     973              : 
     974            9 : HcclResult CollAlgOperator::AHCAlgSelect(
     975              :     AlgTypeLevel1& algType, std::vector<std::vector<std::vector<u32>>>& globalSubGroups,
     976              :     std::map<AHCConcOpType, TemplateType>& ahcAlgOption, AHCAlgSelectParam& ahcAlgSelectParam)
     977              : {
     978              :     // globalSubGroups 参数检查
     979            9 :     CHK_RET(CommAHCBaseInfo::CheckGlobalGroups(globalSubGroups));
     980              : 
     981            9 :     bool isAHCType = false;
     982            9 :     u32 minSubGroupSize = globalSubGroups[0][0].size();
     983            9 :     u32 maxSubGroupSize = globalSubGroups[0][0].size();
     984           45 :     for (u32 i = 1; i < globalSubGroups[0].size(); ++i) {
     985           36 :         if (globalSubGroups[0][i].size() < minSubGroupSize) {
     986            0 :             minSubGroupSize = globalSubGroups[0][i].size();
     987              :         }
     988           36 :         if (globalSubGroups[0][i].size() > maxSubGroupSize) {
     989            0 :             maxSubGroupSize = globalSubGroups[0][i].size();
     990              :         }
     991              :     }
     992           54 :     for (u32 i = 0; i < globalSubGroups[0].size(); ++i) {
     993           45 :         if (globalSubGroups[0][i].size() != minSubGroupSize) {
     994            0 :             isAHCType = true;
     995            0 :             break;
     996              :         }
     997              :     }
     998              : 
     999              :     // 多平面 reduce scatter 和 all gather 算子,强制写死成BROKE类型
    1000            9 :     if (deviceNumPerServer_ != 1 && ahcAlgSelectParam.opType != AHCOpType::AHC_OP_TYPE_ALLREDUCE) {
    1001            0 :         isAHCType = false;
    1002              :     }
    1003              : 
    1004              :     // add AHC Conc Type logic here,  modify init Type  depend on the input para
    1005            9 :     CHK_RET(AHCAlgOptionSelect(algType, globalSubGroups, ahcAlgOption, ahcAlgSelectParam));
    1006              : 
    1007            9 :     if (ahcAlgSelectParam.enableAlgAutoSelect == false) { // 关闭算法自适应功能时,默认设置AHC算法
    1008            0 :         algType = AlgTypeLevel1::ALG_LEVEL1_AHC;
    1009            0 :         return HCCL_SUCCESS;
    1010              :     }
    1011              : 
    1012            9 :     if (isAHCType) {
    1013            0 :         algType = AlgTypeLevel1::ALG_LEVEL1_AHC; // 设置为 AHC 类型
    1014              :     } else {
    1015            9 :         algType = AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE; // 设置为 BROKE 类型
    1016              :     }
    1017              : 
    1018            9 :     HCCL_DEBUG(
    1019              :         "[AHCAlgSelect] end minSubGroupSize = %u maxSubGroupSize = %u isAHCType = %u", minSubGroupSize, maxSubGroupSize,
    1020              :         isAHCType);
    1021              : 
    1022            9 :     return HCCL_SUCCESS;
    1023              : }
    1024              : 
    1025           11 : HcclResult CollAlgOperator::AHCAlgOptionSelect(
    1026              :     const AlgTypeLevel1& algType, std::vector<std::vector<std::vector<u32>>>& globalSubGroups,
    1027              :     std::map<AHCConcOpType, TemplateType>& ahcAlgOption, const AHCAlgSelectParam& ahcAlgSelectParam)
    1028              : {
    1029              :     (void)algType;
    1030              :     (void)ahcAlgSelectParam;
    1031           11 :     AHCConcOpType ahcConcOpType;
    1032              :     // 一层组间拼接时,分组数大于设定阈值则修改默认算法为NHR
    1033           11 :     if (globalSubGroups[0].size() <= AHC_LEVEL0_GROUP_SIZE_THRESHOLD) {
    1034            4 :         HCCL_DEBUG("[AHCAlgSelect] conc inter select type RING ");
    1035            4 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_REDUCE_SCATTER};
    1036            4 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_REDUCESCATTER_RING;
    1037              : 
    1038            4 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_ALLREDUCE};
    1039            4 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_ALL_REDUCE_RING;
    1040              : 
    1041            4 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_ALLGATHER};
    1042            4 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_ALL_GATHER_RING;
    1043              :     } else {
    1044            7 :         HCCL_DEBUG("[AHCAlgSelect] conc inter select type NHR ");
    1045            7 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_REDUCE_SCATTER};
    1046            7 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_REDUCESCATTER_NHR;
    1047              : 
    1048            7 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_ALLREDUCE};
    1049            7 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_ALL_REDUCE_NHR;
    1050              : 
    1051            7 :         ahcConcOpType = {AHCLevel::AHC_LEVEL_0, ConcType::CONC_INTER, AHCOpType::AHC_OP_TYPE_ALLGATHER};
    1052            7 :         ahcAlgOption[ahcConcOpType] = TemplateType::TEMPLATE_ALL_GATHER_NHR;
    1053              :     }
    1054           11 :     return HCCL_SUCCESS;
    1055              : }
    1056              : 
    1057            0 : u32 CollAlgOperator::CalcOptimalIntraRingsize(u64 count, HcclDataType dataType, HcclCMDType opType)
    1058              : {
    1059            0 :     if (!topoMatcher_->GetARSFlag())
    1060            0 :         return 0;
    1061              : 
    1062            0 :     u32 level0RankSize = topoMatcher_->GetCommPlaneRanks(COMM_LEVEL0)[0].size();
    1063            0 :     u32 rankSizeInSuperPod = topoMatcher_->GetCommPlaneRanks(COMM_ARS)[0].size();
    1064            0 :     u32 perDataSize = 0;
    1065            0 :     CHK_RET(SalGetDataTypeSize(dataType, perDataSize));
    1066              :     // 不支持 ARS 或环内卡数不是 2 的倍数
    1067            0 :     u32 level0RingSize = 1;
    1068            0 :     if (!isARSDoubleRing_ || (level0RankSize % FACTOR_TWO != 0)) {
    1069            0 :         HCCL_INFO(
    1070              :             "not Support ARS doubleRing, level0RingSize:[%u], level0RankSize[%u].", level0RingSize, level0RankSize);
    1071            0 :         return level0RingSize;
    1072              :     }
    1073              :     // --- 1. 带宽 & 基本参数 ---
    1074              :     float bwHCCS, bwHBM, bwSIO;
    1075            0 :     constexpr u32 level0 = 0;
    1076            0 :     constexpr u32 level2 = 2;
    1077            0 :     constexpr u32 level3 = 3;
    1078            0 :     CHK_RET(GetBandWidthPerNPU(level0, userRankSize_, deviceNumPerAggregation_, bwHCCS));
    1079            0 :     CHK_RET(GetBandWidthPerNPU(level2, userRankSize_, deviceNumPerAggregation_, bwHBM));
    1080            0 :     CHK_RET(GetBandWidthPerNPU(level3, userRankSize_, deviceNumPerAggregation_, bwSIO));
    1081            0 :     float latency = BASE_COMM_LATENCY / MULTIPLIER_MS2US; // ms
    1082              :     // --- 2. 数据总量 (GB) ---
    1083            0 :     float baseSizeGB = static_cast<double>(count) * perDataSize / GB2B;
    1084            0 :     float totalSize = baseSizeGB;
    1085            0 :     HCCL_INFO(
    1086              :         "CalcOptimalIntraRingsize: count[%u], totalSize:[%lf]GB, perDataSize[%u].", count, totalSize, perDataSize);
    1087            0 :     if (opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER || opType == HcclCMDType::HCCL_CMD_ALLGATHER) {
    1088            0 :         totalSize *= rankSizeInSuperPod;
    1089              :     }
    1090              :     // --- 3. 枚举可能的环大小 ---
    1091            0 :     std::vector<u32> factors;
    1092            0 :     for (u32 i = 1; i <= rankSizeInSuperPod / i; ++i) {
    1093            0 :         if (rankSizeInSuperPod % i == 0) {
    1094            0 :             if (i != rankSizeInSuperPod / i) {
    1095            0 :                 factors.push_back(rankSizeInSuperPod / i);
    1096              :             }
    1097            0 :             factors.push_back(i);
    1098              :         }
    1099              :     }
    1100            0 :     std::sort(factors.begin(), factors.end());
    1101              :     // --- 4. 计算最优带宽 ---
    1102            0 :     double maxBwARS = 0.0;
    1103            0 :     for (u32 N1 : factors) {
    1104              :         // 传输时延 (ms)
    1105              :         double latencyIntra;
    1106            0 :         if (N1 == FACTOR_TWO) {
    1107            0 :             latencyIntra = totalSize * MULTIPLIER_S2MS / FACTOR_TWO / bwSIO;
    1108            0 :         } else if ((N1 % FACTOR_TWO == 0) && (N1 > FACTOR_TWO)) {
    1109            0 :             latencyIntra = (N1 - 1) * totalSize * MULTIPLIER_S2MS / N1 / bwHCCS / FACTOR_TWO;
    1110              :         } else {
    1111            0 :             latencyIntra = (N1 - 1) * totalSize * MULTIPLIER_S2MS / N1 / bwHCCS;
    1112              :         }
    1113            0 :         u32 N2 = rankSizeInSuperPod / N1;
    1114              :         // 静态时延 (ms)
    1115            0 :         double interStep = (algType_.algoLevel1 == AlgTypeLevel1::ALG_LEVEL1_RING) ? (N2 - 1) : log2(N2);
    1116            0 :         double latencyStep = (interStep + (N1 - 1)) * latency;
    1117            0 :         double latencyInter = (N2 - 1) * totalSize * MULTIPLIER_S2MS / N1 / N2 / bwHCCS;
    1118              :         // HBM 拷贝时延 (ms)
    1119            0 :         double latencyCopy = totalSize * MULTIPLIER_S2MS / bwHBM;
    1120            0 :         u8 mul = (HcclCMDType::HCCL_CMD_ALLREDUCE == opType) ? FACTOR_TWO : 1;
    1121            0 :         double timeCost = mul * (latencyStep + latencyIntra + latencyInter) + latencyCopy;
    1122            0 :         double bwARS = totalSize / timeCost; // GB/ms
    1123            0 :         if (bwARS > maxBwARS) {
    1124            0 :             level0RingSize = N1;
    1125            0 :             maxBwARS = bwARS;
    1126              :         }
    1127              :     }
    1128            0 :     HCCL_INFO("level0RingSize:[%u], level0RankSize[%u], totalSize:[%lf]GB", level0RingSize, level0RankSize, totalSize);
    1129            0 :     return level0RingSize;
    1130            0 : }
    1131              : 
    1132           20 : bool CollAlgOperator::IsNeedStrictMode(const OpParam& param)
    1133              : {
    1134              :     bool isStrictMode
    1135           20 :         = (topoMatcher_->GetDeterministicConfig() == DETERMINISTIC_STRICT)
    1136            0 :           && (param.DataDes.dataType == HCCL_DATA_TYPE_FP16 || param.DataDes.dataType == HCCL_DATA_TYPE_FP32
    1137            0 :               || param.DataDes.dataType == HCCL_DATA_TYPE_BFP16 || param.DataDes.dataType == HCCL_DATA_TYPE_FP64)
    1138            0 :           && (param.reduceType == HCCL_REDUCE_SUM || param.reduceType == HCCL_REDUCE_PROD)
    1139           20 :           && userRankSize_ >= MIN_STRICT_RANK_NUM;
    1140              : 
    1141           20 :     return isStrictMode;
    1142              : }
    1143              : 
    1144            0 : bool CollAlgOperator::CheckStrictCondition(const OpParam& param) const
    1145              : {
    1146            0 :     CHK_PRT_RET(
    1147              :         multiModuleDiffDeviceNumMode_ || multiSuperPodDiffDeviceNumMode_ || multiSuperPodDiffServerNumMode_,
    1148              :         HCCL_ERROR("[CollAlgOperator][CheckStrictCondition] DETERMINISTIC_STRICT mode not support asymmetrical topo."),
    1149              :         false);
    1150              : 
    1151            0 :     CHK_PRT_RET(
    1152              :         param.reduceType == HCCL_REDUCE_PROD,
    1153              :         HCCL_ERROR("[CollAlgOperator][CheckStrictCondition] DETERMINISTIC_STRICT mode not support PROD."), false);
    1154              : 
    1155            0 :     CHK_PRT_RET(
    1156              :         param.DataDes.dataType == HCCL_DATA_TYPE_FP64,
    1157              :         HCCL_ERROR("[CollAlgOperator][CheckStrictCondition] DETERMINISTIC_STRICT mode not support FP64."), false);
    1158              : 
    1159            0 :     CHK_PRT_RET(
    1160              :         GetExternalInputInterHccsDisable(),
    1161              :         HCCL_ERROR("[CollAlgOperator][CheckStrictCondition] DETERMINISTIC_STRICT mode not support HCCS disable."),
    1162              :         false);
    1163              : 
    1164            0 :     return true;
    1165              : }
    1166              : 
    1167              : } // namespace hccl
        

Generated by: LCOV version 2.0-1