1 /*
2
3 Copyright (C) 2014, The University of Texas at Austin
4
5 This file is part of libflame and is available under the 3-Clause
6 BSD license, which can be found in the LICENSE file at the top-level
7 directory, or at http://opensource.org/licenses/BSD-3-Clause
8
9 */
10
11 #include "FLAME.h"
12
13 #include "test_libflame.h"
14
15 // Operation modules.
16 #include "test_gemm.h"
17 #include "test_hemm.h"
18 #include "test_herk.h"
19 #include "test_her2k.h"
20 #include "test_symm.h"
21 #include "test_syrk.h"
22 #include "test_syr2k.h"
23 #include "test_trmm.h"
24 #include "test_trsm.h"
25 #include "test_chol.h"
26 #include "test_lu_nopiv.h"
27 #include "test_lu_piv.h"
28 #include "test_lu_incpiv.h"
29 #include "test_qrut.h"
30 #include "test_qrutinc.h"
31 #include "test_lqut.h"
32 #include "test_apqut.h"
33 #include "test_apqutinc.h"
34 #include "test_caqrutinc.h"
35 #include "test_apcaqutinc.h"
36 #include "test_uddateut.h"
37 #include "test_uddateutinc.h"
38 #include "test_apqudut.h"
39 #include "test_apqudutinc.h"
40 #include "test_hessut.h"
41 #include "test_tridiagut.h"
42 #include "test_bidiagut.h"
43 #include "test_eig_gest.h"
44 #include "test_trinv.h"
45 #include "test_spdinv.h"
46 #include "test_sylv.h"
47 #include "test_lyap.h"
48
49
50 // Global variables.
51 char libfla_test_binary_name[ MAX_BINARY_NAME_LENGTH + 1 ];
52 char libfla_test_pass_string[ MAX_PASS_STRING_LENGTH + 1 ];
53 char libfla_test_warn_string[ MAX_PASS_STRING_LENGTH + 1 ];
54 char libfla_test_fail_string[ MAX_PASS_STRING_LENGTH + 1 ];
55
56 char libfla_test_stor_chars[ NUM_STORAGE_CHARS + 1 ];
57
main(int argc,char ** argv)58 int main( int argc, char** argv )
59 {
60 test_params_t params;
61 test_ops_t ops;
62
63 // Initialize libflame.
64 FLA_Init();
65
66 // Initialize some strings.
67 libfla_test_init_strings();
68
69 // Parse the command line parameters.
70 libfla_test_parse_command_line( argc, argv );
71
72 // Read the main test suite parameters.
73 libfla_test_read_parameter_file( PARAMETERS_FILENAME, ¶ms );
74
75 // Read which operations we're going to test.
76 libfla_test_read_operation_file( OPERATIONS_FILENAME, &ops );
77
78 // Test the BLAS level-3 operations.
79 libfla_test_blas3_suite( stdout, params, ops );
80
81 // Test the LAPACK-level operations.
82 libfla_test_lapack_suite( stdout, params, ops );
83
84 // Finalize libflame.
85 FLA_Finalize();
86
87 // Return peacefully.
88 return 0;
89 }
90
91
92
libfla_test_blas3_suite(FILE * output_stream,test_params_t params,test_ops_t ops)93 void libfla_test_blas3_suite( FILE* output_stream, test_params_t params, test_ops_t ops )
94 {
95 // Run the individual test modules.
96
97 libfla_test_output_info( "\n" );
98 libfla_test_output_info( "--- BLAS level-3 operation tests ---------------------\n" );
99 libfla_test_output_info( "\n" );
100
101 // General matrix-matrix multiply.
102 libfla_test_gemm( output_stream, params, ops.gemm );
103
104 // Hermitian matrix-matrix multiply.
105 libfla_test_hemm( output_stream, params, ops.hemm );
106
107 // Hermitian rank-k update.
108 libfla_test_herk( output_stream, params, ops.herk );
109
110 // Hermitian rank-2k update.
111 libfla_test_her2k( output_stream, params, ops.her2k );
112
113 // Symmetric matrix-matrix multiply.
114 libfla_test_symm( output_stream, params, ops.symm );
115
116 // Symmetric rank-k update.
117 libfla_test_syrk( output_stream, params, ops.syrk );
118
119 // Symmetric rank-2k update.
120 libfla_test_syr2k( output_stream, params, ops.syr2k );
121
122 // Triangular matrix-matrix multiply.
123 libfla_test_trmm( output_stream, params, ops.trmm );
124
125 // Triangular solve with multiple rhs.
126 libfla_test_trsm( output_stream, params, ops.trsm );
127 }
128
129
130
libfla_test_lapack_suite(FILE * output_stream,test_params_t params,test_ops_t ops)131 void libfla_test_lapack_suite( FILE* output_stream, test_params_t params, test_ops_t ops )
132 {
133 // Run the individual test modules.
134
135 libfla_test_output_info( "\n" );
136 libfla_test_output_info( "--- LAPACK-level operation tests ---------------------\n" );
137 libfla_test_output_info( "\n" );
138
139 // Cholesky factorization.
140 libfla_test_chol( output_stream, params, ops.chol );
141
142 // LU factorization without pivoting.
143 libfla_test_lu_nopiv( output_stream, params, ops.lu_nopiv );
144
145 // LU factorization with partial pivoting.
146 libfla_test_lu_piv( output_stream, params, ops.lu_piv );
147
148 // LU factorization with incremental pivoting.
149 libfla_test_lu_incpiv( output_stream, params, ops.lu_incpiv );
150
151 // QR factorization via the UT transform.
152 libfla_test_qrut( output_stream, params, ops.qrut );
153
154 // QR factorization via the UT transform (incremental).
155 libfla_test_qrutinc( output_stream, params, ops.qrutinc );
156
157 // LQ factorization via the UT transform.
158 libfla_test_lqut( output_stream, params, ops.lqut );
159
160 // Apply Q via the UT transform.
161 libfla_test_apqut( output_stream, params, ops.apqut );
162
163 // Apply Q via the UT transform (incremental).
164 libfla_test_apqutinc( output_stream, params, ops.apqutinc );
165
166 // Communication-avoiding QR factorization via the UT transform (incremental).
167 libfla_test_caqrutinc( output_stream, params, ops.caqrutinc );
168
169 // Apply communication-avoiding Q via the UT transform (incremental).
170 libfla_test_apcaqutinc( output_stream, params, ops.apcaqutinc );
171
172 // Up/downdating via the UT transform.
173 libfla_test_uddateut( output_stream, params, ops.uddateut );
174
175 // Up/downdating via the UT transform (incremental).
176 libfla_test_uddateutinc( output_stream, params, ops.uddateutinc );
177
178 // Apply up/downdating Q via the UD UT transform.
179 libfla_test_apqudut( output_stream, params, ops.apqudut );
180
181 // Apply up/downdating Q via the UD UT transform (incremental).
182 libfla_test_apqudutinc( output_stream, params, ops.apqudutinc );
183
184 // Reduction to upper Hessenberg form via the UT transform.
185 libfla_test_hessut( output_stream, params, ops.hessut );
186
187 // Reduction to tridiagonal form via the UT transform.
188 libfla_test_tridiagut( output_stream, params, ops.tridiagut );
189
190 // Reduction to bidiagonal form via the UT transform.
191 libfla_test_bidiagut( output_stream, params, ops.bidiagut );
192
193 // Reduction of Hermitian-definite eigenproblem to standard form.
194 libfla_test_eig_gest( output_stream, params, ops.eig_gest );
195
196 // Triangular matrix inversion.
197 libfla_test_trinv( output_stream, params, ops.trinv );
198
199 // Hermitian positive-definite matrix inversion.
200 libfla_test_spdinv( output_stream, params, ops.spdinv );
201
202 // Triangular Sylvester equation solve.
203 libfla_test_sylv( output_stream, params, ops.sylv );
204
205 // Triangular Lyapunov equation solve.
206 libfla_test_lyap( output_stream, params, ops.lyap );
207 }
208
209
210
libfla_test_read_operation_file(char * input_filename,test_ops_t * ops)211 void libfla_test_read_operation_file( char* input_filename, test_ops_t* ops )
212 {
213 FILE* input_stream;
214
215 // Attempt to open input file corresponding to input_filename as
216 // read-only/binary.
217 input_stream = fopen( input_filename, "rb" );
218
219 // Check for success.
220 if ( input_stream == NULL )
221 {
222 libfla_test_output_error( "Failed to open input file %s. Check existence and permissions.\n",
223 input_filename );
224 }
225
226 libfla_test_output_info( "\n" );
227 libfla_test_output_info( "--- operations to test -------------------------------\n" );
228 libfla_test_output_info( "\n" );
229
230 // Read the operation tests for general matrix-matrix multiply.
231 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->gemm) );
232 libfla_test_output_op_struct_blas3( "gemm", ops->gemm );
233
234 // Read the operation tests for Hermitian matrix-matrix multiply.
235 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->hemm) );
236 libfla_test_output_op_struct_blas3( "hemm", ops->hemm );
237
238 // Read the operation tests for Hermitian rank-k update.
239 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->herk) );
240 libfla_test_output_op_struct_blas3( "herk", ops->herk );
241
242 // Read the operation tests for Hermitian rank-2k update.
243 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->her2k) );
244 libfla_test_output_op_struct_blas3( "her2k", ops->her2k );
245
246 // Read the operation tests for Symmetric matrix-matrix multiply.
247 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->symm) );
248 libfla_test_output_op_struct_blas3( "symm", ops->symm );
249
250 // Read the operation tests for Symmetric rank-k update.
251 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->syrk) );
252 libfla_test_output_op_struct_blas3( "syrk", ops->syrk );
253
254 // Read the operation tests for Symmetric rank-2k update.
255 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->syr2k) );
256 libfla_test_output_op_struct_blas3( "syr2k", ops->syr2k );
257
258 // Read the operation tests for Triangular matrix-matrix multiply.
259 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->trmm) );
260 libfla_test_output_op_struct_blas3( "trmm", ops->trmm );
261
262 // Read the operation tests for Triangular solve with multiple rhs.
263 libfla_test_read_tests_for_op_blas3( input_stream, &(ops->trsm) );
264 libfla_test_output_op_struct_blas3( "trsm", ops->trsm );
265
266 // Read the operation tests for Cholesky factorization.
267 libfla_test_read_tests_for_op( input_stream, &(ops->chol) );
268 libfla_test_output_op_struct( "chol", ops->chol );
269
270 // Read the operation tests for LU_nopiv factorization.
271 libfla_test_read_tests_for_op( input_stream, &(ops->lu_nopiv) );
272 libfla_test_output_op_struct( "lu_nopiv", ops->lu_nopiv );
273
274 // Read the operation tests for LU_piv factorization.
275 libfla_test_read_tests_for_op( input_stream, &(ops->lu_piv) );
276 libfla_test_output_op_struct( "lu_piv", ops->lu_piv );
277
278 // Read the operation tests for LU_incpiv factorization.
279 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->lu_incpiv) );
280 libfla_test_output_op_struct_flash_only( "lu_incpiv", ops->lu_incpiv );
281
282 // Read the operation tests for QR_UT factorization.
283 libfla_test_read_tests_for_op( input_stream, &(ops->qrut) );
284 libfla_test_output_op_struct( "qrut", ops->qrut );
285
286 // Read the operation tests for QR_UT_inc factorization.
287 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->qrutinc) );
288 libfla_test_output_op_struct_flash_only( "qrutinc", ops->qrutinc );
289
290 // Read the operation tests for LQ_UT factorization.
291 libfla_test_read_tests_for_op( input_stream, &(ops->lqut) );
292 libfla_test_output_op_struct( "lqut", ops->lqut );
293
294 // Read the operation tests for Apply_Q_UT.
295 libfla_test_read_tests_for_op_front_only( input_stream, &(ops->apqut) );
296 libfla_test_output_op_struct_front_only( "apqut", ops->apqut );
297
298 // Read the operation tests for Apply_Q_UT_inc.
299 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->apqutinc) );
300 libfla_test_output_op_struct_flash_only( "apqutinc", ops->apqutinc );
301
302 // Read the operation tests for CAQR_UT_inc factorization.
303 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->caqrutinc) );
304 libfla_test_output_op_struct_flash_only( "caqrutinc", ops->caqrutinc );
305
306 // Read the operation tests for Apply_CAQ_UT_inc.
307 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->apcaqutinc) );
308 libfla_test_output_op_struct_flash_only( "apcaqutinc", ops->apcaqutinc );
309
310 // Read the operation tests for UDdate_UT.
311 libfla_test_read_tests_for_op_fla_only( input_stream, &(ops->uddateut) );
312 libfla_test_output_op_struct_fla_only( "uddateut", ops->uddateut );
313
314 // Read the operation tests for UDdate_UT_inc.
315 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->uddateutinc) );
316 libfla_test_output_op_struct_flash_only( "uddateutinc", ops->uddateutinc );
317
318 // Read the operation tests for Apply_QUD_UT.
319 libfla_test_read_tests_for_op_front_fla_only( input_stream, &(ops->apqudut) );
320 libfla_test_output_op_struct_front_fla_only( "apqudut", ops->apqudut );
321
322 // Read the operation tests for Apply_QUD_UT_inc.
323 libfla_test_read_tests_for_op_flash_only( input_stream, &(ops->apqudutinc) );
324 libfla_test_output_op_struct_flash_only( "apqudutinc", ops->apqudutinc );
325
326 // Read the operation tests for Hess_UT reduction.
327 libfla_test_read_tests_for_op_fla_only( input_stream, &(ops->hessut) );
328 libfla_test_output_op_struct_fla_only( "hessut", ops->hessut );
329
330 // Read the operation tests for Tridiag_UT reduction.
331 libfla_test_read_tests_for_op_fla_only( input_stream, &(ops->tridiagut) );
332 libfla_test_output_op_struct_fla_only( "tridiagut", ops->tridiagut );
333
334 // Read the operation tests for Bidiag_UT reduction.
335 libfla_test_read_tests_for_op_fla_only( input_stream, &(ops->bidiagut) );
336 libfla_test_output_op_struct_fla_only( "bidiagut", ops->bidiagut );
337
338 // Read the operation tests for Eig_gest.
339 libfla_test_read_tests_for_op( input_stream, &(ops->eig_gest) );
340 libfla_test_output_op_struct( "eig_gest", ops->eig_gest );
341
342 // Read the operation tests for triangular matrix inversion.
343 libfla_test_read_tests_for_op( input_stream, &(ops->trinv) );
344 libfla_test_output_op_struct( "trinv", ops->trinv );
345
346 // Read the operation tests for SPD/HPD matrix inversion.
347 libfla_test_read_tests_for_op_front_only( input_stream, &(ops->spdinv) );
348 libfla_test_output_op_struct_front_only( "spdinv", ops->spdinv );
349
350 // Read the operation tests for triangular Sylvester equation solve.
351 libfla_test_read_tests_for_op( input_stream, &(ops->sylv) );
352 libfla_test_output_op_struct( "sylv", ops->sylv );
353
354 // Read the operation tests for triangular Lyapunov equation solve.
355 libfla_test_read_tests_for_op( input_stream, &(ops->lyap) );
356 libfla_test_output_op_struct( "lyap", ops->lyap );
357
358 // Close the file.
359 fclose( input_stream );
360
361 }
362
363
364
libfla_test_output_op_struct(char * op_str,test_op_t op)365 void libfla_test_output_op_struct( char* op_str, test_op_t op )
366 {
367 libfla_test_output_info( "%s flash_front %d\n", op_str, op.flash_front );
368 libfla_test_output_info( "%s fla_front %d\n", op_str, op.fla_front );
369 libfla_test_output_info( "%s fla_unb_vars %d\n", op_str, op.fla_unb_vars );
370 libfla_test_output_info( "%s fla_opt_vars %d\n", op_str, op.fla_opt_vars );
371 libfla_test_output_info( "%s fla_blk_vars %d\n", op_str, op.fla_blk_vars );
372 }
373
374
375
libfla_test_output_op_struct_flash_only(char * op_str,test_op_t op)376 void libfla_test_output_op_struct_flash_only( char* op_str, test_op_t op )
377 {
378 libfla_test_output_info( "%s flash_front %d\n", op_str, op.flash_front );
379 }
380
381
382
libfla_test_output_op_struct_front_only(char * op_str,test_op_t op)383 void libfla_test_output_op_struct_front_only( char* op_str, test_op_t op )
384 {
385 libfla_test_output_info( "%s flash_front %d\n", op_str, op.flash_front );
386 libfla_test_output_info( "%s fla_front %d\n", op_str, op.fla_front );
387 }
388
389
390
libfla_test_output_op_struct_front_fla_only(char * op_str,test_op_t op)391 void libfla_test_output_op_struct_front_fla_only( char* op_str, test_op_t op )
392 {
393 libfla_test_output_info( "%s fla_front %d\n", op_str, op.fla_front );
394 }
395
396
397
libfla_test_output_op_struct_fla_only(char * op_str,test_op_t op)398 void libfla_test_output_op_struct_fla_only( char* op_str, test_op_t op )
399 {
400 libfla_test_output_info( "%s fla_front %d\n", op_str, op.fla_front );
401 libfla_test_output_info( "%s fla_unb_vars %d\n", op_str, op.fla_unb_vars );
402 libfla_test_output_info( "%s fla_opt_vars %d\n", op_str, op.fla_opt_vars );
403 libfla_test_output_info( "%s fla_blk_vars %d\n", op_str, op.fla_blk_vars );
404 }
405
406
407
libfla_test_output_op_struct_blas3(char * op_str,test_op_t op)408 void libfla_test_output_op_struct_blas3( char* op_str, test_op_t op )
409 {
410 libfla_test_output_info( "%s flash_front %d\n", op_str, op.flash_front );
411 libfla_test_output_info( "%s fla_front %d\n", op_str, op.fla_front );
412 libfla_test_output_info( "%s fla_unb_vars %d\n", op_str, op.fla_unb_vars );
413 libfla_test_output_info( "%s fla_blk_vars %d\n", op_str, op.fla_blk_vars );
414 libfla_test_output_info( "%s fla_unb_ext %d\n", op_str, op.fla_unb_ext );
415 }
416
417
418
libfla_test_read_tests_for_op(FILE * input_stream,test_op_t * op)419 void libfla_test_read_tests_for_op( FILE* input_stream, test_op_t* op )
420 {
421 char buffer[ INPUT_BUFFER_SIZE ];
422 int op_switch;
423 int flash_front;
424 int fla_front;
425 int fla_unb_vars;
426 int fla_opt_vars;
427 int fla_blk_vars;
428
429 // Read the line for the overall operation switch.
430 libfla_test_read_next_line( buffer, input_stream );
431 sscanf( buffer, "%d ", &op_switch );
432
433 // Read the line for the FLASH front-end.
434 libfla_test_read_next_line( buffer, input_stream );
435 sscanf( buffer, "%d ", &flash_front );
436
437 // Read the line for the FLA front-end.
438 libfla_test_read_next_line( buffer, input_stream );
439 sscanf( buffer, "%d ", &fla_front );
440
441 // Read the line for the unblocked variants.
442 libfla_test_read_next_line( buffer, input_stream );
443 sscanf( buffer, "%d ", &fla_unb_vars );
444
445 // Read the line for the optimized unblocked variants.
446 libfla_test_read_next_line( buffer, input_stream );
447 sscanf( buffer, "%d ", &fla_opt_vars );
448
449 // Read the line for the blocked variants.
450 libfla_test_read_next_line( buffer, input_stream );
451 sscanf( buffer, "%d ", &fla_blk_vars );
452
453 if ( op_switch == DISABLE_ALL )
454 {
455 op->flash_front = DISABLE;
456 op->fla_front = DISABLE;
457 op->fla_unb_vars = DISABLE;
458 op->fla_opt_vars = DISABLE;
459 op->fla_blk_vars = DISABLE;
460 }
461 else
462 {
463 op->flash_front = flash_front;
464 op->fla_front = fla_front;
465 op->fla_unb_vars = fla_unb_vars;
466 op->fla_opt_vars = fla_opt_vars;
467 op->fla_blk_vars = fla_blk_vars;
468 }
469 }
470
471
472
libfla_test_read_tests_for_op_flash_only(FILE * input_stream,test_op_t * op)473 void libfla_test_read_tests_for_op_flash_only( FILE* input_stream, test_op_t* op )
474 {
475 char buffer[ INPUT_BUFFER_SIZE ];
476 int op_switch;
477 int flash_front;
478
479 // Read the line for the overall operation switch.
480 libfla_test_read_next_line( buffer, input_stream );
481 sscanf( buffer, "%d ", &op_switch );
482
483 // Read the line for the FLASH front-end.
484 libfla_test_read_next_line( buffer, input_stream );
485 sscanf( buffer, "%d ", &flash_front );
486
487 if ( op_switch == DISABLE_ALL )
488 {
489 op->flash_front = DISABLE;
490 }
491 else
492 {
493 op->flash_front = flash_front;
494 }
495
496 op->fla_front = DISABLE; // not used
497 op->fla_unb_vars = DISABLE; // not used
498 op->fla_opt_vars = DISABLE; // not used
499 op->fla_blk_vars = DISABLE; // not used
500 }
501
502
503
libfla_test_read_tests_for_op_fla_only(FILE * input_stream,test_op_t * op)504 void libfla_test_read_tests_for_op_fla_only( FILE* input_stream, test_op_t* op )
505 {
506 char buffer[ INPUT_BUFFER_SIZE ];
507 int op_switch;
508 int fla_front;
509 int fla_unb_vars;
510 int fla_opt_vars;
511 int fla_blk_vars;
512
513 // Read the line for the overall operation switch.
514 libfla_test_read_next_line( buffer, input_stream );
515 sscanf( buffer, "%d ", &op_switch );
516
517 // Read the line for the FLA front-end.
518 libfla_test_read_next_line( buffer, input_stream );
519 sscanf( buffer, "%d ", &fla_front );
520
521 // Read the line for the unblocked variants.
522 libfla_test_read_next_line( buffer, input_stream );
523 sscanf( buffer, "%d ", &fla_unb_vars );
524
525 // Read the line for the optimized unblocked variants.
526 libfla_test_read_next_line( buffer, input_stream );
527 sscanf( buffer, "%d ", &fla_opt_vars );
528
529 // Read the line for the blocked variants.
530 libfla_test_read_next_line( buffer, input_stream );
531 sscanf( buffer, "%d ", &fla_blk_vars );
532
533 if ( op_switch == DISABLE_ALL )
534 {
535 op->fla_front = DISABLE;
536 op->fla_unb_vars = DISABLE;
537 op->fla_opt_vars = DISABLE;
538 op->fla_blk_vars = DISABLE;
539 }
540 else
541 {
542 op->fla_front = fla_front;
543 op->fla_unb_vars = fla_unb_vars;
544 op->fla_opt_vars = fla_opt_vars;
545 op->fla_blk_vars = fla_blk_vars;
546 }
547
548 op->flash_front = DISABLE; // not used
549 }
550
551
552
libfla_test_read_tests_for_op_front_only(FILE * input_stream,test_op_t * op)553 void libfla_test_read_tests_for_op_front_only( FILE* input_stream, test_op_t* op )
554 {
555 char buffer[ INPUT_BUFFER_SIZE ];
556 int op_switch;
557 int flash_front;
558 int fla_front;
559
560 // Read the line for the overall operation switch.
561 libfla_test_read_next_line( buffer, input_stream );
562 sscanf( buffer, "%d ", &op_switch );
563
564 // Read the line for the FLASH front-end.
565 libfla_test_read_next_line( buffer, input_stream );
566 sscanf( buffer, "%d ", &flash_front );
567
568 // Read the line for the FLA front-end.
569 libfla_test_read_next_line( buffer, input_stream );
570 sscanf( buffer, "%d ", &fla_front );
571
572 if ( op_switch == DISABLE_ALL )
573 {
574 op->flash_front = DISABLE;
575 op->fla_front = DISABLE;
576 }
577 else
578 {
579 op->flash_front = flash_front;
580 op->fla_front = fla_front;
581 }
582
583 op->fla_unb_vars = DISABLE; // not used
584 op->fla_opt_vars = DISABLE; // not used
585 op->fla_blk_vars = DISABLE; // not used
586 }
587
588
589
libfla_test_read_tests_for_op_front_fla_only(FILE * input_stream,test_op_t * op)590 void libfla_test_read_tests_for_op_front_fla_only( FILE* input_stream, test_op_t* op )
591 {
592 char buffer[ INPUT_BUFFER_SIZE ];
593 int op_switch;
594 int fla_front;
595
596 // Read the line for the overall operation switch.
597 libfla_test_read_next_line( buffer, input_stream );
598 sscanf( buffer, "%d ", &op_switch );
599
600 // Read the line for the FLA front-end.
601 libfla_test_read_next_line( buffer, input_stream );
602 sscanf( buffer, "%d ", &fla_front );
603
604 if ( op_switch == DISABLE_ALL )
605 {
606 op->fla_front = DISABLE;
607 }
608 else
609 {
610 op->fla_front = fla_front;
611 }
612
613 op->flash_front = DISABLE; // not used
614 op->fla_unb_vars = DISABLE; // not used
615 op->fla_opt_vars = DISABLE; // not used
616 op->fla_blk_vars = DISABLE; // not used
617 }
618
619
620
libfla_test_read_tests_for_op_blas3(FILE * input_stream,test_op_t * op)621 void libfla_test_read_tests_for_op_blas3( FILE* input_stream, test_op_t* op )
622 {
623 char buffer[ INPUT_BUFFER_SIZE ];
624 int op_switch;
625 int flash_front;
626 int fla_front;
627 int fla_unb_vars;
628 int fla_blk_vars;
629 int fla_unb_ext;
630
631 // Read the line for the overall operation switch.
632 libfla_test_read_next_line( buffer, input_stream );
633 sscanf( buffer, "%d ", &op_switch );
634
635 // Read the line for the FLASH front-end.
636 libfla_test_read_next_line( buffer, input_stream );
637 sscanf( buffer, "%d ", &flash_front );
638
639 // Read the line for the FLA front-end.
640 libfla_test_read_next_line( buffer, input_stream );
641 sscanf( buffer, "%d ", &fla_front );
642
643 // Read the line for the unblocked variants.
644 libfla_test_read_next_line( buffer, input_stream );
645 sscanf( buffer, "%d ", &fla_unb_vars );
646
647 // Read the line for the blocked variants.
648 libfla_test_read_next_line( buffer, input_stream );
649 sscanf( buffer, "%d ", &fla_blk_vars );
650
651 // Read the line for the unblocked external implementation.
652 libfla_test_read_next_line( buffer, input_stream );
653 sscanf( buffer, "%d ", &fla_unb_ext );
654
655 if ( op_switch == DISABLE_ALL )
656 {
657 op->flash_front = DISABLE;
658 op->fla_front = DISABLE;
659 op->fla_unb_vars = DISABLE;
660 op->fla_blk_vars = DISABLE;
661 op->fla_unb_ext = DISABLE;
662 }
663 else
664 {
665 op->flash_front = flash_front;
666 op->fla_front = fla_front;
667 op->fla_unb_vars = fla_unb_vars;
668 op->fla_blk_vars = fla_blk_vars;
669 op->fla_unb_ext = fla_unb_ext ;
670 }
671
672 op->fla_opt_vars = DISABLE; // not used
673 op->fla_blk_ext = DISABLE; // not used
674 }
675
676
677
libfla_test_read_parameter_file(char * input_filename,test_params_t * params)678 void libfla_test_read_parameter_file( char* input_filename, test_params_t* params )
679 {
680 FILE* input_stream;
681 char buffer[ INPUT_BUFFER_SIZE ];
682 char temp[ INPUT_BUFFER_SIZE ];
683 int i;
684
685 // Attempt to open input file corresponding to input_filename as
686 // read-only/binary.
687 input_stream = fopen( input_filename, "rb" );
688
689 // Check for success.
690 if ( input_stream == NULL )
691 {
692 libfla_test_output_error( "Failed to open input file %s. Check existence and permissions.\n",
693 input_filename );
694 }
695
696 // Read the number of repeats.
697 libfla_test_read_next_line( buffer, input_stream );
698 sscanf( buffer, "%u ", &(params->n_repeats) );
699
700 // Read the storage schemes to test. We should have at most three: 'r' for
701 // row-major, 'c' for column-major, and 'g' for general strides, OR just
702 // 'm' for mixed storage.
703 libfla_test_read_next_line( buffer, input_stream );
704 sscanf( buffer, "%s ", temp );
705
706 params->n_storage = strlen( temp );
707 if ( params->n_storage > MAX_NUM_STORAGE )
708 {
709 libfla_test_output_error( "Detected too many storage schemes (%u) in input file.\n",
710 params->n_storage );
711 }
712 strcpy( params->storage, temp );
713
714 // If 'm' is in the string, then remove all other chars.
715 for ( i = 0; i < params->n_storage; ++i )
716 {
717 if ( params->storage[i] == 'm' )
718 {
719 sprintf( params->storage, "m" );
720 break;
721 }
722 }
723
724 // Read the datatypes to test. We should have at most four: 's', 'd', 'c',
725 // and 'z'.
726 libfla_test_read_next_line( buffer, input_stream );
727 sscanf( buffer, "%s ", temp );
728
729 params->n_datatypes = strlen( temp );
730 if ( params->n_datatypes > MAX_NUM_DATATYPES )
731 {
732 libfla_test_output_error( "Detected too many datatype requests (%u) in input file.\n",
733 params->n_datatypes );
734 }
735
736 for( i = 0; i < params->n_datatypes; ++i )
737 {
738 if ( temp[i] == 's' ) params->datatype[i] = FLA_FLOAT;
739 else if ( temp[i] == 'd' ) params->datatype[i] = FLA_DOUBLE;
740 else if ( temp[i] == 'c' ) params->datatype[i] = FLA_COMPLEX;
741 else if ( temp[i] == 'z' ) params->datatype[i] = FLA_DOUBLE_COMPLEX;
742
743 params->datatype_char[i] = temp[i];
744 }
745
746 // Read the blocksize to use for blocked algorithms on flat matrices.
747 libfla_test_read_next_line( buffer, input_stream );
748 sscanf( buffer, "%lu ", &(params->b_alg_flat) );
749
750 // Read the algorithmic blocksize to use for algorithms-by-blocks.
751 libfla_test_read_next_line( buffer, input_stream );
752 sscanf( buffer, "%lu ", &(params->b_alg_hier) );
753
754 // Read the storage (FLASH) blocksize to use for algorithms-by-blocks.
755 libfla_test_read_next_line( buffer, input_stream );
756 sscanf( buffer, "%lu ", &(params->b_flash) );
757
758 // Read the initial problem size to test.
759 libfla_test_read_next_line( buffer, input_stream );
760 sscanf( buffer, "%lu ", &(params->p_first) );
761
762 // Read the maximum problem size to test.
763 libfla_test_read_next_line( buffer, input_stream );
764 sscanf( buffer, "%lu ", &(params->p_max) );
765
766 // Read the problem size increment to test.
767 libfla_test_read_next_line( buffer, input_stream );
768 sscanf( buffer, "%lu ", &(params->p_inc) );
769
770 // Read the number of SuperMatrix threads to test with.
771 libfla_test_read_next_line( buffer, input_stream );
772 sscanf( buffer, "%u ", &(params->n_threads) );
773
774 // Read the requested course of action if a test fails.
775 libfla_test_read_next_line( buffer, input_stream );
776 sscanf( buffer, "%c ", &(params->reaction_to_failure) );
777
778 if ( params->reaction_to_failure != ON_FAILURE_IGNORE_CHAR &&
779 params->reaction_to_failure != ON_FAILURE_SLEEP_CHAR &&
780 params->reaction_to_failure != ON_FAILURE_ABORT_CHAR )
781 {
782 libfla_test_output_error( "Invalid reaction-to-failure character code (%c) in input file.\n",
783 params->reaction_to_failure );
784 }
785
786 // Close the file.
787 fclose( input_stream );
788
789 libfla_test_output_info( "\n" );
790 libfla_test_output_info( "--- test suite parameters ----------------------------\n" );
791 libfla_test_output_info( "\n" );
792 libfla_test_output_info( "n_repeats %u\n", params->n_repeats );
793 libfla_test_output_info( "n_storage %u\n", params->n_storage );
794 libfla_test_output_info( "storage %s\n", params->storage );
795 libfla_test_output_info( "n_datatypes %u\n", params->n_datatypes );
796 libfla_test_output_info( "datatype[0] %d (%c)\n", params->datatype[0],
797 params->datatype_char[0] );
798 for( i = 1; i < params->n_datatypes; ++i )
799 libfla_test_output_info( " [%d] %d (%c)\n", i, params->datatype[i],
800 params->datatype_char[i] );
801 libfla_test_output_info( "b_alg_flat %u\n", params->b_alg_flat );
802 libfla_test_output_info( "b_alg_hier %u\n", params->b_alg_hier );
803 libfla_test_output_info( "b_flash %u\n", params->b_flash );
804 libfla_test_output_info( "p_first %u\n", params->p_first );
805 libfla_test_output_info( "p_max %u\n", params->p_max );
806 libfla_test_output_info( "p_inc %u\n", params->p_inc );
807 libfla_test_output_info( "n_threads %u\n", params->n_threads );
808 libfla_test_output_info( "reaction_to_failure %c\n", params->reaction_to_failure );
809 }
810
811
812
libfla_test_read_next_line(char * buffer,FILE * input_stream)813 void libfla_test_read_next_line( char* buffer, FILE* input_stream )
814 {
815 char temp[ INPUT_BUFFER_SIZE ];
816
817 // We want to read at least one line, so we use a do-while loop.
818 do
819 {
820 // Read the next line into a temporary buffer and check success.
821 if ( fgets( temp, INPUT_BUFFER_SIZE-1, input_stream ) == NULL )
822 {
823 if ( feof( input_stream ) )
824 libfla_test_output_error( "Error reading input file: encountered unexpected EOF." );
825 else
826 libfla_test_output_error( "Error (non-EOF) reading input file." );
827 }
828 }
829 // We continue to read lines into buffer until the line is neither
830 // commented nor blank.
831 while ( temp[0] == COMMENT_CHAR || temp[0] == '\n' ||
832 temp[0] == ' ' || temp[0] == '\t' );
833
834
835 // Save the string in temp, up to first white space character, into buffer.
836 sscanf( temp, "%s ", buffer );
837 }
838
839
840
libfla_test_output_info(char * message,...)841 void libfla_test_output_info( char* message, ... )
842 {
843 FILE* output_stream = stdout;
844 va_list args;
845
846 //fprintf( output_stream, "%s: ", libfla_test_binary_name );
847
848 // Initialize variable argument environment.
849 va_start( args, message );
850
851 // Parse the received message and print its components.
852 libfla_test_parse_message( output_stream, message, args );
853
854 // Shutdown variable argument environment and clean up stack.
855 va_end( args );
856
857 // Flush the output stream.
858 fflush( output_stream );
859 }
860
861
862
libfla_test_output_error(char * message,...)863 void libfla_test_output_error( char* message, ... )
864 {
865 FILE* output_stream = stderr;
866 va_list args;
867
868 fprintf( output_stream, "%s: *** error ***: ", libfla_test_binary_name );
869
870 // Initialize variable argument environment.
871 va_start( args, message );
872
873 // Parse the received message and print its components.
874 libfla_test_parse_message( output_stream, message, args );
875
876 // Shutdown variable argument environment and clean up stack.
877 va_end( args );
878
879 // Flush the output stream.
880 fflush( output_stream );
881
882 // Exit.
883 exit(1);
884 }
885
886
887
libfla_test_parse_message(FILE * output_stream,char * message,va_list args)888 void libfla_test_parse_message( FILE* output_stream, char* message, va_list args )
889 {
890 int c, cf;
891 char format_spec[8];
892 unsigned int the_uint;
893 int the_int;
894 double the_double;
895 char* the_string;
896 char the_char;
897
898 // Begin looping over message to insert variables wherever there are
899 // format specifiers.
900 for ( c = 0; message[c] != '\0'; )
901 {
902 if ( message[c] != '%' )
903 {
904 fprintf( output_stream, "%c", message[c] );
905 c += 1;
906 }
907 else if ( message[c] == '%' && message[c+1] == '%' ) // handle escaped '%' chars.
908 {
909 fprintf( output_stream, "%c", message[c] );
910 c += 2;
911 }
912 else
913 {
914 // Save the format string if there is one.
915 format_spec[0] = '%';
916 for ( c += 1, cf = 1; strchr( "udefsc", message[c] ) == NULL; ++c, ++cf )
917 {
918 format_spec[cf] = message[c];
919 }
920
921 // Add the final type specifier, and null-terminate the string.
922 format_spec[cf] = message[c];
923 format_spec[cf+1] = '\0';
924
925 // Switch based on type, since we can't predict what will
926 // va_args() will return.
927 switch ( message[c] )
928 {
929 case 'u':
930 the_uint = va_arg( args, unsigned int );
931 fprintf( output_stream, format_spec, the_uint );
932 break;
933
934 case 'd':
935 the_int = va_arg( args, int );
936 fprintf( output_stream, format_spec, the_int );
937 break;
938
939 case 'e':
940 the_double = va_arg( args, double );
941 fprintf( output_stream, format_spec, the_double );
942 break;
943
944 case 'f':
945 the_double = va_arg( args, double );
946 fprintf( output_stream, format_spec, the_double );
947 break;
948
949 case 's':
950 the_string = va_arg( args, char* );
951 //fprintf( output_stream, "%s", the_string );
952 fprintf( output_stream, format_spec, the_string );
953 break;
954
955 case 'c':
956 the_char = va_arg( args, int );
957 fprintf( output_stream, "%c", the_char );
958 break;
959 }
960
961 // Move to next character past type specifier.
962 c += 1;
963 }
964 }
965 }
966
967
968
libfla_test_parse_command_line(int argc,char ** argv)969 void libfla_test_parse_command_line( int argc, char** argv )
970 {
971 if ( argc > 1 )
972 {
973 fprintf( stderr, "Too many command line arguments.\n" );
974 exit(1);
975 }
976
977 // Copy the binary name to a global string so we can use it later.
978 strncpy( libfla_test_binary_name, argv[0], MAX_BINARY_NAME_LENGTH );
979 }
980
981
982
libfla_test_get_string_for_result(double residual,FLA_Datatype datatype,test_thresh_t * thresh)983 char* libfla_test_get_string_for_result( double residual,
984 FLA_Datatype datatype,
985 test_thresh_t* thresh )
986 {
987 char* r_val;
988
989 if ( datatype == FLA_FLOAT )
990 {
991 if ( residual > thresh->failwarn_s ) r_val = libfla_test_fail_string;
992 else if ( residual > thresh->warnpass_s ) r_val = libfla_test_warn_string;
993 else r_val = libfla_test_pass_string;
994 }
995 else if ( datatype == FLA_DOUBLE )
996 {
997 if ( residual > thresh->failwarn_d ) r_val = libfla_test_fail_string;
998 else if ( residual > thresh->warnpass_d ) r_val = libfla_test_warn_string;
999 else r_val = libfla_test_pass_string;
1000 }
1001 else if ( datatype == FLA_COMPLEX )
1002 {
1003 if ( residual > thresh->failwarn_c ) r_val = libfla_test_fail_string;
1004 else if ( residual > thresh->warnpass_c ) r_val = libfla_test_warn_string;
1005 else r_val = libfla_test_pass_string;
1006 }
1007 else // if ( datatype == FLA_DOUBLE_COMPLEX )
1008 {
1009 if ( residual > thresh->failwarn_z ) r_val = libfla_test_fail_string;
1010 else if ( residual > thresh->warnpass_z ) r_val = libfla_test_warn_string;
1011 else r_val = libfla_test_pass_string;
1012 }
1013
1014 return r_val;
1015 }
1016
1017
1018
libfla_test_init_strings(void)1019 void libfla_test_init_strings( void )
1020 {
1021 sprintf( libfla_test_pass_string, "PASS" );
1022 sprintf( libfla_test_warn_string, "MARGINAL" );
1023 sprintf( libfla_test_fail_string, "FAILURE" );
1024
1025 sprintf( libfla_test_stor_chars, STORAGE_SCHEME_CHARS );
1026 }
1027
1028
1029
libfla_test_fill_storage_strings(char ** sc_str,unsigned int n_storage_run,unsigned int n_matrices)1030 void libfla_test_fill_storage_strings( char** sc_str, unsigned int n_storage_run,
1031 unsigned int n_matrices )
1032 {
1033 unsigned int sci, mi, i;
1034 unsigned int* c;
1035
1036 // Allocate an array with one element per matrix argument. We will use
1037 // this array to keep track of our progress as we canonically move
1038 // though all possible storage combinations.
1039 c = ( unsigned int* ) malloc( n_matrices * sizeof( unsigned int ) );
1040
1041 // Initialize all values in c to zero.
1042 for ( i = 0; i < n_matrices; ++i ) c[i] = 0;
1043
1044 for ( sci = 0; sci < n_storage_run; ++sci )
1045 {
1046 // Iterate backwards since we want to form (for example):
1047 // (1) ccc, (2) ccr, (3) crc, (4) crr, etc.
1048 for ( i = 0, mi = n_matrices - 1; i < n_matrices; --mi, ++i )
1049 {
1050 // Map the current values in c to storage characters.
1051 sc_str[sci][mi] = libfla_test_stor_chars[ c[mi] ];
1052 }
1053
1054 // Terminate the string.
1055 sc_str[sci][n_matrices] = '\0';
1056
1057 // Only try to increment/carryover if this is NOT the last storage
1058 // run/combo.
1059 if ( sci < n_storage_run - 1 )
1060 {
1061 // Increment the least-most significant counter.
1062 c[ n_matrices - 1 ]++;
1063
1064 // Perform "carryover" if needed.
1065 carryover( &c[ n_matrices - 1 ], n_matrices );
1066 }
1067 }
1068
1069 /*
1070 printf( "\n" );
1071 for ( i = 0; i < n_storage_run; ++i )
1072 printf( "%s\n", sc_str[i] );
1073 printf( "\n" );
1074 abort();
1075 */
1076
1077 // Free the array.
1078 free( c );
1079 }
1080
1081
carryover(unsigned int * c,unsigned int n_matrices)1082 void carryover( unsigned int* c, unsigned int n_matrices )
1083 {
1084 if ( n_matrices == 1 ) return;
1085 else
1086 {
1087 if ( *c == NUM_STORAGE_CHARS )
1088 {
1089 *c = 0;
1090 *(c-1) += 1;
1091 carryover( c-1, n_matrices-1 );
1092 }
1093 }
1094 }
1095
1096
libfla_test_op_driver(char * func_str,char * impl_var_str,unsigned int first_var,unsigned int last_var,unsigned int n_pc,char ** pc_str,unsigned int n_matrices,signed int impl,test_params_t params,test_thresh_t thresh,void (* f_exp)(test_params_t,unsigned int,char *,FLA_Datatype,unsigned int,unsigned int,unsigned int,signed int,double *,double *))1097 void libfla_test_op_driver( char* func_str,
1098 char* impl_var_str,
1099 unsigned int first_var,
1100 unsigned int last_var,
1101 unsigned int n_pc,
1102 char** pc_str,
1103 unsigned int n_matrices,
1104 signed int impl,
1105 test_params_t params,
1106 test_thresh_t thresh,
1107 void (*f_exp) (test_params_t, // params
1108 unsigned int, // var
1109 char*, // sc_cur_str (current storage string)
1110 FLA_Datatype, // datatype
1111 unsigned int, // p_cur
1112 unsigned int, // pci (param combo counter)
1113 unsigned int, // n_repeats
1114 signed int, // impl
1115 double*, // perf
1116 double* ) ) // residual
1117 {
1118 unsigned int n_threads = params.n_threads;
1119 unsigned int n_storage = params.n_storage;
1120 unsigned int n_datatypes = params.n_datatypes;
1121 unsigned int p_first = params.p_first;
1122 unsigned int p_max = params.p_max;
1123 unsigned int p_inc = params.p_inc;
1124 unsigned int n_repeats = params.n_repeats;
1125 unsigned int reaction_to_failure = params.reaction_to_failure;
1126 unsigned int sci, dt, p_cur, mat, pci, var;
1127 char datatype_char;
1128 FLA_Datatype datatype;
1129 double perf, residual;
1130 char* pass_str;
1131 char blank_str[32];
1132 char func_param_str[64];
1133 unsigned int n_spaces;
1134 unsigned int n_storage_run;
1135 char** sc_str;
1136
1137 // Set the number of threads and/or disable SuperMatrix.
1138 if ( n_threads == 0 ) FLASH_Queue_disable();
1139 else FLASH_Queue_set_num_threads( n_threads );
1140
1141 // Execute the variant loop only once if we're runing a front-end test.
1142 if ( impl == FLA_TEST_HIER_FRONT_END ||
1143 impl == FLA_TEST_FLAT_FRONT_END ||
1144 impl == FLA_TEST_FLAT_UNB_EXT ||
1145 impl == FLA_TEST_FLAT_BLK_EXT )
1146 {
1147 first_var = 0;
1148 last_var = 0;
1149 }
1150
1151 // Determine the total number of storage schemes.
1152 if ( params.storage[0] == 'm' )
1153 {
1154 // Prepare to run all NUM_STORAGE_SCHEMES combinations for each
1155 // matrix argument.
1156 n_storage_run = ( unsigned int ) pow( ( double ) NUM_STORAGE_CHARS,
1157 ( double ) n_matrices );
1158
1159 sc_str = ( char** ) malloc( n_storage_run * sizeof( char* ) );
1160 for ( sci = 0; sci < n_storage_run; ++sci )
1161 sc_str[sci] = ( char* ) malloc( ( n_matrices + 1 ) * sizeof( char ) );
1162
1163 libfla_test_fill_storage_strings( sc_str, n_storage_run, n_matrices );
1164 }
1165 else // if ( params.storage[0] == 'c' ||
1166 // params.storage[0] == 'r' ||
1167 // params.storage[0] == 'g' )
1168 {
1169 // Only run combinations where all matrices are stored in one
1170 // storage scheme or another (no mixed storage).
1171 n_storage_run = n_storage;
1172
1173 sc_str = ( char** ) malloc( n_storage_run * sizeof( char* ) );
1174 for ( sci = 0; sci < n_storage_run; ++sci )
1175 {
1176 // Allocate a string for a storage combination.
1177 sc_str[sci] = ( char* ) malloc( ( n_matrices + 1 ) * sizeof( char ) );
1178
1179 // Fill the string with the current storage scheme character
1180 // for each matrix operand.
1181 for ( mat = 0; mat < n_matrices; ++mat )
1182 sc_str[sci][mat] = params.storage[sci];
1183 sc_str[sci][n_matrices] = '\0';
1184 }
1185 }
1186
1187 // Loop over variant, if applicable.
1188 for ( var = first_var; var <= last_var; ++var )
1189 {
1190 // Loop over the requested storage schemes.
1191 for ( sci = 0; sci < n_storage_run; ++sci )
1192 {
1193 // Loop over the requested datatypes.
1194 for ( dt = 0; dt < n_datatypes; ++dt )
1195 {
1196 datatype = params.datatype[dt];
1197 datatype_char = params.datatype_char[dt];
1198
1199 // Loop over the requested problem sizes.
1200 for ( p_cur = p_first; p_cur <= p_max; p_cur += p_inc )
1201 {
1202 // Loop over the operation's parameter combinations.
1203 for ( pci = 0; pci < n_pc; ++pci )
1204 {
1205 f_exp( params,
1206 var,
1207 sc_str[sci],
1208 datatype,
1209 p_cur, pci, n_repeats, impl,
1210 &perf, &residual );
1211
1212 pass_str = libfla_test_get_string_for_result( residual,
1213 datatype,
1214 &thresh );
1215
1216 // Output the results. Use different formats depending on
1217 // whether the results are from a front-end or variant.
1218 libfla_test_build_function_string( func_str, impl,
1219 impl_var_str, var,
1220 n_pc, pc_str[pci],
1221 func_param_str );
1222
1223 n_spaces = MAX_FUNC_STRING_LENGTH - strlen( func_param_str );
1224 fill_string_with_n_spaces( blank_str, n_spaces );
1225
1226 libfla_test_output_info( " %s%s %c|%-6s %5u %6.3lf %9.2le %s\n",
1227 func_param_str, blank_str,
1228 datatype_char, sc_str[sci],
1229 p_cur, perf, residual, pass_str );
1230
1231 // If we need to check whether to do something on failure,
1232 // do so now.
1233 if ( reaction_to_failure == ON_FAILURE_SLEEP_CHAR )
1234 {
1235 if ( strstr( pass_str, FLA_TEST_FAIL_STRING ) == pass_str )
1236 libfla_test_sleep();
1237 }
1238 else if ( reaction_to_failure == ON_FAILURE_ABORT_CHAR )
1239 {
1240 if ( strstr( pass_str, FLA_TEST_FAIL_STRING ) == pass_str )
1241 libfla_test_abort();
1242 }
1243 }
1244 }
1245
1246 libfla_test_output_info( "\n" );
1247 }
1248 }
1249 }
1250
1251 for ( sci = 0; sci < n_storage_run; ++sci )
1252 free( sc_str[sci] );
1253 free( sc_str );
1254 }
1255
1256
1257
libfla_test_build_function_string(char * func_base_str,signed int impl,char * impl_var_str,unsigned int var,unsigned int n_pc,char * pc_str,char * func_str)1258 void libfla_test_build_function_string( char* func_base_str,
1259 signed int impl,
1260 char* impl_var_str,
1261 unsigned int var,
1262 unsigned int n_pc,
1263 char* pc_str,
1264 char* func_str )
1265 {
1266
1267 sprintf( func_str, "%s", func_base_str );
1268
1269 if ( impl == FLA_TEST_HIER_FRONT_END || impl == FLA_TEST_FLAT_FRONT_END )
1270 {
1271 //sprintf( &func_str[strlen(func_str)], "()" );
1272 if ( n_pc > 1 )
1273 sprintf( &func_str[strlen(func_str)], ":%s", pc_str );
1274 }
1275 else if ( impl == FLA_TEST_FLAT_UNB_EXT || impl == FLA_TEST_FLAT_BLK_EXT )
1276 {
1277 sprintf( &func_str[strlen(func_str)], "_%s", impl_var_str );
1278
1279 if ( n_pc > 1 )
1280 sprintf( &func_str[strlen(func_str)], ":%s", pc_str );
1281 }
1282 else
1283 {
1284 if ( n_pc > 1 )
1285 sprintf( &func_str[strlen(func_str)], "_%s", pc_str );
1286
1287 sprintf( &func_str[strlen(func_str)], "_%s%u", impl_var_str, var );
1288 }
1289 }
1290
1291
1292
fill_string_with_n_spaces(char * str,unsigned int n_spaces)1293 void fill_string_with_n_spaces( char* str, unsigned int n_spaces )
1294 {
1295 unsigned int i;
1296
1297 for ( i = 0; i < n_spaces; ++i )
1298 sprintf( &str[i], " " );
1299 }
1300
1301
1302
libfla_test_obj_create(FLA_Datatype dt,FLA_Trans trans,char storage,dim_t m,dim_t n,FLA_Obj * A)1303 void libfla_test_obj_create( FLA_Datatype dt, FLA_Trans trans, char storage, dim_t m, dim_t n, FLA_Obj* A )
1304 {
1305 dim_t m_trans = m;
1306 dim_t n_trans = n;
1307 dim_t rs_g;
1308 dim_t cs_g;
1309
1310 if ( trans == FLA_TRANSPOSE || trans == FLA_CONJ_TRANSPOSE )
1311 {
1312 m_trans = n;
1313 n_trans = m;
1314 }
1315
1316 // In case of general strides, use strides with a column-major tilt.
1317 rs_g = 2 * 1;
1318 cs_g = 2 * m_trans;
1319
1320 if ( storage == 'c' ) FLA_Obj_create( dt, m_trans, n_trans, 0, 0, A );
1321 else if ( storage == 'r' ) FLA_Obj_create( dt, m_trans, n_trans, n_trans, 1, A );
1322 else if ( storage == 'g' ) FLA_Obj_create( dt, m_trans, n_trans, rs_g, cs_g, A );
1323 else FLA_Abort();
1324 }
1325
1326
1327
libfla_test_sleep(void)1328 void libfla_test_sleep( void )
1329 {
1330 int i;
1331
1332 libfla_test_output_info( "Resuming in " );
1333 for ( i = SECONDS_TO_SLEEP; i > 0; --i )
1334 {
1335 libfla_test_output_info( "%d ", i );
1336 sleep(1);
1337 }
1338 libfla_test_output_info( "\n" );
1339 }
1340
1341
libfla_test_abort(void)1342 void libfla_test_abort( void )
1343 {
1344 abort();
1345 }
1346
1347