LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/env_config - env_func.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 71.2 % 559 398
Test Date: 2026-08-04 10:52:23 Functions: 95.1 % 41 39

            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 "env_func.h"
      12              : #include <climits>
      13              : #include <fstream>
      14              : #include <linux/limits.h>
      15              : #include <cctype> 
      16              : #include <algorithm>
      17              : #include <sstream>
      18              : #include <array>
      19              : 
      20              : #include "sal.h"
      21              : #include "string_util.h"
      22              : #include "base_config.h"
      23              : #include "orion_adapter_rts.h"
      24              : #include "adapter_error_manager_pub.h"
      25              : 
      26              : namespace Hccl {
      27              : 
      28              : /*----------------------------- cast functions -------------------------*/
      29              : 
      30           10 : bool CastBin2Bool(const std::string &s)
      31              : {
      32           10 :     bool b = true;
      33           10 :     if (s == "0") {
      34            3 :         b = false;
      35            7 :     } else if (s == "1") {
      36            3 :         b = true;
      37              :     } else {
      38            4 :         THROW<InvalidParamsException>(StringFormat("Env config \"%s\" is not valid. Should be 0 or 1", s.c_str()));
      39              :     }
      40            6 :     return b;
      41              : }
      42              : 
      43            2 : u32 CastBin2UInt(const std::string &s)
      44              : {
      45            2 :     u32 b = std::stoi(s);
      46            2 :     if (b > HCCL_CCU_FLAG_NUM) {
      47            2 :         THROW<InvalidParamsException>(StringFormat("Env config \"%s\" is not valid. Should be 0 or 1 or 2", s.c_str()));
      48              :     }
      49            3 :     HCCL_INFO("[CastBin2UInt] string[%s] to u32[%u]", s.c_str(), b);
      50            1 :     return b;
      51              : }
      52              : 
      53              : 
      54            2 : static HcclResult SplitHcclSocketIfName(const std::string &socketIfName, std::vector<std::string> &configIfNames)
      55              : {
      56            2 :     std::size_t start = 0;
      57            2 :     std::size_t end   = socketIfName.find(",");
      58            4 :     while (end != std::string::npos) {
      59            2 :         if (start == 0 && end == 0) {
      60            0 :             HCCL_ERROR("[Split][HcclSocketIfName] configIfNames config is invalid.");
      61            0 :             return HCCL_E_PARA;
      62              :         }
      63            2 :         configIfNames.push_back(socketIfName.substr(start, end - start));
      64            2 :         start = end + 1;
      65            2 :         end   = socketIfName.find(",", start);
      66              :     }
      67              :     // 处理最后一个部分
      68            2 :     if (start < socketIfName.length()) {
      69            2 :         configIfNames.push_back(socketIfName.substr(start));
      70            0 :     } else if (start == 0) {
      71            0 :         HCCL_ERROR("[Split][HcclSocketIfName] configIfNames config is invalid.");
      72            0 :         return HCCL_E_PARA;
      73              :     }
      74            2 :     return HCCL_SUCCESS;
      75              : }
      76              : 
      77              : // 临时方案,且当前未使用,测试期望在此拦截该环境变量所有异常值
      78            2 : SocketIfName CastSocketIfName(const std::string &s)
      79              : {
      80            2 :     SocketIfName hcclSocketIfNameGroup{};
      81            2 :     hcclSocketIfNameGroup.configIfNameStr = s;
      82            2 :     std::string hcclSocketIfName = s;
      83            2 :     std::string remainSocketIfName = hcclSocketIfName;
      84            2 :     bool searchNot = false;
      85            2 :     bool searchExact = false;
      86              : 
      87            2 :     if (hcclSocketIfName.length() != 0) {
      88              :         // 获取HCCL_SOCKET_IFNAME环境变量匹配规则
      89            2 :         if (!hcclSocketIfName.empty() && hcclSocketIfName.at(0) == '^') {
      90            1 :             searchNot = true;
      91              :             // 获取从1位置开始剩余部分环境变量内容
      92            1 :             remainSocketIfName = hcclSocketIfName.substr(1);
      93              :         }
      94              : 
      95            2 :         if (!remainSocketIfName.empty() && remainSocketIfName.at(0) == '=') {
      96            2 :             searchExact = true;
      97            2 :             remainSocketIfName = remainSocketIfName.substr(1);
      98              :         }
      99              : 
     100              :         // 获取用户输入的网卡名列表(使用逗号隔开),将网卡名列表存放到vector变量中
     101            2 :         HcclResult ret = SplitHcclSocketIfName(remainSocketIfName, hcclSocketIfNameGroup.configIfNames);
     102            2 :         if(ret != HCCL_SUCCESS) {
     103            0 :             THROW<InvalidParamsException>(StringFormat("environmental variable HCCL_SOCKET_IFNAME[%s] is invalid. "\
     104              :                 "please check.", s.c_str()));
     105              :         }
     106            6 :         HCCL_INFO("HCCL_SOCKET_IFNAME set by environment to [%s]", hcclSocketIfName.c_str());
     107              :     } else {
     108            0 :         HCCL_INFO("HCCL_SOCKET_IFNAME set by default to [%s]", hcclSocketIfName.c_str());
     109              :     }
     110            2 :     hcclSocketIfNameGroup.searchNot = searchNot;
     111            2 :     hcclSocketIfNameGroup.searchExact = searchExact;
     112            2 :     return hcclSocketIfNameGroup;
     113            2 : }
     114              : 
     115           36 : bool SplitString(std::string &totalStr, std::string &prefixStr, const std::string &delim)
     116              : {
     117           36 :     std::size_t found = totalStr.find(delim);
     118           36 :     if (found == std::string::npos) {
     119           14 :         return false;
     120              :     }
     121           22 :     prefixStr = totalStr.substr(0, found);
     122           22 :     totalStr = totalStr.substr(found + 1);
     123           22 :     return true;
     124              : }
     125              : 
     126           30 : void GetUIntFromStr(const std::string &digitStr, u32 &val)
     127              : {
     128           30 :     bool isAllDigits = std::all_of(digitStr.begin(), digitStr.end(), ::isdigit);
     129           30 :     CHK_PRT_THROW(!isAllDigits, HCCL_ERROR("[GetUIntFromStr] str[%s] is not all digit.",
     130              :         digitStr.c_str()), InvalidParamsException, "parser portRange fail.");
     131           30 :     auto ret = SalStrToULong(digitStr.c_str(), HCCL_BASE_DECIMAL, val);
     132           30 :     CHK_PRT_THROW(ret != HCCL_SUCCESS, HCCL_ERROR("[GetUIntFromStr] str[%s] is a invalid number.",
     133              :         digitStr.c_str()), InvalidParamsException, "parser portRange fail.");
     134           30 : }
     135              : 
     136           18 : void SplitSinglePortRange(const std::string &envName, std::string &rangeStr, SocketPortRange &portRange)
     137              : {
     138           18 :     std::string rangeMin{};
     139           18 :     const std::string delim = "-";
     140           18 :     if (SplitString(rangeStr, rangeMin, delim)) {
     141           12 :         GetUIntFromStr(rangeMin, portRange.min);
     142           12 :         GetUIntFromStr(rangeStr, portRange.max);
     143              :     } else {
     144            6 :         GetUIntFromStr(rangeStr, portRange.min);
     145            6 :         portRange.max = portRange.min;
     146              :     }
     147           52 :     HCCL_INFO("[SplitSinglePortRange] Load hccl socket port range [%u, %u] from %s",
     148              :         portRange.min, portRange.max, envName.c_str());
     149           18 : }
     150              : 
     151            8 : void CheckSocketPortRangeValid(const std::string &envName, const std::vector<SocketPortRange> &portRanges)
     152              : {
     153            8 :     std::vector<SocketPortRange> rangeVec(portRanges.begin(), portRanges.end());
     154            8 :     std::sort(rangeVec.begin(), rangeVec.end(), [](SocketPortRange &a, SocketPortRange &b) {
     155           18 :         return (a.min == b.min) ? (a.max < b.max) : (a.min < b.min);
     156              :     });
     157           16 :     for (size_t i = 0; i < rangeVec.size(); ++i) {
     158              :         // the socket range should not be inverted
     159           18 :         CHK_PRT_THROW(rangeVec[i].min > rangeVec[i].max,
     160              :             HCCL_ERROR("[%s] In %s, in socket port range [%u, %u], the lower bound is greater than"
     161              :                 " the upper bound.", __func__, envName.c_str(), rangeVec[i].min, rangeVec[i].max), 
     162              :             InvalidParamsException, "check portRange fail.");
     163              : 
     164              :         // the socket range should not include the reserved port for auto listening.
     165           22 :         CHK_PRT_THROW((rangeVec[i].min <= HCCL_SOCKET_PORT_RANGE_AUTO),
     166              :             HCCL_ERROR("[%s] In %s, socket port range [%u, %u] includes the reserved port number [%u]. "
     167              :                 "please do not use port [%u] in socket port range.", __func__, envName.c_str(), 
     168              :                 rangeVec[i].min, rangeVec[i].max, HCCL_SOCKET_PORT_RANGE_AUTO, HCCL_SOCKET_PORT_RANGE_AUTO), 
     169              :             InvalidParamsException, "check portRange fail.");
     170              : 
     171              :         // the socket range should not exceed the maximum port number
     172           15 :         CHK_PRT_THROW(rangeVec[i].max > MAX_PORT_NUMBER,
     173              :             HCCL_ERROR("[%s] In %s, in socket port range [%u, %u], the upper bound exceed max port number[%u].",
     174              :                 __func__, envName.c_str(), rangeVec[i].min, rangeVec[i].max, MAX_PORT_NUMBER), 
     175              :             InvalidParamsException, "check portRange fail.");
     176              : 
     177              :         // the socket range should not be overlapped
     178           14 :         CHK_PRT_THROW(i != 0 && rangeVec[i - 1].max >= rangeVec[i].min,
     179              :             HCCL_ERROR("[%s] In %s, socket port range [%u, %u] is conflict with socket port range [%u, %u].",
     180              :                 __func__, envName.c_str(), rangeVec[i - 1].min, rangeVec[i - 1].max, rangeVec[i].min, rangeVec[i].max),
     181              :             InvalidParamsException, "check portRange fail.");
     182              :     }
     183            8 : }
     184              : 
     185            8 : void SplitHcclSocketPortRange(const std::string &envName, std::string &portRangeConfig,
     186              :     std::vector<SocketPortRange> &portRangeVec)
     187              : {
     188            8 :     std::string rangeStr{};
     189            8 :     const std::string delim = ",";
     190           18 :     while (SplitString(portRangeConfig, rangeStr, delim)) {
     191           10 :         SocketPortRange portRange = {};
     192           10 :         SplitSinglePortRange(envName, rangeStr, portRange);
     193           10 :         portRangeVec.emplace_back(portRange);
     194              :     }
     195            8 :     SocketPortRange portRange = {};
     196            8 :     SplitSinglePortRange(envName, portRangeConfig, portRange);
     197            8 :     portRangeVec.emplace_back(portRange);
     198              : 
     199            8 :     CheckSocketPortRangeValid(envName, portRangeVec);
     200           13 : }
     201              : 
     202            3 : void PrintSocketPortRange(const std::string &envName, const std::vector<SocketPortRange> &portRangeVec)
     203              : {
     204              :     // assemble port ranges into a string to print the result range
     205            3 :     std::ostringstream portRangeOss;
     206            8 :     for (auto range : portRangeVec) {
     207            5 :         portRangeOss << " [" << std::to_string(range.min) << ", " << std::to_string(range.max) << "]";
     208              :     }
     209            7 :     HCCL_INFO("%s is set to%s.", envName.c_str(), portRangeOss.str().c_str());
     210            3 : }
     211              : 
     212            9 : std::vector<SocketPortRange> CastSocketPortRange(const std::string &s, const std::string &envName)
     213              : {
     214            9 :     std::vector<SocketPortRange> hcclSocketPortRange;
     215              :     // the environment variable is not set
     216            9 :     std::string socketPortRange = s;
     217            9 :     if (socketPortRange.length() == 0) {
     218            0 :         return hcclSocketPortRange;
     219              :     }
     220              : 
     221              :     // the socket port range is set to auto, then the os will listen on the ports dymamically and automatically.
     222            9 :     if (socketPortRange == HCCL_AUTO_PORT_CONFIG) {
     223            1 :         SocketPortRange autoSocketPortRange = {
     224              :             HCCL_SOCKET_PORT_RANGE_AUTO,
     225              :             HCCL_SOCKET_PORT_RANGE_AUTO
     226              :         };
     227            1 :         hcclSocketPortRange.emplace_back(autoSocketPortRange);
     228              : 
     229            3 :         HCCL_INFO("HCCL_HOST_SOCKET_PORT_RANGE is set to %s as [%u, %u].", HCCL_AUTO_PORT_CONFIG,
     230              :             autoSocketPortRange.min, autoSocketPortRange.max);
     231            1 :         return hcclSocketPortRange;
     232              :     }
     233              : 
     234              :     // the environment variable is set to an empty string
     235            8 :     socketPortRange.erase(std::remove(socketPortRange.begin(), socketPortRange.end(), ' '), socketPortRange.end());
     236            8 :     if (socketPortRange.empty()) {
     237            0 :         return hcclSocketPortRange;
     238              :     }
     239              : 
     240              :     // load ranges from string
     241            8 :     SplitHcclSocketPortRange(envName, socketPortRange, hcclSocketPortRange);
     242            3 :     CHK_PRT_THROW(hcclSocketPortRange.size() == 0, 
     243              :         HCCL_ERROR("Load empty port range from HCCL_HOST_SOCKET_PORT_RANGE, should not empty, please check."),
     244              :         InvalidParamsException, "parser portRange fail.");
     245              :     
     246            3 :     PrintSocketPortRange(envName, hcclSocketPortRange);
     247            3 :     return hcclSocketPortRange;
     248           14 : }
     249              : 
     250              : constexpr u32 HCCL_RDMA_TC_BASE = 4;    // RDMATrafficClass需要是4的整数倍
     251            4 : void CheckRDMATrafficClass(const u32 &rdmaTrafficClass)
     252              : {
     253            4 :     if (rdmaTrafficClass % HCCL_RDMA_TC_BASE != 0) {
     254            1 :         RPT_ENV_ERR(true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     255              :                             std::vector<std::string>({std::to_string(rdmaTrafficClass), "HCCL_RDMA_TC", "value should be multiple of four"}));
     256            3 :         HCCL_ERROR("rdmaTrafficClass[%u] is not a multiple of [%u]", rdmaTrafficClass, HCCL_RDMA_TC_BASE);
     257            1 :         THROW<InvalidParamsException>(
     258            2 :             StringFormat("rdmaTrafficClass[%u] is not a multiple of [%u]", rdmaTrafficClass, HCCL_RDMA_TC_BASE));
     259              :     }
     260            3 : }
     261              : 
     262              : constexpr u32 BYTES_PER_KB = 1024;    // 单位换算
     263            2 : void ConvertUnitQpThreshold(u32 &multiQpThreshold)
     264              : {
     265            6 :     HCCL_RUN_INFO("[Init][TransferUnitQpThreshold]Env config HCCL_MULTI_QP_THRESHOLD is %u[KB], converted to %u[B] for "
     266              :                "subsequant use.", multiQpThreshold, multiQpThreshold * BYTES_PER_KB);
     267            2 :     multiQpThreshold *= BYTES_PER_KB;
     268            2 : }
     269              : 
     270            1 : static void ParseAlgoLevel(const std::string &algoLevel, u32 &level, HcclAlgoType &algoType)
     271              : {
     272            1 :     std::size_t found = algoLevel.find(':');
     273            1 :     if ((found == 0) || (found == (algoLevel.length() - 1))) {
     274            0 :         THROW<InvalidParamsException>("algo config is invalid.");
     275              :     }
     276            1 :     if (found == std::string::npos) {
     277            1 :         THROW<InvalidParamsException>("algoLevel cannot find \":\".");
     278              :     }
     279              : 
     280            0 :     std::string orginalLevel = algoLevel.substr(0, found);
     281            0 :     std::string orginalAlgo  = algoLevel.substr(found + 1);
     282              : 
     283              :     const std::map<std::string, u32> hcclAlgoLevelMap = {{"level0", HCCL_ALGO_LEVEL_0},
     284              :                                                          {"level1", HCCL_ALGO_LEVEL_1},
     285              :                                                          {"level2", HCCL_ALGO_LEVEL_2},
     286            0 :                                                          {"level3", HCCL_ALGO_LEVEL_3}};
     287              : 
     288              :     const std::map<std::string, HcclAlgoType> hcclAlgoTypeMap = {
     289            0 :         {"null", HcclAlgoType::HCCL_ALGO_TYPE_NULL},
     290            0 :         {"ring", HcclAlgoType::HCCL_ALGO_TYPE_RING},
     291            0 :         {"pipeline", HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE},
     292            0 :         {"fullmesh", HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH},
     293            0 :         {"H-D_R", HcclAlgoType::HCCL_ALGO_TYPE_HDR},
     294            0 :         {"pairwise", HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE},
     295            0 :         {"NHR", HcclAlgoType::HCCL_ALGO_TYPE_NHR},
     296            0 :         {"NB", HcclAlgoType::HCCL_ALGO_TYPE_NB},
     297            0 :         {"NA", HcclAlgoType::HCCL_ALGO_TYPE_NA},
     298            0 :         {"NHR_V1", HcclAlgoType::HCCL_ALGO_TYPE_NHR_V1},
     299            0 :         {"AHC", HcclAlgoType::HCCL_ALGO_TYPE_AHC},
     300            0 :     };
     301              : 
     302            0 :     auto iterAlgoLevel = hcclAlgoLevelMap.find(orginalLevel);
     303            0 :     if (iterAlgoLevel == hcclAlgoLevelMap.end()) {
     304            0 :         THROW<InvalidParamsException>(
     305            0 :             StringFormat("algo config is invalid, level %s is not supported.", orginalLevel.c_str()));
     306              :     }
     307              : 
     308            0 :     auto iterAlgoType = hcclAlgoTypeMap.find(orginalAlgo);
     309            0 :     if (iterAlgoType == hcclAlgoTypeMap.end()) {
     310            0 :         THROW<InvalidParamsException>(
     311            0 :             StringFormat("algo config is invalid, algo %s is not supported.", orginalAlgo.c_str()));
     312              :     }
     313              : 
     314            0 :     level    = iterAlgoLevel->second;
     315            0 :     algoType = iterAlgoType->second;
     316            0 : }
     317              : 
     318            1 : std::vector<HcclAlgoType> CastAlgoTypeVec(const std::string &s)
     319              : {
     320            1 :     std::vector<HcclAlgoType> algoTypeVec(HCCL_ALGO_LEVEL_NUM);
     321            1 :     std::string               algoConfig = s;
     322            1 :     algoConfig.erase(std::remove(algoConfig.begin(), algoConfig.end(), ' '), algoConfig.end());
     323              : 
     324            5 :     for (u32 i = 0; i < HCCL_ALGO_LEVEL_NUM; i++) {
     325            4 :         algoTypeVec[i] = HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT;
     326              :     }
     327              : 
     328            1 :     if (algoConfig.empty()) {
     329            0 :         HCCL_RUN_INFO("hccl algo config is empty, HCCL use built-in algo selection.");
     330            0 :         return algoTypeVec;
     331              :     }
     332              : 
     333            1 :     std::vector<std::string> algoLevels = SplitString(algoConfig, ';');
     334            1 :     if (algoLevels.size() > HCCL_ALGO_LEVEL_NUM) {
     335            0 :         THROW<InvalidParamsException>(
     336            0 :             StringFormat("The number of algo levels is greater than %u.", HCCL_ALGO_LEVEL_NUM));
     337              :     }
     338            1 :     for (const auto &algoLevel : algoLevels) {
     339            1 :         u32          level = 0;
     340            1 :         HcclAlgoType algo  = HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT;
     341            1 :         ParseAlgoLevel(algoLevel, level, algo);
     342              :         // 检查是否存在重复配置level
     343            0 :         if (algoTypeVec[level] != HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT) {
     344            0 :             THROW<InvalidParamsException>(
     345            0 :                 StringFormat("hccl algo config[%s] is invalid. expect: levelX:algo1;levelY:algo2", algoConfig.c_str()));
     346              :         }
     347            0 :         algoTypeVec[level] = algo;
     348              :     }
     349              : 
     350            0 :     DevType devType = HrtGetDeviceType(); // 910A3场景只支持level0为ring算法
     351            0 :     if (devType == DevType::DEV_TYPE_910A3 && algoTypeVec[HCCL_ALGO_LEVEL_0] != HcclAlgoType::HCCL_ALGO_TYPE_RING) {
     352            0 :         algoTypeVec[HCCL_ALGO_LEVEL_0] = HcclAlgoType::HCCL_ALGO_TYPE_RING;
     353              :     }
     354              : 
     355            0 :     return algoTypeVec;
     356            3 : }
     357              : 
     358            5 : HcclResult SplitHcclOpType(const std::string &algoConfig, std::vector<std::string> &algos)
     359              : {
     360            5 :     std::string remainAlgoConfig;
     361            5 :     std::size_t found = algoConfig.find("/");
     362            5 :     if ((found == 0) || (found == (algoConfig.length() - 1))) {
     363            0 :         HCCL_ERROR("[Split][SplitHcclOpType] algo config is invalid.");
     364            0 :         return HCCL_E_PARA;
     365            5 :     } else if (found != std::string::npos) {
     366            0 :         remainAlgoConfig = algoConfig.substr(found + 1);
     367              :     }
     368            5 :     algos.push_back(algoConfig.substr(0, found));
     369            5 :     if (!remainAlgoConfig.empty()) {
     370            0 :         CHK_RET(SplitHcclOpType(remainAlgoConfig, algos));
     371              :     }
     372            5 :     return HCCL_SUCCESS;
     373            5 : }
     374              : 
     375              : // 新的逐算法的配置和原有的统一配置只可使用一种,发现同时存在时报错
     376            5 : HcclResult CheckAlgoConfigValid(
     377              :     std::vector<std::string> &algos,
     378              :     bool& anyCommonConfig,
     379              :     bool& anySpecificConfig)
     380              : {
     381           10 :     for (std::string& algConfig : algos) {
     382            5 :         std::size_t found = algConfig.find("=");
     383            5 :         if ((found == 0) || (found == (algConfig.length() - 1))) {
     384            0 :             HCCL_ERROR("[Split][CheckAlgoConfigValid] algo config is invalid.");
     385            0 :             return HCCL_E_PARA;
     386            5 :         } else if (found != std::string::npos) {
     387            1 :             anySpecificConfig = true;
     388              :         } else {
     389            4 :             anyCommonConfig = true;
     390              :         }
     391              :     }
     392            5 :     if (anyCommonConfig && anySpecificConfig) {
     393            0 :         HCCL_ERROR("[CheckAlgoConfigValid]should not set both algo config way");
     394            0 :         return HCCL_E_PARA;
     395              :     }
     396            5 :     if (anyCommonConfig && algos.size() > 1) {
     397            0 :         HCCL_ERROR("[CheckAlgoConfigValid]should only set one common config");
     398            0 :         return HCCL_E_PARA;
     399              :     }
     400            5 :     return HCCL_SUCCESS;
     401              : }
     402              : 
     403            6 : HcclResult ParserHcclAlgoLevel(const std::string &algoLevel, u32 &level, HcclAlgoType &algoType)
     404              : {
     405            6 :     std::size_t found = algoLevel.find(":");
     406            6 :     if ((found == 0) || (found == (algoLevel.length() - 1))) {
     407            0 :         HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid.");
     408            0 :         return HCCL_E_PARA;
     409              :     }
     410            6 :     if (found == std::string::npos) {
     411            2 :         THROW<InvalidParamsException>("algoLevel cannot find \":\".");
     412              :     }
     413              : 
     414            4 :     std::string orginalLevel = algoLevel.substr(0, found);
     415            4 :     std::string orginalAlgo = algoLevel.substr(found + 1);
     416              : 
     417              :     const std::map<std::string, u32> hcclAlgoLevelMap = {
     418              :         {"level0", HCCL_ALGO_LEVEL_0},
     419              :         {"level1", HCCL_ALGO_LEVEL_1},
     420              :         {"level2", HCCL_ALGO_LEVEL_2},
     421              :         {"level3", HCCL_ALGO_LEVEL_3}
     422           24 :     };
     423              : 
     424              :     const std::map<std::string, HcclAlgoType> hcclAlgoTypeMap = {
     425            0 :         {"null", HcclAlgoType::HCCL_ALGO_TYPE_NULL},
     426            0 :         {"ring", HcclAlgoType::HCCL_ALGO_TYPE_RING},
     427            0 :         {"pipeline", HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE},
     428            0 :         {"fullmesh", HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH},
     429            0 :         {"H-D_R", HcclAlgoType::HCCL_ALGO_TYPE_HDR},
     430            0 :         {"pairwise", HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE},
     431            0 :         {"NHR", HcclAlgoType::HCCL_ALGO_TYPE_NHR},
     432            0 :         {"NB", HcclAlgoType::HCCL_ALGO_TYPE_NB},
     433            0 :         {"NA", HcclAlgoType::HCCL_ALGO_TYPE_NA},
     434            0 :         {"NHR_V1", HcclAlgoType::HCCL_ALGO_TYPE_NHR_V1},
     435            0 :         {"AHC", HcclAlgoType::HCCL_ALGO_TYPE_AHC},
     436           52 :     };
     437              : 
     438            4 :     auto iterAlgoLevel = hcclAlgoLevelMap.find(orginalLevel);
     439            4 :     if (iterAlgoLevel == hcclAlgoLevelMap.end()) {
     440            0 :         HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid, level %s is not supported.", orginalLevel.c_str());
     441            0 :         return HCCL_E_PARA;
     442              :     }
     443              : 
     444            4 :     auto iterAlgoType = hcclAlgoTypeMap.find(orginalAlgo);
     445            4 :     if (iterAlgoType == hcclAlgoTypeMap.end()) {
     446            6 :         HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid, algo %s is not supported.", orginalAlgo.c_str());
     447            2 :         return HCCL_E_PARA;
     448              :     }
     449              : 
     450            2 :     level = iterAlgoLevel->second;
     451            2 :     algoType = iterAlgoType->second;
     452              : 
     453            2 :     return HCCL_SUCCESS;
     454           12 : }
     455              : 
     456              : const std::map<HcclAlgoType, std::string> HcclAlgoTypeMap = {
     457              :     {HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT, "default"},
     458              :     {HcclAlgoType::HCCL_ALGO_TYPE_RING, "ring"},
     459              :     {HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE, "pipeline"},
     460              :     {HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH, "fullmesh"},
     461              :     {HcclAlgoType::HCCL_ALGO_TYPE_HDR, "HDR"},
     462              :     {HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE, "pairwise"},
     463              :     {HcclAlgoType::HCCL_ALGO_TYPE_NHR, "NHR"},
     464              :     {HcclAlgoType::HCCL_ALGO_TYPE_NB, "NB"},
     465              :     {HcclAlgoType::HCCL_ALGO_TYPE_NULL, "null"},
     466              :     {HcclAlgoType::HCCL_ALGO_TYPE_NA, "NA"},
     467              :     {HcclAlgoType::HCCL_ALGO_TYPE_NHR_V1, "NHR_V1"},
     468              :     {HcclAlgoType::HCCL_ALGO_TYPE_AHC, "AHC"},
     469              : };
     470              : 
     471            8 : HcclResult SplitHcclAlgoLevel(const std::string &algoConfig, std::vector<std::string> &algos)
     472              : {
     473            8 :     std::string remainAlgoConfig;
     474            8 :     std::size_t found = algoConfig.find(";");
     475            8 :     if ((found == 0) || (found == (algoConfig.length() - 1))) {
     476            0 :         HCCL_ERROR("[Split][HcclAlgoLevel] algo config is invalid.");
     477            0 :         return HCCL_E_PARA;
     478            8 :     } else if (found != std::string::npos) {
     479            3 :         remainAlgoConfig = algoConfig.substr(found + 1);
     480              :     } else {
     481              :         // 最后一组配置,剩余的字符串为空
     482              :     }
     483            8 :     algos.push_back(algoConfig.substr(0, found));
     484              : 
     485            8 :     if (algos.size() > HCCL_ALGO_LEVEL_NUM) {
     486            0 :         HCCL_ERROR("[Split][HcclAlgoLevel] algo config is invalid. algo level is more than %u.", HCCL_ALGO_LEVEL_NUM);
     487            0 :         return HCCL_E_PARA;
     488              :     }
     489            8 :     if (!remainAlgoConfig.empty()) {
     490            3 :         CHK_RET(SplitHcclAlgoLevel(remainAlgoConfig, algos));
     491              :     }
     492              : 
     493            8 :     return HCCL_SUCCESS;
     494            8 : }
     495              : 
     496            5 : HcclResult ParseAlgoString(std::string opName, std::string &algoString, std::vector<HcclAlgoType>& algType)
     497              : {
     498            5 :     algType = std::vector<HcclAlgoType>(HCCL_ALGO_LEVEL_NUM, HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT);
     499            5 :     std::vector<std::string> algoLevels;
     500            5 :     HcclResult ret = SplitHcclAlgoLevel(algoString, algoLevels);
     501            5 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
     502              :         "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
     503              :         algoString.c_str()), ret);
     504            7 :     for (auto algoLevel : algoLevels) {
     505            6 :         u32 level = 0;
     506            6 :         HcclAlgoType algo = HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT;
     507            6 :         ret = ParserHcclAlgoLevel(algoLevel, level, algo);
     508           10 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
     509              :             "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
     510              :             algoString.c_str()), ret);
     511              :         // 检查是否存在重复配置level
     512            2 :         if (algType[level] != HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT) {
     513            0 :             HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
     514              :                 "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
     515              :                 algoString.c_str());
     516            0 :             return HCCL_E_PARA;
     517              :         }
     518            2 :         algType[level] = algo;
     519            6 :     }
     520            1 :     auto level0Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_0]);
     521            1 :     auto level1Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_1]);
     522            1 :     auto level2Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_2]);
     523            1 :     auto level3Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_3]);
     524            3 :     HCCL_RUN_INFO("hccl algo op %s config: level0:%s, level1:%s, level2:%s, level3:%s",
     525              :         opName.c_str(),
     526              :         level0Iter->second.c_str(), level1Iter->second.c_str(),
     527              :         level2Iter->second.c_str(), level3Iter->second.c_str());
     528            1 :     return HCCL_SUCCESS;
     529            5 : }
     530              : 
     531            4 : HcclResult SetCommonAlgType(std::vector<std::string> &algos, std::map<OpType, std::vector<HcclAlgoType>>& hcclAlgoConfig)
     532              : {
     533            4 :     std::vector<HcclAlgoType> algType;
     534           18 :     CHK_RET(ParseAlgoString("all op type", algos[0], algType));
     535            0 :     for (auto opType : OP_TYPE_SET) {
     536            0 :         hcclAlgoConfig[opType] = algType;
     537              :     }
     538            0 :     return HCCL_SUCCESS;
     539            4 : }
     540              : 
     541            1 : HcclResult SetSpecificAlgType(std::vector<std::string> &algos, std::map<OpType, std::vector<HcclAlgoType>>& hcclAlgoConfig)
     542              : {
     543              :     std::map<std::string, OpType> hcclOpTypeMap = {
     544            0 :         {"broadcast", OpType::BROADCAST},
     545            0 :         {"allreduce", OpType::ALLREDUCE},
     546            0 :         {"reduce", OpType::REDUCE},
     547            0 :         {"send", OpType::SEND},
     548            0 :         {"receive", OpType::RECV},
     549            0 :         {"allgather", OpType::ALLGATHER},
     550            0 :         {"reducescatter", OpType::REDUCESCATTER},
     551            0 :         {"alltoall", OpType::ALLTOALL},
     552            0 :         {"gather", OpType::GATHER},
     553            0 :         {"scatter", OpType::SCATTER},
     554            0 :         {"sendrecv", OpType::BATCHSENDRECV},
     555           13 :     };
     556            2 :     for (std::string& algConfig : algos) {
     557            1 :         std::size_t found = algConfig.find("=");
     558            1 :         std::string opStringName = algConfig.substr(0, found);
     559            1 :         if (hcclOpTypeMap.find(opStringName) != hcclOpTypeMap.end()) {
     560            1 :             OpType optype = hcclOpTypeMap[opStringName];
     561            1 :             std::string remainAlgoConfig = algConfig.substr(found + 1);
     562            1 :             std::vector<HcclAlgoType> algType;
     563            1 :             CHK_RET(ParseAlgoString(opStringName, remainAlgoConfig, algType));
     564            1 :             if (algType[0] == HcclAlgoType::HCCL_ALGO_TYPE_NULL) {
     565            0 :                 HCCL_ERROR("[SetSpecificAlgType] specific config level0 not support null type.");
     566            0 :                 return HCCL_E_PARA;
     567              :             }
     568            1 :             hcclAlgoConfig[optype] = algType;
     569            1 :         } else {
     570            0 :             HCCL_ERROR("[SetSpecificAlgType] specific config optype[%s] is invalid, please check",
     571              :                 opStringName.c_str());
     572            0 :             return HCCL_E_PARA;
     573              :         }
     574            1 :     }
     575            1 :     if (hcclAlgoConfig.find(OpType::ALLTOALL) != hcclAlgoConfig.end()) {
     576            0 :         hcclAlgoConfig[OpType::ALLTOALLV] =
     577            0 :             hcclAlgoConfig[OpType::ALLTOALL];
     578            0 :         hcclAlgoConfig[OpType::ALLTOALLVC] =
     579            0 :             hcclAlgoConfig[OpType::ALLTOALL];
     580              :     }
     581            1 :     return HCCL_SUCCESS;
     582            2 : }
     583              : 
     584            5 : std::map<OpType, std::vector<HcclAlgoType>> SetHcclAlgoConfig(const std::string &hcclAlgo)
     585              : {
     586            5 :     std::string algoConfig = hcclAlgo;
     587            5 :     algoConfig.erase(std::remove(algoConfig.begin(), algoConfig.end(), ' '), algoConfig.end());
     588            5 :     std::map<OpType, std::vector<HcclAlgoType>> hcclAlgoConfig;
     589            5 :     if (algoConfig.empty()) {
     590            0 :         HCCL_RUN_INFO("hccl algo config is empty, HCCL use built-in algo selection.");
     591            0 :         return hcclAlgoConfig;
     592              :     }
     593            5 :     std::vector<std::string> algoPerOptype;
     594            5 :     HcclResult splitRet = SplitHcclOpType(algoConfig, algoPerOptype);
     595            5 :     if (splitRet != HCCL_SUCCESS) {
     596            0 :         THROW<InvalidParamsException>(
     597            0 :             StringFormat("Env HCCL_ALGO config \"%s\" is invalid. example [level0:NA;level1:NHR] or"
     598              :                 "[allreduce=level0:NA;level1:ring/allgather=level0:NA;level1:H-D_R]", hcclAlgo.c_str()));
     599              :     }
     600              : 
     601            5 :     bool anyCommonConfig = false;
     602            5 :     bool anySpecificConfig = false;
     603            5 :     HcclResult checkRet = CheckAlgoConfigValid(algoPerOptype, anyCommonConfig, anySpecificConfig);
     604            5 :     if (checkRet != HCCL_SUCCESS) {
     605            0 :         THROW<InvalidParamsException>(
     606            0 :             StringFormat("Env HCCL_ALGO config \"%s\" is invalid. example [level0:NA;level1:NHR] or"
     607              :                 "[allreduce=level0:NA;level1:ring/allgather=level0:NA;level1:H-D_R]", hcclAlgo.c_str()));
     608              :     }
     609            5 :     HcclResult ret = HCCL_SUCCESS;
     610            5 :     if (anyCommonConfig) {
     611            4 :         ret = SetCommonAlgType(algoPerOptype, hcclAlgoConfig);
     612              :     } else {
     613            1 :         ret = SetSpecificAlgType(algoPerOptype, hcclAlgoConfig);
     614              :     }
     615            3 :     if (ret != HCCL_SUCCESS) {
     616            2 :         THROW<InvalidParamsException>(
     617            6 :             StringFormat("Env HCCL_ALGO config \"%s\" is invalid. example [level0:NA;level1:NHR] or"
     618              :                 "[allreduce=level0:NA;level1:ring/allgather=level0:NA;level1:H-D_R]", hcclAlgo.c_str()));
     619              :     }
     620            1 :     return hcclAlgoConfig;
     621           13 : }
     622              : 
     623           11 : HcclAccelerator CastHcclAccelerator(const std::string &s)
     624              : {
     625           11 :     HcclAccelerator mode;
     626           11 :     if (s == "AI_CPU" || s == "AICPU_TS") {
     627            3 :         mode = HcclAccelerator::AICPU_TS;
     628            8 :     } else if (s == "AIV") {
     629            1 :         mode = HcclAccelerator::AIV;
     630            7 :     } else if (s == "CCU_MS") {
     631            1 :         mode = HcclAccelerator::CCU_MS;
     632            6 :     } else if (s == "CCU_SCHED") {
     633            2 :         mode = HcclAccelerator::CCU_SCHED;
     634              :     } else {
     635           12 :         HCCL_ERROR("Env HCCL_OP_EXPANSION_MODE config do not support %s, it should be one of [AI_CPU, AICPU_TS, AIV, CCU_MS, CCU_SCHED].", s.c_str());
     636            4 :         THROW<InvalidParamsException>(
     637           12 :             StringFormat("Env HCCL_OP_EXPANSION_MODE config \"%s\" is invalid."
     638              :                 "it should be one of [AI_CPU, AICPU_TS, AIV, CCU_MS, CCU_SCHED].", s.c_str()));
     639              :     }
     640            7 :     return mode;
     641              : }
     642              :  
     643            5 : s32 CastSocketFamily(const std::string &s)
     644              : {
     645              :     s32 hcclSocketFamily;
     646            5 :     if (s == "AF_INET") {
     647            1 :         hcclSocketFamily = AF_INET;
     648            4 :     } else if (s == "AF_INET6") {
     649            2 :         hcclSocketFamily = AF_INET6;
     650              :     } else {
     651            2 :         hcclSocketFamily = -1;
     652            2 :         THROW<InvalidParamsException>(
     653            4 :             StringFormat("environmental variable HCCL_SOCKET_FAMILY[%s] is invalid. it should "
     654              :                          "be \"AF_INET\" or \"AF_INET6\".",
     655              :                          s.c_str()));
     656              :     }
     657            3 :     return hcclSocketFamily;
     658              : }
     659              : 
     660           11 : std::string GetCannVersionPath(const std::string &cannEnvStr, const std::string &keyStr)
     661              : {
     662           11 :     std::string cannVersionPath;
     663           11 :     std::string tempPath; // 存放临时路径
     664              :     // 查找cann安装路径
     665          494 :     for (u32 i = 0; i < cannEnvStr.length(); ++i) {
     666              :         // 环境变量中存放的每段路径之间以':'隔开
     667          484 :         if (cannEnvStr[i] != ':') {
     668          483 :             tempPath += cannEnvStr[i];
     669              :         }
     670              :         // 对存放CANN版本文件的路径进行搜索, 有两种情况
     671              :         // 一种是*/latest/version.cfg
     672              :         // 另一种是*/runtime/version.info
     673          484 :         if (cannEnvStr[i] == ':' || i == cannEnvStr.length() - 1) {
     674           12 :             size_t found = tempPath.find(keyStr);
     675           12 :             if (found == string::npos) {
     676           11 :                 tempPath.clear();
     677           11 :                 continue;
     678              :             }
     679              :             // 防止出现类似/runtime*/的情况
     680            1 :             if (tempPath.length() <= found + keyStr.length() || tempPath[found + keyStr.length()] == '/') {
     681            1 :                 cannVersionPath = tempPath.substr(0, found + keyStr.length());
     682            1 :                 break;
     683              :             }
     684            0 :             tempPath.clear();
     685              :         }
     686              :     }
     687              :     // 路径为空
     688           11 :     if (cannVersionPath.empty()) {
     689           20 :         return "NotFound";
     690              :     }
     691            1 :     return cannVersionPath;
     692           11 : }
     693              : 
     694            1 : std::string LoadCannVersionInfoFile(const std::string &realName, const std::string &keyStr)
     695              : {
     696            1 :     std::string cannVersion;
     697              :     // 打开该文件前,判断该文件路径是否有效、规范
     698            1 :     char realFile[PATH_MAX] = {0};
     699            1 :     if (realpath(realName.c_str(), realFile) == nullptr) {
     700            0 :         HCCL_INFO("[CannVersion][Verification]cann version path %s is not a valid real path", realName.c_str());
     701            0 :         return "";
     702              :     }
     703            3 :     HCCL_INFO("Load CannVersion InfoFile in %s", realFile);
     704              : 
     705              :     // realFile转str,然后open这个str
     706            1 :     std::ifstream infile(realFile, std::ifstream::in);
     707              : 
     708            1 :     if (!infile.is_open()) {
     709            3 :         HCCL_INFO("[CannVersion][Verification]%s does not exist.", realFile);
     710            2 :         return "";
     711              :     }
     712              : 
     713              :     // 逐行读取,结果放在line中,寻找带有keyStr的字符串
     714            0 :     string line;
     715            0 :     s32    maxRows = 100; // 在文件中读取的最长行数为100,避免超大文件长时间读取
     716            0 :     while (getline(infile, line)) {
     717            0 :         --maxRows;
     718            0 :         if (maxRows < 0) {
     719            0 :             HCCL_WARNING("[CannVersion][Verification]version file content is too long.");
     720            0 :             return "";
     721              :         }
     722            0 :         u32 found = line.find(keyStr);
     723              :         // 版本字段的两种模式
     724              :         // runtime目录下, version.info文件, Version=1.83.T8.0.B128
     725              :         // latest目录下, version.cfg文件, runtime_running_version=[1.83.T8.0.B128:CANN-1.83]
     726            0 :         if (found == 0) {
     727            0 :             u32 startPos = keyStr.length();                    // 版本字符串开始位置
     728            0 :             u32 endPos   = min(line.find(":"), line.length()); // 版本字符串在":"或结尾处结束
     729              :             // 版本字符串为空
     730            0 :             if (endPos <= startPos) {
     731            0 :                 HCCL_WARNING("[CannVersion][Verification]cannVersion is invalid.");
     732            0 :                 return "";
     733              :             }
     734              : 
     735            0 :             u32 len     = endPos - startPos;          // 版本字符串长度
     736            0 :             cannVersion = line.substr(startPos, len); // 从keyStr截断
     737            0 :             HCCL_INFO("[Parse][CannVersion]success, CannVersion is %s ", cannVersion.c_str());
     738            0 :             break;
     739              :         }
     740              :     }
     741            0 :     infile.close();
     742            0 :     return cannVersion;
     743            1 : }
     744              : 
     745            6 : std::string CastCannVersion(const std::string &cannEnv)
     746              : {
     747            6 :     std::string cannVersionPath = GetCannVersionPath(cannEnv, "/runtime");
     748            6 :     if (cannVersionPath != "NotFound") {
     749            1 :         cannVersionPath += "/version.info";
     750            1 :         std::string cannVersion = LoadCannVersionInfoFile(cannVersionPath, "Version=");
     751            1 :         return cannVersion;
     752            0 :     }
     753              : 
     754            5 :     cannVersionPath = GetCannVersionPath(cannEnv, "/latest");
     755            5 :     if (cannVersionPath != "NotFound") {
     756            0 :         cannVersionPath += "/version.cfg";
     757            0 :         std::string cannVersion = LoadCannVersionInfoFile(cannVersionPath, "runtime_running_version=[");
     758            0 :         return cannVersion;
     759            0 :     }
     760              : 
     761           15 :     HCCL_INFO("cannot found version file in %s.", cannEnv.c_str());
     762           10 :     return "";
     763            6 : }
     764              : 
     765           18 : std::vector<std::string> SplitDfsConfig(const std::string &str, char delimiter)
     766              : {
     767           18 :     std::vector<std::string> tokens;
     768           18 :     std::istringstream       stream(str);
     769           18 :     std::string              token;
     770              : 
     771           44 :     while (std::getline(stream, token, delimiter)) {
     772           26 :         tokens.push_back(token);
     773              :     }
     774           18 :     if (stream.peek() != EOF) {
     775            0 :         std::string remaining;
     776            0 :         std::getline(stream, remaining);
     777            0 :         tokens.push_back(remaining);
     778            0 :     }
     779           18 :     if (!str.empty() && str.back() == delimiter) {
     780            0 :         tokens.push_back("");
     781              :     }
     782           18 :     return tokens;
     783           18 : }
     784              : 
     785            8 : void CastDfsConfigParseTaskExceptionEnable(bool &taskExceptionEnable, const std::string configValue)
     786              : {
     787            8 :     if (configValue == "off") {
     788            2 :         taskExceptionEnable = false;
     789            6 :         HCCL_WARNING("env[HCCL_DFS_CONFIG] task_exception was configed to [%s]", configValue.c_str());
     790            6 :     } else if (configValue == "on") {
     791            5 :         taskExceptionEnable = true;
     792              :     } else {
     793            1 :         THROW<InvalidParamsException>(StringFormat(
     794              :             "env[HCCL_DFS_CONFIG] please set task_exception to 'on' or 'off'.", configValue.c_str()));
     795              :     }
     796            7 : }
     797              : 
     798            0 : void CastDfsConfigParseClusterHeartBeatEnable(bool &clusterHeartBeatEnable, const std::string configValue)
     799              : {
     800            0 :     if (configValue == "off") {
     801            0 :         clusterHeartBeatEnable = false;
     802            0 :         HCCL_WARNING("env[HCCL_DFS_CONFIG] cluster_heartbeat was configed to [%s]", configValue.c_str());
     803            0 :     } else if (configValue == "on") {
     804            0 :         clusterHeartBeatEnable = true;
     805              :     } else {
     806            0 :         THROW<InvalidParamsException>(StringFormat(
     807              :             "env[HCCL_DFS_CONFIG] please set cluster_heartbeat to 'on' or 'off'.", configValue.c_str()));
     808              :     }
     809            0 : }
     810              : 
     811            0 : void CastDfsConfigParseRankConsistentState(int32_t &rankConsistentState, const std::string configValue)
     812              : {
     813            0 :     if (configValue == "off") {
     814            0 :         rankConsistentState = -1;
     815            0 :     }else if (configValue == "first")
     816              :     {
     817            0 :         rankConsistentState = 0;   
     818            0 :     }else if (configValue == "on")
     819              :     {
     820            0 :         rankConsistentState = 1;  
     821              :     }else {
     822            0 :         THROW<InvalidParamsException>(StringFormat(
     823              :             "env[HCCL_DFS_CONFIG] please set inconsistent_check to '-1' or '0' or '1'.", configValue.c_str()));
     824              :     }
     825            0 : }
     826              : 
     827            9 : DfsConfig CastDfsConfig(const std::string &dfsConfigEnv)
     828              : {
     829            9 :     constexpr std::size_t                              DFS_CONFIG_ITEM_NUM = 3;
     830           18 :     const std::array<std::string, DFS_CONFIG_ITEM_NUM> dfsItemName   = {"task_exception", "cluster_heartbeat", "inconsistent_check"};
     831            9 :     bool                                               taskExceptionEnable = true;
     832            9 :     bool                                               clusterHeartBeatEnable = true;
     833            9 :     int32_t                                            rankConsistentState = 0;
     834            9 :     std::string                                        dfsConfigEnvCopy    = dfsConfigEnv;
     835            9 :     dfsConfigEnvCopy.erase(std::remove(dfsConfigEnvCopy.begin(), dfsConfigEnvCopy.end(), ' '), dfsConfigEnvCopy.end());
     836            9 :     auto items = SplitDfsConfig(dfsConfigEnvCopy, ',');
     837           16 :     for (const auto &item : items) {
     838            9 :         auto                  itemPair  = SplitDfsConfig(item, ':');
     839            9 :         constexpr std::size_t ITEM_SIZE = 2;
     840            9 :         if (itemPair.size() != ITEM_SIZE
     841            9 :             || std::find(dfsItemName.begin(), dfsItemName.end(), itemPair[0]) == dfsItemName.end()) {
     842            1 :             THROW<InvalidParamsException>(
     843            3 :                 StringFormat("env[HCCL_DFS_CONFIG] value[%s] is invalid,  please check, example [task_exception:on]", dfsConfigEnv.c_str()));
     844              :         }
     845            8 :         if (itemPair[0] == dfsItemName[0]) {
     846            9 :             CastDfsConfigParseTaskExceptionEnable(taskExceptionEnable, itemPair[1]);
     847            0 :         } else if (itemPair[0] == dfsItemName[1]) {
     848            0 :             CastDfsConfigParseClusterHeartBeatEnable(clusterHeartBeatEnable, itemPair[1]);
     849            0 :         } else if (itemPair[0] == dfsItemName[2]) {
     850            0 :             CastDfsConfigParseRankConsistentState(rankConsistentState, itemPair[1]);
     851              :         }
     852            9 :     }
     853            7 :     DfsConfig config{taskExceptionEnable, clusterHeartBeatEnable, rankConsistentState};
     854              : 
     855            7 :     return config;
     856           13 : }
     857              : 
     858              : /*----------------------------- validate functions -------------------------*/
     859            6 : void CheckExecTimeOut(const u32 &timeOut)
     860              : {
     861            6 :     DevType devType = HrtGetDeviceType();
     862           17 :     if (devType == DevType::DEV_TYPE_910A2 || devType == DevType::DEV_TYPE_910A3 ||
     863           17 :         devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
     864              :         // 910A2和910A3算子超时时间范围0s-2147483647s,其中0代表永不超时
     865            5 :         CheckRange<u32>(timeOut, 0, HCCL_EXEC_TIME_OUT_S_910A3);
     866              :     } else {
     867              :         // 非910A2和910A3算子超时时间范围1s-17340s
     868            1 :         CheckRange<u32>(timeOut, 1, HCCL_EXEC_TIME_OUT_S);
     869              :     }
     870            5 : }
     871              : 
     872            4 : void CheckFilePath(const string &filePath)
     873              : {
     874            4 :     if (filePath.length() >= (PATH_MAX) || filePath.length() == 0) {
     875            1 :         THROW<InvalidParamsException>(
     876            2 :             StringFormat("env[HCCL_WHITELIST_FILE] is invalid, len is %u, should be (0,4096)", filePath.length()));
     877              :     }
     878            3 : }
     879              : 
     880            9 : void CheckRdmaTimeout(const u32 &timeout)
     881              : {
     882              :     // HCCL_RDMA_TIMEOUT 合法范围为:[0, 31],超出31按照0进行处理,表示永不超时
     883              :     // 此处为空实现,原因为非法值在 Str2T<u32> 里面已经处理
     884              :     (void)timeout;
     885            9 : }
     886              : 
     887              : /*-------------------------- post process functions -------------------------*/
     888            3 : void SetRealPath(string &filePath)
     889              : {
     890            3 :     char realFile[PATH_MAX] = {0};
     891            3 :     if (realpath(filePath.c_str(), realFile) == nullptr) {
     892            2 :         THROW<InvalidParamsException>(StringFormat("[Init][EnvVarParam]path %s is not a valid real path", filePath.c_str()));
     893              :     }
     894            2 :     filePath = std::string(realFile);
     895            2 : }
     896              : 
     897            5 : void ProcExecTimeOut(u32 &timeOut)
     898              : {
     899            5 :     DevType devType = HrtGetDeviceType();
     900           14 :     if (devType == DevType::DEV_TYPE_910A2 || devType == DevType::DEV_TYPE_910A3 ||
     901           14 :         devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) {
     902            4 :         return;
     903              :     }
     904              :     // 910A芯片限制超时时长为68的倍数
     905            1 :     s32 intPart = timeOut / HCCL_INTEVAL_EXEC_TIME_OUT_S;
     906            1 :     intPart     = (intPart == 0) ? 1 : intPart;
     907            1 :     timeOut     = intPart * HCCL_INTEVAL_EXEC_TIME_OUT_S;
     908              : }
     909              : 
     910           12 : void ProcRdmaTimeout(u32 &timeout)
     911              : {
     912              :     // HCCL_RDMA_TIMEOUT 合法范围为:[0, 31],超出31按照0进行处理,表示永不超时
     913           12 :     if (timeout > EnvRdmaConfig::HCCL_RDMA_TIMEOUT_MAX) {
     914            9 :         HCCL_WARNING("HCCL_RDMA_TIMEOUT[%u] exceeds max [%u], reset to [%u]", timeout,
     915              :             EnvRdmaConfig::HCCL_RDMA_TIMEOUT_MAX, EnvRdmaConfig::HCCL_RDMA_TIMEOUT_MIN);
     916            3 :         timeout = EnvRdmaConfig::HCCL_RDMA_TIMEOUT_MIN;
     917              :     }
     918           12 : }
     919              : 
     920              : /*-------------------------- detour type -------------------------*/
     921              : // 临时方案,特定场景执行算法会报错,后续适配了再放开
     922            6 : HcclDetourType CastDetourType(const std::string &s)
     923              : {
     924            6 :     if (s == "detour:1") {
     925            6 :         HCCL_INFO("HCCL detour type is 2P (detour:1).");
     926            2 :         return HcclDetourType::HCCL_DETOUR_ENABLE_2P;
     927            4 :     } else if (s == "detour:0") {
     928            3 :         HCCL_INFO("HCCL detour type is disable (detour:0).");
     929              :     } else {
     930            3 :         THROW<NotSupportException>(StringFormat("environment variable HCCL_DETOUR currently only supports"
     931              :                                                 " detour:1 and detour:0 or not set."));
     932              :     }
     933            1 :     return HcclDetourType::HCCL_DETOUR_DISABLE;
     934              : }
     935              : 
     936              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1