LCOV - code coverage report
Current view: top level - legacy/ascend910/framework/common/src/topo - topoinfo_ranktableConcise.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 17.3 % 497 86
Test Date: 2026-08-18 17:47:01 Functions: 25.0 % 32 8

            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 "topoinfo_ranktableConcise.h"
      12              : #include <string>
      13              : #include <fstream>
      14              : #include <algorithm>
      15              : #include <map>
      16              : #include <vector>
      17              : #include <unistd.h>
      18              : #include <chrono>
      19              : #include <iostream>
      20              : #include <arpa/inet.h>
      21              : 
      22              : #include "externalinput.h"
      23              : #include "log.h"
      24              : // ltm指定config路径
      25              : #include "common/src/config.h"
      26              : #include "workflow_pub.h"
      27              : #include "device_capacity.h"
      28              : 
      29              : using namespace std;
      30              : using namespace hccl;
      31              : 
      32              : constexpr u32 MAX_PORT_NUMBER = 65535;
      33              : constexpr u32 HCCL_SOCKET_PORT_RANGE_AUTO = 0;
      34              : constexpr u32 HCCL_DEVICE_PORT_DEFAULT = 16666;
      35              : constexpr u32 HCCL_BACKUP_DEVICE_PORT_DEFAULT = 16667;
      36              : 
      37            5 : TopoinfoRanktableConcise::TopoinfoRanktableConcise(const std::string& rankTableM, const std::string& identify)
      38              :     : TopoInfoRanktableParser(rankTableM, identify),
      39            5 :       isInterSuperPodRetryEnable_(GetExternalInputInterSuperPodRetryEnable())
      40            5 : {}
      41              : 
      42            5 : TopoinfoRanktableConcise::~TopoinfoRanktableConcise() { devIp2ObjIndex_.clear(); }
      43              : 
      44            0 : HcclResult TopoinfoRanktableConcise::Init()
      45              : {
      46            0 :     CHK_RET(LoadRankTableString(rankTableFile_));
      47            0 :     CHK_RET(ParserClusterInfo(params_, rankTable_));
      48            0 :     return HCCL_SUCCESS;
      49              : }
      50              : 
      51            0 : HcclResult TopoinfoRanktableConcise::GetClusterInfo(RankTable_t& clusterInfo)
      52              : {
      53            0 :     clusterInfo.nicDeploy = rankTable_.nicDeploy;
      54            0 :     clusterInfo.deviceNum = rankTable_.deviceNum;
      55            0 :     clusterInfo.serverNum = rankTable_.serverNum;
      56            0 :     clusterInfo.superPodNum = rankTable_.superPodNum;
      57            0 :     clusterInfo.rankNum = rankTable_.rankNum;
      58            0 :     clusterInfo.rankList = rankTable_.rankList;
      59            0 :     clusterInfo.serverList = rankTable_.serverList;
      60            0 :     return HCCL_SUCCESS;
      61              : }
      62              : 
      63            0 : HcclResult TopoinfoRanktableConcise::GetSelfClusterInfo(HcclCommParams& params)
      64              : {
      65              :     // 获取芯片类型信息
      66            0 :     params.deviceType = params_.deviceType;
      67            0 :     params.rank = params_.rank;
      68            0 :     params.userRank = params_.rank;
      69            0 :     params.logicDevId = params_.logicDevId;
      70            0 :     params.totalRanks = params_.totalRanks;
      71            0 :     params.serverId = params_.serverId;
      72            0 :     params.commPortConfig.devPortSwitchOn = params_.commPortConfig.devPortSwitchOn;
      73            0 :     return HCCL_SUCCESS;
      74              : }
      75              : 
      76            0 : HcclResult TopoinfoRanktableConcise::GetClusterInfo(hccl::HcclCommParams& params, hccl::RankTable_t& rankTable)
      77              : {
      78            0 :     CHK_RET(GetClusterInfo(rankTable));
      79            0 :     CHK_RET(GetSelfClusterInfo(params));
      80            0 :     return HCCL_SUCCESS;
      81              : }
      82              : 
      83            0 : HcclResult TopoinfoRanktableConcise::SetIsInterSuperPodRetryEnable(bool isRetryEnable)
      84              : {
      85            0 :     isInterSuperPodRetryEnable_ = isRetryEnable;
      86            0 :     return HCCL_SUCCESS;
      87              : }
      88              : 
      89            0 : void TopoinfoRanktableConcise::DetectNicDepoly(RankTable_t& rankTable)
      90              : {
      91              :     // 只有当hostIp有效而且deviceIp无效时,才使用HOST侧网卡部署,目前策略要求集群中所有卡的deploy
      92              :     // 形式一致,所以取ranklist[0]的方式即可
      93            0 :     auto isIpInvalid = [](const std::vector<HcclIpAddress>& deviceIp) -> bool {
      94            0 :         for (auto& ip : deviceIp) {
      95            0 :             if (!ip.IsInvalid()) { // 遍历vector中所有的IP,只要有任意一个IP有效就认为是有效的,那么返回false
      96            0 :                 return false;
      97              :             }
      98              :         }
      99            0 :         return true;
     100              :     };
     101              : 
     102            0 :     rankTable.nicDeploy = (!rankTable.rankList.empty() && !rankTable.rankList[0].hostIp.IsInvalid()
     103            0 :                            && isIpInvalid(rankTable.rankList[0].deviceInfo.deviceIp)) ?
     104              :                               NICDeployment::NIC_DEPLOYMENT_HOST :
     105              :                               NICDeployment::NIC_DEPLOYMENT_DEVICE;
     106            0 : }
     107              : 
     108            0 : HcclResult TopoinfoRanktableConcise::ParserClusterInfo(hccl::HcclCommParams& params, hccl::RankTable_t& rankTable)
     109              : {
     110            0 :     if (!IsTaskNumCalMode()) {
     111            0 :         CHK_RET(hrtGetDeviceType(params.deviceType));
     112              :     }
     113              :     // 获取ranktable info信息
     114            0 :     CHK_RET(GetRanktableInfo(rankTable));
     115            0 :     for (auto& rankInfo : rankTable.rankList) {
     116            0 :         HCCL_DEBUG(
     117              :             "ParserClusterInfo serverId %s, rankId %u, superDeviceId 0x%x, superPodId %s", rankInfo.serverId.c_str(),
     118              :             rankInfo.rankId, rankInfo.superDeviceId, rankInfo.superPodId.c_str());
     119              :     }
     120              : 
     121            0 :     if (IsTaskNumCalMode()) {
     122            0 :         HCCL_INFO("[ParserClusterInfo] get task num cal mode.");
     123            0 :         return HCCL_SUCCESS;
     124              :     }
     125              : 
     126            0 :     std::sort(
     127            0 :         rankTable.rankList.begin(), rankTable.rankList.end(), [&](const RankInfo_t& a, const RankInfo_t& b) -> bool {
     128            0 :             return a.rankId < b.rankId;
     129              :         });
     130              : 
     131            0 :     u32 rankId = INVALID_VALUE_RANKID;
     132            0 :     if (IsAllDigit(identify_.c_str()) != HCCL_SUCCESS
     133            0 :         || SalStrToULong(identify_, HCCL_BASE_DECIMAL, rankId) != HCCL_SUCCESS) {
     134            0 :         RPT_INPUT_ERR(
     135              :             true, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}),
     136              :             std::vector<std::string>(
     137              :                 {"HcclCommInitRootInfo", identify_.c_str(), "RANK_ID", "a non-negative decimal number"}));
     138            0 :         HCCL_ERROR(
     139              :             "[%s][%s]errNo[0x%016llx] rank_id[%s] is invalid", LOG_KEYWORDS_INIT_GROUP.c_str(),
     140              :             LOG_KEYWORDS_INVALID_ARGUMENT.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), identify_.c_str());
     141            0 :         return HCCL_E_PARA;
     142              :     }
     143              : 
     144            0 :     if (rankId >= rankTable.rankList.size()) {
     145            0 :         RPT_ENV_ERR(
     146              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     147              :             std::vector<std::string>(
     148              :                 {std::to_string(rankId), "rank_id", std::to_string(rankTable.rankList[rankId].rankId)}));
     149            0 :         HCCL_ERROR(
     150              :             "[%s][%s]rankId[%u] is invalid", LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str(),
     151              :             rankId);
     152            0 :         return HCCL_E_PARA;
     153              :     }
     154              : 
     155            0 :     RPT_ENV_ERR(
     156              :         rankId != rankTable.rankList[rankId].rankId, "EI0014",
     157              :         std::vector<std::string>({"value", "variable", "expect"}),
     158              :         std::vector<std::string>(
     159              :             {std::to_string(rankId), "rank_id", std::to_string(rankTable.rankList[rankId].rankId)}));
     160            0 :     CHK_PRT_RET(
     161              :         rankId != rankTable.rankList[rankId].rankId,
     162              :         HCCL_ERROR(
     163              :             "[%s][%s]check rankList[%u] rankId[%u] failed", LOG_KEYWORDS_INIT_GROUP.c_str(),
     164              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), rankId, rankTable.rankList[rankId].rankId),
     165              :         HCCL_E_UNAVAIL);
     166              : 
     167            0 :     if (rankId < rankTable.rankList.size()
     168            0 :         && rankTable.rankList[rankId].deviceInfo.nicDeploy == NICDeployment::NIC_DEPLOYMENT_HOST) {
     169            0 :         rankTable.nicDeploy = NICDeployment::NIC_DEPLOYMENT_HOST;
     170            0 :         SetHostUseDevNicFlag(false);
     171              :     } else {
     172            0 :         DetectNicDepoly(rankTable);
     173              :     }
     174            0 :     CHK_RET(CheckNicDeployConsistence(rankTable, rankTable.nicDeploy));
     175              : 
     176            0 :     u32 devId = rankTable.rankList[rankId].deviceInfo.devicePhyId;
     177            0 :     CHK_RET(hrtGetDevice(&params.logicDevId));
     178              : 
     179            0 :     u32 phyId = 0;
     180            0 :     CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<u32>(params.logicDevId), phyId));
     181            0 :     RPT_ENV_ERR(
     182              :         phyId != static_cast<u32>(devId), "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     183              :         std::vector<std::string>({std::to_string(phyId), "devicePhyId", std::to_string(static_cast<u32>(devId))}));
     184            0 :     CHK_PRT_RET(
     185              :         phyId != static_cast<u32>(devId),
     186              :         HCCL_ERROR(
     187              :             "[%s][%s]ranktable config devId[%d],but local devId[%u]", LOG_KEYWORDS_INIT_GROUP.c_str(),
     188              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), devId, phyId),
     189              :         HCCL_E_UNAVAIL);
     190              : 
     191            0 :     params.rank = rankId;
     192            0 :     params.serverId = rankTable.rankList[rankId].serverId;
     193            0 :     params.totalRanks = rankTable.rankNum;
     194              : 
     195            0 :     return HCCL_SUCCESS;
     196            0 : }
     197              : 
     198            0 : HcclResult TopoinfoRanktableConcise::CheckNicDeployConsistence(RankTable_t& clusterInfo, NICDeployment deploy) const
     199              : {
     200            0 :     CHK_PRT_RET(
     201              :         clusterInfo.rankList.size() == 0, HCCL_DEBUG("rank list size is 0, skip nic deeply check."), HCCL_SUCCESS);
     202              : 
     203            0 :     for (auto& it : clusterInfo.rankList) {
     204            0 :         CHK_PRT_RET(
     205              :             // 因为部分场景下,网卡部署在device侧,但是允许deviceIP无效,所以不检测该场景,只检测使用HOST但是hostIp无效
     206              :             (deploy == NICDeployment::NIC_DEPLOYMENT_HOST && it.hostIp.IsInvalid()),
     207              :             HCCL_ERROR(
     208              :                 "[Get][RanktableInfo]errNo"
     209              :                 "[0x%016llx] hostIp config bettewn ranks is different.",
     210              :                 HCOM_ERROR_CODE(HCCL_E_PARA)),
     211              :             HCCL_E_PARA);
     212              :     }
     213            0 :     return HCCL_SUCCESS;
     214              : }
     215              : 
     216            0 : HcclResult TopoinfoRanktableConcise::GetRanktableInfo(RankTable_t& clusterInfo)
     217              : {
     218              :     // server_list
     219            0 :     CHK_RET(GetServerList(fileContent_, clusterInfo));
     220            0 :     CHK_RET(GetSuperPodList(fileContent_, clusterInfo));
     221            0 :     CHK_RET(GetDevNum(clusterInfo.rankList, clusterInfo.deviceNum));
     222            0 :     clusterInfo.rankNum = clusterInfo.rankList.size();
     223            0 :     return HCCL_SUCCESS;
     224              : }
     225              : 
     226            0 : HcclResult TopoinfoRanktableConcise::GetServerList(const nlohmann::json& obj, RankTable_t& clusterInfo)
     227              : {
     228            0 :     clusterInfo.serverList.clear();
     229            0 :     nlohmann::json serverList;
     230            0 :     CHK_RET(GetJsonProperty(obj, "server_list", serverList, false));
     231            0 :     HCCL_DEBUG("[%s.json] -> server_list: size:[%zu]", fileName_.c_str(), serverList.size());
     232              : 
     233              :     // 获取serverCount并校验
     234            0 :     std::string serverCount;
     235            0 :     HcclResult ret = GetJsonProperty(obj, "server_count", serverCount, true);
     236            0 :     if (ret == HCCL_SUCCESS) {
     237            0 :         HCCL_DEBUG("[%s.json] -> group_count: [%s]", fileName_.c_str(), serverCount.c_str());
     238            0 :         CHK_RET(SalStrToULong(serverCount, HCCL_BASE_DECIMAL, clusterInfo.serverNum));
     239              : 
     240              :         // 校验serverCount
     241            0 :         if (serverList.size() != clusterInfo.serverNum) {
     242            0 :             RPT_INPUT_ERR(
     243              :                 true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     244              :                 std::vector<std::string>({serverCount, "server_count", std::to_string(serverList.size())}));
     245            0 :             HCCL_ERROR(
     246              :                 "[%s][%s]errNo[0x%016llx] serverList size[%zu] neq server num[%u]", LOG_KEYWORDS_INIT_GROUP.c_str(),
     247              :                 LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), serverList.size(),
     248              :                 clusterInfo.serverNum);
     249            0 :             return HCCL_E_PARA;
     250              :         }
     251            0 :     } else if (ret == HCCL_E_NOT_FOUND) {
     252            0 :         clusterInfo.serverNum = serverList.size();
     253            0 :         HCCL_WARNING(
     254              :             "[Get][ServerList]The 'server_count' in ranktable is not found, "
     255              :             "set server_count to server_list size[%u]",
     256              :             serverList.size());
     257              :     } else {
     258            0 :         HCCL_ERROR("[Get][ServerList]get server_count error, ret[%d]", ret);
     259            0 :         return ret;
     260              :     }
     261            0 :     if (clusterInfo.serverNum == 0) {
     262            0 :         RPT_INPUT_ERR(
     263              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     264              :             std::vector<std::string>({std::to_string(clusterInfo.serverNum), "server_count", "is a positive integer"}));
     265            0 :         HCCL_ERROR(
     266              :             "[%s][%s]errNo[0x%016llx] server num is zero", LOG_KEYWORDS_INIT_GROUP.c_str(),
     267              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA));
     268            0 :         return HCCL_E_PARA;
     269              :     }
     270            0 :     HCCL_DEBUG("[Get][ServerList]serverNum is [%u]", clusterInfo.serverNum);
     271              : 
     272            0 :     for (u32 index = 0; index < serverList.size(); index++) {
     273              :         // get single server info
     274            0 :         CHK_RET(GetSingleServer(serverList, index, clusterInfo));
     275              :     }
     276              : 
     277            0 :     for (u32 index = 0; index < clusterInfo.rankList.size(); index++) {
     278            0 :         CHK_RET(VerifyBackupDeviceIpAndPort(clusterInfo.rankList, index));
     279              :     }
     280              :     // 获取device
     281            0 :     return HCCL_SUCCESS;
     282            0 : }
     283              : 
     284              : HcclResult
     285            1 : TopoinfoRanktableConcise::GetSingleServer(const nlohmann::json& serverListObj, u32 objIndex, RankTable_t& clusterInfo)
     286              : {
     287              :     HcclResult ret;
     288            1 :     std::string serverId;
     289            1 :     CHK_RET(GetJsonArrayMemberProperty(serverListObj, objIndex, "server_id", serverId, false));
     290            1 :     if (serverId.empty()) {
     291            0 :         HCCL_ERROR(
     292              :             "[Get][JsonArrayMemberProperty]errNo[0x%016llx] serverId[%s] is empty", HCOM_ERROR_CODE(HCCL_E_PARA),
     293              :             serverId.c_str());
     294            0 :         return HCCL_E_PARA;
     295              :     }
     296              : 
     297            1 :     if (serverId.length() > SERVERID_MAX_LENGTH) {
     298            1 :         HCCL_ERROR(
     299              :             "[Get][GetSingleServer]errNo[0x%016llx] serverId[%s] length[%u] is more than %u",
     300              :             HCOM_ERROR_CODE(HCCL_E_PARA), serverId.c_str(), serverId.length(), SERVERID_MAX_LENGTH);
     301            1 :         return HCCL_E_PARA;
     302              :     }
     303              : 
     304              :     // 将serverId添加到资源池,内部会进行IP地址校验,如果资源池中有serverId,则报错
     305            0 :     CHK_RET(CheckUniqueAndInsertPool(
     306              :         JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID, serverId, JsonCheckOpType::CHECK_OP_TYPE_INSERT));
     307            0 :     HCCL_DEBUG("server id[%u]:[%s]", objIndex, serverId.c_str());
     308              : 
     309              :     u32 serverIdx;
     310            0 :     GenerateServerIdx(serverId, serverIdx);
     311            0 :     HCCL_DEBUG("server id[%u]:[%s], serverIdx[%u]", objIndex, serverId.c_str(), serverIdx);
     312            0 :     std::string hostNicIp;
     313            0 :     HcclIpAddress hostIp;
     314            0 :     ret = GetJsonArrayMemberProperty(serverListObj, objIndex, "host_ip", hostNicIp, true);
     315            0 :     CHK_PRT_RET(
     316              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND, HCCL_ERROR("[Get][SingleServer]get host ip error"), ret);
     317            0 :     HCCL_DEBUG("[%s.json] -> host_ip: [%s]. ret[%u]", fileName_.c_str(), hostNicIp.c_str(), ret);
     318            0 :     if (ret != HCCL_E_NOT_FOUND) {
     319            0 :         CHK_RET(ConvertIpAddress(hostNicIp, hostIp));
     320              :     }
     321              : 
     322              :     // 处理ranklist
     323            0 :     ret = GetDeviceList(serverListObj, objIndex, clusterInfo, serverId, serverIdx, hostIp);
     324            0 :     CHK_PRT_RET(
     325              :         ret != HCCL_SUCCESS, HCCL_ERROR("[Get][SingleServer]get dev list error:serverId[%s]", serverId.c_str()), ret);
     326              : 
     327            0 :     return HCCL_SUCCESS;
     328            1 : }
     329              : 
     330            0 : HcclResult TopoinfoRanktableConcise::GetDeviceList(
     331              :     const nlohmann::json& serverListObj, u32 objIndex, RankTable_t& clusterInfo, std::string& serverId, u32& serverIdx,
     332              :     HcclIpAddress& hostIp)
     333              : {
     334            0 :     HCCL_DEBUG("Get GetDeviceList[%u]: serverId[%s]", objIndex, serverId.c_str());
     335              : 
     336            0 :     nlohmann::json deviceList;
     337            0 :     CHK_RET(GetJsonArrayMemberProperty(serverListObj, objIndex, "device", deviceList, false));
     338              : 
     339            0 :     HCCL_DEBUG("[%s.json] -> device_list: size:%zu", fileName_.c_str(), deviceList.size());
     340              : 
     341            0 :     CHK_PRT_RET(deviceList.size() == 0, HCCL_ERROR("[Get][DeviceList]deviceList size is zero"), HCCL_E_PARA);
     342              : 
     343            0 :     for (u32 index = 0; index < deviceList.size(); index++) {
     344              :         // get single server info
     345            0 :         CHK_RET(GetSingleDevice(deviceList, index, clusterInfo, serverId, serverIdx, hostIp));
     346              :     }
     347              : 
     348              :     // 检查devip的数目是否一致
     349            0 :     u32 rankListSize = clusterInfo.rankList.size();
     350            0 :     CHK_PRT_RET(rankListSize == 0, HCCL_ERROR("[Get][DeviceList]get ranklist is zero"), HCCL_E_PARA);
     351              : 
     352            0 :     u32 checkDeviceIpSize = 0;
     353            0 :     for (u32 index = 0; index < clusterInfo.rankList.size(); index++) {
     354            0 :         if (index == 0) {
     355            0 :             checkDeviceIpSize = clusterInfo.rankList[0].deviceInfo.deviceIp.size();
     356              :         }
     357            0 :         if (clusterInfo.rankList[index].deviceInfo.deviceIp.size() != checkDeviceIpSize) {
     358            0 :             HCCL_ERROR(
     359              :                 "[Get][DeviceList]device[%u] size[%u] neq first device size[%u] error", index,
     360              :                 clusterInfo.rankList[index].deviceInfo.deviceIp.size(), checkDeviceIpSize);
     361            0 :             return HCCL_E_PARA;
     362              :         }
     363              :     }
     364              : 
     365            0 :     return HCCL_SUCCESS;
     366            0 : }
     367              : 
     368              : HcclResult
     369            0 : TopoinfoRanktableConcise::GetSingleNicInfo(const nlohmann::json& serverListObj, u32 objIndex, RankInfo_t& rankinfo)
     370              : {
     371            0 :     std::string netPosition;
     372            0 :     rankinfo.deviceInfo.nicDeploy = NICDeployment::NIC_DEPLOYMENT_DEVICE;
     373            0 :     HcclResult ret = GetJsonArrayMemberProperty(serverListObj, objIndex, "net_position", netPosition, true);
     374            0 :     CHK_PRT_RET(
     375              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND, HCCL_ERROR("[Get][GetSingleNicInfo]get net position error"),
     376              :         ret);
     377            0 :     HCCL_DEBUG("[%s.json] -> net_position: [%s]. ret[%u]", fileName_.c_str(), netPosition.c_str(), ret);
     378            0 :     if (ret != HCCL_E_NOT_FOUND) {
     379            0 :         if (netPosition == "host") { // 默认值为Device模式
     380            0 :             rankinfo.deviceInfo.nicDeploy = NICDeployment::NIC_DEPLOYMENT_HOST;
     381              :         } else {
     382            0 :             rankinfo.deviceInfo.nicDeploy = NICDeployment::NIC_DEPLOYMENT_DEVICE;
     383              :         }
     384              :     }
     385              : 
     386            0 :     std::string netProto;
     387            0 :     ret = GetJsonArrayMemberProperty(serverListObj, objIndex, "net_protocol", netProto, true);
     388            0 :     CHK_PRT_RET(
     389              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND, HCCL_ERROR("[Get][GetSingleNicInfo]get net protocol error"),
     390              :         ret);
     391            0 :     HCCL_DEBUG("[%s.json] -> net_protocol: [%s]. ret[%u]", fileName_.c_str(), netProto.c_str(), ret);
     392            0 :     if (ret != HCCL_E_NOT_FOUND) {
     393            0 :         if (netProto == "rdma") { // 未配置则使用默认值,不处理,使用原有逻辑
     394            0 :             SetExternalInputProtocolType(ProtocolType::RDMA);
     395            0 :             rankinfo.deviceInfo.proto = u32(ProtocolType::RDMA);
     396            0 :         } else if (netProto == "tcp") {
     397            0 :             SetExternalInputProtocolType(ProtocolType::TCP);
     398            0 :             rankinfo.deviceInfo.proto = u32(ProtocolType::TCP);
     399              :         }
     400              :     }
     401              : 
     402            0 :     return HCCL_SUCCESS;
     403            0 : }
     404              : 
     405            0 : HcclResult TopoinfoRanktableConcise::GetSingleDevice(
     406              :     const nlohmann::json& deviceListObj, u32 objIndex, RankTable_t& clusterInfo, std::string& serverId, u32& serverIdx,
     407              :     HcclIpAddress& hostIp)
     408              : {
     409              :     // 获取rank_id
     410            0 :     std::string rankId;
     411            0 :     CHK_RET(GetJsonArrayMemberProperty(deviceListObj, objIndex, "rank_id", rankId, false));
     412            0 :     HCCL_DEBUG("[%s.json] -> rank_id: [%s]", fileName_.c_str(), rankId.c_str());
     413              : 
     414              :     // 获取device type
     415            0 :     DevType deviceType = DevType::DEV_TYPE_COUNT;
     416            0 :     CHK_RET(hrtGetDeviceType(deviceType));
     417              : 
     418              :     // 获取device_id
     419            0 :     std::string strDevid;
     420            0 :     CHK_RET(GetJsonArrayMemberProperty(deviceListObj, objIndex, "device_id", strDevid, false));
     421              : 
     422            0 :     u32 devicePhyId = 0;
     423            0 :     CHK_RET(SalStrToULong(strDevid, HCCL_BASE_DECIMAL, devicePhyId));
     424              : 
     425              :     u32 maxDeviceNum;
     426            0 :     CHK_RET(GetMaxDevNum(maxDeviceNum));
     427            0 :     if ((deviceType == DevType::DEV_TYPE_310P3 || deviceType == DevType::DEV_TYPE_910B
     428            0 :          || deviceType == DevType::DEV_TYPE_910_93)
     429            0 :         && devicePhyId > (maxDeviceNum - 1)) {
     430              :         // deviceid in 0 ~ maxDeviceNum
     431            0 :         HCCL_ERROR(
     432              :             "[Get][SingleDevice]errNo[0x%016llx] device_id[%u] more than maxDeviceNum[%u] invalid",
     433              :             HCOM_ERROR_CODE(HCCL_E_PARA), devicePhyId, maxDeviceNum);
     434            0 :         return HCCL_E_PARA;
     435            0 :     } else if (
     436            0 :         (deviceType != DevType::DEV_TYPE_310P3 && deviceType != DevType::DEV_TYPE_910B
     437            0 :          && deviceType != DevType::DEV_TYPE_910_93)
     438            0 :         && devicePhyId > (HCCL_AISERVER_DEVICE_NUM - 1)) {
     439              :         // deviceid in 0 ~ 7
     440            0 :         HCCL_ERROR(
     441              :             "[Get][SingleDevice]errNo[0x%016llx] device_id[%u] more than 7 is invalid", HCOM_ERROR_CODE(HCCL_E_PARA),
     442              :             devicePhyId);
     443            0 :         return HCCL_E_PARA;
     444              :     }
     445            0 :     HCCL_DEBUG("[%s.json] -> device_id: [%s]", fileName_.c_str(), strDevid.c_str());
     446              : 
     447            0 :     RankInfo_t rankinfo;
     448            0 :     rankinfo.serverId = serverId;
     449            0 :     rankinfo.serverIdx = serverIdx;
     450            0 :     rankinfo.hostIp = hostIp;
     451            0 :     rankinfo.deviceInfo.devicePhyId = devicePhyId;
     452              : 
     453            0 :     CHK_RET(GetSingleDeviceHostPort(deviceListObj, objIndex, rankinfo));
     454            0 :     CHK_RET(GetSingleDeviceIp(deviceListObj, objIndex, clusterInfo, rankinfo, deviceType, rankinfo.hostIp.IsInvalid()));
     455            0 :     CHK_RET(GetSingleDevicePort(deviceListObj, objIndex, rankinfo));
     456            0 :     CHK_RET(GetSingleBackupDeviceIp(deviceListObj, objIndex, rankinfo));
     457            0 :     CHK_RET(GetSingleNicInfo(deviceListObj, objIndex, rankinfo));
     458              : 
     459            0 :     if (SalStrToULong(rankId, HCCL_BASE_DECIMAL, rankinfo.rankId) != HCCL_SUCCESS) {
     460            0 :         RPT_INPUT_ERR(
     461              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     462              :             std::vector<std::string>({rankId, "rank_id", "is a non-negative integer."}));
     463            0 :         HCCL_ERROR(
     464              :             "[%s][%s]errNo[0x%016llx] rankid[%s] is invalid", LOG_KEYWORDS_INIT_GROUP.c_str(),
     465              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), rankId.c_str());
     466            0 :         return HCCL_E_PARA;
     467              :     }
     468              : 
     469            0 :     rankinfo.podName = ""; // podname在新场景下置空
     470            0 :     rankId = "";
     471              : 
     472            0 :     string version;
     473            0 :     CHK_RET(GetRanktableVersion(version));
     474            0 :     if (version.compare(SUPERPOD_CLUSTER_VERSION) != 0) {
     475            0 :         clusterInfo.rankList.push_back(rankinfo);
     476            0 :         HCCL_DEBUG(
     477              :             "[%s.json]->rankId[%u], serverId[%s], devicePhyId[%d]", fileName_.c_str(), rankinfo.rankId,
     478              :             rankinfo.serverId.c_str(), rankinfo.deviceInfo.devicePhyId);
     479              : 
     480            0 :         return HCCL_SUCCESS;
     481              :     }
     482              : 
     483            0 :     CHK_RET(GetSingleSuperDeviceId(deviceListObj, objIndex, clusterInfo, rankinfo));
     484            0 :     clusterInfo.rankList.push_back(rankinfo);
     485            0 :     return HCCL_SUCCESS;
     486            0 : }
     487              : 
     488            2 : HcclResult TopoinfoRanktableConcise::SplitString(
     489              :     const std::string& str, const std::string& strC, std::vector<std::string>& strVector) const
     490              : {
     491            2 :     std::string::size_type startPos = 0;
     492            2 :     std::string::size_type foundPos = str.find(strC);
     493              : 
     494            2 :     while (foundPos != std::string::npos) {
     495            0 :         strVector.push_back(str.substr(startPos, foundPos - startPos));
     496            0 :         startPos = foundPos + strC.size();
     497            0 :         foundPos = str.find(strC, startPos);
     498              :     }
     499            2 :     if (startPos != str.length()) {
     500            2 :         strVector.push_back(str.substr(startPos));
     501              :     }
     502            2 :     return HCCL_SUCCESS;
     503              : }
     504              : 
     505            0 : HcclResult TopoinfoRanktableConcise::GetSingleDeviceIp(
     506              :     const nlohmann::json& deviceListObj, u32 objIndex, RankTable_t& clusterInfo, RankInfo_t& rankinfo,
     507              :     DevType deviceType, bool invalidHostIp)
     508              : {
     509              :     // 获取device_ip (可能有多个)
     510            0 :     std::string deviceIp;
     511            0 :     HcclResult ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "device_ip", deviceIp, true);
     512              :     // 多机和走roce网卡ranktable必须有“device_ip”字段,单机可以没有
     513            0 :     if (clusterInfo.serverNum > 1 || (GetExternalInputIntraRoceSwitch() == 1)) {
     514              :         // 如果没有配置HostIp,那么deviceIp必须有效,否则出错
     515              :         bool isDeviceIpError
     516            0 :             = (ret != HCCL_SUCCESS && invalidHostIp) || (deviceType == DevType::DEV_TYPE_910B && deviceIp == "");
     517              :         // A3超节点内使用vnic建链,不需要device ip
     518            0 :         if (deviceType == DevType::DEV_TYPE_910_93 && clusterInfo.superPodNum <= 1
     519            0 :             && GetExternalInputIntraRoceSwitch() == 0) {
     520            0 :             isDeviceIpError = false;
     521              :         }
     522            0 :         RPT_INPUT_ERR(
     523              :             isDeviceIpError, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     524              :             std::vector<std::string>({deviceIp, "device_ip", "a valid IP address"}));
     525            0 :         CHK_PRT_RET(
     526              :             isDeviceIpError,
     527              :             HCCL_ERROR(
     528              :                 "[%s][%s]'device_ip' is not set correctly, "
     529              :                 "must be set when multi Server or HCCL_INTRA_ROCE_ENABLE enabled",
     530              :                 LOG_KEYWORDS_INIT_GROUP.c_str(), LOG_KEYWORDS_RANKTABLE_CHECK.c_str()),
     531              :             HCCL_E_PARA);
     532            0 :     } else if (clusterInfo.serverNum == 1 && ret == HCCL_E_NOT_FOUND) {
     533            0 :         HcclIpAddress invalidAddr;
     534            0 :         rankinfo.deviceInfo.deviceIp.push_back(invalidAddr);
     535            0 :         HCCL_WARNING("[Get][SingleDeviceIp]'device_ip' in ranktable is not set!");
     536            0 :         return HCCL_SUCCESS;
     537            0 :     } else {
     538              :         // 如果没有配置HostIp,那么deviceIp必须有效,否则出错
     539            0 :         CHK_PRT_RET(
     540              :             ret != HCCL_SUCCESS && invalidHostIp,
     541              :             HCCL_ERROR(
     542              :                 "[Get][SingleDeviceIp]errNo[0x%016llx] 'device_ip' is not set correctly", HCOM_ERROR_CODE(HCCL_E_PARA)),
     543              :             ret);
     544              :     }
     545            0 :     HCCL_DEBUG("[%s.json] -> device_ip: [%s]", fileName_.c_str(), deviceIp.c_str());
     546              : 
     547              :     // 处理字符串device_ip
     548            0 :     std::vector<std::string> strDeviceIp;
     549            0 :     if (deviceIp != "") {
     550            0 :         CHK_RET(SplitString(deviceIp, ",", strDeviceIp));
     551              : 
     552            0 :         CHK_PRT_RET(
     553              :             strDeviceIp.size() == 0, HCCL_ERROR("[Get][SingleDeviceIp]in device:deviceip size is zero"), HCCL_E_PARA);
     554            0 :         for (u32 index = 0; index < strDeviceIp.size(); index++) {
     555            0 :             CHK_RET(CheckUniqueAndInsertPool(
     556              :                 JsonUniqueInfoType::UNIQUE_INFO_TYPE_DEVICE_IP, strDeviceIp[index],
     557              :                 JsonCheckOpType::CHECK_OP_TYPE_INSERT));
     558            0 :             HcclIpAddress ipAddr;
     559            0 :             CHK_RET(ConvertIpAddress(strDeviceIp[index], ipAddr));
     560            0 :             rankinfo.deviceInfo.deviceIp.push_back(ipAddr);
     561            0 :             devIp2ObjIndex_.emplace(ipAddr.GetReadableIP(), objIndex);
     562            0 :         }
     563              :     } else {
     564            0 :         HcclIpAddress invalidAddr;
     565            0 :         rankinfo.deviceInfo.deviceIp.push_back(invalidAddr);
     566            0 :         HCCL_WARNING("objIndex[%u],'device_ip' is not set", objIndex);
     567            0 :     }
     568              : 
     569            0 :     return HCCL_SUCCESS;
     570            0 : }
     571              : 
     572            4 : HcclResult TopoinfoRanktableConcise::GetSingleBackupDeviceIp(
     573              :     const nlohmann::json& deviceListObj, u32 objIndex, RankInfo_t& rankinfo)
     574              : {
     575            4 :     if (params_.deviceType != DevType::DEV_TYPE_910_93 || !GetExternalInputHcclAicpuUnfold()
     576            8 :         || !isInterSuperPodRetryEnable_) {
     577            0 :         return HCCL_SUCCESS;
     578              :     }
     579              :     // 获取backup_device_ip(可能有多个)
     580            4 :     std::string backupDeviceIp;
     581            4 :     HcclResult ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "backup_device_ip", backupDeviceIp);
     582              :     // backup_device_ip字段未配置时通过warning日志提示
     583            4 :     if (ret == HCCL_E_NOT_FOUND) {
     584            0 :         HcclIpAddress invalidAddr;
     585            0 :         rankinfo.deviceInfo.backupDeviceIp.push_back(invalidAddr);
     586            0 :         HCCL_WARNING("[Get][SingleDeviceIp]'backup_device_ip' in ranktable is not set!");
     587            0 :         return HCCL_SUCCESS;
     588            4 :     } else if (ret == HCCL_E_PARA) {
     589            2 :         HCCL_ERROR("[Get][SingleDeviceIp]Get json array member property error");
     590            2 :         return HCCL_E_PARA;
     591              :     }
     592            2 :     HCCL_DEBUG("[%s.json] -> backup_device_ip: [%s]", fileName_.c_str(), backupDeviceIp.c_str());
     593              : 
     594              :     // 处理backup_device_ip字符串
     595            2 :     std::vector<std::string> strBackupDeviceIp;
     596            2 :     if (backupDeviceIp != "") {
     597            4 :         CHK_RET(SplitString(backupDeviceIp, ",", strBackupDeviceIp));
     598              : 
     599            2 :         CHK_PRT_RET(
     600              :             strBackupDeviceIp.size() == 0, HCCL_ERROR("[Get][SingleBackupDeviceIp]in device: deviceip size is zero"),
     601              :             HCCL_E_PARA);
     602            3 :         for (u32 index = 0; index < strBackupDeviceIp.size(); index++) {
     603            2 :             CHK_RET(CheckUniqueAndInsertPool(
     604              :                 JsonUniqueInfoType::UNIQUE_INFO_TYPE_BACKUP_DEVICE_IP, strBackupDeviceIp[index],
     605              :                 JsonCheckOpType::CHECK_OP_TYPE_INSERT));
     606            1 :             HcclIpAddress ipAddr;
     607            1 :             CHK_RET(ConvertIpAddress(strBackupDeviceIp[index], ipAddr));
     608            1 :             rankinfo.deviceInfo.backupDeviceIp.push_back(ipAddr);
     609            1 :         }
     610            1 :         CHK_RET(GetSingleBackupDevicePort(deviceListObj, objIndex, rankinfo));
     611            1 :         HCCL_INFO(
     612              :             "[TopoinfoRanktableConcise][GetSingleBackupDeviceIp]devicePhyId[%u], backupDeviceIp[0]:[%s].",
     613              :             rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.backupDeviceIp[0].GetReadableIP());
     614              :     } else {
     615            0 :         HcclIpAddress invalidAddr;
     616            0 :         rankinfo.deviceInfo.backupDeviceIp.push_back(invalidAddr);
     617            0 :         HCCL_WARNING("objIndex[%u],'bakcup_device_ip' is not set", objIndex);
     618            0 :     }
     619            1 :     return HCCL_SUCCESS;
     620            4 : }
     621              : 
     622            0 : HcclResult TopoinfoRanktableConcise::GetSingleDeviceHostPort(
     623              :     const nlohmann::json& deviceListObj, u32 objIndex, RankInfo_t& rankinfo)
     624              : {
     625            0 :     std::string hostPortStr;
     626            0 :     rankinfo.hostPort = HCCL_INVALID_PORT;
     627            0 :     HcclResult ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "host_port", hostPortStr, true);
     628            0 :     CHK_PRT_RET(
     629              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND,
     630              :         HCCL_ERROR("[Get][SingleDeviceHostPort]get host port error, deviceIndex[%u]", objIndex), ret);
     631            0 :     HCCL_DEBUG("[%s.json] -> host_port: [%s]. ret[%u]", fileName_.c_str(), hostPortStr.c_str(), ret);
     632            0 :     if (ret != HCCL_E_NOT_FOUND) {
     633            0 :         CHK_RET(SalStrToULong(hostPortStr, HCCL_BASE_DECIMAL, rankinfo.hostPort));
     634            0 :         CHK_PRT_RET(
     635              :             rankinfo.hostPort == HCCL_SOCKET_PORT_RANGE_AUTO,
     636              :             HCCL_ERROR(
     637              :                 "[Get][SingleDeviceHostPort] deviceIndex[%u], please do not use the reserved port number[%u]", objIndex,
     638              :                 HCCL_SOCKET_PORT_RANGE_AUTO),
     639              :             HCCL_E_PARA);
     640            0 :         CHK_PRT_RET(
     641              :             rankinfo.hostPort > MAX_PORT_NUMBER,
     642              :             HCCL_ERROR(
     643              :                 "[Get][SingleDeviceHostPort] deviceIndex[%u], port number[%u] exceed max port number[%u]", objIndex,
     644              :                 rankinfo.hostPort, MAX_PORT_NUMBER),
     645              :             HCCL_E_PARA);
     646            0 :         HCCL_INFO(
     647              :             "[TopoinfoRanktableConcise][GetSingleDeviceHostPort] deviceIndex[%u], devicePhyId[%u], "
     648              :             "get HOST port[%u].",
     649              :             objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.hostPort);
     650              :     } else {
     651            0 :         HCCL_INFO(
     652              :             "[Get][SingleDeviceHostPort] deviceIndex[%u], 'host_port' in ranktable is not set. "
     653              :             "Multi-process may not be supported for op retry.",
     654              :             objIndex);
     655              :     }
     656            0 :     return HCCL_SUCCESS;
     657            0 : }
     658              : 
     659              : HcclResult
     660            2 : TopoinfoRanktableConcise::GetSingleDevicePort(const nlohmann::json& deviceListObj, u32 objIndex, RankInfo_t& rankinfo)
     661              : {
     662              :     // 获取device指定的port;如果用户未配置,则置为缺省值
     663            2 :     std::string strDevPort;
     664            2 :     HcclResult ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "device_port", strDevPort, true);
     665            2 :     CHK_PRT_RET(
     666              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND,
     667              :         HCCL_ERROR("[Get][SingleDevicePort]Get json array member property error."), ret);
     668            2 :     if (ret == HCCL_E_NOT_FOUND) {
     669            0 :         rankinfo.deviceInfo.port = HCCL_INVALID_PORT;
     670            0 :         HCCL_INFO(
     671              :             "[Get][SingleDevicePort]deviceIndex[%u], devicePhyId[%u], 'device_port' in ranktable is not set. "
     672              :             "Multi-process may not be supported for device nic.",
     673              :             objIndex, rankinfo.deviceInfo.devicePhyId);
     674            0 :         params_.commPortConfig.devPortSwitchOn = false; // 不启用用户指定的port作为device网卡通信的port
     675            0 :         return HCCL_SUCCESS;
     676              :     } else {
     677            2 :         CHK_RET(SalStrToULong(strDevPort, HCCL_BASE_DECIMAL, rankinfo.deviceInfo.port));
     678            2 :         CHK_PRT_RET(
     679              :             rankinfo.deviceInfo.port == HCCL_SOCKET_PORT_RANGE_AUTO,
     680              :             HCCL_ERROR(
     681              :                 "[Get][SingleDevicePort] deviceIndex[%u], devicePhyId[%u], "
     682              :                 "please do not use the reserved port number [%u]. ",
     683              :                 objIndex, rankinfo.deviceInfo.devicePhyId, HCCL_SOCKET_PORT_RANGE_AUTO),
     684              :             HCCL_E_PARA);
     685            2 :         CHK_PRT_RET(
     686              :             rankinfo.deviceInfo.port > MAX_PORT_NUMBER,
     687              :             HCCL_ERROR(
     688              :                 "[Get][SingleDevicePort] deviceIndex[%u], devicePhyId[%u], "
     689              :                 "port number[%u] exceed max port number[%u]",
     690              :                 objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.port, MAX_PORT_NUMBER),
     691              :             HCCL_E_PARA);
     692            2 :         params_.commPortConfig.devPortSwitchOn = true; // 启用用户指定的port作为device网卡通信的port
     693              :     }
     694              : 
     695              :     // 获取device指定的vnic port;如果未配置,则与device_port相同(仅用于MasterInfo协商解析Ranktable)
     696            2 :     std::string strVnicPort;
     697            2 :     ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "device_vnic_port", strVnicPort, true);
     698            2 :     CHK_PRT_RET(
     699              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND,
     700              :         HCCL_ERROR("[Get][SingleDevicePort]Get json array member property vnic error."), ret);
     701            2 :     if (ret == HCCL_E_NOT_FOUND) {
     702            1 :         rankinfo.deviceInfo.vnicPort = rankinfo.deviceInfo.port;
     703            1 :         HCCL_INFO(
     704              :             "[Get][SingleDevicePort]deviceIndex[%u], devicePhyId[%u], "
     705              :             "'device_vnic_port' in ranktable is not set. ",
     706              :             objIndex, rankinfo.deviceInfo.devicePhyId);
     707              :     } else {
     708            1 :         CHK_RET(SalStrToULong(strVnicPort, HCCL_BASE_DECIMAL, rankinfo.deviceInfo.vnicPort));
     709            1 :         CHK_PRT_RET(
     710              :             rankinfo.deviceInfo.vnicPort == HCCL_SOCKET_PORT_RANGE_AUTO,
     711              :             HCCL_ERROR(
     712              :                 "[Get][SingleDevicePort] deviceIndex[%u], devicePhyId[%u], "
     713              :                 "please do not use the reserved port number [%u] as vnic port number. ",
     714              :                 objIndex, rankinfo.deviceInfo.devicePhyId, HCCL_SOCKET_PORT_RANGE_AUTO),
     715              :             HCCL_E_PARA);
     716            1 :         CHK_PRT_RET(
     717              :             rankinfo.deviceInfo.vnicPort > MAX_PORT_NUMBER,
     718              :             HCCL_ERROR(
     719              :                 "[Get][SingleDevicePort] deviceIndex[%u], devicePhyId[%u], "
     720              :                 "vnic port number[%u] exceed max port number[%u]",
     721              :                 objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.vnicPort, MAX_PORT_NUMBER),
     722              :             HCCL_E_PARA);
     723              :     }
     724              : 
     725            2 :     HCCL_INFO(
     726              :         "[TopoinfoRanktableConcise][GetSingleDevicePort] deviceIndex[%u], devicePhyId[%u], get device port[%u], "
     727              :         "device vnic port[%u].",
     728              :         objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.port, rankinfo.deviceInfo.vnicPort);
     729            2 :     return HCCL_SUCCESS;
     730            2 : }
     731              : 
     732            1 : HcclResult TopoinfoRanktableConcise::GetSingleBackupDevicePort(
     733              :     const nlohmann::json& deviceListObj, u32 objIndex, RankInfo_t& rankinfo)
     734              : {
     735              :     // 获取device指定的backup port;如果用户未配置,则置为缺省值
     736            1 :     std::string strBackupPort;
     737            1 :     HcclResult ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "backup_device_port", strBackupPort, true);
     738            1 :     CHK_PRT_RET(
     739              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND,
     740              :         HCCL_ERROR("[Get][SingleBackupDevicePort]Get json array member property error."), ret);
     741            1 :     if (ret == HCCL_E_NOT_FOUND) {
     742            1 :         rankinfo.deviceInfo.backupPort = HCCL_INVALID_PORT;
     743            1 :         HCCL_INFO(
     744              :             "[Get][SingleBackupDevicePort]deviceIndex[%u], devicePhyId[%u], "
     745              :             "'backup_device_port' in ranktable is not set. Multi-process may not be supported for backup nic.",
     746              :             objIndex, rankinfo.deviceInfo.devicePhyId);
     747            1 :         return HCCL_SUCCESS;
     748              :     }
     749              : 
     750            0 :     CHK_RET(SalStrToULong(strBackupPort, HCCL_BASE_DECIMAL, rankinfo.deviceInfo.backupPort));
     751            0 :     CHK_PRT_RET(
     752              :         rankinfo.deviceInfo.backupPort == HCCL_SOCKET_PORT_RANGE_AUTO,
     753              :         HCCL_ERROR(
     754              :             "[Get][SingleBackupDevicePort] deviceIndex[%u], devicePhyId[%u], "
     755              :             "please do not use the reserved port number [%u]. ",
     756              :             objIndex, rankinfo.deviceInfo.devicePhyId, HCCL_SOCKET_PORT_RANGE_AUTO),
     757              :         HCCL_E_PARA);
     758            0 :     CHK_PRT_RET(
     759              :         rankinfo.deviceInfo.backupPort > MAX_PORT_NUMBER,
     760              :         HCCL_ERROR(
     761              :             "[Get][SingleBackupDevicePort] deviceIndex[%u], devicePhyId[%u], "
     762              :             "port number[%u] exceed max port number[%u]",
     763              :             objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.backupPort, MAX_PORT_NUMBER),
     764              :         HCCL_E_PARA);
     765              : 
     766            0 :     HCCL_INFO(
     767              :         "[TopoinfoRanktableConcise][GetSingleBackupDevicePort] deviceIndex[%u], devicePhyId[%u], "
     768              :         "get backup device port[%u].",
     769              :         objIndex, rankinfo.deviceInfo.devicePhyId, rankinfo.deviceInfo.backupPort);
     770            0 :     return HCCL_SUCCESS;
     771            1 : }
     772              : 
     773            2 : HcclResult TopoinfoRanktableConcise::VerifyBackupDeviceIpAndPort(std::vector<RankInfo_t>& rankList, u32 devIndex)
     774              : {
     775            2 :     if (params_.deviceType != DevType::DEV_TYPE_910_93 || !GetExternalInputHcclAicpuUnfold()
     776            4 :         || !isInterSuperPodRetryEnable_) {
     777            0 :         return HCCL_SUCCESS;
     778              :     }
     779            2 :     RankInfo_t& rankInfo = rankList[devIndex];
     780              : 
     781            3 :     for (auto& backupDevIp : rankInfo.deviceInfo.backupDeviceIp) {
     782            1 :         if (backupDevIp.IsInvalid()) {
     783              :             // 无效备用IP,无需校验
     784            1 :             continue;
     785              :         }
     786            1 :         string backupDevIpStr = backupDevIp.GetReadableIP();
     787            1 :         if (devIp2ObjIndex_.find(backupDevIpStr) == devIp2ObjIndex_.end()) {
     788            1 :             HCCL_RUN_WARNING(
     789              :                 "[Verify][BackupDeviceIp]"
     790              :                 "Backup devIp[%s] for devicePhyId[%d] is not in this comm. "
     791              :                 "The validation of this backup ip could not be verified! "
     792              :                 "Please notice it might be an invalid backup ip!",
     793              :                 backupDevIpStr.c_str(), devIndex);
     794            1 :             continue;
     795              :         }
     796              : 
     797            0 :         RankInfo_t& backupRankInfo = rankList[devIp2ObjIndex_[backupDevIpStr]];
     798              : 
     799            0 :         s32 backupDevPhyId = backupRankInfo.deviceInfo.devicePhyId;
     800            0 :         CHK_PRT_RET(
     801              :             backupDevPhyId == rankInfo.deviceInfo.devicePhyId,
     802              :             HCCL_ERROR(
     803              :                 "[Verify][BackupDeviceIp]"
     804              :                 "PhyId[%d] for backup devIp[%s] is the same with self device[%u] phyId[%d]. "
     805              :                 "Please do not use self ip as backup ip!",
     806              :                 backupDevPhyId, backupDevIpStr.c_str(), devIndex, rankInfo.deviceInfo.devicePhyId),
     807              :             HCCL_E_PARA);
     808              : 
     809            0 :         LinkTypeInServer linkType = LinkTypeInServer::RESERVED_LINK_TYPE;
     810            0 :         CHK_RET(hrtGetPairDeviceLinkType(rankInfo.deviceInfo.devicePhyId, backupDevPhyId, linkType));
     811            0 :         CHK_PRT_RET(
     812              :             linkType != LinkTypeInServer::SIO_TYPE,
     813              :             HCCL_ERROR(
     814              :                 "[Verify][BackupDeviceIp]errNo[0x%016llx], device[%u], "
     815              :                 "link between device phyId[%d] and backup device phyId[%d] is not sio link, backup device ip[%s]. "
     816              :                 "Please check backup ip validation and whether it is on a pair device!",
     817              :                 HCOM_ERROR_CODE(HCCL_E_PARA), devIndex, rankInfo.deviceInfo.devicePhyId, backupDevPhyId,
     818              :                 backupDevIpStr.c_str()),
     819              :             HCCL_E_PARA);
     820              : 
     821              :         // 用于备用网卡的端口不可和用于主网卡的端口冲突
     822            0 :         CHK_PRT_RET(
     823              :             rankInfo.deviceInfo.backupPort != HCCL_INVALID_PORT && backupRankInfo.deviceInfo.port != HCCL_INVALID_PORT
     824              :                 && rankInfo.deviceInfo.backupPort == backupRankInfo.deviceInfo.port,
     825              :             HCCL_ERROR(
     826              :                 "[Verify][BackupDevicePort] deviceIndex[%u], "
     827              :                 "backup device port[%u] on devPhyId[%u] should not be the same with device port[%u] on devPhyId[%u].",
     828              :                 devIndex, rankInfo.deviceInfo.backupPort, rankInfo.deviceInfo.devicePhyId,
     829              :                 backupRankInfo.deviceInfo.port, backupRankInfo.deviceInfo.devicePhyId),
     830              :             HCCL_E_PARA);
     831            1 :     }
     832            2 :     return HCCL_SUCCESS;
     833              : }
     834              : 
     835            0 : HcclResult TopoinfoRanktableConcise::GetSingleSuperDeviceId(
     836              :     const nlohmann::json& deviceListObj, u32 objIndex, [[maybe_unused]] RankTable_t& clusterInfo, RankInfo_t& rankinfo)
     837              : {
     838              :     // 获取super_device_id
     839              :     HcclResult ret;
     840            0 :     std::string strSuperDeviceId;
     841            0 :     ret = GetJsonArrayMemberProperty(deviceListObj, objIndex, "super_device_id", strSuperDeviceId, true);
     842              : 
     843            0 :     CHK_PRT_RET(
     844              :         ret == HCCL_E_NOT_FOUND, HCCL_WARNING("[Get][SingleSuperDeviceId]'super_device_id' is not found"),
     845              :         HCCL_SUCCESS);
     846              : 
     847            0 :     u32 superDeviceId = 0;
     848            0 :     ret = SalStrToULong(strSuperDeviceId, HCCL_BASE_DECIMAL, superDeviceId);
     849            0 :     if (ret != HCCL_SUCCESS) {
     850            0 :         RPT_INPUT_ERR(
     851              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     852              :             std::vector<std::string>({strSuperDeviceId, "super_device_id", "a valid non-negative integer"}));
     853            0 :         HCCL_ERROR(
     854              :             "[%s][%s]errNo[0x%016llx] super_device_id[%s] is invalid", LOG_KEYWORDS_INIT_GROUP.c_str(),
     855              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), strSuperDeviceId.c_str());
     856            0 :         return ret;
     857              :     }
     858              : 
     859            0 :     rankinfo.superDeviceId = superDeviceId;
     860            0 :     HCCL_DEBUG("[%s.json] -> super_device_id: [%s]", fileName_.c_str(), strSuperDeviceId.c_str());
     861            0 :     return HCCL_SUCCESS;
     862            0 : }
     863              : 
     864            0 : HcclResult TopoinfoRanktableConcise::GetSuperPodList(const nlohmann::json& obj, RankTable_t& clusterInfo)
     865              : {
     866            0 :     string version;
     867            0 :     CHK_RET(GetRanktableVersion(version));
     868            0 :     CHK_PRT_RET(
     869              :         version.compare(SUPERPOD_CLUSTER_VERSION) != 0,
     870              :         HCCL_INFO("[Get][SuperPodList]ranktable version[%s], do nothing.", version.c_str()), HCCL_SUCCESS);
     871              : 
     872            0 :     if (!IsTaskNumCalMode()) { // taskNum评估阶段,无法判断是否超节点模式
     873              :         // 环境配置非超节点时,不解析超节点信息, ranktable中记录的superPodId, superDeviceId, superPodNum均为默认值
     874            0 :         bool useSuperPodMode = false;
     875            0 :         CHK_RET(IsSuperPodMode(useSuperPodMode));
     876            0 :         CHK_PRT_RET(!useSuperPodMode, HCCL_INFO("[Get][SuperPodList]not super pod, do nothing"), HCCL_SUCCESS);
     877              :     }
     878              : 
     879              :     HcclResult ret;
     880            0 :     nlohmann::json superPodList;
     881            0 :     ret = GetJsonProperty(obj, "super_pod_list", superPodList, true);
     882            0 :     CHK_PRT_RET(
     883              :         ret == HCCL_E_NOT_FOUND, HCCL_WARNING("[Get][SuperPodList]'super_pod_list' is not found"), HCCL_SUCCESS);
     884            0 :     CHK_PRT_RET(
     885              :         ret != HCCL_SUCCESS && ret != HCCL_E_NOT_FOUND,
     886              :         HCCL_ERROR("[Get][SuperPodList]'super_pod_list' in ranktable is not set correctly, ret[%d]", ret), ret);
     887            0 :     HCCL_DEBUG("[%s.json]super_pod_list -> : size:[%zu]", fileName_.c_str(), superPodList.size());
     888              : 
     889            0 :     for (u32 index = 0; index < superPodList.size(); index++) {
     890            0 :         CHK_RET(GetSingleSuperPod(superPodList, index, clusterInfo));
     891              :     }
     892              : 
     893            0 :     clusterInfo.superPodNum = superPodList.size();
     894            0 :     CHK_RET(CheckSuperPodInfo(clusterInfo));
     895            0 :     return HCCL_SUCCESS;
     896            0 : }
     897              : 
     898              : HcclResult
     899            0 : TopoinfoRanktableConcise::GetSingleSuperPod(const nlohmann::json& superPodList, u32 objIndex, RankTable_t& clusterInfo)
     900              : {
     901            0 :     HcclResult ret = HCCL_SUCCESS;
     902            0 :     std::string superPodId;
     903            0 :     ret = GetJsonArrayMemberProperty(superPodList, objIndex, "super_pod_id", superPodId, true);
     904            0 :     if (ret != HCCL_SUCCESS || superPodId.empty()) {
     905            0 :         RPT_INPUT_ERR(
     906              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     907              :             std::vector<std::string>({superPodId, "super_pod_id", "a valid non-empty string."}));
     908            0 :         HCCL_ERROR(
     909              :             "[%s][%s]errNo[0x%016llx] super_pod_id[%s] is invalid", LOG_KEYWORDS_INIT_GROUP.c_str(),
     910              :             LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(ret), superPodId.c_str());
     911            0 :         return ret;
     912              :     }
     913              : 
     914              :     // 将superPodId添加到资源池进行查重校验
     915            0 :     CHK_RET(CheckUniqueAndInsertPool(
     916              :         JsonUniqueInfoType::UNIQUE_INFO_TYPE_SUPER_POD_ID, superPodId, JsonCheckOpType::CHECK_OP_TYPE_INSERT));
     917            0 :     HCCL_DEBUG("superPod id[%u]:[%s]", objIndex, superPodId.c_str());
     918              : 
     919              :     // 处理ranklist
     920            0 :     ret = GetSuperPodServerList(superPodList, objIndex, clusterInfo, superPodId);
     921            0 :     CHK_PRT_RET(
     922              :         ret != HCCL_SUCCESS,
     923              :         HCCL_ERROR("[Get][SingleSuperPod]get server list error:superPodId[%s]", superPodId.c_str()), ret);
     924              : 
     925            0 :     return HCCL_SUCCESS;
     926            0 : }
     927              : 
     928            0 : HcclResult TopoinfoRanktableConcise::GetSuperPodServerList(
     929              :     const nlohmann::json& superPodList, u32 objIndex, RankTable_t& clusterInfo, std::string superPodId)
     930              : {
     931            0 :     HCCL_DEBUG("GetSuperPodServerList[%u]: superPodId[%s]", objIndex, superPodId.c_str());
     932              : 
     933            0 :     nlohmann::json superPodServerList;
     934            0 :     CHK_RET(GetJsonArrayMemberProperty(superPodList, objIndex, "server_list", superPodServerList, false));
     935            0 :     for (u32 index = 0; index < superPodServerList.size(); index++) {
     936              :         // get single super pod server info
     937            0 :         CHK_RET(GetSingleSuperPodSever(superPodServerList, index, clusterInfo, superPodId));
     938              :     }
     939            0 :     return HCCL_SUCCESS;
     940            0 : }
     941              : 
     942            0 : HcclResult TopoinfoRanktableConcise::GetSingleSuperPodSever(
     943              :     const nlohmann::json& superPodServerList, u32 objIndex, RankTable_t& clusterInfo, std::string superPodId)
     944              : {
     945            0 :     std::string serverId;
     946            0 :     HcclResult ret = HCCL_SUCCESS;
     947              :     do {
     948              :         // 获取server_id
     949            0 :         ret = GetJsonArrayMemberProperty(superPodServerList, objIndex, "server_id", serverId, true);
     950            0 :         CHK_PRT_BREAK(
     951              :             ret != HCCL_SUCCESS,
     952              :             HCCL_ERROR(
     953              :                 "[Get][SingleSuperPodSever]errNo[0x%016llx]server_id is not found or invalid", HCCL_ERROR_CODE(ret)), );
     954              : 
     955              :         // 将super_pod_list下的server_id在资源池中进行校验
     956            0 :         ret = CheckUniqueAndInsertPool(
     957            0 :             JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID, serverId, JsonCheckOpType::CHECK_OP_TYPE_FIND);
     958            0 :         CHK_PRT_BREAK(
     959              :             ret != HCCL_SUCCESS,
     960              :             HCCL_ERROR(
     961              :                 "[Get][SingleSuperPodSever]errNo[0x%016llx]server_id[%s] is not found in server_list",
     962              :                 HCCL_ERROR_CODE(ret), serverId.c_str()), );
     963            0 :         HCCL_DEBUG("[%s.json]super_pod_list -> server_id: [%s]", fileName_.c_str(), serverId.c_str());
     964              :     } while (0);
     965              : 
     966              :     // server_id未找到, 或与server_list中的server_id不一致
     967            0 :     if (ret != HCCL_SUCCESS) {
     968            0 :         RPT_INPUT_ERR(
     969              :             true, "EI0014", std::vector<std::string>({"value", "variable", "expect"}),
     970              :             std::vector<std::string>({serverId, "server_id", "a valid non-empty string."}));
     971            0 :         return ret;
     972              :     }
     973              : 
     974            0 :     u32 superPodIdx = INVALID_UINT;
     975            0 :     GenerateSuperPodIdx(superPodId, superPodIdx);
     976              : 
     977            0 :     bool isFound = false;
     978            0 :     for (RankInfo_t& rankInfo : clusterInfo.rankList) {
     979            0 :         if (rankInfo.serverId == serverId) {
     980            0 :             rankInfo.superPodId = superPodId;
     981            0 :             rankInfo.superPodIdx = superPodIdx;
     982            0 :             isFound = true;
     983              :         }
     984              :     }
     985            0 :     CHK_PRT_RET(
     986              :         isFound == false,
     987              :         HCCL_ERROR("[Get][SingleSuperPodSever]server_id[%s] in super_pod_list is not in server_list", serverId.c_str()),
     988              :         HCCL_E_PARA);
     989              : 
     990            0 :     HCCL_DEBUG(
     991              :         "[%s.json]super_pod_list -> server_id[%s], super_pod_id[%s]", fileName_.c_str(), serverId.c_str(),
     992              :         superPodId.c_str());
     993              : 
     994            0 :     return HCCL_SUCCESS;
     995            0 : }
     996              : 
     997            0 : HcclResult TopoinfoRanktableConcise::CheckSuperPodInfo(RankTable_t& clusterInfo) const
     998              : {
     999            0 :     std::map<std::string, std::set<std::string>> superPodMap; // superPodId -> serverId
    1000            0 :     std::map<std::string, std::set<u32>> superPodSdidMap;     // super_pod_id -> superDeviceId
    1001            0 :     for (RankInfo_t& rankInfo : clusterInfo.rankList) {
    1002              :         // 超节点模式下, 校验superPodId和sdid值有效
    1003            0 :         CHK_PRT_RET(
    1004              :             rankInfo.superPodId.empty() || rankInfo.superDeviceId == INVALID_UINT,
    1005              :             HCCL_ERROR(
    1006              :                 "[Check][SuperPodInfo]superDeviceId[0x%x] or superPod[%s] in rank[%u] is invalid",
    1007              :                 rankInfo.superDeviceId, rankInfo.superPodId.c_str(), rankInfo.rankId),
    1008              :             HCCL_E_PARA);
    1009              : 
    1010            0 :         auto it = superPodMap.find(rankInfo.superPodId);
    1011            0 :         if (it == superPodMap.end()) {
    1012            0 :             std::set<std::string> serverIdSet;
    1013            0 :             serverIdSet.insert(rankInfo.serverId);
    1014            0 :             superPodMap.insert({rankInfo.superPodId, serverIdSet});
    1015            0 :         } else if (it->second.find(rankInfo.serverId) == it->second.end()) {
    1016            0 :             it->second.insert(rankInfo.serverId);
    1017              :         }
    1018              :         // 用户忘记配置,superDeviceId等于无效值
    1019            0 :         CHK_PRT_RET(
    1020              :             rankInfo.superDeviceId == INVALID_UINT,
    1021              :             HCCL_ERROR(
    1022              :                 "[Check][SuperPodInfo]superDeviceId[0x%x] is invalid in rankId[%u], "
    1023              :                 "the configuration may be missing, please check the ranktable config!",
    1024              :                 rankInfo.superDeviceId, rankInfo.rankId),
    1025              :             HCCL_E_PARA);
    1026              : 
    1027            0 :         auto iter = superPodSdidMap.find(rankInfo.superPodId);
    1028            0 :         if (iter == superPodSdidMap.end()) {
    1029            0 :             std::set<u32> superDeviceIdSet;
    1030            0 :             superDeviceIdSet.insert(rankInfo.superDeviceId);
    1031            0 :             superPodSdidMap.insert({rankInfo.superPodId, superDeviceIdSet});
    1032            0 :         } else if (iter->second.find(rankInfo.superDeviceId) == iter->second.end()) {
    1033            0 :             iter->second.insert(rankInfo.superDeviceId);
    1034              :         } else {
    1035              :             // 超节点内superDeviceId在超节点内唯一
    1036            0 :             CHK_PRT_RET(
    1037              :                 iter->second.find(rankInfo.superDeviceId) != iter->second.end(),
    1038              :                 HCCL_ERROR(
    1039              :                     "[Verify][SuperPodInfo]superDeviceId[0x%x] in superPod[%s]"
    1040              :                     "is already exist.",
    1041              :                     rankInfo.superDeviceId, iter->first.c_str()),
    1042              :                 HCCL_E_PARA);
    1043              :         }
    1044              :     }
    1045              : 
    1046            0 :     u32 serverNumTotal = 0;
    1047            0 :     for (auto it = superPodMap.begin(); it != superPodMap.end(); ++it) {
    1048            0 :         serverNumTotal += it->second.size();
    1049              :     }
    1050              : 
    1051              :     // 校验super_pod_list和原有server_list的server数量一致
    1052            0 :     CHK_PRT_RET(
    1053              :         serverNumTotal != clusterInfo.serverNum,
    1054              :         HCCL_ERROR(
    1055              :             "[Get][SuperPodList]serverNum[%u] in super_pod_list and serverNum[%u] in server_list "
    1056              :             "are inconsistent",
    1057              :             serverNumTotal, clusterInfo.serverNum),
    1058              :         HCCL_E_PARA);
    1059            0 :     return HCCL_SUCCESS;
    1060            0 : }
        

Generated by: LCOV version 2.0-1