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