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 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 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 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 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 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 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 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 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 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 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 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 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 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