@@ -37,14 +37,17 @@ using mli::tst::tensor_quantizer;
3737using mli::tst::quality_metrics;
3838using mli::tst::crc32_calc;
3939using mli::tst::reporter_basic;
40+ using mli::tst::reporter_full;
4041using mli::tst::memory_manager;
4142
4243constexpr int kMemSize = 1000 ;
4344static IO_DATA_ATTR int8_t scratch_mem_in[kMemSize ] = { 0 };
45+ static IO_DATA_ATTR int8_t scratch_mem_out[kMemSize ] = { 0 };
4446
4547bool run_test_count_and_size ();
4648bool run_test_quant_params_getters ();
4749bool run_test_accu_bits_getters ();
50+ bool run_test_create_subtensor ();
4851
4952// Main entry point. Running test procedues for various helpers
5053// =============================================================
@@ -58,6 +61,9 @@ int main() {
5861 if (final_status == kSuccess )
5962 final_status = run_test_accu_bits_getters ();
6063
64+ if (final_status == kSuccess )
65+ final_status = run_test_create_subtensor ();
66+
6167 return (final_status == kSuccess ) ? 0 : 1 ;
6268}
6369
@@ -104,7 +110,7 @@ bool run_test_count_and_size() {
104110 if (is_test_passed && (tensor_quantizer::validate_tensor (input) != tensor_quantizer::kOk )) {
105111 is_test_passed = false ;
106112 reporter.report_case (cur_test->descr ,
107- " At quantization step: more memory for in tensor is be required" , is_test_passed);
113+ " At quantization step: more memory for in tensor is required" , is_test_passed);
108114 }
109115
110116 if (is_test_passed && (mem_in_keeper.is_memory_corrupted ())) {
@@ -132,7 +138,7 @@ bool run_test_count_and_size() {
132138 mem_in_keeper.is_memory_corrupted ())) {
133139 is_test_passed = false ;
134140 reporter.report_case (cur_test->descr ,
135- " At function run: memory is corrupted after functions invokation " , is_test_passed);
141+ " At function run: memory is corrupted after functions invocation " , is_test_passed);
136142 }
137143
138144 if (is_test_passed && cur_test->elem_size != cur_elem_size ) {
@@ -233,7 +239,7 @@ bool run_test_quant_params_getters() {
233239 mem_in_keeper.is_memory_corrupted ())) {
234240 is_test_passed = false ;
235241 reporter.report_case (cur_test->descr ,
236- " FAILED at func run: memory is corrupted after functions invokation " , is_test_passed);
242+ " FAILED at func run: memory is corrupted after functions invocation " , is_test_passed);
237243 }
238244
239245 if (is_test_passed) {
@@ -338,3 +344,125 @@ bool run_test_accu_bits_getters() {
338344 return test_status;
339345}
340346
347+ // Tests procedure for mli_hlp_create_subtensor function.
348+ // =======================================================================
349+ struct create_subtensor_test_operands {
350+ const char * descr;
351+ tensor_quantizer in;
352+ tensor_quantizer out;
353+ mli_sub_tensor_cfg cfg;
354+ const quality_metrics threshold;
355+ const crc32_calc check_sum;
356+ };
357+
358+ // Checksums of test tensors for various mli calculations mode.
359+ // When developer finished implementation of kernel and consider it as ok, one needs to populate
360+ // proper checksums for tests in order to highlight any change which affects results.
361+
362+ const crc32_calc test_1_chksum_fx16 { 0x418F5ED6 }, test_1_chksum_fx8 { 0x0820E5D9 },
363+ test_1_chksum_sa8 { 0xBB54537D }, test_1_chksum_sa8_pa { 0x63BAA2A1 },
364+ test_1_chksum_sa32 { 0xDC93E12C }, test_1_chksum_sa32_pa { 0x98D5A2D6 },
365+ test_2_chksum_fx16 { 0xD7B05DED }, test_2_chksum_fx8 { 0x7582D890 },
366+ test_2_chksum_sa8 { 0x4CB81C56 }, test_2_chksum_sa8_pa { 0x2F0B06B8 },
367+ test_2_chksum_sa32 { 0x0B379B11 }, test_2_chksum_sa32_pa { 0x87591FC2 };
368+
369+ const quality_metrics thresholds_test_general { quality_metrics::kPassValueMaxAbsErr , quality_metrics::kPassValueSnr ,
370+ quality_metrics::kPassValueSnrDb , /* QuantErrPerc = */ 100 .0f };
371+
372+ bool run_test_create_subtensor () {
373+ bool test_status = true ;
374+ const reporter_full reporter;
375+ static const create_subtensor_test_operands create_subtensor_tests_list[] = {
376+ {" FX16 tensor " , input_1_fx16, test_1_out_fx16, test_1_cfg,
377+ thresholds_test_general, test_1_chksum_fx16},
378+ {" FX8 tensor " , input_1_fx8, test_1_out_fx8, test_1_cfg,
379+ thresholds_test_general, test_1_chksum_fx8},
380+ {" SA8 tensor " , input_1_sa8, test_1_out_sa8, test_1_cfg,
381+ thresholds_test_general, test_1_chksum_sa8},
382+ {" SA8 tensor per axis" , input_1_sa8_per_axis, test_1_out_sa8_per_axis, test_1_cfg,
383+ thresholds_test_general, test_1_chksum_sa8_pa},
384+ {" SA32 tensor " , input_1_sa32, test_1_out_sa32, test_1_cfg,
385+ thresholds_test_general, test_1_chksum_sa32},
386+ {" SA32 tensor per axis" , input_1_sa32_per_axis, test_1_out_sa32_per_axis, test_1_cfg,
387+ thresholds_test_general, test_1_chksum_sa32_pa},
388+ {" FX16 tensor (rank & offset) " , input_1_fx16, test_2_out_fx16, test_2_cfg,
389+ thresholds_test_general, test_2_chksum_fx16},
390+ {" FX8 tensor (rank & offset)" , input_1_fx8, test_2_out_fx8, test_2_cfg,
391+ thresholds_test_general, test_2_chksum_fx8},
392+ {" SA8 tensor (rank & offset)" , input_1_sa8, test_2_out_sa8, test_2_cfg,
393+ thresholds_test_general, test_2_chksum_sa8},
394+ {" SA8 per axis (rank & offset)" , input_1_sa8_per_axis, test_2_out_sa8_per_axis, test_2_cfg,
395+ thresholds_test_general, test_2_chksum_sa8_pa},
396+ {" SA32 tensor (rank & offset)" , input_1_sa32, test_2_out_sa32, test_2_cfg,
397+ thresholds_test_general, test_2_chksum_sa32},
398+ {" SA32 per axis (rank & offset)" , input_1_sa32_per_axis, test_2_out_sa32_per_axis, test_2_cfg,
399+ thresholds_test_general, test_2_chksum_sa32_pa}
400+ };
401+ constexpr int kTestsNum = sizeof (create_subtensor_tests_list) / sizeof (create_subtensor_tests_list[0 ]);
402+
403+ reporter.report_header (" MLI|Helpers|Create Subtensor Tests" );
404+ for (int i = 0 ; i < kTestsNum ; ++i) {
405+ memory_manager mem_in_keeper ((int8_t *)(scratch_mem_in), sizeof (scratch_mem_in));
406+ memory_manager mem_out_keeper ((int8_t *)(scratch_mem_out), sizeof (scratch_mem_out));
407+ bool is_test_passed = true ;
408+ const create_subtensor_test_operands* cur_test = &create_subtensor_tests_list[i];
409+ quality_metrics test_metrics;
410+
411+ if (!(cur_test->in .is_valid ())) {
412+ is_test_passed = false ;
413+ reporter.report_message (cur_test->descr , " At init: Bad source data for input tensor" );
414+ }
415+
416+ const mli_tensor input = cur_test->in .get_quantized_tensor (mem_in_keeper.allocate_memory (cur_test->in ));
417+ mli_tensor out = { 0 };
418+ if (is_test_passed &&
419+ tensor_quantizer::validate_tensor (input) != tensor_quantizer::kOk ) {
420+ is_test_passed = false ;
421+ reporter.report_message (cur_test->descr ,
422+ " At quantization step: more memory for in tensor is required" );
423+ }
424+
425+ if (is_test_passed &&
426+ mem_in_keeper.is_memory_corrupted ()) {
427+ is_test_passed = false ;
428+ reporter.report_message (cur_test->descr ,
429+ " At quantization step: memory beside one of operands is corrupted" );
430+ }
431+
432+ // Run specific kernel for test
433+ crc32_calc data_crc_before, data_crc_after;
434+ if (is_test_passed) {
435+ data_crc_before (input);
436+ if (mli_hlp_create_subtensor (&input, &cur_test->cfg , &out) != MLI_STATUS_OK) {
437+ is_test_passed = false ;
438+ reporter.report_message (cur_test->descr , " FAILED at kernel run: kernel returned bad status" );
439+ }
440+ data_crc_after (input);
441+ }
442+
443+ if (is_test_passed &&
444+ (data_crc_before.get () != data_crc_after.get () ||
445+ mem_in_keeper.is_memory_corrupted ())) {
446+ is_test_passed = false ;
447+ reporter.report_message (cur_test->descr ,
448+ " At function run: memory is corrupted after functions invocation" );
449+ }
450+
451+ if (is_test_passed &&
452+ test_metrics.calculate_metrics (out, cur_test->out ) == false ) {
453+ reporter.report_message (cur_test->descr , " FAILED at comparison output with reference" );
454+ is_test_passed = false ;
455+ }
456+
457+ if (is_test_passed) {
458+ crc32_calc data_crc;
459+ data_crc (input);
460+ data_crc (out);
461+ is_test_passed &= reporter.evaluate_and_report_case (cur_test->descr , test_metrics, cur_test->threshold ,
462+ data_crc, cur_test->check_sum );
463+ }
464+ test_status &= is_test_passed;
465+ }
466+ reporter.report_outline (" [AUTO] Group: mli_hlp_create_subtensor" , test_status);
467+ return test_status;
468+ }
0 commit comments