Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2022 Marvell.
3 : : */
4 : :
5 : : #include <rte_hash_crc.h>
6 : :
7 : : #include <mldev_utils.h>
8 : :
9 : : #include "cn10k_ml_ocm.h"
10 : :
11 : : #include "cnxk_ml_dev.h"
12 : : #include "cnxk_ml_model.h"
13 : : #include "cnxk_ml_ops.h"
14 : : #include "cnxk_ml_utils.h"
15 : :
16 : : static enum rte_ml_io_type
17 : : cn10k_ml_io_type_map(uint8_t type)
18 : : {
19 : : switch (type) {
20 : : case 1:
21 : : return RTE_ML_IO_TYPE_INT8;
22 : : case 2:
23 : : return RTE_ML_IO_TYPE_UINT8;
24 : : case 3:
25 : : return RTE_ML_IO_TYPE_INT16;
26 : : case 4:
27 : : return RTE_ML_IO_TYPE_UINT16;
28 : : case 5:
29 : : return RTE_ML_IO_TYPE_INT32;
30 : : case 6:
31 : : return RTE_ML_IO_TYPE_UINT32;
32 : : case 7:
33 : : return RTE_ML_IO_TYPE_FP16;
34 : : case 8:
35 : : return RTE_ML_IO_TYPE_FP32;
36 : : case 9:
37 : : return RTE_ML_IO_TYPE_INT64;
38 : : case 10:
39 : : return RTE_ML_IO_TYPE_UINT64;
40 : : }
41 : :
42 : : return RTE_ML_IO_TYPE_UNKNOWN;
43 : : }
44 : :
45 : : int
46 : 0 : cn10k_ml_model_metadata_check(uint8_t *buffer, uint64_t size)
47 : : {
48 : : struct cn10k_ml_model_metadata *metadata;
49 : : uint32_t payload_crc32c;
50 : : uint32_t header_crc32c;
51 : : uint32_t version;
52 : : uint8_t i;
53 : : uint8_t j;
54 : :
55 : : metadata = (struct cn10k_ml_model_metadata *)buffer;
56 : :
57 : : /* Header CRC check */
58 [ # # ]: 0 : if (metadata->header.header_crc32c != 0) {
59 : : header_crc32c =
60 : 0 : rte_hash_crc(buffer, sizeof(metadata->header) - sizeof(uint32_t), 0);
61 : :
62 [ # # ]: 0 : if (header_crc32c != metadata->header.header_crc32c) {
63 : 0 : plt_err("Invalid model, Header CRC mismatch");
64 : 0 : return -EINVAL;
65 : : }
66 : : }
67 : :
68 : : /* Payload CRC check */
69 [ # # ]: 0 : if (metadata->header.payload_crc32c != 0) {
70 : 0 : payload_crc32c = rte_hash_crc(buffer + sizeof(metadata->header),
71 : : size - sizeof(metadata->header), 0);
72 : :
73 [ # # ]: 0 : if (payload_crc32c != metadata->header.payload_crc32c) {
74 : 0 : plt_err("Invalid model, Payload CRC mismatch");
75 : 0 : return -EINVAL;
76 : : }
77 : : }
78 : :
79 : : /* Model magic string */
80 [ # # ]: 0 : if (strncmp((char *)metadata->header.magic, MRVL_ML_MODEL_MAGIC_STRING, 4) != 0) {
81 : 0 : plt_err("Invalid model, magic = %s", metadata->header.magic);
82 : 0 : return -EINVAL;
83 : : }
84 : :
85 : : /* Target architecture */
86 [ # # ]: 0 : if (metadata->header.target_architecture != MRVL_ML_MODEL_TARGET_ARCH) {
87 : 0 : plt_err("Model target architecture (%u) not supported",
88 : : metadata->header.target_architecture);
89 : 0 : return -ENOTSUP;
90 : : }
91 : :
92 : : /* Header version */
93 : 0 : version = metadata->header.version[0] * 1000 + metadata->header.version[1] * 100 +
94 : 0 : metadata->header.version[2] * 10 + metadata->header.version[3];
95 [ # # ]: 0 : if (version < MRVL_ML_MODEL_VERSION_MIN) {
96 : 0 : plt_err("Metadata version = %u.%u.%u.%u (< %u.%u.%u.%u) not supported",
97 : : metadata->header.version[0], metadata->header.version[1],
98 : : metadata->header.version[2], metadata->header.version[3],
99 : : (MRVL_ML_MODEL_VERSION_MIN / 1000) % 10,
100 : : (MRVL_ML_MODEL_VERSION_MIN / 100) % 10,
101 : : (MRVL_ML_MODEL_VERSION_MIN / 10) % 10, MRVL_ML_MODEL_VERSION_MIN % 10);
102 : 0 : return -ENOTSUP;
103 : : }
104 : :
105 : : /* Init section */
106 [ # # ]: 0 : if (metadata->init_model.file_size == 0) {
107 : 0 : plt_err("Invalid metadata, init_model.file_size = %u",
108 : : metadata->init_model.file_size);
109 : 0 : return -EINVAL;
110 : : }
111 : :
112 : : /* Main section */
113 [ # # ]: 0 : if (metadata->main_model.file_size == 0) {
114 : 0 : plt_err("Invalid metadata, main_model.file_size = %u",
115 : : metadata->main_model.file_size);
116 : 0 : return -EINVAL;
117 : : }
118 : :
119 : : /* Finish section */
120 [ # # ]: 0 : if (metadata->finish_model.file_size == 0) {
121 : 0 : plt_err("Invalid metadata, finish_model.file_size = %u",
122 : : metadata->finish_model.file_size);
123 : 0 : return -EINVAL;
124 : : }
125 : :
126 : : /* Weights and Bias */
127 [ # # ]: 0 : if (metadata->weights_bias.file_size == 0) {
128 : 0 : plt_err("Invalid metadata, weights_bias.file_size = %u",
129 : : metadata->weights_bias.file_size);
130 : 0 : return -EINVAL;
131 : : }
132 : :
133 [ # # ]: 0 : if (metadata->weights_bias.relocatable != 1) {
134 : 0 : plt_err("Model not supported, non-relocatable weights and bias");
135 : 0 : return -ENOTSUP;
136 : : }
137 : :
138 : : /* Check input count */
139 [ # # ]: 0 : if (version < 2301) {
140 [ # # ]: 0 : if (metadata->model.num_input > MRVL_ML_NUM_INPUT_OUTPUT_1) {
141 : 0 : plt_err("Invalid metadata, num_input = %u (> %u)",
142 : : metadata->model.num_input, MRVL_ML_NUM_INPUT_OUTPUT_1);
143 : 0 : return -EINVAL;
144 : : }
145 : :
146 : : /* Check output count */
147 [ # # ]: 0 : if (metadata->model.num_output > MRVL_ML_NUM_INPUT_OUTPUT_1) {
148 : 0 : plt_err("Invalid metadata, num_output = %u (> %u)",
149 : : metadata->model.num_output, MRVL_ML_NUM_INPUT_OUTPUT_1);
150 : 0 : return -EINVAL;
151 : : }
152 : : } else {
153 [ # # ]: 0 : if (metadata->model.num_input > MRVL_ML_NUM_INPUT_OUTPUT) {
154 : 0 : plt_err("Invalid metadata, num_input = %u (> %u)",
155 : : metadata->model.num_input, MRVL_ML_NUM_INPUT_OUTPUT);
156 : 0 : return -EINVAL;
157 : : }
158 : :
159 : : /* Check output count */
160 [ # # ]: 0 : if (metadata->model.num_output > MRVL_ML_NUM_INPUT_OUTPUT) {
161 : 0 : plt_err("Invalid metadata, num_output = %u (> %u)",
162 : : metadata->model.num_output, MRVL_ML_NUM_INPUT_OUTPUT);
163 : 0 : return -EINVAL;
164 : : }
165 : : }
166 : :
167 : : /* Inputs */
168 [ # # ]: 0 : for (i = 0; i < metadata->model.num_input; i++) {
169 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
170 [ # # ]: 0 : if (rte_ml_io_type_size_get(
171 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input1[i].input_type)) <= 0) {
172 : 0 : plt_err("Invalid metadata, input1[%u] : input_type = %u", i,
173 : : metadata->input1[i].input_type);
174 : 0 : return -EINVAL;
175 : : }
176 : :
177 [ # # ]: 0 : if (rte_ml_io_type_size_get(cn10k_ml_io_type_map(
178 [ # # ]: 0 : metadata->input1[i].model_input_type)) <= 0) {
179 : 0 : plt_err("Invalid metadata, input1[%u] : model_input_type = %u", i,
180 : : metadata->input1[i].model_input_type);
181 : 0 : return -EINVAL;
182 : : }
183 : :
184 [ # # ]: 0 : if (metadata->input1[i].relocatable != 1) {
185 : 0 : plt_err("Model not supported, non-relocatable input1: %u", i);
186 : 0 : return -ENOTSUP;
187 : : }
188 : : } else {
189 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
190 [ # # ]: 0 : if (rte_ml_io_type_size_get(
191 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input2[j].input_type)) <= 0) {
192 : 0 : plt_err("Invalid metadata, input2[%u] : input_type = %u", j,
193 : : metadata->input2[j].input_type);
194 : 0 : return -EINVAL;
195 : : }
196 : :
197 [ # # ]: 0 : if (rte_ml_io_type_size_get(cn10k_ml_io_type_map(
198 [ # # ]: 0 : metadata->input2[j].model_input_type)) <= 0) {
199 : 0 : plt_err("Invalid metadata, input2[%u] : model_input_type = %u", j,
200 : : metadata->input2[j].model_input_type);
201 : 0 : return -EINVAL;
202 : : }
203 : :
204 [ # # ]: 0 : if (metadata->input2[j].relocatable != 1) {
205 : 0 : plt_err("Model not supported, non-relocatable input2: %u", j);
206 : 0 : return -ENOTSUP;
207 : : }
208 : : }
209 : : }
210 : :
211 : : /* Outputs */
212 [ # # ]: 0 : for (i = 0; i < metadata->model.num_output; i++) {
213 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
214 [ # # ]: 0 : if (rte_ml_io_type_size_get(
215 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output1[i].output_type)) <= 0) {
216 : 0 : plt_err("Invalid metadata, output1[%u] : output_type = %u", i,
217 : : metadata->output1[i].output_type);
218 : 0 : return -EINVAL;
219 : : }
220 : :
221 [ # # ]: 0 : if (rte_ml_io_type_size_get(cn10k_ml_io_type_map(
222 [ # # ]: 0 : metadata->output1[i].model_output_type)) <= 0) {
223 : 0 : plt_err("Invalid metadata, output1[%u] : model_output_type = %u", i,
224 : : metadata->output1[i].model_output_type);
225 : 0 : return -EINVAL;
226 : : }
227 : :
228 [ # # ]: 0 : if (metadata->output1[i].relocatable != 1) {
229 : 0 : plt_err("Model not supported, non-relocatable output1: %u", i);
230 : 0 : return -ENOTSUP;
231 : : }
232 : : } else {
233 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
234 [ # # ]: 0 : if (rte_ml_io_type_size_get(
235 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output2[j].output_type)) <= 0) {
236 : 0 : plt_err("Invalid metadata, output2[%u] : output_type = %u", j,
237 : : metadata->output2[j].output_type);
238 : 0 : return -EINVAL;
239 : : }
240 : :
241 [ # # ]: 0 : if (rte_ml_io_type_size_get(cn10k_ml_io_type_map(
242 [ # # ]: 0 : metadata->output2[j].model_output_type)) <= 0) {
243 : 0 : plt_err("Invalid metadata, output2[%u] : model_output_type = %u", j,
244 : : metadata->output2[j].model_output_type);
245 : 0 : return -EINVAL;
246 : : }
247 : :
248 [ # # ]: 0 : if (metadata->output2[j].relocatable != 1) {
249 : 0 : plt_err("Model not supported, non-relocatable output2: %u", j);
250 : 0 : return -ENOTSUP;
251 : : }
252 : : }
253 : : }
254 : :
255 : : return 0;
256 : : }
257 : :
258 : : void
259 : 0 : cn10k_ml_model_metadata_update(struct cn10k_ml_model_metadata *metadata)
260 : : {
261 : : uint8_t i;
262 : : uint8_t j;
263 : :
264 [ # # ]: 0 : for (i = 0; i < metadata->model.num_input; i++) {
265 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
266 : 0 : metadata->input1[i].input_type =
267 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input1[i].input_type);
268 : 0 : metadata->input1[i].model_input_type =
269 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input1[i].model_input_type);
270 : :
271 [ # # ]: 0 : if (metadata->input1[i].shape.w == 0)
272 : 0 : metadata->input1[i].shape.w = 1;
273 : :
274 [ # # ]: 0 : if (metadata->input1[i].shape.x == 0)
275 : 0 : metadata->input1[i].shape.x = 1;
276 : :
277 [ # # ]: 0 : if (metadata->input1[i].shape.y == 0)
278 : 0 : metadata->input1[i].shape.y = 1;
279 : :
280 [ # # ]: 0 : if (metadata->input1[i].shape.z == 0)
281 : 0 : metadata->input1[i].shape.z = 1;
282 : : } else {
283 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
284 : 0 : metadata->input2[j].input_type =
285 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input2[j].input_type);
286 : 0 : metadata->input2[j].model_input_type =
287 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->input2[j].model_input_type);
288 : :
289 [ # # ]: 0 : if (metadata->input2[j].shape.w == 0)
290 : 0 : metadata->input2[j].shape.w = 1;
291 : :
292 [ # # ]: 0 : if (metadata->input2[j].shape.x == 0)
293 : 0 : metadata->input2[j].shape.x = 1;
294 : :
295 [ # # ]: 0 : if (metadata->input2[j].shape.y == 0)
296 : 0 : metadata->input2[j].shape.y = 1;
297 : :
298 [ # # ]: 0 : if (metadata->input2[j].shape.z == 0)
299 : 0 : metadata->input2[j].shape.z = 1;
300 : : }
301 : : }
302 : :
303 [ # # ]: 0 : for (i = 0; i < metadata->model.num_output; i++) {
304 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
305 : 0 : metadata->output1[i].output_type =
306 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output1[i].output_type);
307 : 0 : metadata->output1[i].model_output_type =
308 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output1[i].model_output_type);
309 : : } else {
310 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
311 : 0 : metadata->output2[j].output_type =
312 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output2[j].output_type);
313 : 0 : metadata->output2[j].model_output_type =
314 [ # # ]: 0 : cn10k_ml_io_type_map(metadata->output2[j].model_output_type);
315 : : }
316 : : }
317 : 0 : }
318 : :
319 : : void
320 : 0 : cn10k_ml_layer_addr_update(struct cnxk_ml_layer *layer, uint8_t *buffer, uint8_t *base_dma_addr)
321 : : {
322 : : struct cn10k_ml_model_metadata *metadata;
323 : : struct cn10k_ml_layer_addr *addr;
324 : : uint8_t *dma_addr_load;
325 : : int fpos;
326 : :
327 : : metadata = &layer->glow.metadata;
328 : : addr = &layer->glow.addr;
329 : :
330 : : /* Base address */
331 : 0 : addr->base_dma_addr_load = base_dma_addr;
332 : :
333 : : /* Init section */
334 : : dma_addr_load = addr->base_dma_addr_load;
335 : : fpos = sizeof(struct cn10k_ml_model_metadata);
336 : 0 : addr->init_load_addr = dma_addr_load;
337 [ # # ]: 0 : rte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->init_model.file_size);
338 : :
339 : : /* Main section */
340 : 0 : dma_addr_load += metadata->init_model.file_size;
341 : 0 : fpos += metadata->init_model.file_size;
342 : 0 : addr->main_load_addr = dma_addr_load;
343 [ # # ]: 0 : rte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->main_model.file_size);
344 : :
345 : : /* Finish section */
346 : 0 : dma_addr_load += metadata->main_model.file_size;
347 : 0 : fpos += metadata->main_model.file_size;
348 : 0 : addr->finish_load_addr = dma_addr_load;
349 [ # # ]: 0 : rte_memcpy(dma_addr_load, PLT_PTR_ADD(buffer, fpos), metadata->finish_model.file_size);
350 : :
351 : : /* Weights and Bias section */
352 : 0 : dma_addr_load += metadata->finish_model.file_size;
353 : 0 : fpos += metadata->finish_model.file_size;
354 : 0 : addr->wb_base_addr = PLT_PTR_SUB(dma_addr_load, metadata->weights_bias.mem_offset);
355 : 0 : addr->wb_load_addr = PLT_PTR_ADD(addr->wb_base_addr, metadata->weights_bias.mem_offset);
356 [ # # ]: 0 : rte_memcpy(addr->wb_load_addr, PLT_PTR_ADD(buffer, fpos), metadata->weights_bias.file_size);
357 : 0 : }
358 : :
359 : : void
360 : 0 : cn10k_ml_layer_io_info_set(struct cnxk_ml_io_info *io_info,
361 : : struct cn10k_ml_model_metadata *metadata)
362 : : {
363 : : uint8_t i;
364 : : uint8_t j;
365 : :
366 : : /* Inputs */
367 : 0 : io_info->nb_inputs = metadata->model.num_input;
368 : 0 : io_info->total_input_sz_d = 0;
369 : 0 : io_info->total_input_sz_q = 0;
370 [ # # ]: 0 : for (i = 0; i < metadata->model.num_input; i++) {
371 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
372 : 0 : rte_strscpy(io_info->input[i].name, (char *)metadata->input1[i].input_name,
373 : : MRVL_ML_INPUT_NAME_LEN);
374 : 0 : io_info->input[i].dtype = metadata->input1[i].input_type;
375 : 0 : io_info->input[i].qtype = metadata->input1[i].model_input_type;
376 : 0 : io_info->input[i].nb_dims = 4;
377 : 0 : io_info->input[i].shape[0] = metadata->input1[i].shape.w;
378 : 0 : io_info->input[i].shape[1] = metadata->input1[i].shape.x;
379 : 0 : io_info->input[i].shape[2] = metadata->input1[i].shape.y;
380 : 0 : io_info->input[i].shape[3] = metadata->input1[i].shape.z;
381 : 0 : io_info->input[i].nb_elements =
382 : 0 : metadata->input1[i].shape.w * metadata->input1[i].shape.x *
383 : 0 : metadata->input1[i].shape.y * metadata->input1[i].shape.z;
384 : 0 : io_info->input[i].sz_d =
385 : 0 : io_info->input[i].nb_elements *
386 : 0 : rte_ml_io_type_size_get(metadata->input1[i].input_type);
387 : 0 : io_info->input[i].sz_q =
388 : 0 : io_info->input[i].nb_elements *
389 : 0 : rte_ml_io_type_size_get(metadata->input1[i].model_input_type);
390 : 0 : io_info->input[i].scale = metadata->input1[i].qscale;
391 : :
392 : 0 : io_info->total_input_sz_d += io_info->input[i].sz_d;
393 : 0 : io_info->total_input_sz_q += io_info->input[i].sz_q;
394 : :
395 : 0 : plt_ml_dbg(
396 : : "layer_name = %s, input1[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u",
397 : : metadata->model.name, i, metadata->input1[i].shape.w,
398 : : metadata->input1[i].shape.x, metadata->input1[i].shape.y,
399 : : metadata->input1[i].shape.z, io_info->input[i].sz_d,
400 : : io_info->input[i].sz_q);
401 : : } else {
402 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
403 : :
404 : 0 : rte_strscpy(io_info->input[i].name, (char *)metadata->input2[j].input_name,
405 : : MRVL_ML_INPUT_NAME_LEN);
406 : 0 : io_info->input[i].dtype = metadata->input2[j].input_type;
407 : 0 : io_info->input[i].qtype = metadata->input2[j].model_input_type;
408 : 0 : io_info->input[i].nb_dims = 4;
409 : 0 : io_info->input[i].shape[0] = metadata->input2[j].shape.w;
410 : 0 : io_info->input[i].shape[1] = metadata->input2[j].shape.x;
411 : 0 : io_info->input[i].shape[2] = metadata->input2[j].shape.y;
412 : 0 : io_info->input[i].shape[3] = metadata->input2[j].shape.z;
413 : 0 : io_info->input[i].nb_elements =
414 : 0 : metadata->input2[j].shape.w * metadata->input2[j].shape.x *
415 : 0 : metadata->input2[j].shape.y * metadata->input2[j].shape.z;
416 : 0 : io_info->input[i].sz_d =
417 : 0 : io_info->input[i].nb_elements *
418 : 0 : rte_ml_io_type_size_get(metadata->input2[j].input_type);
419 : 0 : io_info->input[i].sz_q =
420 : 0 : io_info->input[i].nb_elements *
421 : 0 : rte_ml_io_type_size_get(metadata->input2[j].model_input_type);
422 : 0 : io_info->input[i].scale = metadata->input2[j].qscale;
423 : :
424 : 0 : io_info->total_input_sz_d += io_info->input[i].sz_d;
425 : 0 : io_info->total_input_sz_q += io_info->input[i].sz_q;
426 : :
427 : 0 : plt_ml_dbg(
428 : : "layer_name = %s, input2[%u] - w:%u x:%u y:%u z:%u, sz_d = %u sz_q = %u",
429 : : metadata->model.name, j, metadata->input2[j].shape.w,
430 : : metadata->input2[j].shape.x, metadata->input2[j].shape.y,
431 : : metadata->input2[j].shape.z, io_info->input[i].sz_d,
432 : : io_info->input[i].sz_q);
433 : : }
434 : : }
435 : :
436 : : /* Outputs */
437 : 0 : io_info->nb_outputs = metadata->model.num_output;
438 : 0 : io_info->total_output_sz_q = 0;
439 : 0 : io_info->total_output_sz_d = 0;
440 [ # # ]: 0 : for (i = 0; i < metadata->model.num_output; i++) {
441 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
442 : 0 : rte_strscpy(io_info->output[i].name,
443 : 0 : (char *)metadata->output1[i].output_name,
444 : : MRVL_ML_OUTPUT_NAME_LEN);
445 : 0 : io_info->output[i].dtype = metadata->output1[i].output_type;
446 : 0 : io_info->output[i].qtype = metadata->output1[i].model_output_type;
447 : 0 : io_info->output[i].nb_dims = 1;
448 : 0 : io_info->output[i].shape[0] = metadata->output1[i].size;
449 : 0 : io_info->output[i].nb_elements = metadata->output1[i].size;
450 : 0 : io_info->output[i].sz_d =
451 : 0 : io_info->output[i].nb_elements *
452 : 0 : rte_ml_io_type_size_get(metadata->output1[i].output_type);
453 : 0 : io_info->output[i].sz_q =
454 : 0 : io_info->output[i].nb_elements *
455 : 0 : rte_ml_io_type_size_get(metadata->output1[i].model_output_type);
456 : 0 : io_info->output[i].scale = metadata->output1[i].dscale;
457 : :
458 : 0 : io_info->total_output_sz_q += io_info->output[i].sz_q;
459 : 0 : io_info->total_output_sz_d += io_info->output[i].sz_d;
460 : :
461 : 0 : plt_ml_dbg("layer_name = %s, output1[%u] - sz_d = %u, sz_q = %u",
462 : : metadata->model.name, i, io_info->output[i].sz_d,
463 : : io_info->output[i].sz_q);
464 : : } else {
465 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
466 : :
467 : 0 : rte_strscpy(io_info->output[i].name,
468 : 0 : (char *)metadata->output2[j].output_name,
469 : : MRVL_ML_OUTPUT_NAME_LEN);
470 : 0 : io_info->output[i].dtype = metadata->output2[j].output_type;
471 : 0 : io_info->output[i].qtype = metadata->output2[j].model_output_type;
472 : 0 : io_info->output[i].nb_dims = 1;
473 : 0 : io_info->output[i].shape[0] = metadata->output2[j].size;
474 : 0 : io_info->output[i].nb_elements = metadata->output2[j].size;
475 : 0 : io_info->output[i].sz_d =
476 : 0 : io_info->output[i].nb_elements *
477 : 0 : rte_ml_io_type_size_get(metadata->output2[j].output_type);
478 : 0 : io_info->output[i].sz_q =
479 : 0 : io_info->output[i].nb_elements *
480 : 0 : rte_ml_io_type_size_get(metadata->output2[j].model_output_type);
481 : 0 : io_info->output[i].scale = metadata->output2[j].dscale;
482 : :
483 : 0 : io_info->total_output_sz_q += io_info->output[i].sz_q;
484 : 0 : io_info->total_output_sz_d += io_info->output[i].sz_d;
485 : :
486 : 0 : plt_ml_dbg("layer_name = %s, output2[%u] - sz_d = %u, sz_q = %u",
487 : : metadata->model.name, j, io_info->output[i].sz_d,
488 : : io_info->output[i].sz_q);
489 : : }
490 : : }
491 : 0 : }
492 : :
493 : : struct cnxk_ml_io_info *
494 : 0 : cn10k_ml_model_io_info_get(struct cnxk_ml_model *model, uint16_t layer_id)
495 : : {
496 : 0 : return &model->layer[layer_id].info;
497 : : }
498 : :
499 : : int
500 : 0 : cn10k_ml_model_ocm_pages_count(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_layer *layer,
501 : : uint8_t *buffer, uint16_t *wb_pages, uint16_t *scratch_pages)
502 : : {
503 : : struct cn10k_ml_model_metadata *metadata;
504 : : struct cn10k_ml_ocm *ocm;
505 : : uint64_t scratch_size;
506 : : uint64_t wb_size;
507 : :
508 : : metadata = (struct cn10k_ml_model_metadata *)buffer;
509 : : ocm = &cnxk_mldev->cn10k_mldev.ocm;
510 : :
511 : : /* Assume wb_size is zero for non-relocatable models */
512 [ # # ]: 0 : if (metadata->model.ocm_relocatable)
513 : 0 : wb_size = metadata->model.ocm_wb_range_end - metadata->model.ocm_wb_range_start + 1;
514 : : else
515 : : wb_size = 0;
516 : :
517 [ # # ]: 0 : if (wb_size % ocm->page_size)
518 : 0 : *wb_pages = wb_size / ocm->page_size + 1;
519 : : else
520 : 0 : *wb_pages = wb_size / ocm->page_size;
521 : 0 : plt_ml_dbg("index = %u, wb_size = %" PRIu64 ", wb_pages = %u", layer->index, wb_size,
522 : : *wb_pages);
523 : :
524 : 0 : scratch_size = ocm->size_per_tile - metadata->model.ocm_tmp_range_floor;
525 [ # # ]: 0 : if (metadata->model.ocm_tmp_range_floor % ocm->page_size)
526 : 0 : *scratch_pages = scratch_size / ocm->page_size + 1;
527 : : else
528 : 0 : *scratch_pages = scratch_size / ocm->page_size;
529 : 0 : plt_ml_dbg("index = %u, scratch_size = %" PRIu64 ", scratch_pages = %u", layer->index,
530 : : scratch_size, *scratch_pages);
531 : :
532 : : /* Check if the model can be loaded on OCM */
533 [ # # ]: 0 : if ((*wb_pages + *scratch_pages) > ocm->num_pages) {
534 : 0 : plt_err("Cannot create the model, OCM relocatable = %u",
535 : : metadata->model.ocm_relocatable);
536 : 0 : plt_err("wb_pages (%u) + scratch_pages (%u) > %u", *wb_pages, *scratch_pages,
537 : : ocm->num_pages);
538 : 0 : return -ENOMEM;
539 : : }
540 : :
541 : : /* Update scratch_pages to block the full tile for OCM non-relocatable model. This would
542 : : * prevent the library from allocating the remaining space on the tile to other models.
543 : : */
544 [ # # ]: 0 : if (!metadata->model.ocm_relocatable)
545 : 0 : *scratch_pages =
546 : 0 : PLT_MAX(PLT_U64_CAST(*scratch_pages), PLT_U64_CAST(ocm->num_pages));
547 : :
548 : : return 0;
549 : : }
550 : :
551 : : void
552 : 0 : cn10k_ml_model_info_set(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model *model,
553 : : struct cnxk_ml_io_info *io_info, struct cn10k_ml_model_metadata *metadata)
554 : : {
555 : : struct rte_ml_model_info *info;
556 : : struct rte_ml_io_info *output;
557 : : struct rte_ml_io_info *input;
558 : : uint8_t i;
559 : :
560 : : metadata = &model->glow.metadata;
561 : 0 : info = PLT_PTR_CAST(model->info);
562 : 0 : input = PLT_PTR_ADD(info, sizeof(struct rte_ml_model_info));
563 : 0 : output = PLT_PTR_ADD(input, ML_CNXK_MODEL_MAX_INPUT_OUTPUT * sizeof(struct rte_ml_io_info));
564 : :
565 : : /* Set model info */
566 : : memset(info, 0, sizeof(struct rte_ml_model_info));
567 : : rte_memcpy(info->name, metadata->model.name, MRVL_ML_MODEL_NAME_LEN);
568 : 0 : snprintf(info->version, RTE_ML_STR_MAX, "%u.%u.%u.%u", metadata->model.version[0],
569 : 0 : metadata->model.version[1], metadata->model.version[2],
570 : 0 : metadata->model.version[3]);
571 : 0 : info->model_id = model->model_id;
572 : 0 : info->device_id = cnxk_mldev->mldev->data->dev_id;
573 : 0 : info->io_layout = RTE_ML_IO_LAYOUT_PACKED;
574 : 0 : info->min_batches = model->batch_size;
575 : 0 : info->max_batches =
576 : 0 : cnxk_mldev->cn10k_mldev.fw.req->cn10k_req.jd.fw_load.cap.s.max_num_batches /
577 : : model->batch_size;
578 : 0 : info->nb_inputs = io_info->nb_inputs;
579 : 0 : info->input_info = input;
580 : 0 : info->nb_outputs = io_info->nb_outputs;
581 : 0 : info->output_info = output;
582 : 0 : info->wb_size = metadata->weights_bias.file_size;
583 : :
584 : : /* Set input info */
585 [ # # ]: 0 : for (i = 0; i < info->nb_inputs; i++) {
586 : 0 : rte_memcpy(input[i].name, io_info->input[i].name, MRVL_ML_INPUT_NAME_LEN);
587 : 0 : input[i].nb_dims = io_info->input[i].nb_dims;
588 : 0 : input[i].shape = &io_info->input[i].shape[0];
589 : 0 : input[i].type = io_info->input[i].qtype;
590 : 0 : input[i].nb_elements = io_info->input[i].nb_elements;
591 : 0 : input[i].size = io_info->input[i].nb_elements *
592 : 0 : rte_ml_io_type_size_get(io_info->input[i].qtype);
593 : 0 : input[i].scale = 1.0 / io_info->input[i].scale;
594 : 0 : input[i].zero_point = 0;
595 : : }
596 : :
597 : : /* Set output info */
598 [ # # ]: 0 : for (i = 0; i < info->nb_outputs; i++) {
599 : 0 : rte_memcpy(output[i].name, io_info->output[i].name, MRVL_ML_INPUT_NAME_LEN);
600 : 0 : output[i].nb_dims = io_info->output[i].nb_dims;
601 : 0 : output[i].shape = &io_info->output[i].shape[0];
602 : 0 : output[i].type = io_info->output[i].qtype;
603 : 0 : output[i].nb_elements = io_info->output[i].nb_elements;
604 : 0 : output[i].size = io_info->output[i].nb_elements *
605 : 0 : rte_ml_io_type_size_get(io_info->output[i].qtype);
606 : 0 : output[i].scale = io_info->output[i].scale;
607 : 0 : output[i].zero_point = 0;
608 : : }
609 : 0 : }
610 : :
611 : : void
612 : 0 : cn10k_ml_layer_print(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_layer *layer, FILE *fp)
613 : : {
614 : : struct cn10k_ml_ocm *ocm;
615 : : char str[STR_LEN];
616 : : uint8_t i;
617 : : uint8_t j;
618 : :
619 : : ocm = &cnxk_mldev->cn10k_mldev.ocm;
620 : :
621 : : /* Print debug info */
622 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
623 : 0 : fprintf(fp, " Layer Information (Layer ID: %u, Name: %s)\n",
624 : 0 : cnxk_mldev->index_map[layer->index].layer_id, layer->name);
625 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
626 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "index", layer->index);
627 : : fprintf(fp, "%*s : %s\n", FIELD_LEN, "name", layer->name);
628 : 0 : fprintf(fp, "%*s : %u.%u.%u.%u\n", FIELD_LEN, "version",
629 : 0 : layer->glow.metadata.model.version[0], layer->glow.metadata.model.version[1],
630 : 0 : layer->glow.metadata.model.version[2], layer->glow.metadata.model.version[3]);
631 : 0 : fprintf(fp, "%*s : 0x%016lx\n", FIELD_LEN, "layer", PLT_U64_CAST(layer));
632 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "batch_size", layer->batch_size);
633 : :
634 : : /* Print model state */
635 [ # # ]: 0 : if (layer->state == ML_CNXK_LAYER_STATE_LOADED)
636 : : fprintf(fp, "%*s : %s\n", FIELD_LEN, "state", "loaded");
637 [ # # ]: 0 : if (layer->state == ML_CNXK_LAYER_STATE_JOB_ACTIVE)
638 : : fprintf(fp, "%*s : %s\n", FIELD_LEN, "state", "job_active");
639 [ # # ]: 0 : if (layer->state == ML_CNXK_LAYER_STATE_STARTED)
640 : : fprintf(fp, "%*s : %s\n", FIELD_LEN, "state", "started");
641 : :
642 : : /* Print OCM status */
643 : 0 : fprintf(fp, "%*s : %" PRIu64 " bytes\n", FIELD_LEN, "wb_size",
644 : 0 : layer->glow.metadata.model.ocm_wb_range_end -
645 : 0 : layer->glow.metadata.model.ocm_wb_range_start + 1);
646 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "wb_pages", layer->glow.ocm_map.wb_pages);
647 : 0 : fprintf(fp, "%*s : %" PRIu64 " bytes\n", FIELD_LEN, "scratch_size",
648 : 0 : ocm->size_per_tile - layer->glow.metadata.model.ocm_tmp_range_floor);
649 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "scratch_pages", layer->glow.ocm_map.scratch_pages);
650 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "num_tiles",
651 : 0 : layer->glow.metadata.model.tile_end - layer->glow.metadata.model.tile_start + 1);
652 : :
653 [ # # ]: 0 : if (layer->state == ML_CNXK_LAYER_STATE_STARTED) {
654 : 0 : fprintf(fp, "%*s : 0x%0*" PRIx64 "\n", FIELD_LEN, "tilemask",
655 : : ML_CN10K_OCM_NUMTILES / 4, layer->glow.ocm_map.tilemask);
656 : 0 : fprintf(fp, "%*s : 0x%" PRIx64 "\n", FIELD_LEN, "ocm_wb_start",
657 : 0 : layer->glow.ocm_map.wb_page_start * ocm->page_size);
658 : : }
659 : :
660 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "num_inputs", layer->glow.metadata.model.num_input);
661 : 0 : fprintf(fp, "%*s : %u\n", FIELD_LEN, "num_outputs", layer->glow.metadata.model.num_output);
662 : : fprintf(fp, "\n");
663 : :
664 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
665 : : fprintf(fp, "%8s %16s %12s %18s\n", "input", "input_name", "input_type",
666 : : "model_input_type");
667 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
668 [ # # ]: 0 : for (i = 0; i < layer->glow.metadata.model.num_input; i++) {
669 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
670 : 0 : fprintf(fp, "%8u ", i);
671 : 0 : fprintf(fp, "%*s ", 16, layer->glow.metadata.input1[i].input_name);
672 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.input1[i].input_type, str,
673 : : STR_LEN);
674 : : fprintf(fp, "%*s ", 12, str);
675 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.input1[i].model_input_type, str,
676 : : STR_LEN);
677 : : fprintf(fp, "%*s ", 18, str);
678 : : fprintf(fp, "\n");
679 : : } else {
680 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
681 : :
682 : 0 : fprintf(fp, "%8u ", i);
683 : 0 : fprintf(fp, "%*s ", 16, layer->glow.metadata.input2[j].input_name);
684 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.input2[j].input_type, str,
685 : : STR_LEN);
686 : : fprintf(fp, "%*s ", 12, str);
687 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.input2[j].model_input_type, str,
688 : : STR_LEN);
689 : : fprintf(fp, "%*s ", 18, str);
690 : : fprintf(fp, "\n");
691 : : }
692 : : }
693 : : fprintf(fp, "\n");
694 : :
695 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
696 : : fprintf(fp, "%8s %16s %12s %18s\n", "output", "output_name", "output_type",
697 : : "model_output_type");
698 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
699 [ # # ]: 0 : for (i = 0; i < layer->glow.metadata.model.num_output; i++) {
700 [ # # ]: 0 : if (i < MRVL_ML_NUM_INPUT_OUTPUT_1) {
701 : 0 : fprintf(fp, "%8u ", i);
702 : 0 : fprintf(fp, "%*s ", 16, layer->glow.metadata.output1[i].output_name);
703 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.output1[i].output_type, str,
704 : : STR_LEN);
705 : : fprintf(fp, "%*s ", 12, str);
706 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.output1[i].model_output_type,
707 : : str, STR_LEN);
708 : : fprintf(fp, "%*s ", 18, str);
709 : : fprintf(fp, "\n");
710 : : } else {
711 : 0 : j = i - MRVL_ML_NUM_INPUT_OUTPUT_1;
712 : 0 : fprintf(fp, "%8u ", i);
713 : 0 : fprintf(fp, "%*s ", 16, layer->glow.metadata.output2[j].output_name);
714 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.output2[j].output_type, str,
715 : : STR_LEN);
716 : : fprintf(fp, "%*s ", 12, str);
717 : 0 : rte_ml_io_type_to_str(layer->glow.metadata.output2[j].model_output_type,
718 : : str, STR_LEN);
719 : : fprintf(fp, "%*s ", 18, str);
720 : : fprintf(fp, "\n");
721 : : }
722 : : }
723 : : fprintf(fp, "\n");
724 : 0 : cnxk_ml_print_line(fp, LINE_LEN);
725 : : fprintf(fp, "\n");
726 : 0 : }
727 : :
728 : : int
729 : 0 : cn10k_ml_model_get_layer_id(struct cnxk_ml_model *model, const char *layer_name, uint16_t *layer_id)
730 : : {
731 [ # # ]: 0 : if (model->type == ML_CNXK_MODEL_TYPE_TVM)
732 : 0 : return mvtvm_ml_model_get_layer_id(model, layer_name, layer_id);
733 : :
734 : 0 : *layer_id = 0;
735 : :
736 : 0 : return 0;
737 : : }
|