1 /*
2  * Copyright (c) 2021 Stephanos Ioannidis <root@stephanos.io>
3  * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <zephyr/ztest.h>
9 #include <zephyr/kernel.h>
10 #include <stdlib.h>
11 #include <arm_math.h>
12 #include "../../common/test_common.h"
13 
14 #include "unary_f32.pat"
15 
16 #define SNR_ERROR_THRESH	((float32_t)120)
17 #define REL_ERROR_THRESH	(1.0e-5)
18 #define ABS_ERROR_THRESH	(1.0e-5)
19 
20 #define SNR_ERROR_THRESH_INV	((float32_t)67)
21 #define REL_ERROR_THRESH_INV	(1.0e-3)
22 #define ABS_ERROR_THRESH_INV	(1.0e-3)
23 
24 #define SNR_ERROR_THRESH_CHOL	((float32_t)92)
25 #define REL_ERROR_THRESH_CHOL	(1.0e-5)
26 #define ABS_ERROR_THRESH_CHOL	(5.0e-4)
27 
28 #define NUM_MATRICES		(ARRAY_SIZE(in_dims) / 2)
29 #define MAX_MATRIX_DIM		(40)
30 
31 #define OP2_ADD			(0)
32 #define OP2_SUB			(1)
33 #define OP1_SCALE		(0)
34 #define OP1_TRANS		(1)
35 #define OP2V_VEC_MULT		(0)
36 #define OP1C_CMPLX_TRANS	(0)
37 
test_op2(int op,const uint32_t * ref,size_t length)38 static void test_op2(int op, const uint32_t *ref, size_t length)
39 {
40 	size_t index;
41 	uint16_t *dims = (uint16_t *)in_dims;
42 	float32_t *tmp1, *tmp2, *output;
43 	uint16_t rows, columns;
44 	arm_status status;
45 
46 	arm_matrix_instance_f32 mat_in1;
47 	arm_matrix_instance_f32 mat_in2;
48 	arm_matrix_instance_f32 mat_out;
49 
50 	/* Allocate buffers */
51 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
52 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
53 
54 	tmp2 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
55 	zassert_not_null(tmp2, ASSERT_MSG_BUFFER_ALLOC_FAILED);
56 
57 	output = malloc(length * sizeof(float32_t));
58 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
59 
60 	/* Initialise contexts */
61 	mat_in1.pData = tmp1;
62 	mat_in2.pData = tmp2;
63 	mat_out.pData = output;
64 
65 	/* Iterate matrices */
66 	for (index = 0; index < NUM_MATRICES; index++) {
67 		rows = *dims++;
68 		columns = *dims++;
69 
70 		/* Initialise matrix dimensions */
71 		mat_in1.numRows = mat_in2.numRows = mat_out.numRows = rows;
72 		mat_in1.numCols = mat_in2.numCols = mat_out.numCols = columns;
73 
74 		/* Load matrix data */
75 		memcpy(mat_in1.pData, in_com1,
76 		       rows * columns * sizeof(float32_t));
77 
78 		memcpy(mat_in2.pData, in_com2,
79 		       rows * columns * sizeof(float32_t));
80 
81 		/* Run test function */
82 		switch (op) {
83 		case OP2_ADD:
84 			status = arm_mat_add_f32(&mat_in1, &mat_in2,
85 						 &mat_out);
86 			break;
87 		case OP2_SUB:
88 			status = arm_mat_sub_f32(&mat_in1, &mat_in2,
89 						 &mat_out);
90 			break;
91 		default:
92 			zassert_unreachable("invalid operation");
93 		}
94 
95 		/* Validate status */
96 		zassert_equal(status, ARM_MATH_SUCCESS,
97 			      ASSERT_MSG_INCORRECT_COMP_RESULT);
98 
99 		/* Increment output pointer */
100 		mat_out.pData += (rows * columns);
101 	}
102 
103 	/* Validate output */
104 	zassert_true(
105 		test_snr_error_f32(length, output, (float32_t *)ref,
106 			SNR_ERROR_THRESH),
107 		ASSERT_MSG_SNR_LIMIT_EXCEED);
108 
109 	zassert_true(
110 		test_close_error_f32(length, output, (float32_t *)ref,
111 			ABS_ERROR_THRESH, REL_ERROR_THRESH),
112 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
113 
114 	/* Free buffers */
115 	free(tmp1);
116 	free(tmp2);
117 	free(output);
118 }
119 
120 DEFINE_TEST_VARIANT3(matrix_unary_f32,
121 	op2, arm_mat_add_f32, OP2_ADD,
122 	ref_add, ARRAY_SIZE(ref_add));
123 DEFINE_TEST_VARIANT3(matrix_unary_f32,
124 	op2, arm_mat_sub_f32, OP2_SUB,
125 	ref_sub, ARRAY_SIZE(ref_sub));
126 
test_op1(int op,const uint32_t * ref,size_t length,bool transpose)127 static void test_op1(int op, const uint32_t *ref, size_t length,
128 	bool transpose)
129 {
130 	size_t index;
131 	uint16_t *dims = (uint16_t *)in_dims;
132 	float32_t *tmp1, *output;
133 	uint16_t rows, columns;
134 	arm_status status;
135 
136 	arm_matrix_instance_f32 mat_in1;
137 	arm_matrix_instance_f32 mat_out;
138 
139 	/* Allocate buffers */
140 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
141 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
142 
143 	output = malloc(length * sizeof(float32_t));
144 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
145 
146 	/* Initialise contexts */
147 	mat_in1.pData = tmp1;
148 	mat_out.pData = output;
149 
150 	/* Iterate matrices */
151 	for (index = 0; index < NUM_MATRICES; index++) {
152 		rows = *dims++;
153 		columns = *dims++;
154 
155 		/* Initialise matrix dimensions */
156 		mat_in1.numRows = rows;
157 		mat_in1.numCols = columns;
158 		mat_out.numRows = transpose ? columns : rows;
159 		mat_out.numCols = transpose ? rows : columns;
160 
161 		/* Load matrix data */
162 		memcpy(mat_in1.pData, in_com1,
163 		       rows * columns * sizeof(float32_t));
164 
165 		/* Run test function */
166 		switch (op) {
167 		case OP1_SCALE:
168 			status = arm_mat_scale_f32(&mat_in1, 0.5f, &mat_out);
169 			break;
170 		case OP1_TRANS:
171 			status = arm_mat_trans_f32(&mat_in1, &mat_out);
172 			break;
173 		default:
174 			zassert_unreachable("invalid operation");
175 		}
176 
177 		/* Validate status */
178 		zassert_equal(status, ARM_MATH_SUCCESS,
179 			      ASSERT_MSG_INCORRECT_COMP_RESULT);
180 
181 		/* Increment output pointer */
182 		mat_out.pData += (rows * columns);
183 	}
184 
185 	/* Validate output */
186 	zassert_true(
187 		test_snr_error_f32(length, output, (float32_t *)ref,
188 			SNR_ERROR_THRESH),
189 		ASSERT_MSG_SNR_LIMIT_EXCEED);
190 
191 	zassert_true(
192 		test_close_error_f32(length, output, (float32_t *)ref,
193 			ABS_ERROR_THRESH, REL_ERROR_THRESH),
194 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
195 
196 	/* Free buffers */
197 	free(tmp1);
198 	free(output);
199 }
200 
201 DEFINE_TEST_VARIANT4(matrix_unary_f32,
202 	op1, arm_mat_scale_f32, OP1_SCALE,
203 	ref_scale, ARRAY_SIZE(ref_scale), false);
204 DEFINE_TEST_VARIANT4(matrix_unary_f32,
205 	op1, arm_mat_trans_f32, OP1_TRANS,
206 	ref_trans, ARRAY_SIZE(ref_trans), true);
207 
ZTEST(matrix_unary_f32,test_arm_mat_inverse_f32)208 ZTEST(matrix_unary_f32, test_arm_mat_inverse_f32)
209 {
210 	size_t index;
211 	size_t length = ARRAY_SIZE(ref_inv);
212 	uint16_t *dims = (uint16_t *)in_inv_dims;
213 	float32_t *input, *tmp1, *output;
214 	arm_status status;
215 	uint16_t rows, columns;
216 
217 	arm_matrix_instance_f32 mat_in1;
218 	arm_matrix_instance_f32 mat_out;
219 
220 	/* Allocate buffers */
221 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
222 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
223 
224 	output = malloc(length * sizeof(float32_t));
225 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
226 
227 	/* Initialise contexts */
228 	input = (float32_t *)in_inv;
229 	mat_in1.pData = tmp1;
230 	mat_out.pData = output;
231 
232 	/* Iterate matrices */
233 	for (index = 0; index < ARRAY_SIZE(in_inv_dims); index++) {
234 		rows = columns = *dims++;
235 
236 		/* Initialise matrix dimensions */
237 		mat_in1.numRows = mat_out.numRows = rows;
238 		mat_in1.numCols = mat_out.numCols = columns;
239 
240 		/* Load matrix data */
241 		memcpy(mat_in1.pData,
242 		       input, rows * columns * sizeof(float32_t));
243 
244 		/* Run test function */
245 		status = arm_mat_inverse_f32(&mat_in1, &mat_out);
246 
247 		zassert_equal(status, ARM_MATH_SUCCESS,
248 			ASSERT_MSG_INCORRECT_COMP_RESULT);
249 
250 		/* Increment pointers */
251 		input += (rows * columns);
252 		mat_out.pData += (rows * columns);
253 	}
254 
255 	/* Validate output */
256 	zassert_true(
257 		test_snr_error_f32(length, output, (float32_t *)ref_inv,
258 			SNR_ERROR_THRESH_INV),
259 		ASSERT_MSG_SNR_LIMIT_EXCEED);
260 
261 	zassert_true(
262 		test_close_error_f32(length, output, (float32_t *)ref_inv,
263 			ABS_ERROR_THRESH_INV, REL_ERROR_THRESH_INV),
264 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
265 
266 	/* Free buffers */
267 	free(tmp1);
268 	free(output);
269 }
270 
test_op2v(int op,const uint32_t * ref,size_t length)271 static void test_op2v(int op, const uint32_t *ref, size_t length)
272 {
273 	size_t index;
274 	const uint16_t *dims = in_dims;
275 	float32_t *tmp1, *vec, *output_buf, *output;
276 	uint16_t rows, internal;
277 
278 	arm_matrix_instance_f32 mat_in1;
279 
280 	/* Allocate buffers */
281 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
282 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
283 
284 	vec = malloc(2 * MAX_MATRIX_DIM * sizeof(float32_t));
285 	zassert_not_null(vec, ASSERT_MSG_BUFFER_ALLOC_FAILED);
286 
287 	output_buf = malloc(length * sizeof(float32_t));
288 	zassert_not_null(output_buf, ASSERT_MSG_BUFFER_ALLOC_FAILED);
289 
290 	/* Initialise contexts */
291 	mat_in1.pData = tmp1;
292 	output = output_buf;
293 
294 	/* Iterate matrices */
295 	for (index = 0; index < NUM_MATRICES; index++) {
296 		rows = *dims++;
297 		internal = *dims++;
298 
299 		/* Initialise matrix dimensions */
300 		mat_in1.numRows = rows;
301 		mat_in1.numCols = internal;
302 
303 		/* Load matrix data */
304 		memcpy(mat_in1.pData, in_com1,
305 		       2 * rows * internal * sizeof(float32_t));
306 		memcpy(vec, in_vec1, 2 * internal * sizeof(float32_t));
307 
308 		/* Run test function */
309 		switch (op) {
310 		case OP2V_VEC_MULT:
311 			arm_mat_vec_mult_f32(&mat_in1, vec, output);
312 			break;
313 		default:
314 			zassert_unreachable("invalid operation");
315 		}
316 
317 		/* Increment output pointer */
318 		output += rows;
319 	}
320 
321 	/* Validate output */
322 	zassert_true(
323 		test_snr_error_f32(length, output_buf, (float32_t *)ref,
324 				   SNR_ERROR_THRESH),
325 		ASSERT_MSG_SNR_LIMIT_EXCEED);
326 
327 	zassert_true(
328 		test_close_error_f32(length, output_buf, (float32_t *)ref,
329 				     ABS_ERROR_THRESH, REL_ERROR_THRESH),
330 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
331 
332 	/* Free buffers */
333 	free(tmp1);
334 	free(vec);
335 	free(output_buf);
336 }
337 
338 DEFINE_TEST_VARIANT3(matrix_unary_f32,
339 	op2v, arm_mat_vec_mult_f32, OP2V_VEC_MULT,
340 	ref_vec_mult, ARRAY_SIZE(ref_vec_mult));
341 
test_op1c(int op,const uint32_t * ref,size_t length,bool transpose)342 static void test_op1c(int op, const uint32_t *ref, size_t length, bool transpose)
343 {
344 	size_t index;
345 	const uint16_t *dims = in_dims;
346 	float32_t *tmp1, *output;
347 	uint16_t rows, columns;
348 	arm_status status;
349 
350 	arm_matrix_instance_f32 mat_in1;
351 	arm_matrix_instance_f32 mat_out;
352 
353 	/* Allocate buffers */
354 	tmp1 = malloc(2 * MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
355 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
356 
357 	output = malloc(2 * length * sizeof(float32_t));
358 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
359 
360 	/* Initialise contexts */
361 	mat_in1.pData = tmp1;
362 	mat_out.pData = output;
363 
364 	/* Iterate matrices */
365 	for (index = 0; index < NUM_MATRICES; index++) {
366 		rows = *dims++;
367 		columns = *dims++;
368 
369 		/* Initialise matrix dimensions */
370 		mat_in1.numRows = rows;
371 		mat_in1.numCols = columns;
372 		mat_out.numRows = transpose ? columns : rows;
373 		mat_out.numCols = transpose ? rows : columns;
374 
375 		/* Load matrix data */
376 		memcpy(mat_in1.pData,
377 		       in_cmplx1, 2 * rows * columns * sizeof(float32_t));
378 
379 		/* Run test function */
380 		switch (op) {
381 		case OP1C_CMPLX_TRANS:
382 			status = arm_mat_cmplx_trans_f32(&mat_in1, &mat_out);
383 			break;
384 		default:
385 			zassert_unreachable("invalid operation");
386 		}
387 
388 		/* Validate status */
389 		zassert_equal(status, ARM_MATH_SUCCESS,
390 			      ASSERT_MSG_INCORRECT_COMP_RESULT);
391 
392 		/* Increment output pointer */
393 		mat_out.pData += 2 * (rows * columns);
394 	}
395 
396 	/* Validate output */
397 	zassert_true(
398 		test_snr_error_f32(2 * length, output, (float32_t *)ref,
399 				   SNR_ERROR_THRESH),
400 		ASSERT_MSG_SNR_LIMIT_EXCEED);
401 
402 	zassert_true(
403 		test_close_error_f32(2 * length, output, (float32_t *)ref,
404 				     ABS_ERROR_THRESH, REL_ERROR_THRESH),
405 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
406 
407 	/* Free buffers */
408 	free(tmp1);
409 	free(output);
410 }
411 
412 DEFINE_TEST_VARIANT4(matrix_unary_f32,
413 	op1c, arm_mat_cmplx_trans_f32, OP1C_CMPLX_TRANS,
414 	ref_cmplx_trans, ARRAY_SIZE(ref_cmplx_trans) / 2, true);
415 
ZTEST(matrix_unary_f32,test_arm_mat_cholesky_f32)416 ZTEST(matrix_unary_f32, test_arm_mat_cholesky_f32)
417 {
418 	size_t index;
419 	size_t length = ARRAY_SIZE(ref_cholesky_dpo);
420 	const uint16_t *dims = in_cholesky_dpo_dims;
421 	float32_t *input, *tmp1, *output;
422 	uint16_t rows, columns;
423 	arm_status status;
424 
425 	arm_matrix_instance_f32 mat_in1;
426 	arm_matrix_instance_f32 mat_out;
427 
428 	/* Allocate buffers */
429 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
430 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
431 
432 	output = calloc(length, sizeof(float32_t));
433 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
434 
435 	/* Initialise contexts */
436 	input = (float32_t *)in_cholesky_dpo;
437 	mat_in1.pData = tmp1;
438 	mat_out.pData = output;
439 
440 	/* Iterate matrices */
441 	for (index = 0; index < ARRAY_SIZE(in_cholesky_dpo_dims); index++) {
442 		rows = columns = *dims++;
443 
444 		/* Initialise matrix dimensions */
445 		mat_in1.numRows = mat_out.numRows = rows;
446 		mat_in1.numCols = mat_out.numCols = columns;
447 
448 		/* Load matrix data */
449 		memcpy(mat_in1.pData,
450 		       input, rows * columns * sizeof(float32_t));
451 
452 		/* Run test function */
453 		status = arm_mat_cholesky_f32(&mat_in1, &mat_out);
454 
455 		zassert_equal(status, ARM_MATH_SUCCESS,
456 			ASSERT_MSG_INCORRECT_COMP_RESULT);
457 
458 		/* Increment pointers */
459 		input += (rows * columns);
460 		mat_out.pData += (rows * columns);
461 	}
462 
463 	/* Validate output */
464 	zassert_true(
465 		test_snr_error_f32(length, output, (float32_t *)ref_cholesky_dpo,
466 			SNR_ERROR_THRESH_CHOL),
467 		ASSERT_MSG_SNR_LIMIT_EXCEED);
468 
469 	zassert_true(
470 		test_close_error_f32(length, output, (float32_t *)ref_cholesky_dpo,
471 			ABS_ERROR_THRESH_CHOL, REL_ERROR_THRESH_CHOL),
472 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
473 
474 	/* Free buffers */
475 	free(tmp1);
476 	free(output);
477 }
478 
ZTEST(matrix_unary_f32,test_arm_mat_solve_upper_triangular_f32)479 ZTEST(matrix_unary_f32, test_arm_mat_solve_upper_triangular_f32)
480 {
481 	size_t index;
482 	size_t length = ARRAY_SIZE(ref_uptriangular_dpo);
483 	const uint16_t *dims = in_cholesky_dpo_dims;
484 	float32_t *input1, *input2, *tmp1, *tmp2, *output;
485 	uint16_t rows, columns;
486 	arm_status status;
487 
488 	arm_matrix_instance_f32 mat_in1;
489 	arm_matrix_instance_f32 mat_in2;
490 	arm_matrix_instance_f32 mat_out;
491 
492 	/* Allocate buffers */
493 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
494 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
495 
496 	tmp2 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
497 	zassert_not_null(tmp2, ASSERT_MSG_BUFFER_ALLOC_FAILED);
498 
499 	output = calloc(length, sizeof(float32_t));
500 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
501 
502 	/* Initialise contexts */
503 	input1 = (float32_t *)in_uptriangular_dpo;
504 	input2 = (float32_t *)in_rnda_dpo;
505 	mat_in1.pData = tmp1;
506 	mat_in2.pData = tmp2;
507 	mat_out.pData = output;
508 
509 	/* Iterate matrices */
510 	for (index = 0; index < ARRAY_SIZE(in_cholesky_dpo_dims); index++) {
511 		rows = columns = *dims++;
512 
513 		/* Initialise matrix dimensions */
514 		mat_in1.numRows = mat_in2.numRows = mat_out.numRows = rows;
515 		mat_in1.numCols = mat_in2.numCols = mat_out.numCols = columns;
516 
517 		/* Load matrix data */
518 		memcpy(mat_in1.pData, input1,
519 		       rows * columns * sizeof(float32_t));
520 
521 		memcpy(mat_in2.pData, input2,
522 		       rows * columns * sizeof(float32_t));
523 
524 		/* Run test function */
525 		status = arm_mat_solve_upper_triangular_f32(&mat_in1, &mat_in2,
526 							    &mat_out);
527 
528 		zassert_equal(status, ARM_MATH_SUCCESS,
529 			      ASSERT_MSG_INCORRECT_COMP_RESULT);
530 
531 		/* Increment output pointer */
532 		input1 += (rows * columns);
533 		input2 += (rows * columns);
534 		mat_out.pData += (rows * columns);
535 	}
536 
537 	/* Validate output */
538 	zassert_true(
539 		test_snr_error_f32(length, output,
540 			(float32_t *)ref_uptriangular_dpo,
541 			SNR_ERROR_THRESH),
542 		ASSERT_MSG_SNR_LIMIT_EXCEED);
543 
544 	zassert_true(
545 		test_close_error_f32(length, output,
546 			(float32_t *)ref_uptriangular_dpo,
547 			ABS_ERROR_THRESH, REL_ERROR_THRESH),
548 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
549 
550 	/* Free buffers */
551 	free(tmp1);
552 	free(tmp2);
553 	free(output);
554 }
555 
ZTEST(matrix_unary_f32,test_arm_mat_solve_lower_triangular_f32)556 ZTEST(matrix_unary_f32, test_arm_mat_solve_lower_triangular_f32)
557 {
558 	size_t index;
559 	size_t length = ARRAY_SIZE(ref_lotriangular_dpo);
560 	const uint16_t *dims = in_cholesky_dpo_dims;
561 	float32_t *input1, *input2, *tmp1, *tmp2, *output;
562 	uint16_t rows, columns;
563 	arm_status status;
564 
565 	arm_matrix_instance_f32 mat_in1;
566 	arm_matrix_instance_f32 mat_in2;
567 	arm_matrix_instance_f32 mat_out;
568 
569 	/* Allocate buffers */
570 	tmp1 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
571 	zassert_not_null(tmp1, ASSERT_MSG_BUFFER_ALLOC_FAILED);
572 
573 	tmp2 = malloc(MAX_MATRIX_DIM * MAX_MATRIX_DIM * sizeof(float32_t));
574 	zassert_not_null(tmp2, ASSERT_MSG_BUFFER_ALLOC_FAILED);
575 
576 	output = calloc(length, sizeof(float32_t));
577 	zassert_not_null(output, ASSERT_MSG_BUFFER_ALLOC_FAILED);
578 
579 	/* Initialise contexts */
580 	input1 = (float32_t *)in_lotriangular_dpo;
581 	input2 = (float32_t *)in_rnda_dpo;
582 	mat_in1.pData = tmp1;
583 	mat_in2.pData = tmp2;
584 	mat_out.pData = output;
585 
586 	/* Iterate matrices */
587 	for (index = 0; index < ARRAY_SIZE(in_cholesky_dpo_dims); index++) {
588 		rows = columns = *dims++;
589 
590 		/* Initialise matrix dimensions */
591 		mat_in1.numRows = mat_in2.numRows = mat_out.numRows = rows;
592 		mat_in1.numCols = mat_in2.numCols = mat_out.numCols = columns;
593 
594 		/* Load matrix data */
595 		memcpy(mat_in1.pData, input1,
596 		       rows * columns * sizeof(float32_t));
597 
598 		memcpy(mat_in2.pData, input2,
599 		       rows * columns * sizeof(float32_t));
600 
601 		/* Run test function */
602 		status = arm_mat_solve_lower_triangular_f32(&mat_in1, &mat_in2,
603 							    &mat_out);
604 
605 		zassert_equal(status, ARM_MATH_SUCCESS,
606 			      ASSERT_MSG_INCORRECT_COMP_RESULT);
607 
608 		/* Increment output pointer */
609 		input1 += (rows * columns);
610 		input2 += (rows * columns);
611 		mat_out.pData += (rows * columns);
612 	}
613 
614 	/* Validate output */
615 	zassert_true(
616 		test_snr_error_f32(length, output,
617 			(float32_t *)ref_lotriangular_dpo,
618 			SNR_ERROR_THRESH),
619 		ASSERT_MSG_SNR_LIMIT_EXCEED);
620 
621 	zassert_true(
622 		test_close_error_f32(length, output,
623 			(float32_t *)ref_lotriangular_dpo,
624 			ABS_ERROR_THRESH, REL_ERROR_THRESH),
625 		ASSERT_MSG_ERROR_LIMIT_EXCEED);
626 
627 	/* Free buffers */
628 	free(tmp1);
629 	free(tmp2);
630 	free(output);
631 }
632 
633 /*
634  * NOTE: arm_mat_ldlt_f32 tests are not implemented for now because they
635  *       require on-device test pattern generation which defeats the purpose
636  *       of on-device testing. Add these tests when the upstream testsuite is
637  *       updated to use pre-generated test patterns.
638  */
639 
640 ZTEST_SUITE(matrix_unary_f32, NULL, NULL, NULL, NULL, NULL);
641