1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2022 Marvell.
3 */
4
5 #include <unistd.h>
6
7 #include <rte_common.h>
8 #include <rte_malloc.h>
9 #include <rte_mldev.h>
10
11 #include "test_model_ops.h"
12 #include "test_stats.h"
13
14 static bool
test_model_ops_cap_check(struct ml_options * opt)15 test_model_ops_cap_check(struct ml_options *opt)
16 {
17 if (!ml_test_cap_check(opt))
18 return false;
19
20 return true;
21 }
22
23 static int
test_model_ops_opt_check(struct ml_options * opt)24 test_model_ops_opt_check(struct ml_options *opt)
25 {
26 uint32_t i;
27 int ret;
28
29 /* check common opts */
30 ret = ml_test_opt_check(opt);
31 if (ret != 0)
32 return ret;
33
34 /* check for at least one model */
35 if (opt->nb_filelist == 0) {
36 ml_err("Models list empty, need at least one model to run the test\n");
37 return -EINVAL;
38 }
39
40 /* check model file availability */
41 for (i = 0; i < opt->nb_filelist; i++) {
42 if (access(opt->filelist[i].model, F_OK) == -1) {
43 ml_err("Model file not available: id = %u, file = %s", i,
44 opt->filelist[i].model);
45 return -ENOENT;
46 }
47 }
48
49 return 0;
50 }
51
52 static void
test_model_ops_opt_dump(struct ml_options * opt)53 test_model_ops_opt_dump(struct ml_options *opt)
54 {
55 uint32_t i;
56
57 /* dump common opts */
58 ml_test_opt_dump(opt);
59
60 /* dump test specific opts */
61 ml_dump_begin("models");
62 for (i = 0; i < opt->nb_filelist; i++)
63 ml_dump_list("model", i, opt->filelist[i].model);
64 ml_dump_end;
65 }
66
67 static int
test_model_ops_setup(struct ml_test * test,struct ml_options * opt)68 test_model_ops_setup(struct ml_test *test, struct ml_options *opt)
69 {
70 struct test_model_ops *t;
71 void *test_model_ops;
72 int ret = 0;
73 uint32_t i;
74
75 /* allocate model ops test structure */
76 test_model_ops = rte_zmalloc_socket(test->name, sizeof(struct test_model_ops),
77 RTE_CACHE_LINE_SIZE, opt->socket_id);
78 if (test_model_ops == NULL) {
79 ml_err("Failed to allocate memory for test_model");
80 ret = -ENOMEM;
81 goto error;
82 }
83 test->test_priv = test_model_ops;
84 t = ml_test_priv(test);
85
86 t->cmn.result = ML_TEST_FAILED;
87 t->cmn.opt = opt;
88
89 /* get device info */
90 ret = rte_ml_dev_info_get(opt->dev_id, &t->cmn.dev_info);
91 if (ret < 0) {
92 ml_err("Failed to get device info");
93 goto error;
94 }
95
96 /* set model initial state */
97 for (i = 0; i < opt->nb_filelist; i++)
98 t->model[i].state = MODEL_INITIAL;
99
100 return 0;
101
102 error:
103 rte_free(test_model_ops);
104
105 return ret;
106 }
107
108 static void
test_model_ops_destroy(struct ml_test * test,struct ml_options * opt)109 test_model_ops_destroy(struct ml_test *test, struct ml_options *opt)
110 {
111 struct test_model_ops *t;
112
113 RTE_SET_USED(opt);
114
115 t = ml_test_priv(test);
116 rte_free(t);
117 }
118
119 static int
test_model_ops_mldev_setup(struct ml_test * test,struct ml_options * opt)120 test_model_ops_mldev_setup(struct ml_test *test, struct ml_options *opt)
121 {
122 int ret;
123
124 ret = ml_test_device_configure(test, opt);
125 if (ret != 0)
126 return ret;
127
128 ret = ml_test_device_start(test, opt);
129 if (ret != 0)
130 goto error;
131
132 return 0;
133
134 error:
135 ml_test_device_close(test, opt);
136
137 return ret;
138 }
139
140 static int
test_model_ops_mldev_destroy(struct ml_test * test,struct ml_options * opt)141 test_model_ops_mldev_destroy(struct ml_test *test, struct ml_options *opt)
142 {
143 int ret;
144
145 ret = ml_test_device_stop(test, opt);
146 if (ret != 0)
147 goto error;
148
149 ret = ml_test_device_close(test, opt);
150 if (ret != 0)
151 return ret;
152
153 return 0;
154
155 error:
156 ml_test_device_close(test, opt);
157
158 return ret;
159 }
160
161 /* Sub-test A: (load -> start -> stop -> unload) x n */
162 static int
test_model_ops_subtest_a(struct ml_test * test,struct ml_options * opt)163 test_model_ops_subtest_a(struct ml_test *test, struct ml_options *opt)
164 {
165 struct test_model_ops *t;
166 int ret = 0;
167 uint32_t i;
168
169 t = ml_test_priv(test);
170
171 /* load + start + stop + unload */
172 for (i = 0; i < opt->nb_filelist; i++) {
173 ret = ml_model_load(test, opt, &t->model[i], i);
174 if (ret != 0)
175 goto error;
176
177 ret = ml_model_start(test, opt, &t->model[i], i);
178 if (ret != 0)
179 goto error;
180
181 ret = ml_model_stop(test, opt, &t->model[i], i);
182 if (ret != 0)
183 goto error;
184
185 ret = ml_model_unload(test, opt, &t->model[i], i);
186 if (ret != 0)
187 goto error;
188 }
189
190 error:
191 for (i = 0; i < opt->nb_filelist; i++)
192 ml_model_stop(test, opt, &t->model[i], i);
193
194 for (i = 0; i < opt->nb_filelist; i++)
195 ml_model_unload(test, opt, &t->model[i], i);
196
197 return ret;
198 }
199
200 /* Sub-test B: load x n -> start x n -> stop x n -> unload x n */
201 static int
test_model_ops_subtest_b(struct ml_test * test,struct ml_options * opt)202 test_model_ops_subtest_b(struct ml_test *test, struct ml_options *opt)
203 {
204 struct test_model_ops *t;
205 int ret = 0;
206 uint32_t i;
207
208 t = ml_test_priv(test);
209
210 /* load */
211 for (i = 0; i < opt->nb_filelist; i++) {
212 ret = ml_model_load(test, opt, &t->model[i], i);
213 if (ret != 0)
214 goto error;
215 }
216
217 /* start */
218 for (i = 0; i < opt->nb_filelist; i++) {
219 ret = ml_model_start(test, opt, &t->model[i], i);
220 if (ret != 0)
221 goto error;
222 }
223
224 /* stop */
225 for (i = 0; i < opt->nb_filelist; i++) {
226 ret = ml_model_stop(test, opt, &t->model[i], i);
227 if (ret != 0)
228 goto error;
229 }
230
231 /* unload */
232 for (i = 0; i < opt->nb_filelist; i++) {
233 ret = ml_model_unload(test, opt, &t->model[i], i);
234 if (ret != 0)
235 goto error;
236 }
237
238 return 0;
239
240 error:
241 for (i = 0; i < opt->nb_filelist; i++)
242 ml_model_stop(test, opt, &t->model[i], i);
243
244 for (i = 0; i < opt->nb_filelist; i++)
245 ml_model_unload(test, opt, &t->model[i], i);
246
247 return ret;
248 }
249
250 /* Sub-test C: load x n + (start + stop) x n + unload x n */
251 static int
test_model_ops_subtest_c(struct ml_test * test,struct ml_options * opt)252 test_model_ops_subtest_c(struct ml_test *test, struct ml_options *opt)
253 {
254 struct test_model_ops *t;
255 int ret = 0;
256 uint32_t i;
257
258 t = ml_test_priv(test);
259
260 /* load */
261 for (i = 0; i < opt->nb_filelist; i++) {
262 ret = ml_model_load(test, opt, &t->model[i], i);
263 if (ret != 0)
264 goto error;
265 }
266
267 /* start + stop */
268 for (i = 0; i < opt->nb_filelist; i++) {
269 ret = ml_model_start(test, opt, &t->model[i], i);
270 if (ret != 0)
271 goto error;
272
273 ret = ml_model_stop(test, opt, &t->model[i], i);
274 if (ret != 0)
275 goto error;
276 }
277
278 /* unload */
279 for (i = 0; i < opt->nb_filelist; i++) {
280 ret = ml_model_unload(test, opt, &t->model[i], i);
281 if (ret != 0)
282 goto error;
283 }
284
285 return 0;
286
287 error:
288 for (i = 0; i < opt->nb_filelist; i++)
289 ml_model_stop(test, opt, &t->model[i], i);
290
291 for (i = 0; i < opt->nb_filelist; i++)
292 ml_model_unload(test, opt, &t->model[i], i);
293
294 return ret;
295 }
296
297 /* Sub-test D: (load + start) x n -> (stop + unload) x n */
298 static int
test_model_ops_subtest_d(struct ml_test * test,struct ml_options * opt)299 test_model_ops_subtest_d(struct ml_test *test, struct ml_options *opt)
300 {
301 struct test_model_ops *t;
302 int ret = 0;
303 uint32_t i;
304
305 t = ml_test_priv(test);
306
307 /* load + start */
308 for (i = 0; i < opt->nb_filelist; i++) {
309 ret = ml_model_load(test, opt, &t->model[i], i);
310 if (ret != 0)
311 goto error;
312
313 ret = ml_model_start(test, opt, &t->model[i], i);
314 if (ret != 0)
315 goto error;
316 }
317
318 /* stop + unload */
319 for (i = 0; i < opt->nb_filelist; i++) {
320 ret = ml_model_stop(test, opt, &t->model[i], i);
321 if (ret != 0)
322 goto error;
323
324 ret = ml_model_unload(test, opt, &t->model[i], i);
325 if (ret != 0)
326 goto error;
327 }
328
329 return 0;
330
331 error:
332 for (i = 0; i < opt->nb_filelist; i++)
333 ml_model_stop(test, opt, &t->model[i], i);
334
335 for (i = 0; i < opt->nb_filelist; i++)
336 ml_model_unload(test, opt, &t->model[i], i);
337
338 return ret;
339 }
340
341 static int
test_model_ops_driver(struct ml_test * test,struct ml_options * opt)342 test_model_ops_driver(struct ml_test *test, struct ml_options *opt)
343 {
344 struct test_model_ops *t;
345 int ret = 0;
346
347 t = ml_test_priv(test);
348
349 /* device setup */
350 ret = test_model_ops_mldev_setup(test, opt);
351 if (ret != 0)
352 return ret;
353
354 printf("\n");
355
356 /* sub-test A */
357 ret = test_model_ops_subtest_a(test, opt);
358 if (ret != 0) {
359 printf("Model Ops Sub-test A: " CLRED "%s" CLNRM "\n", "Failed");
360 goto error;
361 } else {
362 printf("Model Ops Sub-test A: " CLYEL "%s" CLNRM "\n", "Passed");
363 }
364
365 /* sub-test B */
366 ret = test_model_ops_subtest_b(test, opt);
367 if (ret != 0) {
368 printf("Model Ops Sub-test B: " CLRED "%s" CLNRM "\n", "Failed");
369 goto error;
370 } else {
371 printf("Model Ops Sub-test B: " CLYEL "%s" CLNRM "\n", "Passed");
372 }
373
374 /* sub-test C */
375 ret = test_model_ops_subtest_c(test, opt);
376 if (ret != 0) {
377 printf("Model Ops Sub-test C: " CLRED "%s" CLNRM "\n", "Failed");
378 goto error;
379 } else {
380 printf("Model Ops Sub-test C: " CLYEL "%s" CLNRM "\n", "Passed");
381 }
382
383 /* sub-test D */
384 ret = test_model_ops_subtest_d(test, opt);
385 if (ret != 0) {
386 printf("Model Ops Sub-test D: " CLRED "%s" CLNRM "\n", "Failed");
387 goto error;
388 } else {
389 printf("Model Ops Sub-test D: " CLYEL "%s" CLNRM "\n", "Passed");
390 }
391
392 printf("\n");
393
394 ml_stats_get(test, opt, RTE_ML_DEV_XSTATS_DEVICE, -1);
395
396 /* device destroy */
397 ret = test_model_ops_mldev_destroy(test, opt);
398 if (ret != 0)
399 return ret;
400
401 t->cmn.result = ML_TEST_SUCCESS;
402
403 return 0;
404
405 error:
406 test_model_ops_mldev_destroy(test, opt);
407
408 t->cmn.result = ML_TEST_FAILED;
409
410 return ret;
411 }
412
413 static int
test_model_ops_result(struct ml_test * test,struct ml_options * opt)414 test_model_ops_result(struct ml_test *test, struct ml_options *opt)
415 {
416 struct test_model_ops *t;
417
418 RTE_SET_USED(opt);
419
420 t = ml_test_priv(test);
421
422 return t->cmn.result;
423 }
424
425 static const struct ml_test_ops model_ops = {
426 .cap_check = test_model_ops_cap_check,
427 .opt_check = test_model_ops_opt_check,
428 .opt_dump = test_model_ops_opt_dump,
429 .test_setup = test_model_ops_setup,
430 .test_destroy = test_model_ops_destroy,
431 .test_driver = test_model_ops_driver,
432 .test_result = test_model_ops_result,
433 };
434
435 ML_TEST_REGISTER(model_ops);
436