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_ranktableHeterog.h"
12 :
13 : #include <map>
14 : #include <vector>
15 : #include <string>
16 : #include <fstream>
17 : #include <algorithm>
18 : #include <unistd.h>
19 : #include <chrono>
20 : #include <iostream>
21 : #include <arpa/inet.h>
22 :
23 : #include "externalinput_pub.h"
24 : // ltm指定config路径
25 : #include "common/src/config.h"
26 : #include "workflow_pub.h"
27 :
28 : using namespace std;
29 : using namespace hccl;
30 :
31 : constexpr u32 MAX_PORT_ID = 65535;
32 0 : TopoinfoRanktableHeterog::TopoinfoRanktableHeterog(const std::string &rankTableM,
33 0 : const std::string &identify, DevType deviceType)
34 0 : : TopoInfoRanktableParser(rankTableM, identify), deviceType_(deviceType)
35 : {
36 0 : }
37 :
38 0 : TopoinfoRanktableHeterog::~TopoinfoRanktableHeterog()
39 : {
40 0 : }
41 :
42 0 : HcclResult TopoinfoRanktableHeterog::Init()
43 : {
44 : // 根据rankTable类型标记执行读文件或读字符串,将内容保存在json对象fileContent_中
45 0 : CHK_RET(LoadRankTableString(rankTableFile_));
46 : // 解析rankTable
47 0 : CHK_RET(ParserClusterInfo(params_, rankTable_));
48 0 : return HCCL_SUCCESS;
49 : }
50 :
51 0 : HcclResult TopoinfoRanktableHeterog::GetSelfClusterInfo(HcclCommParams ¶ms)
52 : {
53 : // 获取params
54 0 : params.rank = params_.rank;
55 0 : params.userRank = params_.rank;
56 0 : params.totalRanks = params_.totalRanks;
57 0 : params.logicDevId = params_.logicDevId;
58 0 : params.serverId = params_.serverId;
59 0 : params.deviceType = params_.deviceType;
60 0 : return HCCL_SUCCESS;
61 : }
62 :
63 0 : HcclResult TopoinfoRanktableHeterog::GetClusterInfo(hccl::HcclCommParams ¶ms,
64 : hccl::RankTable_t &rankTable)
65 : {
66 0 : CHK_RET(GetClusterInfo(rankTable));
67 0 : CHK_RET(GetSelfClusterInfo(params));
68 0 : return HCCL_SUCCESS;
69 : }
70 :
71 0 : HcclResult TopoinfoRanktableHeterog::GetClusterInfo(RankTable_t &clusterInfo)
72 : {
73 : // 获取rankInfo
74 0 : clusterInfo.deviceNum = rankTable_.deviceNum;
75 0 : clusterInfo.serverNum = rankTable_.serverNum;
76 0 : clusterInfo.nicDeploy = rankTable_.nicDeploy;
77 0 : clusterInfo.rankNum = rankTable_.rankNum;
78 0 : clusterInfo.rankList = rankTable_.rankList;
79 0 : clusterInfo.serverList = rankTable_.serverList;
80 0 : clusterInfo.collectiveId = rankTable_.collectiveId;
81 0 : clusterInfo.version = rankTable_.version;
82 0 : clusterInfo.mode = rankTable_.mode;
83 0 : return HCCL_SUCCESS;
84 : }
85 :
86 0 : HcclResult TopoinfoRanktableHeterog::ParserClusterInfo(hccl::HcclCommParams ¶ms,
87 : hccl::RankTable_t &rankTable)
88 : {
89 : // 获取ranktable info信息
90 0 : CHK_RET(GetRanktableInfo(rankTable));
91 0 : if (!IsTaskNumCalMode()) {
92 0 : CHK_RET(CheckNicDeployConsistence(rankTable));
93 0 : rankTable.nicDeploy = NICDeployment::NIC_DEPLOYMENT_DEVICE;
94 0 : std::sort(rankTable.rankList.begin(), rankTable.rankList.end(),
95 0 : [&](const RankInfo_t &a, const RankInfo_t &b) -> bool {return a.rankId < b.rankId;});
96 :
97 0 : unordered_map<std::string, u32> minRankPerServerMap;
98 0 : for (auto &iter : rankTable.rankList) {
99 0 : if (minRankPerServerMap.find(iter.serverId) == minRankPerServerMap.end()) {
100 0 : minRankPerServerMap[iter.serverId] = iter.rankId;
101 0 : } else if (minRankPerServerMap[iter.serverId] > iter.rankId) {
102 0 : minRankPerServerMap[iter.serverId] = iter.rankId;
103 : }
104 : }
105 0 : map<u32, std::string> minRankInServerMap;
106 0 : for (auto &iter : minRankPerServerMap) {
107 0 : minRankInServerMap.insert(std::make_pair(iter.second, iter.first));
108 : }
109 :
110 0 : u32 serverIndex = 0;
111 0 : for (auto &iter : minRankInServerMap) {
112 0 : for (u32 rankIndex = 0; rankIndex < rankTable.rankList.size(); rankIndex++) {
113 0 : if (rankTable.rankList[rankIndex].serverId == iter.second) {
114 0 : rankTable.rankList[rankIndex].serverIdx = serverIndex;
115 0 : ServerInfo_t serverinfo;
116 0 : NetworkInfo_t networkInfo;
117 0 : serverinfo.serverId = iter.second;
118 0 : networkInfo.ipAddr = rankTable.rankList[rankIndex].hostIp;
119 0 : serverinfo.networkInfo.push_back(networkInfo);
120 0 : std::vector<ServerInfo_t>::iterator found = find(rankTable.serverList.begin(),
121 : rankTable.serverList.end(), serverinfo);
122 0 : if (found == rankTable.serverList.end()) {
123 0 : rankTable.serverList.push_back(serverinfo);
124 : }
125 0 : }
126 : }
127 0 : serverIndex++;
128 : }
129 :
130 0 : u32 rankId = INVALID_VALUE_RANKID;
131 0 : std::string errormessage = "";
132 0 : if (SalStrToULong(identify_, HCCL_BASE_DECIMAL, rankId) != HCCL_SUCCESS) {
133 0 : errormessage = "Value [" + identify_ + "] for rankTable variable [rank_id] is invalid, expected value is a valid integer.";
134 0 : HCCL_ERROR("[%s][%s]errNo[0x%016llx] [%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
135 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), errormessage.c_str());
136 0 : return HCCL_E_PARA;
137 : }
138 : // 校验rank id合法性
139 0 : if (rankId >= rankTable.rankList.size()) {
140 0 : errormessage = "Value [" + std::to_string(rankId) + "] for rankTable variable [rank_id] is invalid, "\
141 0 : "expected value is a valid rank ID in [0, " + std::to_string(rankTable.rankList.size() - 1) + "].";
142 0 : HCCL_ERROR("[%s][%s] [%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
143 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), errormessage.c_str());
144 0 : return HCCL_E_PARA;
145 : }
146 0 : errormessage = "The current node's rankId [" + std::to_string(rankId) + "] does not match "\
147 0 : "the rankId [" + std::to_string(rankTable.rankList[rankId].rankId) + "] in the rankTable.";
148 0 : CHK_PRT_RET(rankId != rankTable.rankList[rankId].rankId,
149 : HCCL_ERROR("[%s][%s] [%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
150 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), errormessage.c_str()), HCCL_E_UNAVAIL);
151 :
152 : // params内容填入
153 0 : params.rank = rankId;
154 0 : params.logicDevId = rankTable.rankList[rankId].deviceInfo.devicePhyId;
155 0 : params.serverId = rankTable.rankList[rankId].serverId;
156 0 : params.totalRanks = rankTable.rankNum;
157 0 : params.deviceType = deviceType_;
158 0 : }
159 0 : return HCCL_SUCCESS;
160 : }
161 :
162 0 : HcclResult TopoinfoRanktableHeterog::GetRanktableInfo(RankTable_t &clusterInfo)
163 : {
164 : // 清空list
165 0 : clusterInfo.serverList.clear();
166 0 : clusterInfo.rankList.clear();
167 :
168 : // 获取信息
169 0 : std::string collective_id;
170 0 : nlohmann::json node_list;
171 0 : std::string version;
172 0 : std::string mode;
173 :
174 0 : std::string heterogSubVersion;
175 : // 解析91093-ES专属标志
176 0 : if (fileContent_.find("heterog_sub_version") != fileContent_.end()) {
177 0 : CHK_RET(GetJsonProperty(fileContent_, "heterog_sub_version", heterogSubVersion, false));
178 0 : CHK_RET(CheckHeterogSubVersion(heterogSubVersion));
179 0 : HCCL_DEBUG("[Get][RanktableInfo] heterog_sub_version exists!");
180 0 : is91093_ = true;
181 : }
182 :
183 0 : CHK_RET(GetJsonProperty(fileContent_, "collective_id", collective_id, false));
184 0 : if (collective_id.length() > COLLECTIVEID_MAX_LEN) {
185 0 : HCCL_ERROR("[Get][RanktableInfo]errNo[0x%016llx] collectiveId length is over than %d bytes.",
186 : HCOM_ERROR_CODE(HCCL_E_PARA), collective_id.length());
187 0 : return HCCL_E_PARA;
188 : }
189 0 : CHK_RET(GetJsonProperty(fileContent_, "node_list", node_list, false));
190 0 : CHK_RET(GetJsonProperty(fileContent_, "version", version, false));
191 :
192 0 : if (fileContent_.find("mode") != fileContent_.end()) {
193 0 : CHK_RET(GetJsonProperty(fileContent_, "mode", mode, false));
194 0 : CHK_RET(CheckMode(mode));
195 : }
196 :
197 0 : HCCL_DEBUG("[rankTableJson] -> collectiveId: [%s], nodeListSize: [%zu]", collective_id.c_str(), node_list.size());
198 :
199 : // 保存serverNum
200 0 : clusterInfo.serverNum = node_list.size();
201 0 : if (clusterInfo.serverNum == 0) {
202 0 : HCCL_ERROR("[Get][RanktableInfo]errNo[0x%016llx] node num is zero", HCOM_ERROR_CODE(HCCL_E_PARA));
203 0 : return HCCL_E_PARA;
204 : }
205 : // 获得single node信息
206 0 : for (u32 index = 0; index < clusterInfo.serverNum; index++) {
207 0 : CHK_RET(GetSingleNode(node_list, index, clusterInfo));
208 : }
209 :
210 : // 保存deviceNum和rankNum
211 0 : CHK_RET(GetDevNum(clusterInfo.rankList, clusterInfo.deviceNum));
212 0 : clusterInfo.rankNum = clusterInfo.rankList.size();
213 0 : clusterInfo.collectiveId = collective_id;
214 0 : clusterInfo.version = version;
215 0 : clusterInfo.mode = mode;
216 0 : return HCCL_SUCCESS;
217 0 : }
218 :
219 0 : HcclResult TopoinfoRanktableHeterog::CheckNicDeployConsistence(RankTable_t &clusterInfo) const
220 : {
221 : // 检查rankList的大小
222 0 : CHK_PRT_RET(clusterInfo.rankList.size() == 0, HCCL_DEBUG("rank list size is 0, skip nic deeply check."),
223 : HCCL_SUCCESS);
224 0 : NICDeployment tmpNicDeply = clusterInfo.rankList.begin()->hostIp.IsInvalid() ?
225 0 : NICDeployment::NIC_DEPLOYMENT_DEVICE : NICDeployment::NIC_DEPLOYMENT_HOST;
226 0 : for (auto &it:clusterInfo.rankList) {
227 0 : CHK_PRT_RET((tmpNicDeply == NICDeployment::NIC_DEPLOYMENT_DEVICE && !it.hostIp.IsInvalid()) ||
228 : (tmpNicDeply == NICDeployment::NIC_DEPLOYMENT_HOST &&
229 : it.hostIp.IsInvalid()), HCCL_ERROR("[Get][RanktableInfo] errNo[0x%016llx] " \
230 : "hostIp config bettewn ranks is different.", HCOM_ERROR_CODE(HCCL_E_PARA)), HCCL_E_PARA);
231 : }
232 0 : return HCCL_SUCCESS;
233 : }
234 :
235 0 : HcclResult TopoinfoRanktableHeterog::CheckMode(std::string &mode) const
236 : {
237 0 : if (mode == "tcp" || mode == "rdma") {
238 0 : return HCCL_SUCCESS;
239 : }
240 0 : HCCL_ERROR("[Get][RanktableInfo]errNo[0x%016llx] mode[%s] is not supported, support for [tcp] and [rdma]",
241 : HCOM_ERROR_CODE(HCCL_E_PARA), mode.c_str());
242 0 : return HCCL_E_PARA;
243 : }
244 :
245 0 : HcclResult TopoinfoRanktableHeterog::CheckHeterogSubVersion(std::string &subVersion) const
246 : {
247 0 : if (subVersion == "1.2") {
248 0 : return HCCL_SUCCESS;
249 : }
250 :
251 0 : HCCL_ERROR("[Get][RanktableInfo]errNo[0x%016llx] subVersion[%s] is not supported, support for 1.2",
252 : HCOM_ERROR_CODE(HCCL_E_PARA), subVersion.c_str());
253 0 : return HCCL_E_PARA;
254 : }
255 :
256 0 : HcclResult TopoinfoRanktableHeterog::GetHostPort(const u32 &localRank, u32 &hostPort)
257 : {
258 0 : u32 basePort = (GetExternalInputHcclIfBasePort() == HCCL_INVALID_PORT) ?
259 0 : HOST_PARA_BASE_PORT : GetExternalInputHcclIfBasePort();
260 0 : hostPort = basePort + localRank;
261 0 : CHK_PRT_RET(hostPort > MAX_PORT_ID, HCCL_ERROR("[Get][HostPort]invalid port id[%u]", hostPort), HCCL_E_INTERNAL);
262 0 : if (hostPortMap_.find(hostPort) == hostPortMap_.end()) {
263 0 : return HCCL_SUCCESS;
264 : }
265 0 : while (hostPortMap_[hostPort] == HOST_PORT_USED) {
266 0 : hostPort++;
267 0 : CHK_PRT_RET(hostPort > MAX_PORT_ID, HCCL_ERROR("[Get][HostPort]invalid port id[%u]", hostPort),
268 : HCCL_E_INTERNAL);
269 : }
270 0 : return HCCL_SUCCESS;
271 : }
272 :
273 0 : HcclResult TopoinfoRanktableHeterog::GetRanks(const nlohmann::json &NodeListObj, u32 objIndex,
274 : RankTable_t &clusterInfo, std::string &serverId, u32 &serverIdx, HcclIpAddress &nodeIp)
275 : {
276 0 : HCCL_DEBUG("Get Node[%u]: nodeAddr:[%s], nodeIdx:[%u]", objIndex, serverId.c_str(), serverIdx);
277 : // 获取信息
278 0 : nlohmann::json Ranks;
279 0 : CHK_RET(GetJsonArrayMemberProperty(NodeListObj, objIndex, "ranks", Ranks, false));
280 :
281 0 : HCCL_DEBUG("[%s.json] -> rank_list: size:%zu", fileName_.c_str(), Ranks.size());
282 0 : CHK_PRT_RET(Ranks.size() == 0, HCCL_ERROR("[Get][Ranks]Ranks size is zero"), HCCL_E_PARA);
283 :
284 : // 91093的GetSingleRank单独操作
285 0 : if (is91093_) {
286 0 : for (u32 index = 0; index < Ranks.size(); index++) {
287 0 : CHK_RET(GetSingleRank91093(Ranks, index, clusterInfo, serverId, serverIdx, nodeIp));
288 : }
289 : } else {
290 : // 获取单rank信息
291 0 : for (u32 index = 0; index < Ranks.size(); index++) {
292 0 : CHK_RET(GetSingleRank(Ranks, index, clusterInfo, serverId, serverIdx, nodeIp));
293 : }
294 : }
295 :
296 : // 重新分配host port
297 0 : for (auto &rankInfo : clusterInfo.rankList) {
298 0 : if (rankInfo.hostPort == HCCL_INVALID_PORT) {
299 0 : CHK_RET(GetHostPort(rankInfo.localRank, rankInfo.hostPort));
300 : }
301 0 : HCCL_DEBUG("rank id: %u localRank:%u host port: %u", rankInfo.rankId, rankInfo.localRank, rankInfo.hostPort);
302 : }
303 0 : hostPortMap_.clear();
304 0 : return HCCL_SUCCESS;
305 0 : }
306 :
307 0 : HcclResult TopoinfoRanktableHeterog::GetSingleNode(const nlohmann::json &NodeListObj, u32 objIndex,
308 : RankTable_t &clusterInfo)
309 : {
310 : // 获取信息
311 : HcclResult ret;
312 0 : std::string nodeAddr;
313 0 : std::string serverId;
314 0 : CHK_RET(GetJsonArrayMemberProperty(NodeListObj, objIndex, "node_addr", nodeAddr, false));
315 : // 将serverId添加到资源池,内部会进行IP地址校验,如果资源池中有serverId,则报错
316 0 : serverId = nodeAddr;
317 0 : CHK_RET(CheckUniqueAndInsertPool(JsonUniqueInfoType::UNIQUE_INFO_TYPE_SERVER_ID, serverId,
318 : JsonCheckOpType::CHECK_OP_TYPE_INSERT));
319 : // 设置serverIdx
320 : u32 serverIdx;
321 0 : GenerateServerIdx(serverId, serverIdx);
322 :
323 : // 计算node ip
324 0 : HcclIpAddress nodeIp;
325 0 : CHK_RET(ConvertIpAddress(nodeAddr, nodeIp));
326 :
327 : // 处理ranklist
328 0 : ret = GetRanks(NodeListObj, objIndex, clusterInfo, serverId, serverIdx, nodeIp);
329 0 : CHK_PRT_RET(ret != HCCL_SUCCESS,
330 : HCCL_ERROR("[Get][GetRanks]get rank list error:nodeAddr:[%s]", serverId.c_str()), ret);
331 0 : return HCCL_SUCCESS;
332 0 : }
333 :
334 : // 91093暂定所有字段都是必选字段。除了ranks里面的 bind_device_id
335 0 : HcclResult TopoinfoRanktableHeterog::GetSingleRank91093(const nlohmann::json &ranksObj, u32 objIndex,
336 : RankTable_t &clusterInfo, std::string &serverId, u32 &serverIdx, HcclIpAddress &nodeIp)
337 : {
338 0 : HCCL_INFO("Entry-GetSingleRank91093");
339 0 : std::string rankId;
340 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_id", rankId, false));
341 :
342 0 : s32 devicePhyId = 0;
343 0 : std::string devPhyIdStr;
344 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "device_id", devPhyIdStr, false));
345 0 : CHK_RET(SalStrToInt(devPhyIdStr, HCCL_BASE_DECIMAL, devicePhyId));
346 :
347 0 : s32 port = HCCL_INVALID_PORT;
348 0 : std::string portStr;
349 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "port", portStr, false));
350 0 : CHK_RET(SalStrToInt(portStr, HCCL_BASE_DECIMAL, port));
351 :
352 : // 如果device没有网卡,则缺省,通信使用node_addr
353 0 : HcclIpAddress rankIp;
354 0 : std::string rankIpStr;
355 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_ip", rankIpStr, false));
356 0 : if (rankIpStr.empty()) {
357 0 : rankIp = nodeIp;
358 : } else {
359 0 : CHK_RET(ConvertIpAddress(rankIpStr, rankIp));
360 : }
361 :
362 0 : s32 sdid = 0;
363 0 : std::string sdidStr;
364 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "sdid", sdidStr, false));
365 0 : CHK_RET(SalStrToInt(sdidStr, HCCL_BASE_DECIMAL, sdid));
366 :
367 : // 如果deviceId == -1, 则去获取可选字段
368 0 : s32 bindDeviceId = -1;
369 0 : std::string bindDeviceIdStr;
370 0 : if (devicePhyId == HOST_DEVICE_ID) {
371 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "bind_device_id", bindDeviceIdStr, false));
372 0 : CHK_RET(SalStrToInt(bindDeviceIdStr, HCCL_BASE_DECIMAL, bindDeviceId));
373 : }
374 :
375 : // rankList
376 0 : RankInfo_t rankInfo;
377 0 : rankInfo.localRank = objIndex;
378 0 : rankInfo.serverId = serverId;
379 0 : rankInfo.serverIdx = serverIdx;
380 0 : rankInfo.hostIp = nodeIp;
381 0 : rankInfo.superDeviceId = sdid;
382 0 : rankInfo.bindDeviceId = bindDeviceId;
383 0 : rankInfo.deviceInfo.devicePhyId = devicePhyId;
384 0 : rankInfo.deviceInfo.port = port;
385 0 : rankInfo.deviceInfo.deviceIp.push_back(rankIp);
386 :
387 0 : std::string errormessage = "";
388 0 : if (SalStrToULong(rankId, HCCL_BASE_DECIMAL, rankInfo.rankId) != HCCL_SUCCESS) {
389 0 : errormessage = "Value [" + rankId + "] for rankTable variable [rank_id] is invalid, expected value is a non-negative integer.";
390 0 : HCCL_ERROR("[%s][%s]errNo[0x%016llx] [%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
391 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), errormessage.c_str());
392 0 : return HCCL_E_PARA;
393 : }
394 :
395 0 : rankInfo.podName = ""; // podname在新场景下置空
396 : // ranktable中port无效,设置为环境变量HCCL_IF_BASE_PORT+该rank的local_rank_id,否则按照配置的port使用
397 0 : if (port == 0) {
398 0 : rankInfo.hostPort = HCCL_INVALID_PORT;
399 : } else {
400 0 : rankInfo.hostPort = port;
401 0 : hostPortMap_[rankInfo.hostPort] = HOST_PORT_USED;
402 : }
403 0 : clusterInfo.rankList.push_back(rankInfo);
404 0 : HCCL_DEBUG("[%s.json]->rankId[%u], nodeAddr[%s]", fileName_.c_str(),
405 : rankInfo.rankId, rankInfo.serverId.c_str());
406 :
407 0 : return HCCL_SUCCESS;
408 0 : }
409 :
410 0 : HcclResult TopoinfoRanktableHeterog::GetSingleRank(const nlohmann::json &ranksObj, u32 objIndex,
411 : RankTable_t &clusterInfo, std::string &serverId, u32 &serverIdx, HcclIpAddress &nodeIp)
412 : {
413 : // 获取rank_id
414 0 : std::string rankId;
415 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_id", rankId, false));
416 :
417 0 : s32 devicePhyId = 0;
418 0 : std::string devPhyIdStr;
419 0 : if (GetJsonArrayMemberProperty(ranksObj, objIndex, "device_id", devPhyIdStr, true) == HCCL_E_NOT_FOUND) {
420 0 : devicePhyId = HOST_DEVICE_ID;
421 : } else {
422 0 : HCCL_DEBUG("[Get][GetRanks]device_id:[%s]", devPhyIdStr.c_str());
423 0 : CHK_RET(SalStrToInt(devPhyIdStr, HCCL_BASE_DECIMAL, devicePhyId));
424 : }
425 :
426 0 : s32 port = HCCL_INVALID_PORT;
427 0 : std::string portStr;
428 0 : if (GetJsonArrayMemberProperty(ranksObj, objIndex, "port", portStr, true) == HCCL_E_NOT_FOUND) {
429 0 : port = HCCL_INVALID_PORT;
430 : } else {
431 0 : CHK_RET(SalStrToInt(portStr, HCCL_BASE_DECIMAL, port));
432 : }
433 :
434 : // 如果device没有网卡,则缺省,通信使用node_addr
435 0 : HcclIpAddress rankIp;
436 0 : std::string rankIpStr;
437 0 : if (GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_ip", rankIpStr, true) == HCCL_E_NOT_FOUND) {
438 0 : rankIp = nodeIp;
439 : } else {
440 0 : if (rankIpStr.empty()) {
441 0 : rankIp = nodeIp;
442 : } else {
443 0 : CHK_RET(ConvertIpAddress(rankIpStr, rankIp));
444 : }
445 : }
446 :
447 : // rankList
448 0 : RankInfo_t rankInfo;
449 0 : rankInfo.localRank = objIndex;
450 0 : rankInfo.serverId = serverId;
451 0 : rankInfo.serverIdx = serverIdx;
452 0 : rankInfo.hostIp = nodeIp;
453 0 : rankInfo.deviceInfo.devicePhyId = devicePhyId;
454 0 : rankInfo.deviceInfo.port = port;
455 0 : rankInfo.deviceInfo.deviceIp.push_back(rankIp);
456 0 : std::string errormessage = "";
457 0 : if (SalStrToULong(rankId, HCCL_BASE_DECIMAL, rankInfo.rankId) != HCCL_SUCCESS) {
458 0 : errormessage = "Value [" + rankId + "] for rankTable variable [rank_id] is invalid, expected value is a non-negative integer.";
459 0 : HCCL_ERROR("[%s][%s]errNo[0x%016llx] [%s]", LOG_KEYWORDS_INIT_GROUP.c_str(),
460 : LOG_KEYWORDS_RANKTABLE_CHECK.c_str(), HCOM_ERROR_CODE(HCCL_E_PARA), errormessage.c_str());
461 0 : return HCCL_E_PARA;
462 : }
463 0 : rankInfo.podName = ""; // podname在新场景下置空
464 : // ranktable中port无效,设置为环境变量HCCL_IF_BASE_PORT+该rank的local_rank_id,否则按照配置的port使用
465 0 : if (port == 0) {
466 0 : rankInfo.hostPort = HCCL_INVALID_PORT;
467 : } else {
468 0 : rankInfo.hostPort = port;
469 0 : hostPortMap_[rankInfo.hostPort] = HOST_PORT_USED;
470 : }
471 0 : clusterInfo.rankList.push_back(rankInfo);
472 0 : HCCL_DEBUG("[%s.json]->rankId[%u], nodeAddr[%s]", fileName_.c_str(),
473 : rankInfo.rankId, rankInfo.serverId.c_str());
474 :
475 0 : return HCCL_SUCCESS;
476 0 : }
|