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