LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/communicator/impl/resource_manager - multi_qpInfo_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 389 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 40 0

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "multi_qpInfo_manager.h"
      12              : #include "adapter_hccp_common.h"
      13              : #include <queue>
      14              : #include <cstdlib>
      15              : #include <fstream>
      16              : #include "externalinput_pub.h"
      17              : #include "adapter_error_manager_pub.h"
      18              : #include "../../../nslbdp/hccl_nslbdp.h"
      19              : #include "mmpa_api.h"
      20              : namespace hccl {
      21              : static std::vector<std::string> devCfgPortMode{"multi_qp", "nslb_dp", ""};
      22              : 
      23            0 : static std::string MultiQpFromToString(MUL_QP_FROM value)
      24              : {
      25              :     static const std::map<MUL_QP_FROM, std::string> map
      26            0 :         = {{MUL_QP_FROM::MUL_QP_FROM_DEV_CFG, "DEV_CFG"},
      27            0 :            {MUL_QP_FROM::MUL_QP_FROM_DEV_NSLB, "DEV_NSLB"},
      28            0 :            {MUL_QP_FROM::MUL_QP_FROM_ENV_PORT_CONFIG_PATH, "ENV_HCCL_RDMA_QP_PORT_CONFIG_PATH"},
      29            0 :            {MUL_QP_FROM::MUL_QP_FROM_ENV_PER_CONNECTION, "ENV_HCCL_RDMA_QPS_PER_CONNECTION"},
      30            0 :            {MUL_QP_FROM::MUL_QP_FROM_UNKNOWN, "MUL_QP_FROM_UNKNOWN"}};
      31              : 
      32            0 :     auto it = map.find(value);
      33            0 :     if (it != map.end()) {
      34            0 :         return it->second;
      35              :     }
      36            0 :     return "UNKNOWN";
      37            0 : }
      38              : 
      39            0 : HcclResult MulQpInfoCacheBase::Init() { return initStatus_; }
      40              : 
      41            0 : void MulQpInfoCacheBase::SetMulQpInfoFrom(MUL_QP_FROM mulQpInfoFrom) { mulQpInfoFrom_ = mulQpInfoFrom; }
      42              : 
      43            0 : MUL_QP_FROM MulQpInfoCacheBase::MulQpInfoFrom() const { return mulQpInfoFrom_; }
      44              : 
      45            0 : HcclResult MulQpInfoCacheBase::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair) const
      46              : {
      47              :     (void)portNum;
      48              :     (void)ipPair;
      49            0 :     return HcclResult::HCCL_E_INTERNAL;
      50              : }
      51              : 
      52            0 : HcclResult MulQpInfoCacheBase::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair) const
      53              : {
      54              :     (void)sourcePorts;
      55              :     (void)ipPair;
      56            0 :     return HcclResult::HCCL_E_INTERNAL;
      57              : }
      58              : 
      59            0 : DevCfgMulQpInfoCache::DevCfgMulQpInfoCache(const NICDeployment nicDeployment, const std::int32_t phyId)
      60            0 :     : nicDeployment_(nicDeployment),
      61            0 :       phyId_(phyId)
      62              : {
      63            0 :     SetMulQpInfoFrom(MUL_QP_FROM::MUL_QP_FROM_DEV_CFG);
      64            0 : }
      65              : 
      66            0 : HcclResult MulQpInfo::Init(const InitParams& params)
      67              : {
      68            0 :     std::lock_guard<std::mutex> initLock(initLock_);
      69            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE
      70            0 :         || (params.GetDevType() != DevType::DEV_TYPE_910_93 && params.GetDevType() != DevType::DEV_TYPE_910B)) {
      71            0 :         return HcclResult::HCCL_SUCCESS;
      72              :     }
      73            0 :     if (initStatus_ != HcclResult::HCCL_E_RESERVED) {
      74            0 :         return initStatus_;
      75              :     }
      76              :     // 生成队列排序
      77            0 :     std::queue<std::unique_ptr<MulQpInfoCacheBase>> parseOrderQueue;
      78            0 :     std::unique_ptr<DevCfgMulQpInfoCache> devCfgMulQpInfoCache;
      79            0 :     std::unique_ptr<DevNslbMulQpInfoCache> devNslbMulQpInfoCache;
      80            0 :     std::unique_ptr<EnvConfigPathCache> envConfigPathCache;
      81            0 :     std::unique_ptr<EnvPerConnectionQpInfoCache> envPerConnectionQpInfoCache;
      82            0 :     EXCEPTION_CATCH(
      83              :         (devCfgMulQpInfoCache = std::make_unique<DevCfgMulQpInfoCache>(params.GetNicDeployment(), params.GetPhyId())),
      84              :         return HCCL_E_INTERNAL);
      85            0 :     EXCEPTION_CATCH(
      86              :         (devNslbMulQpInfoCache = std::make_unique<DevNslbMulQpInfoCache>(params.GetNicDeployment(), params.GetPhyId())),
      87              :         return HCCL_E_INTERNAL);
      88            0 :     EXCEPTION_CATCH((envConfigPathCache = std::make_unique<EnvConfigPathCache>()), return HCCL_E_INTERNAL);
      89            0 :     EXCEPTION_CATCH(
      90              :         (envPerConnectionQpInfoCache = std::make_unique<EnvPerConnectionQpInfoCache>()), return HCCL_E_INTERNAL);
      91            0 :     parseOrderQueue.emplace(std::move(devCfgMulQpInfoCache));
      92            0 :     parseOrderQueue.emplace(std::move(devNslbMulQpInfoCache));
      93            0 :     parseOrderQueue.emplace(std::move(envConfigPathCache));
      94            0 :     parseOrderQueue.emplace(std::move(envPerConnectionQpInfoCache));
      95            0 :     while (!parseOrderQueue.empty()) {
      96            0 :         auto&& item = parseOrderQueue.front();
      97            0 :         initStatus_ = item->Init();
      98            0 :         if (initStatus_ != HcclResult::HCCL_SUCCESS) {
      99            0 :             return initStatus_;
     100              :         }
     101            0 :         if (item->IsAvailable()) {
     102            0 :             config_ = std::move(item);
     103            0 :             break; // 解析成功
     104              :         }
     105            0 :         parseOrderQueue.pop();
     106              :     }
     107            0 :     if (config_ && config_->IsAvailable()) {
     108            0 :         HCCL_RUN_INFO(
     109              :             "[MultiQp][MulQpInfo] Init Success,Device PhyId[%d] MultiQp config from type[%s]", params.GetPhyId(),
     110              :             MultiQpFromToString(config_->MulQpInfoFrom()).c_str());
     111              :     }
     112            0 :     initStatus_ = HcclResult::HCCL_SUCCESS; // 均未设置 或某种方式解析成功
     113            0 :     return initStatus_;
     114            0 : }
     115              : 
     116            0 : bool MulQpInfo::IsInitialized()
     117              : {
     118            0 :     std::lock_guard<std::mutex> initLock(initLock_);
     119            0 :     return initStatus_ != HcclResult::HCCL_E_RESERVED;
     120            0 : }
     121              : 
     122            0 : HcclResult MulQpInfo::IsEnableMulQp(bool& isEnableMulQp)
     123              : {
     124            0 :     std::lock_guard<std::mutex> initLock(initLock_);
     125            0 :     isEnableMulQp = initStatus_ == HcclResult::HCCL_SUCCESS && config_ && config_->IsAvailable();
     126            0 :     return HcclResult::HCCL_SUCCESS;
     127            0 : }
     128              : 
     129            0 : static HcclResult DevStrToUint16(const std::string& value, std::uint16_t& count)
     130              : {
     131            0 :     HcclResult result = HcclResult::HCCL_SUCCESS;
     132            0 :     unsigned long tempCount = 0;
     133              :     try {
     134            0 :         if (!value.empty()) {
     135            0 :             std::size_t parsePos = 0;
     136            0 :             tempCount = std::stoul(value, &parsePos, 0);
     137            0 :             if (parsePos != value.size()) {
     138            0 :                 HCCL_ERROR(
     139              :                     "[MulQpInfo][StrToUint16]The string is not a valid unsigned integer, str[%s] pos[%llu]"
     140              :                     " str size[%llu], val[%lu]",
     141              :                     value.c_str(), static_cast<std::uint64_t>(parsePos), static_cast<std::uint64_t>(value.size()),
     142              :                     tempCount);
     143            0 :                 result = HcclResult::HCCL_E_PARA;
     144            0 :             } else if (tempCount <= 0xFFFFU) {
     145            0 :                 count = static_cast<std::uint16_t>(tempCount);
     146              :             } else {
     147            0 :                 HCCL_ERROR(
     148              :                     "[MulQpInfo][StrToUint16]result of stoul is greater than 0xFFFFU, str[%s] base[%d] val[%lu]",
     149              :                     value.c_str(), 0, tempCount);
     150            0 :                 result = HcclResult::HCCL_E_PARA;
     151              :             }
     152              :         }
     153            0 :     } catch (std::invalid_argument& e) {
     154            0 :         HCCL_ERROR(
     155              :             "[MulQpInfo][StrToUint16]stoul invalid arg: %s, str[%s] base[%d] val[%lu]", e.what(), value.c_str(), 0,
     156              :             tempCount);
     157            0 :         result = HcclResult::HCCL_E_PARA;
     158            0 :     } catch (std::out_of_range& e) {
     159            0 :         HCCL_ERROR(
     160              :             "[MulQpInfo][StrToUint16]stoul out of range: %s, str[%s] base[%d] val[%lu]", e.what(), value.c_str(), 0,
     161              :             tempCount);
     162            0 :         result = HcclResult::HCCL_E_PARA;
     163            0 :     } catch (...) {
     164            0 :         HCCL_ERROR("[MulQpInfo][StrToUint16]stoul catch error, str[%s] base[%d] val[%lu]", value.c_str(), 0, tempCount);
     165            0 :         result = HcclResult::HCCL_E_PARA;
     166            0 :     }
     167            0 :     return result;
     168              : };
     169              : 
     170            0 : static HcclResult DevMulPorts(const std::string& value, std::vector<std::uint16_t>& ports)
     171              : {
     172            0 :     HcclResult ret = HcclResult::HCCL_SUCCESS;
     173            0 :     if (!value.empty()) {
     174            0 :         std::uint16_t tempCount = 0;
     175            0 :         constexpr char separator = ',';
     176            0 :         std::size_t pos{0U};
     177            0 :         std::size_t start{0U};
     178            0 :         while ((pos = value.find(separator, start)) != std::string::npos) {
     179            0 :             if (pos == start) {
     180            0 :                 HCCL_ERROR("[MulQpInfo][DevMulPorts]format error, value[%s]", value.c_str());
     181            0 :                 ret = HcclResult::HCCL_E_PARA;
     182            0 :                 break;
     183              :             }
     184            0 :             ret = DevStrToUint16(value.substr(start, pos - start), tempCount);
     185            0 :             if (ret != HcclResult::HCCL_SUCCESS) {
     186            0 :                 return ret;
     187              :             }
     188            0 :             ports.emplace_back(tempCount);
     189            0 :             start = pos + 1U;
     190              :         }
     191            0 :         if (start >= value.size()) {
     192            0 :             HCCL_ERROR("[MulQpInfo][DevMulPorts]format error, value[%s]", value.c_str());
     193            0 :             ret = HcclResult::HCCL_E_NETWORK;
     194              :         }
     195            0 :         (void)ports.emplace_back(std::stoul(value.substr(start), nullptr, 0));
     196              :     }
     197            0 :     return ret;
     198              : }
     199              : 
     200            0 : HcclResult DevCfgMulQpInfoCache::Init()
     201              : {
     202            0 :     std::string modeValue;
     203            0 :     initStatus_ = HrtRaGetHccnCfg(
     204            0 :         static_cast<std::uint32_t>(nicDeployment_), phyId_, HccnCfgKeyT::HCCN_UDP_PORT_MODE, modeValue);
     205            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     206            0 :         return initStatus_;
     207              :     }
     208            0 :     std::string countValue;
     209            0 :     initStatus_ = HrtRaGetHccnCfg(
     210            0 :         static_cast<std::uint32_t>(nicDeployment_), phyId_, HccnCfgKeyT::HCCN_MULTI_QP_COUNT, countValue);
     211            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     212            0 :         return initStatus_;
     213              :     }
     214            0 :     std::uint16_t qpCount{0U};
     215            0 :     initStatus_ = DevStrToUint16(countValue, qpCount);
     216            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     217            0 :         return initStatus_;
     218              :     }
     219            0 :     std::string portValue;
     220            0 :     std::vector<std::uint16_t> qpPorts{};
     221            0 :     initStatus_ = HrtRaGetHccnCfg(
     222            0 :         static_cast<std::uint32_t>(nicDeployment_), phyId_, HccnCfgKeyT::HCCN_MULTI_QP_UDP_PORTS, portValue);
     223            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     224            0 :         return initStatus_;
     225              :     }
     226            0 :     initStatus_ = DevMulPorts(portValue, qpPorts);
     227            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     228            0 :         return initStatus_;
     229              :     }
     230            0 :     const bool isNotConfig = modeValue.empty() && countValue.empty() && portValue.empty();
     231              :     const bool isNumQpConfigSuccess
     232            0 :         = !modeValue.empty() && modeValue == "multi_qp" && qpCount >= 1 && qpPorts.size() == qpCount;
     233            0 :     constexpr std::size_t afterPortStartIndex = 1;
     234            0 :     if (!(isNotConfig || isNumQpConfigSuccess)) { // 对于dev multiQp cfg非正常场景
     235              :         // 合法 portMode 不应在此解析
     236            0 :         if (devCfgPortMode.end()
     237            0 :             != std::find(devCfgPortMode.begin() + afterPortStartIndex, devCfgPortMode.end(), modeValue)) {
     238            0 :             initStatus_ = HcclResult::HCCL_SUCCESS;
     239              :         } else {
     240            0 :             HCCL_ERROR(
     241              :                 "[MulQpInfo][DevCfgMulQpInfoCache][Init]mul qp config invalid, mode[%s] count[%s] ports "
     242              :                 "[%s]",
     243              :                 modeValue.c_str(), countValue.c_str(), portValue.c_str());
     244            0 :             initStatus_ = HcclResult::HCCL_E_INTERNAL;
     245              :         }
     246              :     }
     247            0 :     if (initStatus_ == HcclResult::HCCL_SUCCESS && isNumQpConfigSuccess) {
     248            0 :         cacheInfo_ = qpPorts;
     249              :     }
     250            0 :     return initStatus_;
     251            0 : }
     252              : 
     253            0 : bool DevCfgMulQpInfoCache::IsAvailable() const
     254              : {
     255            0 :     return initStatus_ == HcclResult::HCCL_SUCCESS && !cacheInfo_.empty();
     256              : }
     257              : 
     258            0 : HcclResult DevCfgMulQpInfoCache::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair) const
     259              : {
     260              :     (void)ipPair;
     261            0 :     portNum = cacheInfo_.size();
     262            0 :     return HcclResult::HCCL_SUCCESS;
     263              : }
     264              : 
     265              : HcclResult
     266            0 : DevCfgMulQpInfoCache::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair) const
     267              : {
     268              :     (void)ipPair;
     269            0 :     sourcePorts = cacheInfo_;
     270            0 :     return HcclResult::HCCL_SUCCESS;
     271              : }
     272              : 
     273            0 : DevNslbMulQpInfoCache::DevNslbMulQpInfoCache(const NICDeployment nicDeployment, const std::int32_t phyId)
     274            0 :     : nicDeployment_(nicDeployment),
     275            0 :       phyId_(phyId),
     276            0 :       isEnableNslb_(false)
     277              : {
     278            0 :     SetMulQpInfoFrom(MUL_QP_FROM::MUL_QP_FROM_DEV_NSLB);
     279            0 : }
     280              : 
     281            0 : HcclResult DevNslbMulQpInfoCache::Init()
     282              : {
     283            0 :     std::string modeValue;
     284            0 :     initStatus_ = HrtRaGetHccnCfg(
     285            0 :         static_cast<std::uint32_t>(nicDeployment_), phyId_, HccnCfgKeyT::HCCN_UDP_PORT_MODE, modeValue);
     286            0 :     if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     287            0 :         return initStatus_;
     288              :     }
     289              : 
     290            0 :     const bool isNumQpConfigSuccess = !modeValue.empty() && modeValue == "nslb_dp";
     291            0 :     constexpr std::size_t afterPortStartIndex = 2;
     292            0 :     if (initStatus_ == HcclResult::HCCL_SUCCESS && isNumQpConfigSuccess) {
     293            0 :         isEnableNslb_ = true;
     294            0 :     } else if (
     295            0 :         initStatus_ != HcclResult::HCCL_SUCCESS
     296            0 :         || devCfgPortMode.end()
     297            0 :                == std::find(devCfgPortMode.begin() + afterPortStartIndex, devCfgPortMode.end(), modeValue)) {
     298            0 :         initStatus_ = HcclResult::HCCL_E_INTERNAL;
     299            0 :         isEnableNslb_ = false;
     300            0 :         HCCL_ERROR("[MulQpInfo][DevCfgMulQpInfoCache][Init]mul qp config invalid, mode[%s]", modeValue.c_str());
     301              :     }
     302            0 :     return initStatus_;
     303            0 : }
     304              : 
     305            0 : bool DevNslbMulQpInfoCache::IsAvailable() const { return initStatus_ == HcclResult::HCCL_SUCCESS && isEnableNslb_; }
     306              : 
     307            0 : HcclResult DevNslbMulQpInfoCache::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair) const
     308              : {
     309              :     (void)ipPair;
     310            0 :     portNum = 1;
     311            0 :     return HcclResult::HCCL_SUCCESS;
     312              : }
     313              : 
     314              : HcclResult
     315            0 : DevNslbMulQpInfoCache::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair) const
     316              : {
     317              :     (void)ipPair;
     318            0 :     sourcePorts = MulQpSourcePorts{static_cast<Port>(hcclNslbDp::GetInstance().Getl4SPortId())};
     319            0 :     return HcclResult::HCCL_SUCCESS;
     320              : }
     321              : 
     322            0 : static std::vector<std::string> Split(std::string& s, const std::string& delimiter)
     323              : {
     324            0 :     size_t posStart = 0;
     325            0 :     size_t posEnd = s.find(delimiter, posStart);
     326            0 :     std::vector<std::string> res;
     327            0 :     while (posEnd != std::string::npos) {
     328            0 :         std::string token = s.substr(posStart, posEnd - posStart);
     329            0 :         res.push_back(token);
     330            0 :         posStart = posEnd + delimiter.length();
     331            0 :         posEnd = s.find(delimiter, posStart);
     332            0 :     }
     333            0 :     res.push_back(s.substr(posStart));
     334            0 :     return res;
     335            0 : }
     336              : 
     337            0 : static HcclResult GetSrcPortsFromString(
     338              :     std::string& s, std::vector<std::uint16_t>& srcPorts, std::uint32_t lineCnt, const std::string& lineAvator)
     339              : {
     340            0 :     const std::vector<std::string> strPorts = Split(s, ",");
     341            0 :     srcPorts.resize(strPorts.size(), 0);
     342            0 :     CHK_PRT_RET(
     343              :         strPorts.size() > MULTI_QP_CONFIG_SRC_PORT_NUM_MAX || strPorts.empty(),
     344              :         HCCL_ERROR(
     345              :             "[MulQpInfo][GetSrcPortsFromString][line: %u]config ports num[%u] more than the "
     346              :             "threshold[%u].[%s]",
     347              :             lineCnt, static_cast<unsigned>(strPorts.size()), MULTI_QP_CONFIG_SRC_PORT_NUM_MAX, lineAvator.c_str()),
     348              :         HcclResult::HCCL_E_PARA);
     349              : 
     350            0 :     for (std::uint32_t i = 0; i < strPorts.size(); i++) {
     351              :         // 检查端口号是否为全数字的字符串
     352            0 :         CHK_PRT_RET(
     353              :             strPorts[i].empty() || DevStrToUint16(strPorts[i], srcPorts[i]) != HcclResult::HCCL_SUCCESS,
     354              :             HCCL_ERROR(
     355              :                 "[MulQpInfo][GetSrcPortsFromString][line: %u]src port[%s]"
     356              :                 "should be within the range of[1, %u] and configured as a valid integer.[%s]",
     357              :                 lineCnt, strPorts[i].c_str(), MULTI_QP_CONFIG_SRC_PORT_ID_MAX, lineAvator.c_str()),
     358              :             HcclResult::HCCL_E_PARA);
     359              :     }
     360            0 :     return HcclResult::HCCL_SUCCESS;
     361            0 : }
     362              : 
     363            0 : EnvConfigPathCache::EnvConfigPathCache() { SetMulQpInfoFrom(MUL_QP_FROM::MUL_QP_FROM_ENV_PORT_CONFIG_PATH); }
     364              : 
     365            0 : HcclResult EnvConfigPathCache::Init()
     366              : {
     367            0 :     if (!GetExternalInputQpSrcPortConfigPath().empty()) {
     368            0 :         initStatus_ = LoadMultiQpSrcPortFromFile();
     369            0 :         if (initStatus_ != HcclResult::HCCL_SUCCESS) {
     370            0 :             return initStatus_;
     371              :         }
     372              :     } else {
     373            0 :         initStatus_ = HcclResult::HCCL_SUCCESS;
     374              :     }
     375            0 :     return initStatus_;
     376              : }
     377              : 
     378            0 : bool EnvConfigPathCache::IsAvailable() const { return initStatus_ == HcclResult::HCCL_SUCCESS && !cacheInfo_.empty(); }
     379              : 
     380            0 : HcclResult EnvConfigPathCache::LoadMultiQpSrcPortFromFile()
     381              : {
     382              :     // 读取配置文件
     383            0 :     std::string fileStr = GetExternalInputQpSrcPortConfigPath() + "/MultiQpSrcPort.cfg";
     384            0 :     std::array<char, PATH_MAX> realFile{};
     385            0 :     if (realpath(fileStr.c_str(), realFile.data()) == nullptr) {
     386            0 :         RPT_INPUT_ERR(
     387              :             true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     388              :             std::vector<std::string>({fileStr, "config file path", "valid absolute path"}));
     389            0 :         HCCL_ERROR(
     390              :             "[%s][%s]file[%s] path invalid.", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(),
     391              :             fileStr.c_str());
     392            0 :         return HcclResult::HCCL_E_PARA;
     393              :     }
     394              : 
     395            0 :     std::ifstream inFile(fileStr.c_str(), std::ifstream::in);
     396            0 :     if (!inFile) {
     397            0 :         RPT_INPUT_ERR(
     398              :             true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     399              :             std::vector<std::string>({fileStr, "config file", "file exists and readable"}));
     400            0 :         HCCL_ERROR(
     401              :             "[%s][%s]open config file[%s] failed.", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(),
     402              :             fileStr.c_str());
     403            0 :         return HcclResult::HCCL_E_PARA;
     404              :     }
     405            0 :     HCCL_INFO(
     406              :         "[%s][%s]open config file[%s] success.", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(),
     407              :         fileStr.c_str());
     408              : 
     409              :     // 逐行解析配置文件
     410            0 :     std::uint32_t lineCnt = 1;
     411            0 :     std::string line;
     412            0 :     while (std::getline(inFile, line)) {
     413            0 :         std::string lineAvator = line; // 每行内容的快照, 用于dfx
     414              :         // 去除空格和tab
     415            0 :         line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
     416            0 :         line.erase(std::remove(line.begin(), line.end(), '\t'), line.end());
     417              : 
     418              :         // 去除注释
     419            0 :         std::string lineInfo = Split(line, "#")[0]; // 只保留#号前的内容
     420            0 :         if (lineInfo.empty()) {
     421            0 :             HCCL_DEBUG(
     422              :                 "[EnvConfigPathCache][LoadMultiQpSrcPortFromFile][line: %u]comment line, do not parse.[%s]", lineCnt,
     423              :                 lineAvator.c_str());
     424            0 :             lineCnt++;
     425            0 :             continue;
     426              :         }
     427              : 
     428              :         // 切分字符串, 检查配置格式
     429            0 :         std::vector<std::string> strIpPort = Split(lineInfo, "=");
     430            0 :         if (strIpPort.size() != MULTI_QP_CONFIG_IP_NUM) {
     431            0 :             const std::string formattedExpect = "[line: " + std::to_string(lineCnt)
     432            0 :                                                 + "] Expected format: 'srcIPN,dstIPN=srcPort0,srcPort1,...,srcPortN'";
     433            0 :             RPT_INPUT_ERR(
     434              :                 true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     435              :                 std::vector<std::string>({lineInfo, "config line format", formattedExpect}));
     436            0 :             HCCL_ERROR(
     437              :                 "[%s][%s] %s Config content[%s]", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(),
     438              :                 formattedExpect.c_str(), lineAvator.c_str());
     439            0 :             inFile.close();
     440            0 :             return HcclResult::HCCL_E_PARA;
     441            0 :         }
     442              : 
     443              :         // 解析ip对
     444            0 :         std::string ipPair;
     445            0 :         auto ret = GetIpPairFromString(strIpPort[0], ipPair, lineCnt, lineAvator);
     446            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
     447            0 :             RPT_INPUT_ERR(
     448              :                 true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     449              :                 std::vector<std::string>({strIpPort[0], "IP pair", "valid IPv4 or IPv6 address"}));
     450            0 :             HCCL_ERROR(
     451              :                 "[%s][%s] %s", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(), "IP format error");
     452            0 :             inFile.close();
     453            0 :             return ret;
     454              :         }
     455              : 
     456              :         // 解析源端口号
     457            0 :         std::vector<std::uint16_t> srcPorts;
     458            0 :         ret = GetSrcPortsFromString(strIpPort[1], srcPorts, lineCnt, lineAvator);
     459            0 :         if (ret != HcclResult::HCCL_SUCCESS) {
     460            0 :             RPT_INPUT_ERR(
     461              :                 true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     462              :                 std::vector<std::string>({strIpPort[1], "Source Ports", "comma-separated list of valid ports"}));
     463            0 :             HCCL_ERROR(
     464              :                 "[%s][%s] %s", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_ENV_CONFIG.c_str(), "port format error");
     465            0 :             inFile.close();
     466            0 :             return ret;
     467              :         }
     468              : 
     469              :         // 配置源端口号
     470            0 :         if (cacheInfo_.find(ipPair) != cacheInfo_.end()) {
     471              :             const std::string DUPLICATE_IPPAIR_ERROR
     472            0 :                 = "[line: " + std::to_string(lineCnt) + "] ip pair: " + ipPair + " has existed";
     473            0 :             RPT_INPUT_ERR(
     474              :                 true, "EI0001", std::vector<std::string>({"value", "env", "expect"}),
     475              :                 std::vector<std::string>({ipPair, "IP pair Key", "unique IP pair without duplicates"}));
     476            0 :             HCCL_ERROR(
     477              :                 "[%s][%s][line: %u]ip pair[%s] has existed.[%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
     478              :                 LOG_KEYWORDS_ENV_CONFIG.c_str(), lineCnt, ipPair.c_str(), lineAvator.c_str());
     479            0 :             inFile.close();
     480            0 :             return HcclResult::HCCL_E_PARA;
     481            0 :         }
     482            0 :         cacheInfo_[ipPair] = srcPorts;
     483              : 
     484              :         // 判断文件行数是否超过上限
     485            0 :         if (lineCnt >= MULTI_QP_CONFIG_FILE_LINE_MAX) {
     486            0 :             HCCL_RUN_INFO("[EnvConfigPathCache][LoadMultiQpSrcPortFromFile]config file is too large.");
     487            0 :             break;
     488              :         }
     489            0 :         lineCnt++;
     490            0 :     }
     491            0 :     inFile.close();
     492            0 :     return HcclResult::HCCL_SUCCESS;
     493            0 : }
     494              : 
     495            0 : HcclResult EnvConfigPathCache::GetIpPairFromString(
     496              :     std::string& s, std::string& ipPair, const std::uint32_t lineCnt, const std::string& lineAvator)
     497              : {
     498            0 :     std::vector<std::string> strIps = Split(s, ",");
     499            0 :     CHK_PRT_RET(
     500              :         strIps.size() != MULTI_QP_CONFIG_IP_NUM,
     501              :         HCCL_ERROR(
     502              :             "[EnvConfigPathCache][GetIpPairFromString][line: %u]invalid Ip format.[%s]", lineCnt, lineAvator.c_str()),
     503              :         HcclResult::HCCL_E_PARA);
     504              : 
     505            0 :     HcclIpAddress srcIpAddr{};
     506              :     // 解析源ip
     507            0 :     auto ret = srcIpAddr.SetReadableAddress(strIps[0]);
     508            0 :     CHK_PRT_RET(
     509              :         ret != HcclResult::HCCL_SUCCESS,
     510              :         HCCL_ERROR(
     511              :             "[EnvConfigPathCache][GetIpPairFromString][line: %u]srcIp is an invalid format.[%s]", lineCnt,
     512              :             lineAvator.c_str()),
     513              :         HcclResult::HCCL_E_PARA);
     514              : 
     515              :     // 解析目的ip
     516            0 :     HcclIpAddress dstIpAddr{};
     517            0 :     ret = dstIpAddr.SetReadableAddress(strIps[1]);
     518            0 :     CHK_PRT_RET(
     519              :         ret != HcclResult::HCCL_SUCCESS,
     520              :         HCCL_ERROR(
     521              :             "[EnvConfigPathCache][GetIpPairFromString][line: %u]dstIp is an invalid format.[%s]", lineCnt,
     522              :             lineAvator.c_str()),
     523              :         HcclResult::HCCL_E_PARA);
     524              : 
     525              :     // 记录ip对
     526            0 :     ipPair = s;
     527            0 :     return HcclResult::HCCL_SUCCESS;
     528            0 : }
     529              : 
     530            0 : HcclResult EnvConfigPathCache::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair) const
     531              : {
     532            0 :     const std::string srcIp = std::string(ipPair.first.GetReadableIP());
     533            0 :     const std::string dstIp = std::string(ipPair.second.GetReadableIP());
     534              :     // 匹配sip和dip
     535            0 :     std::string pair = srcIp + std::string(",") + dstIp;
     536            0 :     auto iter = cacheInfo_.find(pair);
     537            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), portNum = iter->second.size(), HcclResult::HCCL_SUCCESS);
     538              :     // 匹配dip
     539            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     540            0 :         pair = std::string("0.0.0.0,") + dstIp;
     541              :     } else {
     542            0 :         pair = std::string("::/128,") + dstIp;
     543              :     }
     544            0 :     iter = cacheInfo_.find(pair);
     545            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), portNum = iter->second.size(), HcclResult::HCCL_SUCCESS);
     546              :     // 匹配sip
     547            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     548            0 :         pair = srcIp + std::string(",0.0.0.0");
     549              :     } else {
     550            0 :         pair = srcIp + std::string(",::/128");
     551              :     }
     552            0 :     iter = cacheInfo_.find(pair);
     553            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), portNum = iter->second.size(), HcclResult::HCCL_SUCCESS);
     554              :     // 通配
     555            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     556            0 :         pair = std::string("0.0.0.0,0.0.0.0");
     557              :     } else {
     558            0 :         pair = std::string("::/128,::/128");
     559              :     }
     560            0 :     iter = cacheInfo_.find(pair);
     561            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), portNum = iter->second.size(), HcclResult::HCCL_SUCCESS);
     562            0 :     portNum = 0;
     563            0 :     return HcclResult::HCCL_SUCCESS;
     564            0 : }
     565              : 
     566            0 : HcclResult EnvConfigPathCache::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair) const
     567              : {
     568            0 :     const std::string srcIp = std::string(ipPair.first.GetReadableIP());
     569            0 :     const std::string dstIp = std::string(ipPair.second.GetReadableIP());
     570              :     // 匹配sip和dip
     571            0 :     std::string pair = srcIp + std::string(",") + dstIp;
     572            0 :     auto iter = cacheInfo_.find(pair);
     573            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), sourcePorts = iter->second, HcclResult::HCCL_SUCCESS);
     574              :     // 匹配dip
     575            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     576            0 :         pair = std::string("0.0.0.0,") + dstIp;
     577              :     } else {
     578            0 :         pair = std::string("::/128,") + dstIp;
     579              :     }
     580            0 :     iter = cacheInfo_.find(pair);
     581            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), sourcePorts = iter->second, HcclResult::HCCL_SUCCESS);
     582              :     // 匹配sip
     583            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     584            0 :         pair = srcIp + std::string(",0.0.0.0");
     585              :     } else {
     586            0 :         pair = srcIp + std::string(",::/128");
     587              :     }
     588            0 :     iter = cacheInfo_.find(pair);
     589            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), sourcePorts = iter->second, HcclResult::HCCL_SUCCESS);
     590              :     // 通配
     591            0 :     if (ipPair.first.GetFamily() == AF_INET) {
     592            0 :         pair = std::string("0.0.0.0,0.0.0.0");
     593              :     } else {
     594            0 :         pair = std::string("::/128,::/128");
     595              :     }
     596            0 :     iter = cacheInfo_.find(pair);
     597            0 :     CHK_PRT_RET(iter != cacheInfo_.end(), sourcePorts = iter->second, HcclResult::HCCL_SUCCESS);
     598            0 :     sourcePorts.clear();
     599            0 :     return HcclResult::HCCL_SUCCESS;
     600            0 : }
     601              : 
     602            0 : EnvPerConnectionQpInfoCache::EnvPerConnectionQpInfoCache() : cacheInfo_(0), isSetEnvPerConnectionQp_(false)
     603              : {
     604            0 :     SetMulQpInfoFrom(MUL_QP_FROM::MUL_QP_FROM_ENV_PER_CONNECTION);
     605            0 : }
     606              : 
     607            0 : HcclResult EnvPerConnectionQpInfoCache::Init()
     608              : {
     609            0 :     char* mmSysGetEnvValue = nullptr;
     610            0 :     MM_SYS_GET_ENV(MM_ENV_HCCL_RDMA_QPS_PER_CONNECTION, mmSysGetEnvValue);
     611            0 :     std::string rdmaQpsPerConnectionEnv = (mmSysGetEnvValue != nullptr) ? mmSysGetEnvValue : "EmptyString";
     612            0 :     if (rdmaQpsPerConnectionEnv == "EmptyString") {
     613            0 :         return HCCL_SUCCESS;
     614              :     }
     615            0 :     cacheInfo_ = GetExternalInputQpsPerConnection();
     616            0 :     isSetEnvPerConnectionQp_ = true;
     617            0 :     initStatus_ = HcclResult::HCCL_SUCCESS;
     618            0 :     return initStatus_;
     619            0 : }
     620              : 
     621            0 : bool EnvPerConnectionQpInfoCache::IsAvailable() const { return isSetEnvPerConnectionQp_ && cacheInfo_ >= 1; }
     622              : 
     623            0 : HcclResult EnvPerConnectionQpInfoCache::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair) const
     624              : {
     625              :     (void)ipPair;
     626            0 :     portNum = cacheInfo_;
     627            0 :     return HcclResult::HCCL_SUCCESS;
     628              : }
     629              : 
     630              : HcclResult
     631            0 : EnvPerConnectionQpInfoCache::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair) const
     632              : {
     633              :     (void)ipPair;
     634            0 :     sourcePorts.resize(cacheInfo_, 0);
     635            0 :     return HcclResult::HCCL_SUCCESS;
     636              : }
     637              : 
     638            0 : MulQpInfo::~MulQpInfo()
     639              : {
     640            0 :     if (config_) {
     641            0 :         config_.reset();
     642              :     }
     643            0 : }
     644              : 
     645            0 : HcclResult MulQpInfo::GetMulQpFromType(MUL_QP_FROM& type)
     646              : {
     647            0 :     std::lock_guard<std::mutex> initLock(initLock_);
     648            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     649            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     650              :     }
     651            0 :     CHK_SMART_PTR_NULL(config_);
     652            0 :     type = config_->MulQpInfoFrom();
     653            0 :     return HcclResult::HCCL_SUCCESS;
     654            0 : }
     655              : 
     656            0 : HcclResult MulQpInfo::GetPortsNumByIpPair(PortNum& portNum, const KeyPair& ipPair)
     657              : {
     658            0 :     std::lock_guard<std::mutex> initLock(initLock_);
     659            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     660            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     661              :     }
     662            0 :     CHK_SMART_PTR_NULL(config_);
     663            0 :     return config_->GetPortsNumByIpPair(portNum, ipPair);
     664            0 : }
     665              : 
     666            0 : HcclResult MulQpInfo::GetSpecialSourcePortsByIpPair(MulQpSourcePorts& sourcePorts, const KeyPair& ipPair)
     667              : {
     668            0 :     std::lock_guard<std::mutex> initLock(initLock_);
     669            0 :     if (GetWorkflowMode() != HcclWorkflowMode::HCCL_WORKFLOW_MODE_OP_BASE) {
     670            0 :         return HcclResult::HCCL_E_NOT_SUPPORT;
     671              :     }
     672            0 :     CHK_SMART_PTR_NULL(config_);
     673            0 :     return config_->GetSpecialSourcePortsByIpPair(sourcePorts, ipPair);
     674            0 : }
     675              : } // namespace hccl
        

Generated by: LCOV version 2.0-1