|
@@ -0,0 +1,370 @@
|
|
|
|
+#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_ */
|