Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 : #include "rank_info_types.h"
11 : #include "npu_nic_affinity.h"
12 : #include <stdio.h>
13 : #include <string.h>
14 : #include <stdlib.h>
15 : #include "securec.h"
16 : #include "hal.h"
17 : #include "topo_addr_info_log.h"
18 : #include "topo_addr_info_perf.h"
19 :
20 : #define MAX_PORTS_STR_LEN (512)
21 :
22 291 : char* AddrToString(const Addr* addr)
23 : {
24 291 : const size_t max_buffer_size = 102400;
25 291 : char* buf = (char*)malloc(max_buffer_size);
26 291 : int ret = 0;
27 291 : if (buf == NULL) {
28 0 : return NULL;
29 : }
30 291 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
31 291 : char ports[MAX_PORTS_STR_LEN] = {0};
32 618 : for (int i = 0; i < addr->port_count; i++) {
33 327 : if (i > (MAX_PORT_NUM - 1)) {
34 0 : break;
35 : }
36 327 : char port[MAX_PORT_LEN] = {0};
37 327 : ret = sprintf_s(port, sizeof(port), "\"%s\"", addr->ports[i]);
38 327 : if (ret < 0) {
39 0 : break;
40 : }
41 327 : errno_t r = strcat_s(ports, MAX_PORTS_STR_LEN, port);
42 327 : if (r != 0) {
43 0 : break;
44 : }
45 327 : if (i != addr->port_count - 1) {
46 36 : r = strcat_s(ports, MAX_PORTS_STR_LEN, ",");
47 36 : if (r != 0) {
48 0 : break;
49 : }
50 : }
51 : }
52 291 : ret = sprintf_s(
53 : buf, max_buffer_size, "{\"addr_type\": \"%s\", \"addr\": \"%s\", \"plane_id\": \"%s\", \"ports\": [%s]}",
54 291 : addr->addr_type, addr->addr, addr->plane_id, ports);
55 291 : if (ret < 0) {
56 0 : free(buf);
57 0 : buf = NULL;
58 : }
59 291 : return buf;
60 : }
61 :
62 654 : void NetLayerInit(NetLayer* layer, int level, const char* layer_id)
63 : {
64 654 : memset_s(layer, sizeof(NetLayer), 0, sizeof(NetLayer));
65 654 : layer->net_layer = level;
66 654 : layer->addr_count = 0;
67 654 : (void)strcpy_s(layer->net_instance_id, sizeof(layer->net_instance_id), layer_id);
68 654 : }
69 :
70 654 : void NetLayerSetNetType(NetLayer* layer, const char* net_type)
71 : {
72 654 : (void)strcpy_s(layer->net_type, sizeof(layer->net_type), net_type);
73 654 : }
74 :
75 290 : void NetLayerAddAddr(NetLayer* layer, const Addr* addr)
76 : {
77 290 : if (layer->addr_count >= MAX_ADDR_NUM) {
78 0 : return;
79 : }
80 290 : (void)memcpy_s(&layer->rank_addr_list[layer->addr_count], sizeof(Addr), addr, sizeof(Addr));
81 290 : layer->addr_count++;
82 : }
83 :
84 2 : void NetLayerSetAddrAt(NetLayer* layer, const Addr* addr, int index)
85 : {
86 2 : if (index < 0 || index >= MAX_ADDR_NUM) {
87 0 : return;
88 : }
89 2 : (void)memcpy_s(&layer->rank_addr_list[index], sizeof(Addr), addr, sizeof(Addr));
90 2 : layer->addr_count++;
91 : }
92 :
93 364 : char* NetLayerToString(const NetLayer* layer)
94 : {
95 364 : const size_t max_buffer_size = 102400;
96 364 : char* buf = (char*)malloc(max_buffer_size);
97 364 : if (buf == NULL) {
98 0 : return NULL;
99 : }
100 364 : char* addr_list = (char*)malloc(max_buffer_size);
101 364 : if (addr_list == NULL) {
102 0 : free(buf);
103 0 : return NULL;
104 : }
105 364 : memset_s(addr_list, max_buffer_size, 0, max_buffer_size);
106 364 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
107 655 : for (int i = 0; i < layer->addr_count; i++) {
108 291 : char* addr = AddrToString(&layer->rank_addr_list[i]);
109 291 : if (addr == NULL) {
110 0 : continue;
111 : }
112 291 : if (strcat_s(addr_list, max_buffer_size, addr) != 0) {
113 0 : free(addr);
114 0 : break;
115 : }
116 291 : if (i != layer->addr_count - 1) {
117 55 : if (strcat_s(addr_list, max_buffer_size, ",") != 0) {
118 0 : free(addr);
119 0 : break;
120 : }
121 : }
122 291 : free(addr);
123 : }
124 364 : int ret = sprintf_s(
125 : buf, max_buffer_size,
126 : "{\"net_layer\": %d, \"net_instance_id\": \"%s\", \"net_type\": \"%s\",\"net_attr\":\"%s\","
127 : "\"rank_addr_list\": [%s]}",
128 364 : layer->net_layer, layer->net_instance_id, layer->net_type, layer->net_attr, addr_list);
129 364 : free(addr_list);
130 364 : if (ret < 0) {
131 0 : free(buf);
132 0 : buf = NULL;
133 : }
134 364 : return buf;
135 : }
136 :
137 330 : char* RankListToString(const RootInfo* rootinfo)
138 : {
139 330 : const size_t max_buffer_size = 102400;
140 330 : char* buf = (char*)malloc(max_buffer_size);
141 330 : if (buf == NULL) {
142 0 : return NULL;
143 : }
144 330 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
145 660 : for (int i = 0; i < rootinfo->rank_count; i++) {
146 330 : char* rank = RankToString(&rootinfo->ranks[i]);
147 330 : errno_t ret = strcat_s(buf, max_buffer_size, rank);
148 330 : if (ret != 0) {
149 0 : free(rank);
150 0 : break;
151 : }
152 330 : if (i != rootinfo->rank_count - 1) {
153 0 : if (strcat_s(buf, max_buffer_size, ",") != 0) {
154 0 : free(rank);
155 0 : break;
156 : }
157 : }
158 330 : free(rank);
159 : }
160 330 : return buf;
161 : }
162 :
163 330 : void RankInit(Rank* rank, int deviceId, int localId)
164 : {
165 330 : memset_s(rank, sizeof(Rank), 0, sizeof(Rank));
166 330 : rank->device_id = deviceId;
167 330 : rank->local_id = localId;
168 330 : rank->level_count = 0;
169 330 : }
170 :
171 364 : void RankAddNetLayer(Rank* rank, const NetLayer* layer)
172 : {
173 364 : if (rank->level_count >= MAX_NET_LEVEL_NUM) {
174 0 : return;
175 : }
176 364 : memcpy_s(&rank->level_list[rank->level_count], sizeof(NetLayer), layer, sizeof(NetLayer));
177 364 : rank->level_count++;
178 : }
179 :
180 330 : char* RootInfoToString(const RootInfo* rootinfo)
181 : {
182 330 : const size_t max_buffer_size = 102400;
183 330 : char* buf = (char*)malloc(max_buffer_size);
184 330 : if (buf == NULL) {
185 0 : return NULL;
186 : }
187 330 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
188 330 : char* rank_list = RankListToString(rootinfo);
189 330 : int ret = sprintf_s(
190 : buf, max_buffer_size,
191 : "{\"version\": \"%s\", \"topo_file_path\": \"%s\","
192 : "\"rank_count\": %d, \"rank_list\": [%s]}",
193 330 : rootinfo->version, rootinfo->topo_file_path, rootinfo->rank_count, rank_list);
194 330 : free(rank_list);
195 330 : if (ret < 0) {
196 0 : free(buf);
197 0 : buf = NULL;
198 : }
199 330 : return buf;
200 : }
201 :
202 330 : void RootInfoInit(RootInfo* rootinfo)
203 : {
204 330 : memset_s(rootinfo, sizeof(RootInfo), 0, sizeof(RootInfo));
205 330 : strcpy_s(rootinfo->version, sizeof(rootinfo->version), "2.0");
206 330 : rootinfo->rank_count = 0;
207 330 : }
208 :
209 330 : void RootInfoAddRank(RootInfo* rootinfo, const Rank* rank)
210 : {
211 330 : if (rootinfo->rank_count >= MAX_RANK_NUM) {
212 0 : return;
213 : }
214 330 : memcpy_s(&rootinfo->ranks[rootinfo->rank_count], sizeof(Rank), rank, sizeof(Rank));
215 330 : rootinfo->rank_count++;
216 : }
217 :
218 0 : void AddrInit(Addr* addr) { memset_s(addr, sizeof(Addr), 0, sizeof(Addr)); }
219 :
220 68 : void AddrSetEID(Addr* addr, const dcmi_urma_eid_t* eid)
221 : {
222 1156 : for (int i = 0; i < DCMI_URMA_EID_SIZE; i++) {
223 1088 : int ret = sprintf_s(&addr->addr[i * 2], MAX_NET_ADDR_LEN - (i * 2), "%02x", eid->raw[i]);
224 1088 : if (ret < 0) {
225 0 : return;
226 : }
227 : }
228 68 : (void)strcpy_s(addr->addr_type, sizeof(addr->addr_type), "EID");
229 : }
230 :
231 224 : void AddrSetIP(Addr* addr, const char* ip)
232 : {
233 224 : (void)strcpy_s(addr->addr, sizeof(addr->addr), ip);
234 224 : (void)strcpy_s(addr->addr_type, sizeof(addr->addr_type), "IPV4");
235 224 : }
236 :
237 70 : void AddrSetPlaneId(Addr* addr, const char* plane_id)
238 : {
239 70 : (void)strcpy_s(addr->plane_id, sizeof(addr->plane_id), plane_id);
240 70 : }
241 :
242 328 : int AddrAddPort(Addr* addr, const char* port)
243 : {
244 328 : if (addr->port_count >= (MAX_PORT_NUM - 1)) {
245 0 : return -1;
246 : }
247 328 : return strcpy_s(addr->ports[addr->port_count++], MAX_PORT_LEN, port);
248 : }
249 :
250 330 : char* RankToString(const Rank* rank)
251 : {
252 330 : const size_t max_buf_size = 102400;
253 330 : char* buf = (char*)malloc(max_buf_size);
254 330 : if (buf == NULL) {
255 0 : return NULL;
256 : }
257 330 : char* level_list = (char*)malloc(max_buf_size);
258 330 : if (level_list == NULL) {
259 0 : free(buf);
260 0 : return NULL;
261 : }
262 330 : (void)memset_s(buf, max_buf_size, 0, max_buf_size);
263 330 : (void)memset_s(level_list, max_buf_size, 0, max_buf_size);
264 694 : for (int i = 0; i < rank->level_count; ++i) {
265 364 : char* layer = NetLayerToString(&rank->level_list[i]);
266 364 : if (strcat_s(level_list, max_buf_size, layer) != 0) {
267 0 : free(layer);
268 0 : break;
269 : }
270 364 : if (i != (rank->level_count - 1)) {
271 114 : if (strcat_s(level_list, max_buf_size, ", ") != 0) {
272 0 : free(layer);
273 0 : break;
274 : }
275 : }
276 364 : free(layer);
277 : }
278 330 : int ret = sprintf_s(
279 330 : buf, max_buf_size, "{\"device_id\": %d, \"local_id\": %d, \"level_list\": [%s]}", rank->device_id,
280 330 : rank->local_id, level_list);
281 330 : free(level_list);
282 330 : if (ret < 0) {
283 0 : free(buf);
284 0 : buf = NULL;
285 : }
286 330 : return buf;
287 : }
288 :
289 332 : TopoAddrResult ProcessLayerRoce(int npu_id, NetLayer* layer)
290 : {
291 332 : TOPO_PERF_BEGIN(ProcessLayerRoce);
292 : #define PROC_ROCE_LEVEL (3)
293 332 : char ip[MAX_ADDR_LEN] = {0};
294 332 : TopoAddrResult ret = GetRoceIpFromXml(npu_id, ip, sizeof(ip));
295 332 : if (ret != TOPO_SUCCESS || ip[0] == '\0') {
296 110 : TOPO_INFO("ProcessLayerRoce: GetRoceIpFromXml failed for npu_id=%d, ret=%d", npu_id, ret);
297 110 : TOPO_PERF_END(ProcessLayerRoce);
298 110 : return (ret != TOPO_SUCCESS) ? ret : TOPO_ERR_NOT_FOUND;
299 : }
300 222 : NetLayerInit(layer, PROC_ROCE_LEVEL, "cluster");
301 222 : NetLayerSetNetType(layer, NET_TYPE_CLOS);
302 : Addr addr;
303 222 : (void)memset_s(&addr, sizeof(Addr), 0x00, sizeof(Addr));
304 222 : AddrSetIP(&addr, ip);
305 222 : (void)strcpy_s(addr.plane_id, MAX_PLANE_ID_LEN, "plane0");
306 222 : AddrAddPort(&addr, "d2h");
307 222 : NetLayerAddAddr(layer, &addr);
308 222 : TOPO_PERF_END(ProcessLayerRoce);
309 222 : return TOPO_SUCCESS;
310 : }
|