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(buf, max_buffer_size,
53 291 : "{\"addr_type\": \"%s\", \"addr\": \"%s\", \"plane_id\": \"%s\", \"ports\": [%s]}", addr->addr_type, addr->addr,
54 291 : 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(buf, max_buffer_size,
125 : "{\"net_layer\": %d, \"net_instance_id\": \"%s\", \"net_type\": \"%s\",\"net_attr\":\"%s\","
126 : "\"rank_addr_list\": [%s]}",
127 364 : layer->net_layer, layer->net_instance_id, layer->net_type, layer->net_attr, addr_list);
128 364 : free(addr_list);
129 364 : if (ret < 0) {
130 0 : free(buf);
131 0 : buf = NULL;
132 : }
133 364 : return buf;
134 : }
135 :
136 330 : char *RankListToString(const RootInfo *rootinfo)
137 : {
138 330 : const size_t max_buffer_size = 102400;
139 330 : char *buf = (char *)malloc(max_buffer_size);
140 330 : if (buf == NULL) {
141 0 : return NULL;
142 : }
143 330 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
144 660 : for (int i = 0; i < rootinfo->rank_count; i++) {
145 330 : char *rank = RankToString(&rootinfo->ranks[i]);
146 330 : errno_t ret = strcat_s(buf, max_buffer_size, rank);
147 330 : if (ret != 0) {
148 0 : free(rank);
149 0 : break;
150 : }
151 330 : if (i != rootinfo->rank_count - 1) {
152 0 : if (strcat_s(buf, max_buffer_size, ",") != 0) {
153 0 : free(rank);
154 0 : break;
155 : }
156 : }
157 330 : free(rank);
158 : }
159 330 : return buf;
160 : }
161 :
162 330 : void RankInit(Rank *rank, int deviceId, int localId)
163 : {
164 330 : memset_s(rank, sizeof(Rank), 0, sizeof(Rank));
165 330 : rank->device_id = deviceId;
166 330 : rank->local_id = localId;
167 330 : rank->level_count = 0;
168 330 : }
169 :
170 364 : void RankAddNetLayer(Rank *rank, const NetLayer *layer)
171 : {
172 364 : if (rank->level_count >= MAX_NET_LEVEL_NUM) {
173 0 : return;
174 : }
175 364 : memcpy_s(&rank->level_list[rank->level_count], sizeof(NetLayer), layer, sizeof(NetLayer));
176 364 : rank->level_count++;
177 : }
178 :
179 330 : char *RootInfoToString(const RootInfo *rootinfo)
180 : {
181 330 : const size_t max_buffer_size = 102400;
182 330 : char *buf = (char *)malloc(max_buffer_size);
183 330 : if (buf == NULL) {
184 0 : return NULL;
185 : }
186 330 : memset_s(buf, max_buffer_size, 0, max_buffer_size);
187 330 : char *rank_list = RankListToString(rootinfo);
188 330 : int ret = sprintf_s(buf, max_buffer_size,
189 : "{\"version\": \"%s\", \"topo_file_path\": \"%s\","
190 : "\"rank_count\": %d, \"rank_list\": [%s]}",
191 330 : rootinfo->version, rootinfo->topo_file_path, rootinfo->rank_count, rank_list);
192 330 : free(rank_list);
193 330 : if (ret < 0) {
194 0 : free(buf);
195 0 : buf = NULL;
196 : }
197 330 : return buf;
198 : }
199 :
200 330 : void RootInfoInit(RootInfo *rootinfo)
201 : {
202 330 : memset_s(rootinfo, sizeof(RootInfo), 0, sizeof(RootInfo));
203 330 : strcpy_s(rootinfo->version, sizeof(rootinfo->version), "2.0");
204 330 : rootinfo->rank_count = 0;
205 330 : }
206 :
207 330 : void RootInfoAddRank(RootInfo *rootinfo, const Rank *rank)
208 : {
209 330 : if (rootinfo->rank_count >= MAX_RANK_NUM) {
210 0 : return;
211 : }
212 330 : memcpy_s(&rootinfo->ranks[rootinfo->rank_count], sizeof(Rank), rank, sizeof(Rank));
213 330 : rootinfo->rank_count++;
214 : }
215 :
216 0 : void AddrInit(Addr *addr)
217 : {
218 0 : memset_s(addr, sizeof(Addr), 0, sizeof(Addr));
219 0 : }
220 :
221 68 : void AddrSetEID(Addr *addr, const dcmi_urma_eid_t *eid)
222 : {
223 1156 : for (int i = 0; i < DCMI_URMA_EID_SIZE; i++) {
224 1088 : int ret = sprintf_s(&addr->addr[i * 2], MAX_NET_ADDR_LEN - (i * 2), "%02x", eid->raw[i]);
225 1088 : if (ret < 0) {
226 0 : return;
227 : }
228 : }
229 68 : (void)strcpy_s(addr->addr_type, sizeof(addr->addr_type), "EID");
230 : }
231 :
232 224 : void AddrSetIP(Addr *addr, const char *ip)
233 : {
234 224 : (void)strcpy_s(addr->addr, sizeof(addr->addr), ip);
235 224 : (void)strcpy_s(addr->addr_type, sizeof(addr->addr_type), "IPV4");
236 224 : }
237 :
238 70 : void AddrSetPlaneId(Addr *addr, const char *plane_id)
239 : {
240 70 : (void)strcpy_s(addr->plane_id, sizeof(addr->plane_id), plane_id);
241 70 : }
242 :
243 328 : int AddrAddPort(Addr *addr, const char *port)
244 : {
245 328 : if (addr->port_count >= (MAX_PORT_NUM - 1)) {
246 0 : return -1;
247 : }
248 328 : return strcpy_s(addr->ports[addr->port_count++], MAX_PORT_LEN, port);
249 : }
250 :
251 330 : char *RankToString(const Rank *rank)
252 : {
253 330 : const size_t max_buf_size = 102400;
254 330 : char *buf = (char *)malloc(max_buf_size);
255 330 : if (buf == NULL) {
256 0 : return NULL;
257 : }
258 330 : char *level_list = (char *)malloc(max_buf_size);
259 330 : if (level_list == NULL) {
260 0 : free(buf);
261 0 : return NULL;
262 : }
263 330 : (void)memset_s(buf, max_buf_size, 0, max_buf_size);
264 330 : (void)memset_s(level_list, max_buf_size, 0, max_buf_size);
265 694 : for (int i = 0; i < rank->level_count; ++i) {
266 364 : char *layer = NetLayerToString(&rank->level_list[i]);
267 364 : if (strcat_s(level_list, max_buf_size, layer) != 0) {
268 0 : free(layer);
269 0 : break;
270 : }
271 364 : if (i != (rank->level_count - 1)) {
272 114 : if (strcat_s(level_list, max_buf_size, ", ") != 0) {
273 0 : free(layer);
274 0 : break;
275 : }
276 : }
277 364 : free(layer);
278 : }
279 330 : int ret = sprintf_s(buf, max_buf_size, "{\"device_id\": %d, \"local_id\": %d, \"level_list\": [%s]}",
280 330 : rank->device_id, 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_ERR("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 : }
|