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_ranktableOffline.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 "sal_pub.h"
24 : #include "config.h"
25 :
26 : using namespace hccl;
27 :
28 0 : TopoinfoRanktableOffline::TopoinfoRanktableOffline(const std::string &rankTableM)
29 0 : : TopoInfoRanktableParser(rankTableM, "0"), deviceNumPerServer_(0), curServerDeviceNum_(0)
30 : {
31 0 : }
32 :
33 0 : TopoinfoRanktableOffline::~TopoinfoRanktableOffline()
34 : {
35 0 : }
36 :
37 0 : HcclResult TopoinfoRanktableOffline::GetSingleRank(const nlohmann::json &ranksObj, u32 objIndex,
38 : RankTable_t &clusterInfo, u32 &serverIdx, std::string &nodeId)
39 : {
40 0 : RankInfo_t rankInfo;
41 :
42 : // 获取rank_id
43 0 : std::string rankInfoStr;
44 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_id", rankInfoStr, false));
45 0 : if (SalStrToULong(rankInfoStr, HCCL_BASE_DECIMAL, rankInfo.rankId) != HCCL_SUCCESS) {
46 0 : HCCL_ERROR("[Get][SingleRank]errNo[0x%016llx] rankid[%s] is invalid",
47 : HCOM_ERROR_CODE(HCCL_E_PARA), rankInfoStr.c_str());
48 0 : return HCCL_E_PARA;
49 : }
50 : // 获取item_id, -1表示 host
51 0 : CHK_RET(GetJsonArrayMemberProperty(ranksObj, objIndex, "item_id", rankInfoStr, false));
52 0 : CHK_RET(SalStrToInt(rankInfoStr, HCCL_BASE_DECIMAL, rankInfo.itemId));
53 : // 为了适配GetDevNum函数
54 0 : if (rankInfo.itemId == HOST_DEVICE_ID) {
55 0 : rankInfo.deviceInfo.devicePhyId = HOST_DEVICE_ID;
56 : } else {
57 0 : curServerDeviceNum_++;
58 : }
59 : // 获取rank_ip
60 0 : if (GetJsonArrayMemberProperty(ranksObj, objIndex, "rank_ip", rankInfoStr, true) == HCCL_E_NOT_FOUND) {
61 0 : rankInfo.hostIp = HcclIpAddress();
62 : } else {
63 0 : CHK_RET(ConvertIpAddress(rankInfoStr, rankInfo.hostIp));
64 : }
65 :
66 0 : rankInfo.serverId = nodeId;
67 0 : rankInfo.localRank = objIndex;
68 0 : rankInfo.serverIdx = serverIdx;
69 0 : clusterInfo.rankList.push_back(rankInfo);
70 0 : HCCL_INFO("[%s.json]->rankId[%u], serverIdx[%u]", fileName_.c_str(),
71 : rankInfo.rankId, rankInfo.serverIdx);
72 :
73 0 : return HCCL_SUCCESS;
74 0 : }
75 :
76 0 : HcclResult TopoinfoRanktableOffline::GetSingleNode(const nlohmann::json &NodeListObj, u32 objIndex,
77 : RankTable_t &clusterInfo, u32 &serverIdx)
78 : {
79 : // 获取信息
80 0 : nlohmann::json Ranks;
81 0 : std::string nodeId;
82 :
83 : // 处理ranklist
84 : // 获取node_id
85 0 : CHK_RET(GetJsonArrayMemberProperty(NodeListObj, objIndex, "node_id", nodeId, false));
86 0 : HCCL_DEBUG("Get Node[%u]: serverIdx:[%u] nodeId[%s]", objIndex, serverIdx, nodeId.c_str());
87 0 : CHK_RET(GetJsonArrayMemberProperty(NodeListObj, objIndex, "rank_list", Ranks, false));
88 :
89 0 : HCCL_INFO("[%s.json] -> rank_list: size:%zu", fileName_.c_str(), Ranks.size());
90 0 : CHK_PRT_RET(Ranks.size() == 0, HCCL_ERROR("[Get][Ranks]Ranks size is zero"), HCCL_E_PARA);
91 :
92 : // 获取单rank信息
93 0 : for (u32 index = 0; index < Ranks.size(); index++) {
94 0 : CHK_RET(GetSingleRank(Ranks, index, clusterInfo, serverIdx, nodeId));
95 : }
96 :
97 0 : return HCCL_SUCCESS;
98 0 : }
99 :
100 0 : HcclResult TopoinfoRanktableOffline::GetRanktableInfo(RankTable_t &clusterInfo)
101 : {
102 : // 清空list
103 0 : clusterInfo.rankList.clear();
104 :
105 : // 获取信息
106 0 : nlohmann::json node_list;
107 :
108 0 : CHK_RET(GetJsonProperty(fileContent_, "node_list", node_list, false));
109 0 : HCCL_DEBUG("[rankTableJson] -> nodeListSize: [%zu]", node_list.size());
110 :
111 : // 保存serverNum
112 0 : clusterInfo.serverNum = node_list.size();
113 0 : if (clusterInfo.serverNum == 0) {
114 0 : HCCL_ERROR("[Get][RanktableInfo]errNo[0x%016llx] node num is zero", HCOM_ERROR_CODE(HCCL_E_PARA));
115 0 : return HCCL_E_PARA;
116 : }
117 : // 获得single node信息
118 0 : for (u32 index = 0; index < clusterInfo.serverNum; index++) {
119 0 : curServerDeviceNum_ = 0;
120 0 : CHK_RET(GetSingleNode(node_list, index, clusterInfo, index));
121 0 : if (index == 0) {
122 0 : deviceNumPerServer_ = curServerDeviceNum_;
123 0 : } else if (curServerDeviceNum_ != deviceNumPerServer_) {
124 0 : HCCL_ERROR("[GetRanktableInfo] device num is diff.first node device num:[%d] cur node device num:[%d]",
125 : curServerDeviceNum_, deviceNumPerServer_);
126 0 : return HCCL_E_PARA;
127 : }
128 : }
129 :
130 : // 保存deviceNum和rankNum
131 0 : CHK_RET(GetDevNum(clusterInfo.rankList, clusterInfo.deviceNum));
132 0 : clusterInfo.rankNum = clusterInfo.rankList.size();
133 :
134 0 : return HCCL_SUCCESS;
135 0 : }
136 :
137 0 : HcclResult TopoinfoRanktableOffline::ParserClusterInfo(hccl::RankTable_t &rankTable)
138 : {
139 : // 获取ranktable info信息
140 0 : CHK_RET(GetRanktableInfo(rankTable));
141 0 : std::sort(rankTable.rankList.begin(), rankTable.rankList.end(),
142 0 : [&](const RankInfo_t &a, const RankInfo_t &b) -> bool {return a.rankId < b.rankId;});
143 :
144 : // 校验ranktable是否正确
145 0 : CHK_RET(CheckRankListInfo(rankTable.rankList));
146 0 : return HCCL_SUCCESS;
147 : }
148 :
149 0 : HcclResult TopoinfoRanktableOffline::Init()
150 : {
151 : // 根据rankTable类型标记执行读文件或读字符串,将内容保存在json对象fileContent_中
152 0 : CHK_RET(LoadRankTableString(rankTableFile_));
153 : // 解析rankTable
154 0 : CHK_RET(ParserClusterInfo(rankTable_));
155 0 : return HCCL_SUCCESS;
156 : }
157 :
158 0 : HcclResult TopoinfoRanktableOffline::GetClusterInfo(RankTable_t &clusterInfo)
159 : {
160 : // 获取rankInfo
161 0 : clusterInfo.deviceNum = rankTable_.deviceNum;
162 0 : clusterInfo.serverNum = rankTable_.serverNum;
163 0 : clusterInfo.rankNum = rankTable_.rankNum;
164 0 : clusterInfo.rankList = rankTable_.rankList;
165 0 : return HCCL_SUCCESS;
166 : }
167 :
168 0 : HcclResult TopoinfoRanktableOffline::GetDeviceNumPerServer(s32 &deviceNum)
169 : {
170 0 : deviceNum = deviceNumPerServer_;
171 0 : return HCCL_SUCCESS;
172 : }
|