#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_ */
|