| #ifndef _MATRIX_TEMPLATES_H_ |
| #define _MATRIX_TEMPLATES_H_ |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* Includes */ |
| /*--------------------------------------------------------------------------------*/ |
| #include "test_templates.h" |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* Group Specific Templates */ |
| /*--------------------------------------------------------------------------------*/ |
| |
| /** |
| * Compare the outputs from the function under test and the reference |
| * function. |
| */ |
| #define MATRIX_COMPARE_INTERFACE(output_type, output_content_type) \ |
| TEST_ASSERT_BUFFERS_EQUAL( \ |
| ((output_type *) &matrix_output_ref)->pData, \ |
| ((output_type *) &matrix_output_fut)->pData, \ |
| ((output_type *) &matrix_output_fut)->numRows * \ |
| ((output_type *) &matrix_output_ref)->numCols * \ |
| sizeof(output_content_type)) |
| |
| /** |
| * Comparison SNR thresholds for the data types used in matrix_tests. |
| */ |
| #define MATRIX_SNR_THRESHOLD 120 |
| |
| /** |
| * Compare the outputs from the function under test and the reference |
| * function using SNR. |
| */ |
| #define MATRIX_SNR_COMPARE_INTERFACE(output_type, output_content_type) \ |
| do \ |
| { \ |
| TEST_CONVERT_AND_ASSERT_SNR( \ |
| (float32_t *)matrix_output_f32_ref, \ |
| ((output_type *) &matrix_output_ref)->pData, \ |
| (float32_t *)matrix_output_f32_fut, \ |
| ((output_type *) &matrix_output_ref)->pData, \ |
| ((output_type *) &matrix_output_fut)->numRows * \ |
| ((output_type *) &matrix_output_ref)->numCols, \ |
| output_content_type, \ |
| MATRIX_SNR_THRESHOLD \ |
| ); \ |
| } while (0) |
| |
| /** |
| * Compare the outputs from the function under test and the reference |
| * function using SNR. This is special for float64_t |
| */ |
| #define MATRIX_DBL_SNR_COMPARE_INTERFACE(output_type) \ |
| do \ |
| { \ |
| TEST_ASSERT_DBL_SNR( \ |
| (float64_t *)matrix_output_f32_ref, \ |
| (float64_t *)matrix_output_f32_fut, \ |
| ((output_type *) &matrix_output_fut)->numRows * \ |
| ((output_type *) &matrix_output_ref)->numCols, \ |
| MATRIX_SNR_THRESHOLD \ |
| ); \ |
| } while (0) |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* Input Interfaces */ |
| /*--------------------------------------------------------------------------------*/ |
| /* |
| * General: |
| * Input interfaces provide inputs to functions inside test templates. They |
| * ONLY provide the inputs. The output variables should be hard coded. |
| * |
| * The input interfaces must have the following format: |
| * |
| * ARM_xxx_INPUT_INTERFACE() or |
| * REF_xxx_INPUT_INTERFACE() |
| * |
| * The xxx must be lowercase, and is intended to be the indentifying substring |
| * in the function's name. Acceptable values are 'sub' or 'add' from the |
| * functions arm_add_q31. |
| */ |
| |
| #define ARM_mat_add_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_add_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_cmplx_mult_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_cmplx_mult_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_inverse_INPUT_INTERFACE(input_ptr) \ |
| PAREN(input_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_inverse_INPUT_INTERFACE(input_ptr) \ |
| PAREN(input_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_mult_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_mult_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_mult_fast_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_mult_fast_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_sub_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_sub_INPUT_INTERFACE(input_a_ptr, input_b_ptr) \ |
| PAREN(input_a_ptr, input_b_ptr, (void *) &matrix_output_ref) |
| |
| #define ARM_mat_trans_INPUT_INTERFACE(input_ptr) \ |
| PAREN(input_ptr, (void *) &matrix_output_fut) |
| |
| #define REF_mat_trans_INPUT_INTERFACE(input_ptr) \ |
| PAREN(input_ptr, (void *) &matrix_output_ref) |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* Dimension Validation Interfaces */ |
| /*--------------------------------------------------------------------------------*/ |
| |
| #define MATRIX_TEST_VALID_ADDITIVE_DIMENSIONS(input_type, \ |
| matrix_a_ptr, \ |
| matrix_b_ptr) \ |
| ((((input_type) (matrix_a_ptr))->numRows == \ |
| ((input_type) (matrix_b_ptr))->numRows) && \ |
| (((input_type) (matrix_a_ptr))->numCols == \ |
| ((input_type) (matrix_b_ptr))->numCols)) |
| |
| #define MATRIX_TEST_VALID_MULTIPLICATIVE_DIMENSIONS(input_type, \ |
| matrix_a_ptr, \ |
| matrix_b_ptr) \ |
| (((input_type) (matrix_a_ptr))->numCols == \ |
| ((input_type) (matrix_b_ptr))->numRows) |
| |
| #define MATRIX_TEST_VALID_SQUARE_DIMENSIONS(input_type, \ |
| matrix_ptr) \ |
| (((input_type)(matrix_ptr))->numRows == \ |
| ((input_type)(matrix_ptr))->numCols) |
| |
| #define MATRIX_TEST_VALID_DIMENSIONS_ALWAYS(input_type, \ |
| matrix_ptr) \ |
| (1 == 1) \ |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* Output Configuration Interfaces */ |
| /*--------------------------------------------------------------------------------*/ |
| /* The matrix tests assume the output matrix is always the correct size. These |
| * interfaces size the properly size the output matrices according to the input |
| * matrices and the operation at hand.*/ |
| |
| #define MATRIX_TEST_CONFIG_ADDITIVE_OUTPUT(input_type, \ |
| matrix_a_ptr, \ |
| matrix_b_ptr) \ |
| do \ |
| { \ |
| ((input_type) &matrix_output_fut)->numRows = \ |
| ((input_type)(matrix_a_ptr))->numRows; \ |
| ((input_type) &matrix_output_fut)->numCols = \ |
| ((input_type)(matrix_a_ptr))->numCols; \ |
| ((input_type) &matrix_output_ref)->numRows = \ |
| ((input_type)(matrix_a_ptr))->numRows; \ |
| ((input_type) &matrix_output_ref)->numCols = \ |
| ((input_type)(matrix_a_ptr))->numCols; \ |
| } while (0) |
| |
| #define MATRIX_TEST_CONFIG_MULTIPLICATIVE_OUTPUT(input_type, \ |
| matrix_a_ptr, \ |
| matrix_b_ptr) \ |
| do \ |
| { \ |
| ((input_type) &matrix_output_fut)->numRows = \ |
| ((input_type)(matrix_a_ptr))->numRows; \ |
| ((input_type) &matrix_output_fut)->numCols = \ |
| ((input_type)(matrix_b_ptr))->numCols; \ |
| ((input_type) &matrix_output_ref)->numRows = \ |
| ((input_type)(matrix_a_ptr))->numRows; \ |
| ((input_type) &matrix_output_ref)->numCols = \ |
| ((input_type)(matrix_b_ptr))->numCols; \ |
| } while (0) |
| |
| #define MATRIX_TEST_CONFIG_SAMESIZE_OUTPUT(input_type, \ |
| matrix_ptr) \ |
| do \ |
| { \ |
| ((input_type) &matrix_output_fut)->numRows = \ |
| ((input_type)(matrix_ptr))->numRows; \ |
| ((input_type) &matrix_output_fut)->numCols = \ |
| ((input_type)(matrix_ptr))->numCols; \ |
| ((input_type) &matrix_output_ref)->numRows = \ |
| ((input_type)(matrix_ptr))->numRows; \ |
| ((input_type) &matrix_output_ref)->numCols = \ |
| ((input_type)(matrix_ptr))->numCols; \ |
| } while (0) |
| |
| #define MATRIX_TEST_CONFIG_TRANSPOSE_OUTPUT(input_type, \ |
| matrix_ptr) \ |
| do \ |
| { \ |
| ((input_type) &matrix_output_fut)->numRows = \ |
| ((input_type)(matrix_ptr))->numCols; \ |
| ((input_type) &matrix_output_fut)->numCols = \ |
| ((input_type)(matrix_ptr))->numRows; \ |
| ((input_type) &matrix_output_ref)->numRows = \ |
| ((input_type)(matrix_ptr))->numCols; \ |
| ((input_type) &matrix_output_ref)->numCols = \ |
| ((input_type)(matrix_ptr))->numRows; \ |
| } while (0) |
| |
| /*--------------------------------------------------------------------------------*/ |
| /* TEST Templates */ |
| /*--------------------------------------------------------------------------------*/ |
| |
| #define MATRIX_TEST_TEMPLATE_ELT1(arr_desc_inputs, \ |
| input_type, \ |
| output_type, output_content_type, \ |
| fut, fut_arg_interface, \ |
| ref, ref_arg_interface, \ |
| output_config_interface, \ |
| dim_validation_interface, \ |
| compare_interface) \ |
| do \ |
| { \ |
| TEMPLATE_DO_ARR_DESC( \ |
| input_idx, input_type, input, arr_desc_inputs \ |
| , \ |
| JTEST_DUMP_STRF("Matrix Dimensions: %dx%d\n", \ |
| (int)input->numRows, \ |
| (int)input->numCols); \ |
| \ |
| if (dim_validation_interface(input_type, \ |
| input)) { \ |
| output_config_interface(input_type, \ |
| input); \ |
| TEST_CALL_FUT_AND_REF( \ |
| fut, fut_arg_interface(input), \ |
| ref, ref_arg_interface(input)); \ |
| compare_interface(output_type, \ |
| output_content_type); \ |
| } else { \ |
| arm_status matrix_test_retval; \ |
| TEST_CALL_FUT( \ |
| matrix_test_retval = fut, \ |
| fut_arg_interface(input)); \ |
| \ |
| /* If dimensions are known bad, the fut should */ \ |
| /* detect it. */ \ |
| if ( matrix_test_retval != ARM_MATH_SIZE_MISMATCH) { \ |
| return JTEST_TEST_FAILED; \ |
| } \ |
| }); \ |
| return JTEST_TEST_PASSED; \ |
| } while (0) |
| |
| |
| #define MATRIX_TEST_TEMPLATE_ELT2(arr_desc_inputs_a, \ |
| arr_desc_inputs_b, \ |
| input_type, \ |
| output_type, output_content_type, \ |
| fut, fut_arg_interface, \ |
| ref, ref_arg_interface, \ |
| output_config_interface, \ |
| dim_validation_interface, \ |
| compare_interface) \ |
| do \ |
| { \ |
| TEMPLATE_DO_ARR_DESC( \ |
| input_a_idx, input_type, input_a, arr_desc_inputs_a \ |
| , \ |
| input_type input_b = ARR_DESC_ELT( \ |
| input_type, input_a_idx, \ |
| &(arr_desc_inputs_b)); \ |
| \ |
| JTEST_DUMP_STRF("Matrix Dimensions: A %dx%d B %dx%d\n", \ |
| (int)input_a->numRows, \ |
| (int)input_a->numCols, \ |
| (int)input_b->numRows, \ |
| (int)input_b->numCols); \ |
| \ |
| if (dim_validation_interface(input_type, \ |
| input_a, \ |
| input_b)) { \ |
| \ |
| output_config_interface(input_type, \ |
| input_a, \ |
| input_b); \ |
| \ |
| TEST_CALL_FUT_AND_REF( \ |
| fut, fut_arg_interface(input_a, input_b), \ |
| ref, ref_arg_interface(input_a, input_b)); \ |
| \ |
| compare_interface(output_type, output_content_type); \ |
| \ |
| } else { \ |
| arm_status matrix_test_retval; \ |
| TEST_CALL_FUT( \ |
| matrix_test_retval = fut, fut_arg_interface(input_a, input_b)); \ |
| \ |
| /* If dimensions are known bad, the fut should */ \ |
| /* detect it. */ \ |
| if ( matrix_test_retval != ARM_MATH_SIZE_MISMATCH) { \ |
| return JTEST_TEST_FAILED; \ |
| } \ |
| }); \ |
| return JTEST_TEST_PASSED; \ |
| } while (0) |
| |
| /** |
| * Specialization of #MATRIX_TEST_TEMPLATE_ELT2() for matrix tests. |
| * |
| * @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and |
| * REF_xxx_INPUT_INTERFACEs. |
| */ |
| #define MATRIX_DEFINE_TEST_TEMPLATE_ELT2(fn_name, suffix, \ |
| output_config_interface, \ |
| dim_validation_interface, \ |
| comparison_interface) \ |
| JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \ |
| arm_##fn_name##_##suffix) \ |
| { \ |
| MATRIX_TEST_TEMPLATE_ELT2( \ |
| matrix_##suffix##_a_inputs, \ |
| matrix_##suffix##_b_inputs, \ |
| arm_matrix_instance_##suffix * , \ |
| arm_matrix_instance_##suffix, \ |
| TYPE_FROM_ABBREV(suffix), \ |
| arm_##fn_name##_##suffix, \ |
| ARM_##fn_name##_INPUT_INTERFACE, \ |
| ref_##fn_name##_##suffix, \ |
| REF_##fn_name##_INPUT_INTERFACE, \ |
| output_config_interface, \ |
| dim_validation_interface, \ |
| comparison_interface); \ |
| } \ |
| |
| /** |
| * Specialization of #MATRIX_TEST_TEMPLATE_ELT1() for matrix tests. |
| * |
| * @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and |
| * REF_xxx_INPUT_INTERFACEs. |
| */ |
| #define MATRIX_DEFINE_TEST_TEMPLATE_ELT1(fn_name, suffix, \ |
| output_config_interface, \ |
| dim_validation_interface) \ |
| JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \ |
| arm_##fn_name##_##suffix) \ |
| { \ |
| MATRIX_TEST_TEMPLATE_ELT1( \ |
| matrix_##suffix##_a_inputs, \ |
| arm_matrix_instance_##suffix * , \ |
| arm_matrix_instance_##suffix, \ |
| TYPE_FROM_ABBREV(suffix), \ |
| arm_##fn_name##_##suffix, \ |
| ARM_##fn_name##_INPUT_INTERFACE, \ |
| ref_##fn_name##_##suffix, \ |
| REF_##fn_name##_INPUT_INTERFACE, \ |
| output_config_interface, \ |
| dim_validation_interface, \ |
| MATRIX_COMPARE_INTERFACE); \ |
| } \ |
| |
| |
| #endif /* _MATRIX_TEMPLATES_H_ */ |