Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | mjames | 1 | #ifndef _TEST_TEMPLATES_H_ |
2 | #define _TEST_TEMPLATES_H_ |
||
3 | |||
4 | /*--------------------------------------------------------------------------------*/ |
||
5 | /* Includes */ |
||
6 | /*--------------------------------------------------------------------------------*/ |
||
7 | #include "template.h" |
||
8 | #include <string.h> /* memcmp() */ |
||
9 | #include <inttypes.h> /* PRIu32 */ |
||
10 | #include "math_helper.h" /* arm_snr_f32() */ |
||
11 | |||
12 | /*--------------------------------------------------------------------------------*/ |
||
13 | /* Function Aliases for use in Templates. */ |
||
14 | /*--------------------------------------------------------------------------------*/ |
||
15 | #define ref_q31_t_to_float ref_q31_to_float |
||
16 | #define ref_q15_t_to_float ref_q15_to_float |
||
17 | #define ref_q7_t_to_float ref_q7_to_float |
||
18 | #define ref_float_to_q31_t ref_float_to_q31 |
||
19 | #define ref_float_to_q15_t ref_float_to_q15 |
||
20 | #define ref_float_to_q7_t ref_float_to_q7 |
||
21 | #define ref_float32_t_to_float ref_copy_f32 |
||
22 | #define ref_float_to_float32_t ref_copy_f32 |
||
23 | |||
24 | |||
25 | /*--------------------------------------------------------------------------------*/ |
||
26 | /* Macros and Defines */ |
||
27 | /*--------------------------------------------------------------------------------*/ |
||
28 | |||
29 | /** |
||
30 | * Call the function-under-test. |
||
31 | */ |
||
32 | #define TEST_CALL_FUT(fut, fut_args) \ |
||
33 | JTEST_COUNT_CYCLES(TEMPLATE_CALL_FN(fut, fut_args)) |
||
34 | |||
35 | /** |
||
36 | * Call the reference-function. |
||
37 | */ |
||
38 | #define TEST_CALL_REF(ref, ref_args) \ |
||
39 | TEMPLATE_CALL_FN(ref, ref_args) |
||
40 | |||
41 | /** |
||
42 | * Call the function-under-test and the reference-function. |
||
43 | */ |
||
44 | #define TEST_CALL_FUT_AND_REF(fut, fut_args, ref, ref_args) \ |
||
45 | do { \ |
||
46 | TEST_CALL_FUT(fut, fut_args); \ |
||
47 | TEST_CALL_REF(ref, ref_args); \ |
||
48 | } while (0) |
||
49 | |||
50 | /** |
||
51 | * This macro eats a variable number of arguments and evaluates to a null |
||
52 | * statement. |
||
53 | */ |
||
54 | #define TEST_NULL_STATEMENT(...) (void) "TEST_NULL_STATEMENT" |
||
55 | |||
56 | /** |
||
57 | * A function name, Usable in any template where a fut or ref name is accepted, |
||
58 | * that evaluates to a #TEST_NULL_STATEMENT(). |
||
59 | */ |
||
60 | #define TEST_NULL_FN TEST_NULL_STATEMENT |
||
61 | |||
62 | /** |
||
63 | * Assert that buffers A and B are byte-equivalent for a number of bytes. |
||
64 | */ |
||
65 | #define TEST_ASSERT_BUFFERS_EQUAL(buf_a, buf_b, bytes) \ |
||
66 | do \ |
||
67 | { \ |
||
68 | if (memcmp(buf_a, buf_b, bytes) != 0) \ |
||
69 | { \ |
||
70 | return JTEST_TEST_FAILED; \ |
||
71 | } \ |
||
72 | } while (0) |
||
73 | |||
74 | /** |
||
75 | * Assert that the two entities are equal. |
||
76 | */ |
||
77 | #define TEST_ASSERT_EQUAL(a, b) \ |
||
78 | do \ |
||
79 | { \ |
||
80 | if ((a) != (b)) \ |
||
81 | { \ |
||
82 | return JTEST_TEST_FAILED; \ |
||
83 | } \ |
||
84 | } while (0) |
||
85 | |||
86 | /** |
||
87 | * Convert elements to from src_type to float. |
||
88 | */ |
||
89 | #define TEST_CONVERT_TO_FLOAT(src_ptr, dst_ptr, block_size, src_type) \ |
||
90 | do \ |
||
91 | { \ |
||
92 | ref_##src_type##_to_float( \ |
||
93 | src_ptr, \ |
||
94 | dst_ptr, \ |
||
95 | block_size); \ |
||
96 | } while (0) \ |
||
97 | |||
98 | /** |
||
99 | * Convert elements to from float to dst_type . |
||
100 | */ |
||
101 | #define TEST_CONVERT_FLOAT_TO(src_ptr, dst_ptr, block_size, dst_type) \ |
||
102 | do \ |
||
103 | { \ |
||
104 | ref_float_to_##dst_type( \ |
||
105 | src_ptr, \ |
||
106 | dst_ptr, \ |
||
107 | block_size); \ |
||
108 | } while (0) \ |
||
109 | |||
110 | /** |
||
111 | * Assert that the SNR between a reference and test sample is above a given |
||
112 | * threshold. |
||
113 | */ |
||
114 | #define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold) \ |
||
115 | do \ |
||
116 | { \ |
||
117 | float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size); \ |
||
118 | if ( snr <= threshold) \ |
||
119 | { \ |
||
120 | JTEST_DUMP_STRF("SNR: %f\n", snr); \ |
||
121 | return JTEST_TEST_FAILED; \ |
||
122 | } \ |
||
123 | } while (0) \ |
||
124 | |||
125 | /** |
||
126 | * Assert that the SNR between a reference and test sample is above a given |
||
127 | * threshold. Special case for float64_t |
||
128 | */ |
||
129 | #define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold) \ |
||
130 | do \ |
||
131 | { \ |
||
132 | float64_t snr = arm_snr_f64(ref_ptr, tst_ptr, block_size); \ |
||
133 | if ( snr <= threshold) \ |
||
134 | { \ |
||
135 | JTEST_DUMP_STRF("SNR: %f\n", snr); \ |
||
136 | return JTEST_TEST_FAILED; \ |
||
137 | } \ |
||
138 | } while (0) \ |
||
139 | |||
140 | /** |
||
141 | * Compare test and reference elements by converting to float and |
||
142 | * calculating an SNR. |
||
143 | * |
||
144 | * This macro is a merger of the #TEST_CONVERT_TO_FLOAT() and |
||
145 | * #TEST_ASSERT_SNR() macros. |
||
146 | */ |
||
147 | #define TEST_CONVERT_AND_ASSERT_SNR(ref_dst_ptr, ref_src_ptr, \ |
||
148 | tst_dst_ptr, tst_src_ptr, \ |
||
149 | block_size, \ |
||
150 | tst_src_type, \ |
||
151 | threshold) \ |
||
152 | do \ |
||
153 | { \ |
||
154 | TEST_CONVERT_TO_FLOAT(ref_src_ptr, \ |
||
155 | ref_dst_ptr, \ |
||
156 | block_size, \ |
||
157 | tst_src_type); \ |
||
158 | TEST_CONVERT_TO_FLOAT(tst_src_ptr, \ |
||
159 | tst_dst_ptr, \ |
||
160 | block_size, \ |
||
161 | tst_src_type); \ |
||
162 | TEST_ASSERT_SNR(ref_dst_ptr, \ |
||
163 | tst_dst_ptr, \ |
||
164 | block_size, \ |
||
165 | threshold); \ |
||
166 | } while (0) |
||
167 | |||
168 | /** |
||
169 | * Execute statements only if the combination of block size, function type |
||
170 | * specifier, and input ARR_DESC_t are valid. |
||
171 | * |
||
172 | * @example An ARR_DESC_t that contains 64 bytes cant service a 32 element |
||
173 | * block size if they are extracted in float32_t increments. |
||
174 | * |
||
175 | * 8 * 32 = 256 > 64. |
||
176 | */ |
||
177 | #define TEST_DO_VALID_BLOCKSIZE(block_size, fn_type_spec, \ |
||
178 | input_arr_desc, body) \ |
||
179 | do \ |
||
180 | { \ |
||
181 | if (block_size * sizeof(fn_type_spec) <= \ |
||
182 | ARR_DESC_BYTES(input_arr_desc)) \ |
||
183 | { \ |
||
184 | JTEST_DUMP_STRF("Block Size: %"PRIu32"\n", block_size); \ |
||
185 | body; \ |
||
186 | } \ |
||
187 | } while (0) \ |
||
188 | |||
189 | /** |
||
190 | * Template for tests that rely on one input buffer and a blocksize parameter. |
||
191 | * |
||
192 | * The buffer is an #ARR_DESC_t. It is iterated over and it's values are |
||
193 | * passed to the function under test and reference functions through their |
||
194 | * appropriate argument interfaces. The argument interfaces this template to |
||
195 | * execute structurally similar functions. |
||
196 | * |
||
197 | */ |
||
198 | #define TEST_TEMPLATE_BUF1_BLK(arr_desc_inputs, \ |
||
199 | arr_desc_block_sizes, \ |
||
200 | input_type, output_type, \ |
||
201 | fut, fut_arg_interface, \ |
||
202 | ref, ref_arg_interface, \ |
||
203 | compare_interface) \ |
||
204 | do \ |
||
205 | { \ |
||
206 | TEMPLATE_DO_ARR_DESC( \ |
||
207 | input_idx, ARR_DESC_t *, input_ptr, arr_desc_inputs \ |
||
208 | , \ |
||
209 | TEMPLATE_DO_ARR_DESC( \ |
||
210 | block_size_idx, uint32_t, block_size, arr_desc_block_sizes \ |
||
211 | , \ |
||
212 | void * input_data_ptr = input_ptr->data_ptr; \ |
||
213 | \ |
||
214 | TEST_DO_VALID_BLOCKSIZE( \ |
||
215 | block_size, input_type, input_ptr \ |
||
216 | , \ |
||
217 | TEST_CALL_FUT_AND_REF( \ |
||
218 | fut, fut_arg_interface( \ |
||
219 | input_data_ptr, block_size), \ |
||
220 | ref, ref_arg_interface( \ |
||
221 | input_data_ptr, block_size)); \ |
||
222 | \ |
||
223 | compare_interface(block_size, output_type)))); \ |
||
224 | \ |
||
225 | return JTEST_TEST_PASSED; \ |
||
226 | \ |
||
227 | } while (0) |
||
228 | |||
229 | /** |
||
230 | * Template for tests that rely on an input buffer and an element. |
||
231 | * |
||
232 | * An element can is any thing which doesn't walk and talk like a |
||
233 | * sequence. Examples include numbers, and structures. |
||
234 | */ |
||
235 | #define TEST_TEMPLATE_BUF1_ELT1(arr_desc_inputs, \ |
||
236 | arr_desc_elts, \ |
||
237 | input_type, elt_type, output_type, \ |
||
238 | fut, fut_arg_interface, \ |
||
239 | ref, ref_arg_interface, \ |
||
240 | compare_interface) \ |
||
241 | do \ |
||
242 | { \ |
||
243 | TEMPLATE_DO_ARR_DESC( \ |
||
244 | input_idx, ARR_DESC_t *, input_ptr, arr_desc_inputs \ |
||
245 | , \ |
||
246 | TEMPLATE_DO_ARR_DESC( \ |
||
247 | elt_idx, elt_type, elt, arr_desc_elts \ |
||
248 | , \ |
||
249 | void * input_data_ptr = input_ptr->data_ptr; \ |
||
250 | TEST_CALL_FUT_AND_REF( \ |
||
251 | fut, fut_arg_interface(input_data_ptr, elt), \ |
||
252 | ref, ref_arg_interface(input_data_ptr, elt)); \ |
||
253 | \ |
||
254 | compare_interface(output_type))); \ |
||
255 | return JTEST_TEST_PASSED; \ |
||
256 | } while (0) |
||
257 | |||
258 | /** |
||
259 | * Template for tests that rely on an input buffer, an element, and a blocksize |
||
260 | * parameter. |
||
261 | */ |
||
262 | #define TEST_TEMPLATE_BUF1_ELT1_BLK(arr_desc_inputs, \ |
||
263 | arr_desc_elts, \ |
||
264 | arr_desc_block_sizes, \ |
||
265 | input_type, elt_type, output_type, \ |
||
266 | fut, fut_arg_interface, \ |
||
267 | ref, ref_arg_interface, \ |
||
268 | compare_interface); \ |
||
269 | do \ |
||
270 | { \ |
||
271 | TEMPLATE_DO_ARR_DESC( \ |
||
272 | inut_idx, ARR_DESC_t *, input_ptr, arr_desc_inputs \ |
||
273 | , \ |
||
274 | TEMPLATE_DO_ARR_DESC( \ |
||
275 | block_size_idx, uint32_t, block_size, \ |
||
276 | arr_desc_block_sizes \ |
||
277 | , \ |
||
278 | TEMPLATE_DO_ARR_DESC( \ |
||
279 | elt_idx, elt_type, elt, arr_desc_elts \ |
||
280 | , \ |
||
281 | void * input_data_ptr = input_ptr->data_ptr; \ |
||
282 | TEST_DO_VALID_BLOCKSIZE( \ |
||
283 | block_size, input_type, input_ptr, \ |
||
284 | \ |
||
285 | TEST_CALL_FUT_AND_REF( \ |
||
286 | fut, fut_arg_interface( \ |
||
287 | input_data_ptr, elt, block_size), \ |
||
288 | ref, ref_arg_interface( \ |
||
289 | input_data_ptr, elt, block_size)); \ |
||
290 | compare_interface(block_size, output_type))))); \ |
||
291 | return JTEST_TEST_PASSED; \ |
||
292 | } while (0) |
||
293 | |||
294 | /** |
||
295 | * Template for tests that rely on an input buffer, two elements, and a blocksize |
||
296 | * parameter. |
||
297 | */ |
||
298 | #define TEST_TEMPLATE_BUF1_ELT2_BLK(arr_desc_inputs, \ |
||
299 | arr_desc_elt1s, \ |
||
300 | arr_desc_elt2s, \ |
||
301 | arr_desc_block_sizes, \ |
||
302 | input_type, elt1_type, \ |
||
303 | elt2_type, output_type, \ |
||
304 | fut, fut_arg_interface, \ |
||
305 | ref, ref_arg_interface, \ |
||
306 | compare_interface) \ |
||
307 | do \ |
||
308 | { \ |
||
309 | TEMPLATE_DO_ARR_DESC( \ |
||
310 | inut_idx, ARR_DESC_t *, input_ptr, arr_desc_inputs \ |
||
311 | , \ |
||
312 | TEMPLATE_DO_ARR_DESC( \ |
||
313 | block_size_idx, uint32_t, block_size, \ |
||
314 | arr_desc_block_sizes \ |
||
315 | , \ |
||
316 | TEMPLATE_DO_ARR_DESC( \ |
||
317 | elt1_idx, elt1_type, elt1, arr_desc_elt1s \ |
||
318 | , \ |
||
319 | TEMPLATE_DO_ARR_DESC( \ |
||
320 | elt2_idx, elt2_type, elt2, arr_desc_elt2s \ |
||
321 | , \ |
||
322 | void * input_data_ptr = input_ptr->data_ptr; \ |
||
323 | TEST_DO_VALID_BLOCKSIZE( \ |
||
324 | block_size, input_type, input_ptr, \ |
||
325 | TEST_CALL_FUT_AND_REF( \ |
||
326 | fut, fut_arg_interface( \ |
||
327 | input_data_ptr, elt1, elt2, block_size), \ |
||
328 | ref, ref_arg_interface( \ |
||
329 | input_data_ptr, elt1, elt2, block_size)); \ |
||
330 | compare_interface(block_size, output_type)))))); \ |
||
331 | return JTEST_TEST_PASSED; \ |
||
332 | } while (0) |
||
333 | |||
334 | /** |
||
335 | * Template for tests that rely on two input buffers and a blocksize parameter. |
||
336 | * |
||
337 | * The two #ARR_DESC_t, input buffers are iterated through in parallel. The |
||
338 | * length of the first #ARR_DESC_t determines the length of the iteration. |
||
339 | */ |
||
340 | #define TEST_TEMPLATE_BUF2_BLK(arr_desc_inputs_a, \ |
||
341 | arr_desc_inputs_b, \ |
||
342 | arr_desc_block_sizes, \ |
||
343 | input_type, output_type, \ |
||
344 | fut, fut_arg_interface, \ |
||
345 | ref, ref_arg_interface, \ |
||
346 | compare_interface) \ |
||
347 | do \ |
||
348 | { \ |
||
349 | /* Iterate over two input arrays in parallel.*/ \ |
||
350 | TEMPLATE_DO_ARR_DESC( \ |
||
351 | input_idx, ARR_DESC_t *, input_ptr, arr_desc_inputs_a \ |
||
352 | , \ |
||
353 | TEMPLATE_DO_ARR_DESC( \ |
||
354 | block_size_idx, uint32_t, block_size, arr_desc_block_sizes, \ |
||
355 | void * input_a_ptr = input_ptr->data_ptr; \ |
||
356 | void * input_b_ptr = ARR_DESC_ELT( \ |
||
357 | ARR_DESC_t *, input_idx, \ |
||
358 | &(arr_desc_inputs_b))->data_ptr; \ |
||
359 | \ |
||
360 | TEST_DO_VALID_BLOCKSIZE( \ |
||
361 | block_size, input_type, input_ptr \ |
||
362 | , \ |
||
363 | TEST_CALL_FUT_AND_REF( \ |
||
364 | fut, fut_arg_interface( \ |
||
365 | input_a_ptr, input_b_ptr, block_size), \ |
||
366 | ref, ref_arg_interface( \ |
||
367 | input_a_ptr, input_b_ptr, block_size)); \ |
||
368 | \ |
||
369 | compare_interface(block_size, output_type)))); \ |
||
370 | return JTEST_TEST_PASSED; \ |
||
371 | } while (0) |
||
372 | |||
373 | /** |
||
374 | * Test template that uses a single element. |
||
375 | */ |
||
376 | #define TEST_TEMPLATE_ELT1(arr_desc_elts, \ |
||
377 | elt_type, output_type, \ |
||
378 | fut, fut_arg_interface, \ |
||
379 | ref, ref_arg_interface, \ |
||
380 | compare_interface) \ |
||
381 | do \ |
||
382 | { \ |
||
383 | TEMPLATE_DO_ARR_DESC( \ |
||
384 | elt_idx, elt_type, elt, arr_desc_elts \ |
||
385 | , \ |
||
386 | TEST_CALL_FUT_AND_REF( \ |
||
387 | fut, fut_arg_interface( \ |
||
388 | elt), \ |
||
389 | ref, ref_arg_interface( \ |
||
390 | elt)); \ |
||
391 | /* Comparison interfaces typically accept */ \ |
||
392 | /* a block_size. Pass a dummy value 1.*/ \ |
||
393 | compare_interface(1, output_type)); \ |
||
394 | return JTEST_TEST_PASSED; \ |
||
395 | } while (0) |
||
396 | |||
397 | /** |
||
398 | * Test template that iterates over two sets of elements in parallel. |
||
399 | * |
||
400 | * The length of the first set determines the number of iteratsions. |
||
401 | */ |
||
402 | #define TEST_TEMPLATE_ELT2(arr_desc_elts_a, \ |
||
403 | arr_desc_elts_b, \ |
||
404 | elt_a_type, elt_b_type, output_type, \ |
||
405 | fut, fut_arg_interface, \ |
||
406 | ref, ref_arg_interface, \ |
||
407 | compare_interface) \ |
||
408 | do \ |
||
409 | { \ |
||
410 | TEMPLATE_DO_ARR_DESC( \ |
||
411 | elt_a_idx, elt_a_type, elt_a, arr_desc_elts_a \ |
||
412 | , \ |
||
413 | elt_b_type * elt_b = ARR_DESC_ELT( \ |
||
414 | elt_b_type, \ |
||
415 | elt_a_idx, \ |
||
416 | arr_desc_elts_b); \ |
||
417 | \ |
||
418 | TEST_CALL_FUT_AND_REF( \ |
||
419 | fut, fut_arg_interface( \ |
||
420 | elt_a, elt_b), \ |
||
421 | ref, ref_arg_interface( \ |
||
422 | elt_a, elt_b)); \ |
||
423 | /* Comparison interfaces typically accept */ \ |
||
424 | /* a block_size. Pass a dummy value 1.*/ \ |
||
425 | compare_interface(1, output_type)); \ |
||
426 | return JTEST_TEST_PASSED; \ |
||
427 | } while (0) |
||
428 | |||
429 | /** |
||
430 | * Test template that uses an element and a block size. |
||
431 | */ |
||
432 | #define TEST_TEMPLATE_ELT1_BLK(arr_desc_elts, \ |
||
433 | arr_desc_block_sizes, \ |
||
434 | elt_type, output_type, \ |
||
435 | fut, fut_arg_interface, \ |
||
436 | ref, ref_arg_interface, \ |
||
437 | compare_interface) \ |
||
438 | do \ |
||
439 | { \ |
||
440 | TEMPLATE_DO_ARR_DESC( \ |
||
441 | block_size_idx, uint32_t, block_size, \ |
||
442 | arr_desc_block_sizes \ |
||
443 | , \ |
||
444 | TEMPLATE_DO_ARR_DESC( \ |
||
445 | elt_idx, elt_type, elt, arr_desc_elts \ |
||
446 | , \ |
||
447 | JTEST_DUMP_STRF("Block Size: %d\n", \ |
||
448 | (int)block_size); \ |
||
449 | TEST_CALL_FUT_AND_REF( \ |
||
450 | fut, fut_arg_interface( \ |
||
451 | elt, block_size), \ |
||
452 | ref, ref_arg_interface( \ |
||
453 | elt, block_size)); \ |
||
454 | compare_interface(block_size, output_type))); \ |
||
455 | return JTEST_TEST_PASSED; \ |
||
456 | } while (0) |
||
457 | |||
458 | #endif /* _TEST_TEMPLATES_H_ */ |