xref: /dpdk/app/test-mldev/test_model_ops.c (revision a1474e134dd5561a678984a05ac03be340715b6f)
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