#include "blis.h"
#include "test_libblis.h"
char libblis_test_binary_name[ MAX_BINARY_NAME_LENGTH + 1 ];
char libblis_test_parameters_filename[ MAX_FILENAME_LENGTH + 1 ];
char libblis_test_operations_filename[ MAX_FILENAME_LENGTH + 1 ];
bool libblis_test_quiet_mode = FALSE;
char libblis_test_pass_string[ MAX_PASS_STRING_LENGTH + 1 ];
char libblis_test_warn_string[ MAX_PASS_STRING_LENGTH + 1 ];
char libblis_test_fail_string[ MAX_PASS_STRING_LENGTH + 1 ];
char libblis_test_store_chars[ NUM_OPERAND_TYPES ][ MAX_STORE_VALS_PER_TYPE + 1 ];
char libblis_test_param_chars[ NUM_PARAM_TYPES ][ MAX_PARAM_VALS_PER_TYPE + 1 ];
char libblis_test_sp_chars[ 2 + 1 ] = "sc";
char libblis_test_dp_chars[ 2 + 1 ] = "dz";
char libblis_test_rd_chars[ 2 + 1 ] = "sd";
char libblis_test_cd_chars[ 2 + 1 ] = "cz";
char libblis_test_dt_chars[ 4 + 1 ] = "sdcz";
int main( int argc, char** argv )
{
test_params_t params;
test_ops_t ops;
#ifdef BLIS_ENABLE_HPX
bli_thread_initialize_hpx( 1, argv );
#endif
libblis_test_init_strings();
libblis_test_parse_command_line( argc, argv );
libblis_test_read_params_file( libblis_test_parameters_filename, ¶ms );
libblis_test_read_ops_file( libblis_test_operations_filename, &ops );
libblis_test_thread_decorator( ¶ms, &ops );
bli_finalize();
#ifdef BLIS_ENABLE_HPX
return bli_thread_finalize_hpx();
#else
return 0;
#endif
}
#if 0#endif
void* libblis_test_thread_entry( void* tdata_void )
{
thread_data_t* tdata = tdata_void;
test_params_t* params = tdata->params;
test_ops_t* ops = tdata->ops;
libblis_test_all_ops( tdata, params, ops );
return NULL;
}
void libblis_test_thread_decorator( test_params_t* params, test_ops_t* ops )
{
err_t r_val;
#ifdef BLIS_ENABLE_HPX
size_t nt = ( size_t )params->n_app_threads;
size_t tdata_size = ( size_t )nt *
( size_t )sizeof( thread_data_t );
thread_data_t* tdata = bli_malloc_user( tdata_size, &r_val );
tdata->params = params;
tdata->ops = ops;
tdata->nt = nt;
tdata->id = 0;
tdata->xc = 0;
libblis_test_all_ops( tdata, params, ops );
bli_free_user( tdata );
#else
size_t nt = ( size_t )params->n_app_threads;
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
bli_pthread_t* pthread = bli_malloc_user( sizeof( bli_pthread_t ) * nt, &r_val );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
thread_data_t* tdata = bli_malloc_user( sizeof( thread_data_t ) * nt, &r_val );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
bli_pthread_barrier_t* barrier = bli_malloc_user( sizeof( bli_pthread_barrier_t ), &r_val );
bli_pthread_barrier_init( barrier, NULL, nt );
for ( signed int id = nt - 1; 0 <= id; id-- )
{
tdata[id].params = params;
tdata[id].ops = ops;
tdata[id].nt = nt;
tdata[id].id = id;
tdata[id].xc = 0;
tdata[id].barrier = barrier;
if ( id != 0 )
bli_pthread_create( &pthread[id], NULL, libblis_test_thread_entry, &tdata[id] );
else
libblis_test_thread_entry( ( void* )(&tdata[0]) );
}
for ( unsigned int id = 1; id < nt; id++ )
{
bli_pthread_join( pthread[id], NULL );
}
bli_pthread_barrier_destroy( barrier );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
bli_free_user( pthread );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
bli_free_user( tdata );
#ifdef BLIS_ENABLE_MEM_TRACING
printf( "libblis_test_thread_decorator(): " );
#endif
bli_free_user( barrier );
#endif
}
void libblis_test_all_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_utility_ops( tdata, params, ops );
libblis_test_level1v_ops( tdata, params, ops );
libblis_test_level1m_ops( tdata, params, ops );
libblis_test_level1f_ops( tdata, params, ops );
libblis_test_level2_ops( tdata, params, ops );
libblis_test_level3_ukrs( tdata, params, ops );
libblis_test_level3_ops( tdata, params, ops );
}
void libblis_test_utility_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_randv( tdata, params, &(ops->randv) );
libblis_test_randm( tdata, params, &(ops->randm) );
}
void libblis_test_level1v_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_addv( tdata, params, &(ops->addv) );
libblis_test_amaxv( tdata, params, &(ops->amaxv) );
libblis_test_axpbyv( tdata, params, &(ops->axpbyv) );
libblis_test_axpyv( tdata, params, &(ops->axpyv) );
libblis_test_copyv( tdata, params, &(ops->copyv) );
libblis_test_dotv( tdata, params, &(ops->dotv) );
libblis_test_dotxv( tdata, params, &(ops->dotxv) );
libblis_test_normfv( tdata, params, &(ops->normfv) );
libblis_test_invscalv( tdata, params, &(ops->invscalv) );
libblis_test_scalv( tdata, params, &(ops->scalv) );
libblis_test_scal2v( tdata, params, &(ops->scal2v) );
libblis_test_setv( tdata, params, &(ops->setv) );
libblis_test_subv( tdata, params, &(ops->subv) );
libblis_test_xpbyv( tdata, params, &(ops->xpbyv) );
}
void libblis_test_level1m_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_addm( tdata, params, &(ops->addm) );
libblis_test_axpym( tdata, params, &(ops->axpym) );
libblis_test_copym( tdata, params, &(ops->copym) );
libblis_test_normfm( tdata, params, &(ops->normfm) );
libblis_test_invscalm( tdata, params, &(ops->invscalm) );
libblis_test_scalm( tdata, params, &(ops->scalm) );
libblis_test_scal2m( tdata, params, &(ops->scal2m) );
libblis_test_setm( tdata, params, &(ops->setm) );
libblis_test_subm( tdata, params, &(ops->subm) );
libblis_test_xpbym( tdata, params, &(ops->xpbym) );
}
void libblis_test_level1f_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_axpy2v( tdata, params, &(ops->axpy2v) );
libblis_test_dotaxpyv( tdata, params, &(ops->dotaxpyv) );
libblis_test_axpyf( tdata, params, &(ops->axpyf) );
libblis_test_dotxf( tdata, params, &(ops->dotxf) );
libblis_test_dotxaxpyf( tdata, params, &(ops->dotxaxpyf) );
}
void libblis_test_level2_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_gemv( tdata, params, &(ops->gemv) );
libblis_test_ger( tdata, params, &(ops->ger) );
libblis_test_hemv( tdata, params, &(ops->hemv) );
libblis_test_her( tdata, params, &(ops->her) );
libblis_test_her2( tdata, params, &(ops->her2) );
libblis_test_symv( tdata, params, &(ops->symv) );
libblis_test_syr( tdata, params, &(ops->syr) );
libblis_test_syr2( tdata, params, &(ops->syr2) );
libblis_test_trmv( tdata, params, &(ops->trmv) );
libblis_test_trsv( tdata, params, &(ops->trsv) );
}
void libblis_test_level3_ukrs( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_gemm_ukr( tdata, params, &(ops->gemm_ukr) );
libblis_test_trsm_ukr( tdata, params, &(ops->trsm_ukr) );
libblis_test_gemmtrsm_ukr( tdata, params, &(ops->gemmtrsm_ukr) );
}
void libblis_test_level3_ops( thread_data_t* tdata, test_params_t* params, test_ops_t* ops )
{
libblis_test_gemm( tdata, params, &(ops->gemm) );
libblis_test_gemmt( tdata, params, &(ops->gemmt) );
libblis_test_hemm( tdata, params, &(ops->hemm) );
libblis_test_herk( tdata, params, &(ops->herk) );
libblis_test_her2k( tdata, params, &(ops->her2k) );
libblis_test_symm( tdata, params, &(ops->symm) );
libblis_test_syrk( tdata, params, &(ops->syrk) );
libblis_test_syr2k( tdata, params, &(ops->syr2k) );
libblis_test_trmm( tdata, params, &(ops->trmm) );
libblis_test_trmm3( tdata, params, &(ops->trmm3) );
libblis_test_trsm( tdata, params, &(ops->trsm) );
}
void libblis_test_read_ops_file( char* input_filename, test_ops_t* ops )
{
FILE* input_stream;
input_stream = fopen( input_filename, "rb" );
libblis_test_fopen_check_stream( input_filename, input_stream );
ops->indiv_over = FALSE;
libblis_test_read_section_override( ops, input_stream, &(ops->util_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l1v_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l1m_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l1f_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l2_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l3ukr_over) );
libblis_test_read_section_override( ops, input_stream, &(ops->l3_over) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 0, &(ops->randv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 0, &(ops->randm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->addv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 0, &(ops->amaxv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->axpbyv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->axpyv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->copyv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 2, &(ops->dotv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 2, &(ops->dotxv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 0, &(ops->normfv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->invscalv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->scalv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->scal2v) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 0, &(ops->setv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->subv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 1, &(ops->xpbyv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->addm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->axpym) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->copym) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 0, &(ops->normfm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->invscalm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->scalm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->scal2m) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 0, &(ops->setm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->subm) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 1, &(ops->xpbym) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 2, &(ops->axpy2v) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->dotaxpyv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MF, 2, &(ops->axpyf) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MF, 2, &(ops->dotxf) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MF, 4, &(ops->dotxaxpyf) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 2, &(ops->gemv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_MN, 2, &(ops->ger) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->hemv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 2, &(ops->her) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->her2) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->symv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 2, &(ops->syr) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->syr2) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->trmv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_M, 3, &(ops->trsv) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_K, 0, &(ops->gemm_ukr) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_NO_DIMS, 1, &(ops->trsm_ukr) );
libblis_test_read_op_info( ops, input_stream, BLIS_NOID, BLIS_TEST_DIMS_K, 1, &(ops->gemmtrsm_ukr) );
libblis_test_read_op_info( ops, input_stream, BLIS_GEMM, BLIS_TEST_DIMS_MNK, 2, &(ops->gemm) );
libblis_test_read_op_info( ops, input_stream, BLIS_GEMMT, BLIS_TEST_DIMS_MK, 3, &(ops->gemmt) );
libblis_test_read_op_info( ops, input_stream, BLIS_HEMM, BLIS_TEST_DIMS_MN, 4, &(ops->hemm) );
libblis_test_read_op_info( ops, input_stream, BLIS_HERK, BLIS_TEST_DIMS_MK, 2, &(ops->herk) );
libblis_test_read_op_info( ops, input_stream, BLIS_HER2K, BLIS_TEST_DIMS_MK, 3, &(ops->her2k) );
libblis_test_read_op_info( ops, input_stream, BLIS_SYMM, BLIS_TEST_DIMS_MN, 4, &(ops->symm) );
libblis_test_read_op_info( ops, input_stream, BLIS_SYRK, BLIS_TEST_DIMS_MK, 2, &(ops->syrk) );
libblis_test_read_op_info( ops, input_stream, BLIS_SYR2K, BLIS_TEST_DIMS_MK, 3, &(ops->syr2k) );
libblis_test_read_op_info( ops, input_stream, BLIS_TRMM, BLIS_TEST_DIMS_MN, 4, &(ops->trmm) );
libblis_test_read_op_info( ops, input_stream, BLIS_TRMM3, BLIS_TEST_DIMS_MN, 5, &(ops->trmm3) );
libblis_test_read_op_info( ops, input_stream, BLIS_TRSM, BLIS_TEST_DIMS_MN, 4, &(ops->trsm) );
libblis_test_output_section_overrides( stdout, ops );
fclose( input_stream );
}
void libblis_test_read_params_file( char* input_filename, test_params_t* params )
{
FILE* input_stream;
char buffer[ INPUT_BUFFER_SIZE ];
char temp[ INPUT_BUFFER_SIZE ];
int i;
input_stream = fopen( input_filename, "rb" );
libblis_test_fopen_check_stream( input_filename, input_stream );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->n_repeats) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%s ", temp );
params->n_mstorage = strlen( temp );
if ( params->n_mstorage > MAX_NUM_MSTORAGE )
{
libblis_test_printf_error( "Detected too many matrix storage schemes (%u) in input file.\n",
params->n_mstorage );
}
strcpy( params->storage[ BLIS_TEST_MATRIX_OPERAND ], temp );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%s ", temp );
params->n_vstorage = strlen( temp );
if ( params->n_vstorage > MAX_NUM_VSTORAGE )
{
libblis_test_printf_error( "Detected too many vector storage schemes (%u) in input file.\n",
params->n_vstorage );
}
strcpy( params->storage[ BLIS_TEST_VECTOR_OPERAND ], temp );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->mix_all_storage) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->alignment) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->rand_method) );
if ( params->rand_method != BLIS_TEST_RAND_REAL_VALUES &&
params->rand_method != BLIS_TEST_RAND_NARROW_POW2 )
{
libblis_test_printf_error( "Invalid randomization method (%u) in input file.\n",
params->rand_method );
}
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->gs_spacing) );
strcpy( libblis_test_store_chars[BLIS_TEST_MATRIX_OPERAND],
params->storage[BLIS_TEST_MATRIX_OPERAND] );
strcpy( libblis_test_store_chars[BLIS_TEST_VECTOR_OPERAND],
params->storage[BLIS_TEST_VECTOR_OPERAND] );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%s ", temp );
params->n_datatypes = strlen( temp );
if ( params->n_datatypes > MAX_NUM_DATATYPES )
{
libblis_test_printf_error( "Detected too many datatype requests (%u) in input file.\n",
params->n_datatypes );
}
for( i = 0; i < params->n_datatypes; ++i )
{
bli_param_map_char_to_blis_dt( temp[i], &(params->datatype[i]) );
params->datatype_char[i] = temp[i];
}
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->mixed_domain) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->mixed_precision) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->p_first) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->p_max) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->p_inc) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->ind_enable[ BLIS_1M ]) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->ind_enable[ BLIS_NAT ]) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->n_app_threads) );
if ( params->n_app_threads < 1 ) params->n_app_threads = 1;
if ( params->n_app_threads > 1 )
{
if ( params->ind_enable[ BLIS_1M ] )
{
libblis_test_printf_infoc( "simulating multiple application threads; disabling induced methods.\n" );
params->ind_enable[ BLIS_1M ] = 0;
}
}
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->error_checking_level) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%c ", &(params->reaction_to_failure) );
if ( params->reaction_to_failure != ON_FAILURE_IGNORE_CHAR &&
params->reaction_to_failure != ON_FAILURE_SLEEP_CHAR &&
params->reaction_to_failure != ON_FAILURE_ABORT_CHAR )
{
libblis_test_printf_error( "Invalid reaction-to-failure character code (%c) in input file.\n",
params->reaction_to_failure );
}
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->output_matlab_format) );
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%u ", &(params->output_files) );
fclose( input_stream );
libblis_test_output_params_struct( stdout, params );
}
void libblis_test_read_section_override( test_ops_t* ops,
FILE* input_stream,
int* override )
{
char buffer[ INPUT_BUFFER_SIZE ];
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%d ", override );
}
void libblis_test_read_op_info( test_ops_t* ops,
FILE* input_stream,
opid_t opid,
dimset_t dimset,
unsigned int n_params,
test_op_t* op )
{
char buffer[ INPUT_BUFFER_SIZE ];
char temp[ INPUT_BUFFER_SIZE ];
int i, p;
op->opid = opid;
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%d ", &(op->op_switch) );
if ( op->op_switch == ENABLE_ONLY )
{
ops->indiv_over = TRUE;
}
op->n_dims = libblis_test_get_n_dims_from_dimset( dimset );
op->dimset = dimset;
if ( op->n_dims > MAX_NUM_DIMENSIONS )
{
libblis_test_printf_error( "Detected too many dimensions (%u) in input file to store.\n",
op->n_dims );
}
if ( op->n_dims > 0 )
{
libblis_test_read_next_line( buffer, input_stream );
for ( i = 0, p = 0; i < op->n_dims; ++i )
{
for ( ; isspace( buffer[p] ); ++p ) ;
sscanf( &buffer[p], "%d", &(op->dim_spec[i]) );
for ( ; !isspace( buffer[p] ); ++p ) ;
}
}
if ( n_params > 0 )
{
libblis_test_read_next_line( buffer, input_stream );
sscanf( buffer, "%s ", temp );
op->n_params = strlen( temp );
if ( op->n_params > MAX_NUM_PARAMETERS )
{
libblis_test_printf_error( "Detected too many parameters (%u) in input file.\n",
op->n_params );
}
if ( op->n_params != n_params )
{
libblis_test_printf_error( "Number of parameters specified by caller does not match length of parameter string in input file. strlen( temp ) = %u; n_params = %u\n", op->n_params, n_params );
}
strcpy( op->params, temp );
}
else
{
op->n_params = 0;
strcpy( op->params, "" );
}
op->test_done = FALSE;
op->ops = ops;
}
void libblis_test_output_section_overrides( FILE* os, test_ops_t* ops )
{
if ( libblis_test_quiet_mode ) return;
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- Section overrides ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "Utility operations %d\n", ops->util_over );
libblis_test_fprintf_c( os, "Level-1v operations %d\n", ops->l1v_over );
libblis_test_fprintf_c( os, "Level-1m operations %d\n", ops->l1m_over );
libblis_test_fprintf_c( os, "Level-1f operations %d\n", ops->l1f_over );
libblis_test_fprintf_c( os, "Level-2 operations %d\n", ops->l2_over );
libblis_test_fprintf_c( os, "Level-3 micro-kernels %d\n", ops->l3ukr_over );
libblis_test_fprintf_c( os, "Level-3 operations %d\n", ops->l3_over );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf( os, "\n" );
}
void libblis_test_output_params_struct( FILE* os, test_params_t* params )
{
int i;
gint_t int_type_size;
ind_t im;
cntx_t* cntx;
cntx_t* cntx_c;
cntx_t* cntx_z;
#ifndef BLIS_ENABLE_GEMM_MD
if ( params->mixed_domain || params->mixed_precision )
{
libblis_test_printf_error( "mixed domain and/or mixed precision testing requested, but building against BLIS without mixed datatype support.\n" );
}
#endif
if ( libblis_test_quiet_mode ) return;
if ( bli_info_get_int_type_size() == 32 ||
bli_info_get_int_type_size() == 64 )
int_type_size = bli_info_get_int_type_size();
else
int_type_size = sizeof(gint_t) * 8;
char impl_str[32];
char def_impl_set_str[32];
char def_impl_unset_str[32];
char jrir_str[32];
const bool has_openmp = bli_info_get_enable_openmp();
const bool has_pthreads = bli_info_get_enable_pthreads();
const bool has_hpx = bli_info_get_enable_hpx();
const bool openmp_is_def = bli_info_get_enable_openmp_as_default();
const bool pthreads_is_def = bli_info_get_enable_pthreads_as_default();
const bool hpx_is_def = bli_info_get_enable_hpx_as_default();
const timpl_t ti = bli_thread_get_thread_impl();
if ( has_hpx && has_openmp && has_pthreads ) sprintf( impl_str, "openmp,pthreads,hpx,single" );
else if ( has_hpx && has_openmp ) sprintf( impl_str, "openmp,hpx,single" );
else if ( has_hpx && has_pthreads ) sprintf( impl_str, "pthreads,hpx,single" );
else if ( has_hpx ) sprintf( impl_str, "hpx,single" );
else if ( has_openmp && has_pthreads ) sprintf( impl_str, "openmp,pthreads,single" );
else if ( has_openmp ) sprintf( impl_str, "openmp,single" );
else if ( has_pthreads ) sprintf( impl_str, "pthreads,single" );
else sprintf( impl_str, "single only" );
if ( openmp_is_def ) sprintf( def_impl_unset_str, "openmp" );
else if ( pthreads_is_def ) sprintf( def_impl_unset_str, "pthreads" );
else if ( hpx_is_def ) sprintf( def_impl_unset_str, "hpx" );
else sprintf( def_impl_unset_str, "single" );
if ( ti == BLIS_OPENMP ) sprintf( def_impl_set_str, "openmp" );
else if ( ti == BLIS_POSIX ) sprintf( def_impl_set_str, "pthreads" );
else if ( ti == BLIS_HPX ) sprintf( def_impl_set_str, "hpx" );
else sprintf( def_impl_set_str, "single" );
if ( bli_info_get_thread_jrir_slab() ) sprintf( jrir_str, "slab" );
else if ( bli_info_get_thread_jrir_rr() ) sprintf( jrir_str, "round-robin" );
else sprintf( jrir_str, "tile-level (slab)" );
char nt_str[16];
char jc_nt_str[16];
char pc_nt_str[16];
char ic_nt_str[16];
char jr_nt_str[16];
char ir_nt_str[16];
dim_t nt = bli_thread_get_num_threads();
dim_t jc_nt = bli_thread_get_jc_nt();
dim_t pc_nt = bli_thread_get_pc_nt();
dim_t ic_nt = bli_thread_get_ic_nt();
dim_t jr_nt = bli_thread_get_jr_nt();
dim_t ir_nt = bli_thread_get_ir_nt();
sprintf( nt_str, "%d", ( int ) nt );
sprintf( jc_nt_str, "%d", ( int )jc_nt );
sprintf( pc_nt_str, "%d", ( int )pc_nt );
sprintf( ic_nt_str, "%d", ( int )ic_nt );
sprintf( jr_nt_str, "%d", ( int )jr_nt );
sprintf( ir_nt_str, "%d", ( int )ir_nt );
rntm_t gemm, herk, trmm_l, trmm_r, trsm_l, trsm_r;
dim_t m = 1000, n = 1000, k = 1000;
bli_rntm_init_from_global( &gemm );
bli_rntm_init_from_global( &herk );
bli_rntm_init_from_global( &trmm_l );
bli_rntm_init_from_global( &trmm_r );
bli_rntm_init_from_global( &trsm_l );
bli_rntm_init_from_global( &trsm_r );
bli_rntm_set_ways_for_op( BLIS_GEMM, BLIS_LEFT, m, n, k, &gemm );
bli_rntm_set_ways_for_op( BLIS_HERK, BLIS_LEFT, m, n, k, &herk );
bli_rntm_set_ways_for_op( BLIS_TRMM, BLIS_LEFT, m, n, k, &trmm_l );
bli_rntm_set_ways_for_op( BLIS_TRMM, BLIS_RIGHT, m, n, k, &trmm_r );
bli_rntm_set_ways_for_op( BLIS_TRSM, BLIS_LEFT, m, n, k, &trsm_l );
bli_rntm_set_ways_for_op( BLIS_TRSM, BLIS_RIGHT, m, n, k, &trsm_r );
const bool tls_enabled = bli_info_get_enable_tls();
const bool thr_enabled = bli_info_get_enable_threading();
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS library info -------------------------------------\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "version string %s\n", bli_info_get_version_str() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS configuration info ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "active sub-configuration %s\n", bli_arch_string( bli_arch_query_id() ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "BLIS integer type size (bits) %d\n", ( int )int_type_size );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "Assumed max # of SIMD regs %d\n", ( int )bli_info_get_simd_num_registers() );
libblis_test_fprintf_c( os, "SIMD size (bytes) %d\n", ( int )bli_info_get_simd_size() );
libblis_test_fprintf_c( os, "SIMD alignment (bytes) %d\n", ( int )bli_info_get_simd_align_size() );
libblis_test_fprintf_c( os, "Max stack buffer size (bytes) %d\n", ( int )bli_info_get_stack_buf_max_size() );
libblis_test_fprintf_c( os, "Page size (bytes) %d\n", ( int )bli_info_get_page_size() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "memory pools\n" );
libblis_test_fprintf_c( os, " enabled for packing blocks? %d\n", ( int )bli_info_get_enable_pba_pools() );
libblis_test_fprintf_c( os, " enabled for small blocks? %d\n", ( int )bli_info_get_enable_sba_pools() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "memory alignment (bytes) \n" );
libblis_test_fprintf_c( os, " stack address %d\n", ( int )bli_info_get_stack_buf_align_size() );
libblis_test_fprintf_c( os, " obj_t address %d\n", ( int )bli_info_get_heap_addr_align_size() );
libblis_test_fprintf_c( os, " obj_t stride %d\n", ( int )bli_info_get_heap_stride_align_size() );
libblis_test_fprintf_c( os, " pool block addr A (+offset) %d (+%d)\n", ( int )bli_info_get_pool_addr_align_size_a(), ( int )bli_info_get_pool_addr_offset_size_a() );
libblis_test_fprintf_c( os, " pool block addr B (+offset) %d (+%d)\n", ( int )bli_info_get_pool_addr_align_size_b(), ( int )bli_info_get_pool_addr_offset_size_b() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "BLAS/CBLAS compatibility layers \n" );
libblis_test_fprintf_c( os, " BLAS API enabled? %d\n", ( int )bli_info_get_enable_blas() );
libblis_test_fprintf_c( os, " CBLAS API enabled? %d\n", ( int )bli_info_get_enable_cblas() );
libblis_test_fprintf_c( os, " integer type size (bits) %d\n", ( int )bli_info_get_blas_int_type_size() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "libmemkind \n" );
libblis_test_fprintf_c( os, " enabled? %d\n", ( int )bli_info_get_enable_memkind() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "gemm sandbox \n" );
libblis_test_fprintf_c( os, " enabled? %d\n", ( int )bli_info_get_enable_sandbox() );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "floating-point types s d c z \n" );
libblis_test_fprintf_c( os, " sizes (bytes) %7u %7u %7u %7u\n", sizeof(float),
sizeof(double),
sizeof(scomplex),
sizeof(dcomplex) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS parallelization info ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "thread-local storage (TLS) %d\n", ( int )tls_enabled );
if ( !tls_enabled && thr_enabled )
{
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "[WARNING] BLIS was compiled with TLS disabled. We assume you know what\n" );
libblis_test_fprintf_c( os, "[WARNING] you're doing! Multithreaded race conditions, correctness\n" );
libblis_test_fprintf_c( os, "[WARNING] issues, and deadlocks may occur. If any of these happen,\n" );
libblis_test_fprintf_c( os, "[WARNING] please consider reconfiguring with --disable-threading.\n" );
}
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "multithreading modes %s\n", impl_str );
libblis_test_fprintf_c( os, " default mode %s\n", def_impl_unset_str );
libblis_test_fprintf_c( os, " current mode %s\n", def_impl_set_str );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "thread auto-factorization \n" );
libblis_test_fprintf_c( os, " m dim thread ratio %d\n", ( int )BLIS_THREAD_RATIO_M );
libblis_test_fprintf_c( os, " n dim thread ratio %d\n", ( int )BLIS_THREAD_RATIO_N );
libblis_test_fprintf_c( os, " jr max threads %d\n", ( int )BLIS_THREAD_MAX_JR );
libblis_test_fprintf_c( os, " ir max threads %d\n", ( int )BLIS_THREAD_MAX_IR );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "ways of parallelism nt jc pc ic jr ir\n" );
libblis_test_fprintf_c( os, " environment %5s %5s %5s %5s %5s %5s\n",
nt_str, jc_nt_str, pc_nt_str,
ic_nt_str, jr_nt_str, ir_nt_str );
libblis_test_fprintf_c( os, " gemm (m,n,k=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &gemm ), ( int )bli_rntm_pc_ways( &gemm ),
( int )bli_rntm_ic_ways( &gemm ),
( int )bli_rntm_jr_ways( &gemm ), ( int )bli_rntm_ir_ways( &gemm ) );
libblis_test_fprintf_c( os, " herk (m,k=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &herk ), ( int )bli_rntm_pc_ways( &herk ),
( int )bli_rntm_ic_ways( &herk ),
( int )bli_rntm_jr_ways( &herk ), ( int )bli_rntm_ir_ways( &herk ) );
libblis_test_fprintf_c( os, " trmm_l (m,n=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &trmm_l ), ( int )bli_rntm_pc_ways( &trmm_l ),
( int )bli_rntm_ic_ways( &trmm_l ),
( int )bli_rntm_jr_ways( &trmm_l ), ( int )bli_rntm_ir_ways( &trmm_l ) );
libblis_test_fprintf_c( os, " trmm_r (m,n=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &trmm_r ), ( int )bli_rntm_pc_ways( &trmm_r ),
( int )bli_rntm_ic_ways( &trmm_r ),
( int )bli_rntm_jr_ways( &trmm_r ), ( int )bli_rntm_ir_ways( &trmm_r ) );
libblis_test_fprintf_c( os, " trsm_l (m,n=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &trsm_l ), ( int )bli_rntm_pc_ways( &trsm_l ),
( int )bli_rntm_ic_ways( &trsm_l ),
( int )bli_rntm_jr_ways( &trsm_l ), ( int )bli_rntm_ir_ways( &trsm_l ) );
libblis_test_fprintf_c( os, " trsm_r (m,n=1000) %5d %5d %5d %5d %5d\n",
( int )bli_rntm_jc_ways( &trsm_r ), ( int )bli_rntm_pc_ways( &trsm_r ),
( int )bli_rntm_ic_ways( &trsm_r ),
( int )bli_rntm_jr_ways( &trsm_r ), ( int )bli_rntm_ir_ways( &trsm_r ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "thread partitioning \n" );
libblis_test_fprintf_c( os, " jr/ir loops %s\n", jrir_str );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS default implementations ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "level-3 implementations s d c z\n" );
libblis_test_fprintf_c( os, " gemm %7s %7s %7s %7s\n",
bli_info_get_gemm_impl_string( BLIS_FLOAT ),
bli_info_get_gemm_impl_string( BLIS_DOUBLE ),
bli_info_get_gemm_impl_string( BLIS_SCOMPLEX ),
bli_info_get_gemm_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " hemm %7s %7s %7s %7s\n",
bli_info_get_hemm_impl_string( BLIS_FLOAT ),
bli_info_get_hemm_impl_string( BLIS_DOUBLE ),
bli_info_get_hemm_impl_string( BLIS_SCOMPLEX ),
bli_info_get_hemm_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " herk %7s %7s %7s %7s\n",
bli_info_get_herk_impl_string( BLIS_FLOAT ),
bli_info_get_herk_impl_string( BLIS_DOUBLE ),
bli_info_get_herk_impl_string( BLIS_SCOMPLEX ),
bli_info_get_herk_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " her2k %7s %7s %7s %7s\n",
bli_info_get_her2k_impl_string( BLIS_FLOAT ),
bli_info_get_her2k_impl_string( BLIS_DOUBLE ),
bli_info_get_her2k_impl_string( BLIS_SCOMPLEX ),
bli_info_get_her2k_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " symm %7s %7s %7s %7s\n",
bli_info_get_symm_impl_string( BLIS_FLOAT ),
bli_info_get_symm_impl_string( BLIS_DOUBLE ),
bli_info_get_symm_impl_string( BLIS_SCOMPLEX ),
bli_info_get_symm_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " syrk %7s %7s %7s %7s\n",
bli_info_get_syrk_impl_string( BLIS_FLOAT ),
bli_info_get_syrk_impl_string( BLIS_DOUBLE ),
bli_info_get_syrk_impl_string( BLIS_SCOMPLEX ),
bli_info_get_syrk_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " syr2k %7s %7s %7s %7s\n",
bli_info_get_syr2k_impl_string( BLIS_FLOAT ),
bli_info_get_syr2k_impl_string( BLIS_DOUBLE ),
bli_info_get_syr2k_impl_string( BLIS_SCOMPLEX ),
bli_info_get_syr2k_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trmm %7s %7s %7s %7s\n",
bli_info_get_trmm_impl_string( BLIS_FLOAT ),
bli_info_get_trmm_impl_string( BLIS_DOUBLE ),
bli_info_get_trmm_impl_string( BLIS_SCOMPLEX ),
bli_info_get_trmm_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trmm3 %7s %7s %7s %7s\n",
bli_info_get_trmm3_impl_string( BLIS_FLOAT ),
bli_info_get_trmm3_impl_string( BLIS_DOUBLE ),
bli_info_get_trmm3_impl_string( BLIS_SCOMPLEX ),
bli_info_get_trmm3_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trsm %7s %7s %7s %7s\n",
bli_info_get_trsm_impl_string( BLIS_FLOAT ),
bli_info_get_trsm_impl_string( BLIS_DOUBLE ),
bli_info_get_trsm_impl_string( BLIS_SCOMPLEX ),
bli_info_get_trsm_impl_string( BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
bli_ind_oper_enable_only( BLIS_GEMM, BLIS_NAT, BLIS_SCOMPLEX );
bli_ind_oper_enable_only( BLIS_GEMM, BLIS_NAT, BLIS_DCOMPLEX );
libblis_test_fprintf_c( os, "--- BLIS native implementation info ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " c z \n" );
libblis_test_fprintf_c( os, "complex implementation %7s %7s\n",
bli_ind_oper_get_avail_impl_string( BLIS_GEMM, BLIS_SCOMPLEX ),
bli_ind_oper_get_avail_impl_string( BLIS_GEMM, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, "\n" );
cntx = ( cntx_t* )bli_gks_query_nat_cntx();
libblis_test_fprintf_c( os, "level-3 blocksizes s d c z \n" );
libblis_test_fprintf_c( os, " mc %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_MC, cntx ) );
libblis_test_fprintf_c( os, " kc %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_KC, cntx ) );
libblis_test_fprintf_c( os, " nc %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_NC, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mc maximum %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_FLOAT, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DOUBLE, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_MC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_MC, cntx ) );
libblis_test_fprintf_c( os, " kc maximum %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_FLOAT, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DOUBLE, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_KC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_KC, cntx ) );
libblis_test_fprintf_c( os, " nc maximum %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_FLOAT, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DOUBLE, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_NC, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_NC, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mr %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_MR, cntx ) );
libblis_test_fprintf_c( os, " nr %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_NR, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mr packdim %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_FLOAT, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DOUBLE, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_MR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_MR, cntx ) );
libblis_test_fprintf_c( os, " nr packdim %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_FLOAT, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DOUBLE, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_NR, cntx ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_NR, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "micro-kernel types s d c z\n" );
libblis_test_fprintf_c( os, " gemm %7s %7s %7s %7s\n",
bli_info_get_gemm_ukr_impl_string( BLIS_NAT, BLIS_FLOAT ),
bli_info_get_gemm_ukr_impl_string( BLIS_NAT, BLIS_DOUBLE ),
bli_info_get_gemm_ukr_impl_string( BLIS_NAT, BLIS_SCOMPLEX ),
bli_info_get_gemm_ukr_impl_string( BLIS_NAT, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " gemmtrsm_l %7s %7s %7s %7s\n",
bli_info_get_gemmtrsm_l_ukr_impl_string( BLIS_NAT, BLIS_FLOAT ),
bli_info_get_gemmtrsm_l_ukr_impl_string( BLIS_NAT, BLIS_DOUBLE ),
bli_info_get_gemmtrsm_l_ukr_impl_string( BLIS_NAT, BLIS_SCOMPLEX ),
bli_info_get_gemmtrsm_l_ukr_impl_string( BLIS_NAT, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " gemmtrsm_u %7s %7s %7s %7s\n",
bli_info_get_gemmtrsm_u_ukr_impl_string( BLIS_NAT, BLIS_FLOAT ),
bli_info_get_gemmtrsm_u_ukr_impl_string( BLIS_NAT, BLIS_DOUBLE ),
bli_info_get_gemmtrsm_u_ukr_impl_string( BLIS_NAT, BLIS_SCOMPLEX ),
bli_info_get_gemmtrsm_u_ukr_impl_string( BLIS_NAT, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trsm_l %7s %7s %7s %7s\n",
bli_info_get_trsm_l_ukr_impl_string( BLIS_NAT, BLIS_FLOAT ),
bli_info_get_trsm_l_ukr_impl_string( BLIS_NAT, BLIS_DOUBLE ),
bli_info_get_trsm_l_ukr_impl_string( BLIS_NAT, BLIS_SCOMPLEX ),
bli_info_get_trsm_l_ukr_impl_string( BLIS_NAT, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trsm_u %7s %7s %7s %7s\n",
bli_info_get_trsm_u_ukr_impl_string( BLIS_NAT, BLIS_FLOAT ),
bli_info_get_trsm_u_ukr_impl_string( BLIS_NAT, BLIS_DOUBLE ),
bli_info_get_trsm_u_ukr_impl_string( BLIS_NAT, BLIS_SCOMPLEX ),
bli_info_get_trsm_u_ukr_impl_string( BLIS_NAT, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "micro-kernel prefers rows? s d c z\n" );
libblis_test_fprintf_c( os, " gemm %7d %7d %7d %7d\n",
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_FLOAT, BLIS_GEMM_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DOUBLE, BLIS_GEMM_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_SCOMPLEX, BLIS_GEMM_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DCOMPLEX, BLIS_GEMM_UKR, cntx ) );
libblis_test_fprintf_c( os, " gemmtrsm_l %7d %7d %7d %7d\n",
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_FLOAT, BLIS_GEMMTRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DOUBLE, BLIS_GEMMTRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_SCOMPLEX, BLIS_GEMMTRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DCOMPLEX, BLIS_GEMMTRSM_L_UKR, cntx ) );
libblis_test_fprintf_c( os, " gemmtrsm_u %7d %7d %7d %7d\n",
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_FLOAT, BLIS_GEMMTRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DOUBLE, BLIS_GEMMTRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_SCOMPLEX, BLIS_GEMMTRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DCOMPLEX, BLIS_GEMMTRSM_U_UKR, cntx ) );
libblis_test_fprintf_c( os, " trsm_l %7d %7d %7d %7d\n",
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_FLOAT, BLIS_TRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DOUBLE, BLIS_TRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_SCOMPLEX, BLIS_TRSM_L_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DCOMPLEX, BLIS_TRSM_L_UKR, cntx ) );
libblis_test_fprintf_c( os, " trsm_u %7d %7d %7d %7d\n",
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_FLOAT, BLIS_TRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DOUBLE, BLIS_TRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_SCOMPLEX, BLIS_TRSM_U_UKR, cntx ),
( int )bli_cntx_ukr_prefers_rows_dt( BLIS_DCOMPLEX, BLIS_TRSM_U_UKR, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS induced implementation info ---\n" );
libblis_test_fprintf_c( os, "\n" );
for ( im = 0; im < BLIS_NAT; ++im )
{
if ( params->ind_enable[ im ] == 0 ) continue;
bli_ind_oper_enable_only( BLIS_GEMM, im, BLIS_SCOMPLEX );
bli_ind_oper_enable_only( BLIS_GEMM, im, BLIS_DCOMPLEX );
libblis_test_fprintf_c( os, " c z \n" );
libblis_test_fprintf_c( os, "complex implementation %7s %7s\n",
bli_ind_oper_get_avail_impl_string( BLIS_GEMM, BLIS_SCOMPLEX ),
bli_ind_oper_get_avail_impl_string( BLIS_GEMM, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, "\n" );
cntx_c = ( cntx_t* )bli_gks_query_ind_cntx( im );
cntx_z = ( cntx_t* )bli_gks_query_ind_cntx( im );
libblis_test_fprintf_c( os, "level-3 blocksizes c z \n" );
libblis_test_fprintf_c( os, " mc %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_MC, cntx_c ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_MC, cntx_z ) );
libblis_test_fprintf_c( os, " kc %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_KC, cntx_c ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_KC, cntx_z ) );
libblis_test_fprintf_c( os, " nc %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_NC, cntx_c ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_NC, cntx_z ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mc maximum %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_MC, cntx_c ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_MC, cntx_z ) );
libblis_test_fprintf_c( os, " kc maximum %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_KC, cntx_c ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_KC, cntx_z ) );
libblis_test_fprintf_c( os, " nc maximum %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_NC, cntx_c ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_NC, cntx_z ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mr %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_MR, cntx_c ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_MR, cntx_z ) );
libblis_test_fprintf_c( os, " nr %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_NR, cntx_c ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_NR, cntx_z ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, " mr packdim %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_MR, cntx_c ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_MR, cntx_z ) );
libblis_test_fprintf_c( os, " nr packdim %7d %7d\n",
( int )bli_cntx_get_blksz_max_dt( BLIS_SCOMPLEX, BLIS_NR, cntx_c ),
( int )bli_cntx_get_blksz_max_dt( BLIS_DCOMPLEX, BLIS_NR, cntx_z ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "micro-kernel types c z\n" );
libblis_test_fprintf_c( os, " gemm %7s %7s\n",
bli_info_get_gemm_ukr_impl_string( im, BLIS_SCOMPLEX ),
bli_info_get_gemm_ukr_impl_string( im, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " gemmtrsm_l %7s %7s\n",
bli_info_get_gemmtrsm_l_ukr_impl_string( im, BLIS_SCOMPLEX ),
bli_info_get_gemmtrsm_l_ukr_impl_string( im, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " gemmtrsm_u %7s %7s\n",
bli_info_get_gemmtrsm_u_ukr_impl_string( im, BLIS_SCOMPLEX ),
bli_info_get_gemmtrsm_u_ukr_impl_string( im, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trsm_l %7s %7s\n",
bli_info_get_trsm_l_ukr_impl_string( im, BLIS_SCOMPLEX ),
bli_info_get_trsm_l_ukr_impl_string( im, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, " trsm_u %7s %7s\n",
bli_info_get_trsm_u_ukr_impl_string( im, BLIS_SCOMPLEX ),
bli_info_get_trsm_u_ukr_impl_string( im, BLIS_DCOMPLEX ) );
libblis_test_fprintf_c( os, "\n" );
}
bli_ind_disable_all();
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS misc. other info ---\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "level-2 cache blocksizes s d c z \n" );
libblis_test_fprintf_c( os, " m dimension %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_M2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_M2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_M2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_M2, cntx ) );
libblis_test_fprintf_c( os, " n dimension %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_N2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_N2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_N2, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_N2, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "level-1f fusing factors s d c z \n" );
libblis_test_fprintf_c( os, " axpyf %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_AF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_AF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_AF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_AF, cntx ) );
libblis_test_fprintf_c( os, " dotxf %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_DF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_DF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_DF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_DF, cntx ) );
libblis_test_fprintf_c( os, " dotxaxpyf %7d %7d %7d %7d\n",
( int )bli_cntx_get_blksz_def_dt( BLIS_FLOAT, BLIS_XF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DOUBLE, BLIS_XF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_SCOMPLEX, BLIS_XF, cntx ),
( int )bli_cntx_get_blksz_def_dt( BLIS_DCOMPLEX, BLIS_XF, cntx ) );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf( os, "\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "--- BLIS test suite parameters ----------------------------\n" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf_c( os, "num repeats per experiment %u\n", params->n_repeats );
libblis_test_fprintf_c( os, "num matrix storage schemes %u\n", params->n_mstorage );
libblis_test_fprintf_c( os, "storage[ matrix ] %s\n", params->storage[ BLIS_TEST_MATRIX_OPERAND ] );
libblis_test_fprintf_c( os, "num vector storage schemes %u\n", params->n_vstorage );
libblis_test_fprintf_c( os, "storage[ vector ] %s\n", params->storage[ BLIS_TEST_VECTOR_OPERAND ] );
libblis_test_fprintf_c( os, "mix all storage schemes? %u\n", params->mix_all_storage );
libblis_test_fprintf_c( os, "test with aligned memory? %u\n", params->alignment );
libblis_test_fprintf_c( os, "randomization method %u\n", params->rand_method );
libblis_test_fprintf_c( os, "general stride spacing %u\n", params->gs_spacing );
libblis_test_fprintf_c( os, "num datatypes %u\n", params->n_datatypes );
libblis_test_fprintf_c( os, "datatype[0] %d (%c)\n", params->datatype[0],
params->datatype_char[0] );
for( i = 1; i < params->n_datatypes; ++i )
libblis_test_fprintf_c( os, " [%d] %d (%c)\n", i, params->datatype[i],
params->datatype_char[i] );
libblis_test_fprintf_c( os, "mix domains for gemm? %u\n", params->mixed_domain );
libblis_test_fprintf_c( os, "mix precisions for gemm? %u\n", params->mixed_precision );
libblis_test_fprintf_c( os, "problem size: first to test %u\n", params->p_first );
libblis_test_fprintf_c( os, "problem size: max to test %u\n", params->p_max );
libblis_test_fprintf_c( os, "problem size increment %u\n", params->p_inc );
libblis_test_fprintf_c( os, "complex implementations \n" );
libblis_test_fprintf_c( os, " 1m? %u\n", params->ind_enable[ BLIS_1M ] );
libblis_test_fprintf_c( os, " native? %u\n", params->ind_enable[ BLIS_NAT ] );
libblis_test_fprintf_c( os, "simulated app-level threads %u\n", params->n_app_threads );
libblis_test_fprintf_c( os, "error-checking level %u\n", params->error_checking_level );
libblis_test_fprintf_c( os, "reaction to failure %c\n", params->reaction_to_failure );
libblis_test_fprintf_c( os, "output in matlab format? %u\n", params->output_matlab_format );
libblis_test_fprintf_c( os, "output to stdout AND files? %u\n", params->output_files );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf( os, "\n" );
if ( params->mixed_domain || params->mixed_precision )
{
ind_t im;
for ( im = BLIS_IND_FIRST; im < BLIS_IND_LAST+1; ++im )
{
if ( im != BLIS_1M && im != BLIS_NAT )
params->ind_enable[ im ] = 0;
}
}
}
void libblis_test_output_op_struct( FILE* os, test_op_t* op, char* op_str )
{
if ( libblis_test_quiet_mode ) return;
libblis_test_fprintf_c( os, "--- %s ---\n", op_str );
libblis_test_fprintf_c( os, "\n" );
dimset_t dimset = op->dimset;
if ( dimset == BLIS_TEST_DIMS_MNK )
{
libblis_test_fprintf_c( os, "%s m n k %d %d %d\n", op_str,
op->dim_spec[0], op->dim_spec[1], op->dim_spec[2] );
}
else if ( dimset == BLIS_TEST_DIMS_MN )
{
libblis_test_fprintf_c( os, "%s m n %d %d\n", op_str,
op->dim_spec[0], op->dim_spec[1] );
}
else if ( dimset == BLIS_TEST_DIMS_MK )
{
libblis_test_fprintf_c( os, "%s m k %d %d\n", op_str,
op->dim_spec[0], op->dim_spec[1] );
}
else if ( dimset == BLIS_TEST_DIMS_M ||
dimset == BLIS_TEST_DIMS_MF )
{
libblis_test_fprintf_c( os, "%s m %d\n", op_str,
op->dim_spec[0] );
}
else if ( dimset == BLIS_TEST_DIMS_K )
{
libblis_test_fprintf_c( os, "%s k %d\n", op_str,
op->dim_spec[0] );
}
else if ( dimset == BLIS_TEST_NO_DIMS )
{
}
else
{
libblis_test_printf_error( "Invalid dimension combination.\n" );
}
if ( op->n_params > 0 )
libblis_test_fprintf_c( os, "%s operand params %s\n", op_str, op->params );
else
libblis_test_fprintf_c( os, "%s operand params %s\n", op_str, "(none)" );
libblis_test_fprintf_c( os, "\n" );
libblis_test_fprintf( os, "\n" );
}
char* libblis_test_get_string_for_result( double resid,
num_t dt,
thresh_t* thresh )
{
char* r_val;
if ( bli_isnan( resid ) || bli_isinf( resid ) )
{
r_val = libblis_test_fail_string;
}
else
{
if ( resid > thresh[dt].failwarn ) r_val = libblis_test_fail_string;
else if ( resid > thresh[dt].warnpass ) r_val = libblis_test_warn_string;
else r_val = libblis_test_pass_string;
}
return r_val;
}
param_t libblis_test_get_param_type_for_char( char p_type )
{
param_t r_val;
if ( p_type == 's' ) r_val = BLIS_TEST_PARAM_SIDE;
else if ( p_type == 'u' ) r_val = BLIS_TEST_PARAM_UPLO;
else if ( p_type == 'e' ) r_val = BLIS_TEST_PARAM_UPLODE;
else if ( p_type == 'h' ) r_val = BLIS_TEST_PARAM_TRANS;
else if ( p_type == 'c' ) r_val = BLIS_TEST_PARAM_CONJ;
else if ( p_type == 'd' ) r_val = BLIS_TEST_PARAM_DIAG;
else
{
r_val = 0;
libblis_test_printf_error( "Invalid parameter character.\n" );
}
return r_val;
}
operand_t libblis_test_get_operand_type_for_char( char o_type )
{
operand_t r_val;
if ( o_type == 'm' ) r_val = BLIS_TEST_MATRIX_OPERAND;
else if ( o_type == 'v' ) r_val = BLIS_TEST_VECTOR_OPERAND;
else
{
r_val = 0;
libblis_test_printf_error( "Invalid operand character.\n" );
}
return r_val;
}
unsigned int libblis_test_get_n_dims_from_dimset( dimset_t dimset )
{
unsigned int n_dims;
if ( dimset == BLIS_TEST_DIMS_MNK ) n_dims = 3;
else if ( dimset == BLIS_TEST_DIMS_MN ) n_dims = 2;
else if ( dimset == BLIS_TEST_DIMS_MK ) n_dims = 2;
else if ( dimset == BLIS_TEST_DIMS_M ) n_dims = 1;
else if ( dimset == BLIS_TEST_DIMS_MF ) n_dims = 1;
else if ( dimset == BLIS_TEST_DIMS_K ) n_dims = 1;
else if ( dimset == BLIS_TEST_NO_DIMS ) n_dims = 0;
else
{
n_dims = 0;
libblis_test_printf_error( "Invalid dimension combination.\n" );
}
return n_dims;
}
unsigned int libblis_test_get_n_dims_from_string( char* dims_str )
{
unsigned int n_dims;
char* cp;
cp = dims_str;
for ( n_dims = 0; *cp != '\0'; ++n_dims )
{
while ( isspace( *cp ) )
{
++cp;
}
while ( isdigit( *cp ) )
{
++cp;
}
}
return n_dims;
}
dim_t libblis_test_get_dim_from_prob_size( int dim_spec,
unsigned int p_size )
{
dim_t dim;
if ( dim_spec < 0 ) dim = p_size / bli_abs(dim_spec);
else dim = dim_spec;
return dim;
}
void libblis_test_fill_param_strings( char* p_spec_str,
char** chars_for_param,
unsigned int n_params,
unsigned int n_param_combos,
char** pc_str )
{
unsigned int pci, pi, i;
unsigned int* counter;
unsigned int* n_vals_for_param;
n_vals_for_param = ( unsigned int* ) malloc( n_params * sizeof( unsigned int ) );
for ( i = 0; i < n_params; ++i )
{
if ( p_spec_str[i] == '?' ) n_vals_for_param[i] = strlen( chars_for_param[i] );
else n_vals_for_param[i] = 1;
}
counter = ( unsigned int* ) malloc( n_params * sizeof( unsigned int ) );
for ( i = 0; i < n_params; ++i ) counter[i] = 0;
for ( pci = 0; pci < n_param_combos; ++pci )
{
for ( i = 0, pi = n_params - 1; i < n_params; --pi, ++i )
{
if ( p_spec_str[pi] != '?' )
pc_str[pci][pi] = p_spec_str[pi];
else
pc_str[pci][pi] = chars_for_param[ pi ][ counter[pi] ];
}
pc_str[pci][n_params] = '\0';
if ( pci < n_param_combos - 1 )
{
counter[ n_params - 1 ]++;
carryover( &counter[ n_params - 1 ],
&n_vals_for_param[ n_params - 1 ],
n_params );
}
}
free( counter );
free( n_vals_for_param );
}
void carryover( unsigned int* c,
unsigned int* n_vals_for_param,
unsigned int n_params )
{
if ( n_params == 1 ) return;
else
{
if ( *c == *n_vals_for_param )
{
*c = 0;
*(c-1) += 1;
carryover( c-1, n_vals_for_param-1, n_params-1 );
}
}
}
void libblis_test_op_driver
(
thread_data_t* tdata,
test_params_t* params,
test_op_t* op,
iface_t iface,
char* op_str,
char* p_types,
char* o_types,
thresh_t* thresh,
void (*f_exp) (test_params_t*, test_op_t*, iface_t, char*, char*, char*, unsigned int, double*, double* ) )
{
unsigned int n_mstorage = params->n_mstorage;
unsigned int n_vstorage = params->n_vstorage;
unsigned int n_datatypes = params->n_datatypes;
unsigned int p_first = params->p_first;
unsigned int p_max = params->p_max;
unsigned int p_inc = params->p_inc;
unsigned int mix_all_storage = params->mix_all_storage;
unsigned int mixed_domain = params->mixed_domain;
unsigned int mixed_precision = params->mixed_precision;
unsigned int reaction_to_failure = params->reaction_to_failure;
num_t datatype;
num_t dt_check;
char dt_char;
char* p_spec_str;
unsigned int n_params;
char** chars_for_param;
unsigned int n_param_combos;
char** pc_str;
char s_spec_str[ MAX_NUM_OPERANDS + 1 ];
unsigned int n_operands;
unsigned int n_operandsp1;
char** chars_for_storage;
unsigned int n_store_combos;
char** sc_str;
char d_spec_str[ MAX_NUM_OPERANDS + 1 ];
char** chars_for_spdt;
char** chars_for_dpdt;
unsigned int n_spdt_combos;
unsigned int n_dpdt_combos;
unsigned int n_dt_combos;
char** dc_str;
char** chars_for_dt;
char** chars_for_rddt;
char** chars_for_cddt;
unsigned int n_rddt_combos;
unsigned int n_cddt_combos;
unsigned int p_cur, pi;
unsigned int indi, pci, sci, dci, i, j, o;
unsigned int is_mixed_dt;
double perf, resid;
char* pass_str;
char* ind_str;
char blank_str[32];
char funcname_str[64];
char dims_str[64];
char label_str[128];
unsigned int n_spaces;
unsigned int n_dims_print;
FILE* output_stream = NULL;
chars_for_rddt = NULL;
chars_for_cddt = NULL;
chars_for_spdt = NULL;
chars_for_dpdt = NULL;
if ( params->output_files )
libblis_test_fopen_ofile( op_str, iface, &output_stream );
if ( params->error_checking_level == 0 )
bli_error_checking_level_set( BLIS_NO_ERROR_CHECKING );
else
bli_error_checking_level_set( BLIS_FULL_ERROR_CHECKING );
p_spec_str = op->params;
n_params = strlen( p_types );
if ( strlen( p_types ) != strlen( p_spec_str) )
{
libblis_test_printf_error( "Parameter specification string from input file does not match length of p_types string.\n" );
}
chars_for_param = ( char** ) malloc( n_params * sizeof( char* ) );
for ( i = 0; i < n_params; ++i )
{
param_t param_type = libblis_test_get_param_type_for_char( p_types[i] );
chars_for_param[i] = libblis_test_param_chars[ param_type ];
}
n_param_combos = libblis_test_count_combos( n_params, p_spec_str,
chars_for_param );
pc_str = ( char** ) malloc( n_param_combos * sizeof( char* ) );
for ( i = 0; i < n_param_combos; ++i )
pc_str[i] = ( char* ) malloc( ( n_params + 1 ) * sizeof( char ) );
libblis_test_fill_param_strings( p_spec_str,
chars_for_param,
n_params,
n_param_combos,
pc_str );
n_operands = strlen( o_types );
if ( iface == BLIS_TEST_SEQ_UKERNEL )
mix_all_storage = DISABLE;
if ( mix_all_storage )
{
for ( i = 0; i < n_operands; ++i ) s_spec_str[i] = '?';
s_spec_str[i] = '\0';
chars_for_storage = ( char** ) malloc( n_operands * sizeof( char* ) );
for ( i = 0; i < n_operands; ++i )
{
operand_t operand_type = libblis_test_get_operand_type_for_char( o_types[i] );
chars_for_storage[i] = libblis_test_store_chars[ operand_type ];
}
n_store_combos = libblis_test_count_combos( n_operands, s_spec_str,
chars_for_storage );
sc_str = ( char** ) malloc( n_store_combos * sizeof( char* ) );
for ( sci = 0; sci < n_store_combos; ++sci )
sc_str[sci] = ( char* ) malloc( ( n_operands + 1 ) * sizeof( char ) );
libblis_test_fill_param_strings( s_spec_str,
chars_for_storage,
n_operands,
n_store_combos,
sc_str );
}
else {
unsigned int n_mat_operands = 0;
unsigned int n_vec_operands = 0;
for ( o = 0; o < n_operands; ++o )
{
operand_t operand_type
= libblis_test_get_operand_type_for_char( o_types[o] );
if ( operand_type == BLIS_TEST_MATRIX_OPERAND ) ++n_mat_operands;
else if ( operand_type == BLIS_TEST_VECTOR_OPERAND ) ++n_vec_operands;
}
if ( n_vec_operands == 0 )
{
n_store_combos = n_mstorage;
n_vstorage = 1;
}
else if ( n_mat_operands == 0 )
{
n_store_combos = n_vstorage;
n_mstorage = 1;
}
else
{
n_store_combos = n_mstorage * n_vstorage;
}
sc_str = ( char** ) malloc( n_store_combos * sizeof( char* ) );
for ( j = 0; j < n_mstorage; ++j )
{
for ( i = 0; i < n_vstorage; ++i )
{
sci = j*n_vstorage + i;
sc_str[ sci ]
= ( char* ) malloc( ( n_operands + 1 ) * sizeof( char ) );
for ( o = 0; o < n_operands; ++o )
{
unsigned int ij;
operand_t operand_type
= libblis_test_get_operand_type_for_char( o_types[o] );
if ( operand_type == BLIS_TEST_MATRIX_OPERAND ) ij = j;
else ij = i;
sc_str[sci][o] = params->storage[ operand_type ][ij];
}
sc_str[sci][n_operands] = '\0';
}
}
}
if ( !mixed_domain && mixed_precision && op->opid == BLIS_GEMM )
{
is_mixed_dt = TRUE;
n_operandsp1 = n_operands + 1;
unsigned int has_rd = libblis_test_dt_str_has_rd_char( params );
unsigned int has_cd = libblis_test_dt_str_has_cd_char( params );
for ( i = 0; i < n_operandsp1; ++i ) d_spec_str[i] = '?';
d_spec_str[i] = '\0';
chars_for_rddt = ( char** ) malloc( n_operandsp1 * sizeof( char* ) );
chars_for_cddt = ( char** ) malloc( n_operandsp1 * sizeof( char* ) );
for ( i = 0; i < n_operandsp1; ++i )
{
chars_for_rddt[i] = libblis_test_rd_chars;
chars_for_cddt[i] = libblis_test_cd_chars;
}
chars_for_cddt[i-1] = libblis_test_rd_chars;
n_rddt_combos = 0; n_cddt_combos = 0;
if ( has_rd )
n_rddt_combos = libblis_test_count_combos( n_operandsp1, d_spec_str,
chars_for_rddt );
if ( has_cd )
n_cddt_combos = libblis_test_count_combos( n_operandsp1, d_spec_str,
chars_for_cddt );
n_dt_combos = n_rddt_combos + n_cddt_combos;
dc_str = ( char** ) malloc( n_dt_combos * sizeof( char* ) );
for ( dci = 0; dci < n_dt_combos; ++dci )
dc_str[dci] = ( char* ) malloc( ( n_operandsp1 + 1 ) * sizeof( char ) );
char** dc_str_p = dc_str;
if ( has_rd )
{
libblis_test_fill_param_strings( d_spec_str,
chars_for_rddt,
n_operandsp1,
n_rddt_combos,
dc_str_p );
dc_str_p += n_rddt_combos;
}
if ( has_cd )
{
libblis_test_fill_param_strings( d_spec_str,
chars_for_cddt,
n_operandsp1,
n_cddt_combos,
dc_str_p );
dc_str_p += n_cddt_combos;
}
#if 0#endif
}
else if ( mixed_domain && !mixed_precision && op->opid == BLIS_GEMM )
{
is_mixed_dt = TRUE;
n_operandsp1 = n_operands + 1;
unsigned int has_sp = libblis_test_dt_str_has_sp_char( params );
unsigned int has_dp = libblis_test_dt_str_has_dp_char( params );
for ( i = 0; i < n_operands; ++i ) d_spec_str[i] = '?';
d_spec_str[i] = '\0';
chars_for_spdt = ( char** ) malloc( n_operands * sizeof( char* ) );
chars_for_dpdt = ( char** ) malloc( n_operands * sizeof( char* ) );
for ( i = 0; i < n_operands; ++i )
{
chars_for_spdt[i] = libblis_test_sp_chars;
chars_for_dpdt[i] = libblis_test_dp_chars;
}
n_spdt_combos = 0; n_dpdt_combos = 0;
if ( has_sp )
n_spdt_combos = libblis_test_count_combos( n_operands, d_spec_str,
chars_for_spdt );
if ( has_dp )
n_dpdt_combos = libblis_test_count_combos( n_operands, d_spec_str,
chars_for_dpdt );
n_dt_combos = n_spdt_combos + n_dpdt_combos;
dc_str = ( char** ) malloc( n_dt_combos * sizeof( char* ) );
for ( dci = 0; dci < n_dt_combos; ++dci )
dc_str[dci] = ( char* ) malloc( ( n_operandsp1 + 1 ) * sizeof( char ) );
char** dc_str_p = dc_str;
if ( has_sp )
{
libblis_test_fill_param_strings( d_spec_str,
chars_for_spdt,
n_operands,
n_spdt_combos,
dc_str_p );
dc_str_p += n_spdt_combos;
}
if ( has_dp )
{
libblis_test_fill_param_strings( d_spec_str,
chars_for_dpdt,
n_operands,
n_dpdt_combos,
dc_str_p );
dc_str_p += n_dpdt_combos;
}
int prec_i = n_operands;
for ( i = 0; i < n_dt_combos; ++i )
{
dc_str[i][prec_i] = libblis_test_proj_dtchar_to_precchar( dc_str[i][0] );
dc_str[i][prec_i+1] = '\0';
}
#if 0#endif
}
else if ( mixed_domain && mixed_precision && op->opid == BLIS_GEMM )
{
is_mixed_dt = TRUE;
n_operandsp1 = n_operands + 1;
for ( i = 0; i < n_operandsp1; ++i ) d_spec_str[i] = '?';
d_spec_str[i] = '\0';
chars_for_dt = ( char** ) malloc( n_operandsp1 * sizeof( char* ) );
for ( i = 0; i < n_operandsp1; ++i )
{
chars_for_dt[i] = libblis_test_dt_chars;
}
chars_for_dt[i-1] = libblis_test_rd_chars;
n_dt_combos = libblis_test_count_combos( n_operandsp1, d_spec_str,
chars_for_dt );
dc_str = ( char** ) malloc( n_dt_combos * sizeof( char* ) );
for ( dci = 0; dci < n_dt_combos; ++dci )
dc_str[dci] = ( char* ) malloc( ( n_operandsp1 + 1 ) * sizeof( char ) );
libblis_test_fill_param_strings( d_spec_str,
chars_for_dt,
n_operandsp1,
n_dt_combos,
dc_str );
#if 0#endif
}
else {
is_mixed_dt = FALSE;
n_operandsp1 = n_operands + 1;
n_dt_combos = n_datatypes;
dc_str = ( char** ) malloc( n_dt_combos * sizeof( char* ) );
for ( dci = 0; dci < n_dt_combos; ++dci )
dc_str[dci] = ( char* ) malloc( ( n_operandsp1 + 1 ) * sizeof( char ) );
for ( dci = 0; dci < n_dt_combos; ++dci )
{
dt_char = params->datatype_char[dci];
for ( i = 0; i < n_operands; ++i )
dc_str[dci][i] = dt_char;
dc_str[dci][i] = libblis_test_proj_dtchar_to_precchar( dc_str[dci][0] );
dc_str[dci][i+1] = '\0';
}
#if 0#endif
}
if ( tdata->id == 0 )
{
libblis_test_output_op_struct( stdout, op, op_str );
if ( output_stream )
{
libblis_test_output_params_struct( output_stream, params );
libblis_test_output_op_struct( output_stream, op, op_str );
}
}
for ( sci = 0; sci < n_store_combos; ++sci )
{
for ( dci = 0; dci < n_dt_combos; ++dci )
{
bli_param_map_char_to_blis_dt( dc_str[dci][0], &datatype );
dt_check = datatype;
int has_sp = libblis_test_dt_str_has_sp_char_str( n_operandsp1,
dc_str[dci] );
int has_dp = libblis_test_dt_str_has_dp_char_str( n_operandsp1,
dc_str[dci] );
int has_samep = (has_sp && !has_dp ) ||
(has_dp && !has_sp );
int has_cd_only =
!libblis_test_dt_str_has_rd_char_str( n_operands,
dc_str[dci] );
if ( has_sp )
{
dt_check = bli_dt_proj_to_single_prec( datatype );
}
libblis_test_build_col_labels_string( params, op, label_str );
if ( tdata->id == 0 )
{
libblis_test_fprintf( stdout, "%s\n", label_str );
if ( output_stream )
libblis_test_fprintf( output_stream, "%s\n", label_str );
}
ind_t ind_first = BLIS_NAT;
dim_t ind_last = BLIS_NAT;
if ( bli_opid_is_level3( op->opid ) && has_cd_only )
ind_first = 0;
for ( indi = ind_first; indi <= ind_last; ++indi )
{
if ( bli_is_real( datatype ) ) { ; }
else if ( bli_ind_oper_is_impl( op->opid, indi ) &&
params->ind_enable[ indi ] == 1 )
{
if ( indi == BLIS_1M )
{
if ( op->opid == BLIS_GEMM && has_cd_only ) { ; }
else if ( has_samep && has_cd_only ) { ; }
else { continue; }
}
else { ; }
}
else { continue; }
bli_ind_oper_enable_only( op->opid, indi, datatype );
ind_str = ( char* )bli_ind_oper_get_avail_impl_string( op->opid, datatype );
for ( pci = 0; pci < n_param_combos; ++pci )
{
for ( p_cur = p_first, pi = 1; p_cur <= p_max; p_cur += p_inc, ++pi )
{
if ( tdata->xc % tdata->nt != tdata->id )
{
tdata->xc++;
continue;
}
f_exp( params,
op,
iface,
dc_str[dci],
pc_str[pci],
sc_str[sci],
p_cur,
&perf, &resid );
resid = bli_fabs( resid );
if ( resid == -0.0 ) resid = 0.0;
pass_str = libblis_test_get_string_for_result( resid,
dt_check,
thresh );
libblis_test_build_function_string( BLIS_FILEDATA_PREFIX_STR,
op->opid,
indi,
ind_str,
op_str,
is_mixed_dt,
dc_str[dci],
n_param_combos,
pc_str[pci],
sc_str[sci],
funcname_str );
n_spaces = MAX_FUNC_STRING_LENGTH - strlen( funcname_str );
fill_string_with_n_spaces( blank_str, n_spaces );
libblis_test_build_dims_string( op, p_cur, dims_str );
n_dims_print = libblis_test_get_n_dims_from_string( dims_str );
if ( params->output_matlab_format )
{
fprintf( stdout,
"%s%s( %3u, 1:%u ) = [%s %7.2lf %8.2le ]; %c %s\n",
funcname_str, blank_str, pi, n_dims_print + 2,
dims_str, perf, resid,
OUTPUT_COMMENT_CHAR,
pass_str );
if ( output_stream )
fprintf( output_stream,
"%s%s( %3u, 1:%u ) = [%s %7.2lf %8.2le ]; %c %s\n",
funcname_str, blank_str, pi, n_dims_print + 2,
dims_str, perf, resid,
OUTPUT_COMMENT_CHAR,
pass_str );
}
else
{
fprintf( stdout,
"%s%s %s %7.2lf %8.2le %s\n",
funcname_str, blank_str,
dims_str, perf, resid,
pass_str );
if ( output_stream )
fprintf( output_stream,
"%s%s %s %7.2lf %8.2le %s\n",
funcname_str, blank_str,
dims_str, perf, resid,
pass_str );
}
if ( reaction_to_failure == ON_FAILURE_SLEEP_CHAR )
{
if ( strstr( pass_str, BLIS_TEST_FAIL_STRING ) == pass_str )
libblis_test_sleep();
}
else if ( reaction_to_failure == ON_FAILURE_ABORT_CHAR )
{
if ( strstr( pass_str, BLIS_TEST_FAIL_STRING ) == pass_str )
libblis_test_abort();
}
tdata->xc += 1;
}
}
}
#ifndef BLIS_ENABLE_HPX
bli_pthread_barrier_wait( tdata->barrier );
#endif
if ( tdata->id == 0 )
{
libblis_test_fprintf( stdout, "\n" );
if ( output_stream )
libblis_test_fprintf( output_stream, "\n" );
}
}
}
free( chars_for_param );
for ( pci = 0; pci < n_param_combos; ++pci )
free( pc_str[pci] );
free( pc_str );
for ( sci = 0; sci < n_store_combos; ++sci )
free( sc_str[sci] );
free( sc_str );
free( chars_for_rddt );
free( chars_for_cddt );
free( chars_for_spdt );
free( chars_for_dpdt );
for ( dci = 0; dci < n_dt_combos; ++dci )
free( dc_str[dci] );
free( dc_str );
if ( output_stream )
libblis_test_fclose_ofile( output_stream );
if ( tdata->id == 0 )
op->test_done = TRUE;
#ifndef BLIS_ENABLE_HPX
bli_pthread_barrier_wait( tdata->barrier );
#endif
}
void libblis_test_build_function_string
(
char* prefix_str,
opid_t opid,
ind_t method,
char* ind_str,
char* op_str,
unsigned int is_mixed_dt,
char* dc_str,
unsigned int n_param_combos,
char* pc_str,
char* sc_str,
char* funcname_str
)
{
if ( is_mixed_dt == TRUE && opid == BLIS_GEMM )
sprintf( funcname_str, "%s_%s%s", prefix_str, dc_str, op_str );
else
sprintf( funcname_str, "%s_%c%s", prefix_str, dc_str[0], op_str );
if ( method != BLIS_NAT )
sprintf( &funcname_str[strlen(funcname_str)], "%s", ind_str );
if ( n_param_combos > 1 || strlen(pc_str) > 0 )
sprintf( &funcname_str[strlen(funcname_str)], "_%s_%s", pc_str, sc_str );
else
sprintf( &funcname_str[strlen(funcname_str)], "_%s", sc_str );
if ( strlen( funcname_str ) > MAX_FUNC_STRING_LENGTH )
libblis_test_printf_error( "Function name string length (%d) exceeds maximum (%d).\n",
strlen( funcname_str ), MAX_FUNC_STRING_LENGTH );
}
void libblis_test_build_dims_string( test_op_t* op,
dim_t p_cur,
char* dims_str )
{
unsigned int i;
if ( op->dimset == BLIS_TEST_DIMS_MF )
{
sprintf( dims_str, " %5u %5u",
( unsigned int )
libblis_test_get_dim_from_prob_size( op->dim_spec[0],
p_cur ),
( unsigned int ) op->dim_aux[0] );
}
else if ( op->dimset == BLIS_TEST_DIMS_K )
{
sprintf( dims_str, " %5u %5u %5u",
( unsigned int ) op->dim_aux[0],
( unsigned int ) op->dim_aux[1],
( unsigned int )
libblis_test_get_dim_from_prob_size( op->dim_spec[0],
p_cur ) );
}
else if ( op->dimset == BLIS_TEST_NO_DIMS )
{
sprintf( dims_str, " %5u %5u",
( unsigned int ) op->dim_aux[0],
( unsigned int ) op->dim_aux[1] );
}
else {
sprintf( dims_str, "%s", "" );
for ( i = 0; i < op->n_dims; ++i )
{
sprintf( &dims_str[strlen(dims_str)], " %5u",
( unsigned int )
libblis_test_get_dim_from_prob_size( op->dim_spec[i],
p_cur ) );
}
}
}
void libblis_test_build_col_labels_string( test_params_t* params, test_op_t* op, char* l_str )
{
unsigned int n_spaces;
char blank_str[64];
strcpy( l_str, "" );
if ( op->n_params > 0 )
{
sprintf( &l_str[strlen(l_str)], "%c %s_%s", OUTPUT_COMMENT_CHAR,
BLIS_FILEDATA_PREFIX_STR,
"<dt><op>_<params>_<stor>" );
}
else {
sprintf( &l_str[strlen(l_str)], "%c %s_%s", OUTPUT_COMMENT_CHAR,
BLIS_FILEDATA_PREFIX_STR,
"<dt><op>_<stor> " );
}
if ( params->output_matlab_format ) n_spaces = 11;
else n_spaces = 1;
fill_string_with_n_spaces( blank_str, n_spaces );
sprintf( &l_str[strlen(l_str)], "%s", blank_str );
if ( op->dimset == BLIS_TEST_DIMS_MNK ||
op->dimset == BLIS_TEST_DIMS_MN ||
op->dimset == BLIS_TEST_DIMS_MK ||
op->dimset == BLIS_TEST_DIMS_M ||
op->dimset == BLIS_TEST_DIMS_K ||
op->dimset == BLIS_TEST_DIMS_MF ||
op->dimset == BLIS_TEST_NO_DIMS )
sprintf( &l_str[strlen(l_str)], " %5s", "m" );
if ( op->dimset == BLIS_TEST_DIMS_MNK ||
op->dimset == BLIS_TEST_DIMS_MN ||
op->dimset == BLIS_TEST_DIMS_K ||
op->dimset == BLIS_TEST_DIMS_MF ||
op->dimset == BLIS_TEST_NO_DIMS )
sprintf( &l_str[strlen(l_str)], " %5s", "n" );
if ( op->dimset == BLIS_TEST_DIMS_MNK ||
op->dimset == BLIS_TEST_DIMS_MK ||
op->dimset == BLIS_TEST_DIMS_K )
sprintf( &l_str[strlen(l_str)], " %5s", "k" );
sprintf( &l_str[strlen(l_str)], "%s", " gflops resid result" );
}
void libblis_test_build_filename_string( char* prefix_str,
char* op_str,
char* funcname_str )
{
sprintf( funcname_str, "%s_%s.m", prefix_str, op_str );
}
void fill_string_with_n_spaces( char* str, unsigned int n_spaces )
{
unsigned int i;
sprintf( str, "%s", "" );
for ( i = 0; i < n_spaces; ++i )
sprintf( &str[i], " " );
}
void libblis_test_mobj_create( test_params_t* params, num_t dt, trans_t trans, char storage, dim_t m, dim_t n, obj_t* a )
{
dim_t gs = params->gs_spacing;
bool alignment = params->alignment;
siz_t elem_size = bli_dt_size( dt );
dim_t m_trans = m;
dim_t n_trans = n;
dim_t rs = 1; dim_t cs = 1;
bli_set_dims_with_trans( trans, m, n, &m_trans, &n_trans );
if ( storage == 'c' )
{
rs = 1;
cs = m_trans;
if ( alignment )
cs = bli_align_dim_to_size( cs, elem_size,
BLIS_HEAP_STRIDE_ALIGN_SIZE );
}
else if ( storage == 'r' )
{
rs = n_trans;
cs = 1;
if ( alignment )
rs = bli_align_dim_to_size( rs, elem_size,
BLIS_HEAP_STRIDE_ALIGN_SIZE );
}
else if ( storage == 'g' )
{
rs = gs;
cs = gs * m_trans;
if ( alignment )
cs = bli_align_dim_to_size( cs, elem_size,
BLIS_HEAP_STRIDE_ALIGN_SIZE );
}
else
{
libblis_test_printf_error( "Invalid storage character: %c\n", storage );
}
bli_obj_create( dt, m_trans, n_trans, rs, cs, a );
}
thrinfo_t* libblis_test_pobj_create( bszid_t bmult_id_m, bszid_t bmult_id_n, invdiag_t inv_diag, pack_t pack_schema, packbuf_t pack_buf, obj_t* a, obj_t* p, cntx_t* cntx )
{
bool does_inv_diag;
if ( inv_diag == BLIS_NO_INVERT_DIAG ) does_inv_diag = FALSE;
else does_inv_diag = TRUE;
rntm_t rntm = BLIS_RNTM_INITIALIZER;
cntl_t* cntl = bli_packm_cntl_create_node
(
NULL, NULL, bmult_id_m,
bmult_id_n,
does_inv_diag,
FALSE,
FALSE,
pack_schema,
pack_buf,
NULL );
thrinfo_t* thread = bli_l3_thrinfo_create( 0, &BLIS_SINGLE_COMM, NULL, &rntm, cntl );
bli_packm_blk_var1( a, p, cntx, cntl, thread );
bli_l3_cntl_free( NULL, cntl );
return thread;
}
void libblis_test_vobj_create( test_params_t* params, num_t dt, char storage, dim_t m, obj_t* x )
{
dim_t gs = params->gs_spacing;
if ( storage == 'c' ) bli_obj_create( dt, m, 1, 1, m, x );
else if ( storage == 'r' ) bli_obj_create( dt, 1, m, m, 1, x );
else if ( storage == 'j' ) bli_obj_create( dt, m, 1, gs, gs*m, x );
else if ( storage == 'i' ) bli_obj_create( dt, 1, m, gs*m, gs, x );
else
{
libblis_test_printf_error( "Invalid storage character: %c\n", storage );
}
}
void libblis_test_vobj_randomize( test_params_t* params, bool normalize, obj_t* x )
{
if ( params->rand_method == BLIS_TEST_RAND_REAL_VALUES )
bli_randv( x );
else bli_randnv( x );
if ( normalize )
{
num_t dt = bli_obj_dt( x );
num_t dt_r = bli_obj_dt_proj_to_real( x );
obj_t kappa;
obj_t kappa_r;
bli_obj_scalar_init_detached( dt, &kappa );
bli_obj_scalar_init_detached( dt_r, &kappa_r );
bli_normfv( x, &kappa_r );
libblis_test_ceil_pow2( &kappa_r );
bli_copysc( &kappa_r, &kappa );
bli_invscalv( &kappa, x );
}
}
void libblis_test_mobj_randomize( test_params_t* params, bool normalize, obj_t* a )
{
if ( params->rand_method == BLIS_TEST_RAND_REAL_VALUES )
bli_randm( a );
else bli_randnm( a );
if ( normalize )
{
#if 0#endif
num_t dt = bli_obj_dt( a );
num_t dt_r = bli_obj_dt_proj_to_real( a );
obj_t kappa;
obj_t kappa_r;
bli_obj_scalar_init_detached( dt, &kappa );
bli_obj_scalar_init_detached( dt_r, &kappa_r );
bli_norm1m( a, &kappa_r );
libblis_test_ceil_pow2( &kappa_r );
bli_copysc( &kappa_r, &kappa );
bli_invscalm( &kappa, a );
}
}
void libblis_test_ceil_pow2( obj_t* alpha )
{
double alpha_r;
double alpha_i;
bli_getsc( alpha, &alpha_r, &alpha_i );
alpha_r = pow( 2.0, ceil( log2( alpha_r ) ) );
bli_setsc( alpha_r, alpha_i, alpha );
}
void libblis_test_mobj_load_diag( test_params_t* params, obj_t* a )
{
bli_shiftd( &BLIS_TWO, a );
}
void libblis_test_init_strings( void )
{
strcpy( libblis_test_pass_string, BLIS_TEST_PASS_STRING );
strcpy( libblis_test_warn_string, BLIS_TEST_WARN_STRING );
strcpy( libblis_test_fail_string, BLIS_TEST_FAIL_STRING );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_SIDE], BLIS_TEST_PARAM_SIDE_CHARS );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_UPLO], BLIS_TEST_PARAM_UPLO_CHARS );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_UPLODE], BLIS_TEST_PARAM_UPLODE_CHARS );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_TRANS], BLIS_TEST_PARAM_TRANS_CHARS );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_CONJ], BLIS_TEST_PARAM_CONJ_CHARS );
strcpy( libblis_test_param_chars[BLIS_TEST_PARAM_DIAG], BLIS_TEST_PARAM_DIAG_CHARS );
strcpy( libblis_test_store_chars[BLIS_TEST_MATRIX_OPERAND], BLIS_TEST_MSTORE_CHARS );
strcpy( libblis_test_store_chars[BLIS_TEST_VECTOR_OPERAND], BLIS_TEST_VSTORE_CHARS );
}
void libblis_test_sleep( void )
{
int i;
libblis_test_printf_infoc( "Resuming in " );
for ( i = SECONDS_TO_SLEEP; i > 0; --i )
{
libblis_test_printf_info( "%d ", i );
bli_sleep(1);
}
libblis_test_printf_info( "\n" );
}
void libblis_test_abort( void )
{
abort();
}
void libblis_test_fopen_ofile( char* op_str, iface_t iface, FILE** output_stream )
{
char filename_str[ MAX_FILENAME_LENGTH ];
if ( iface == BLIS_TEST_MT_FRONT_END )
bli_check_error_code( BLIS_NOT_YET_IMPLEMENTED );
libblis_test_build_filename_string( BLIS_FILE_PREFIX_STR,
op_str,
filename_str );
*output_stream = fopen( filename_str, "wb" );
libblis_test_fopen_check_stream( filename_str, *output_stream );
}
void libblis_test_fclose_ofile( FILE* output_stream )
{
fclose( output_stream );
}
void libblis_test_fopen_check_stream( char* filename_str,
FILE* stream )
{
if ( stream == NULL )
{
libblis_test_printf_error( "Failed to open file %s. Check existence (if file is being read), permissions (if file is being overwritten), and/or storage limit.\n",
filename_str );
}
}
void libblis_test_read_next_line( char* buffer, FILE* input_stream )
{
char temp[ INPUT_BUFFER_SIZE ];
do
{
if ( fgets( temp, INPUT_BUFFER_SIZE-1, input_stream ) == NULL )
{
if ( feof( input_stream ) )
libblis_test_printf_error( "Error reading input file: encountered unexpected EOF." );
else
libblis_test_printf_error( "Error (non-EOF) reading input file." );
}
}
while ( temp[0] == INPUT_COMMENT_CHAR || temp[0] == '\n' ||
temp[0] == ' ' || temp[0] == '\t' );
strcpy( buffer, temp );
}
void libblis_test_fprintf( FILE* output_stream, char* message, ... )
{
va_list args;
va_start( args, message );
libblis_test_parse_message( output_stream, message, args );
va_end( args );
fflush( output_stream );
}
void libblis_test_fprintf_c( FILE* output_stream, char* message, ... )
{
va_list args;
fprintf( output_stream, "%c ", OUTPUT_COMMENT_CHAR );
va_start( args, message );
libblis_test_parse_message( output_stream, message, args );
va_end( args );
fflush( output_stream );
}
void libblis_test_printf_info( char* message, ... )
{
FILE* output_stream = stdout;
va_list args;
va_start( args, message );
libblis_test_parse_message( output_stream, message, args );
va_end( args );
fflush( output_stream );
}
void libblis_test_printf_infoc( char* message, ... )
{
FILE* output_stream = stdout;
va_list args;
fprintf( output_stream, "%c ", OUTPUT_COMMENT_CHAR );
va_start( args, message );
libblis_test_parse_message( output_stream, message, args );
va_end( args );
fflush( output_stream );
}
void libblis_test_printf_error( char* message, ... )
{
FILE* output_stream = stderr;
va_list args;
fprintf( output_stream, "%s: *** error ***: ", libblis_test_binary_name );
va_start( args, message );
libblis_test_parse_message( output_stream, message, args );
va_end( args );
fflush( output_stream );
exit(1);
}
void libblis_test_parse_message( FILE* output_stream, char* message, va_list args )
{
int c, cf;
char format_spec[8];
unsigned int the_uint;
int the_int;
double the_double;
char* the_string;
char the_char;
for ( c = 0; message[c] != '\0'; )
{
if ( message[c] != '%' )
{
fprintf( output_stream, "%c", message[c] );
c += 1;
}
else if ( message[c] == '%' && message[c+1] == '%' ) {
fprintf( output_stream, "%c", message[c] );
c += 2;
}
else
{
format_spec[0] = '%';
for ( c += 1, cf = 1; strchr( "udefsc", message[c] ) == NULL; ++c, ++cf )
{
format_spec[cf] = message[c];
}
format_spec[cf] = message[c];
format_spec[cf+1] = '\0';
switch ( message[c] )
{
case 'u':
the_uint = va_arg( args, unsigned int );
fprintf( output_stream, format_spec, the_uint );
break;
case 'd':
the_int = va_arg( args, int );
fprintf( output_stream, format_spec, the_int );
break;
case 'e':
the_double = va_arg( args, double );
fprintf( output_stream, format_spec, the_double );
break;
case 'f':
the_double = va_arg( args, double );
fprintf( output_stream, format_spec, the_double );
break;
case 's':
the_string = va_arg( args, char* );
fprintf( output_stream, format_spec, the_string );
break;
case 'c':
the_char = va_arg( args, int );
fprintf( output_stream, "%c", the_char );
break;
}
c += 1;
}
}
}
void libblis_test_parse_command_line( int argc, char** argv )
{
bool gave_option_g = FALSE;
bool gave_option_o = FALSE;
int opt;
char opt_ch;
getopt_t state;
strncpy( libblis_test_binary_name, argv[0], MAX_BINARY_NAME_LENGTH );
bli_getopt_init_state( 0, &state );
while( (opt = bli_getopt( argc, ( const char** )argv, "g:o:q", &state )) != -1 )
{
opt_ch = ( char )opt;
switch( opt_ch )
{
case 'g':
strncpy( libblis_test_parameters_filename,
state.optarg, MAX_FILENAME_LENGTH );
gave_option_g = TRUE;
break;
case 'o':
strncpy( libblis_test_operations_filename,
state.optarg, MAX_FILENAME_LENGTH );
gave_option_o = TRUE;
break;
case 'q':
libblis_test_quiet_mode = TRUE;
break;
case '?':
libblis_test_printf_error( "unexpected option '%c' given or missing option argument\n", state.optopt );
break;
default:
libblis_test_printf_error( "unexpected option chararcter returned from getopt: %c\n", opt_ch );
}
}
if ( gave_option_g == FALSE )
{
if ( !libblis_test_quiet_mode )
libblis_test_printf_infoc( "no -g option given; defaulting to \"%s\" for parameters filename.\n", PARAMETERS_FILENAME );
strncpy( libblis_test_parameters_filename,
PARAMETERS_FILENAME, MAX_FILENAME_LENGTH );
}
else
{
if ( !libblis_test_quiet_mode )
libblis_test_printf_infoc( "detected -g option; using \"%s\" for parameters filename.\n", state.optarg );
}
if ( gave_option_o == FALSE )
{
if ( !libblis_test_quiet_mode )
libblis_test_printf_infoc( "no -o option given; defaulting to \"%s\" for operations filename.\n", OPERATIONS_FILENAME );
strncpy( libblis_test_operations_filename,
OPERATIONS_FILENAME, MAX_FILENAME_LENGTH );
}
else
{
if ( !libblis_test_quiet_mode )
libblis_test_printf_infoc( "detected -o option; using \"%s\" for operations filename.\n", state.optarg );
}
if ( state.optind < argc )
{
libblis_test_printf_error( "Encountered unexpected non-option argument: %s\n", argv[ state.optind ] );
}
}
void libblis_test_check_empty_problem( obj_t* c, double* perf, double* resid )
{
if ( bli_obj_has_zero_dim( c ) )
{
*perf = 0.0;
*resid = 0.0;
}
}
int libblis_test_op_is_disabled( test_op_t* op )
{
int r_val;
if ( op->ops->indiv_over == TRUE )
{
if ( op->op_switch != ENABLE_ONLY ) r_val = TRUE;
else r_val = FALSE;
}
else {
if ( op->op_switch == DISABLE ) r_val = TRUE;
else r_val = FALSE;
}
return r_val;
}
bool libblis_test_op_is_done( test_op_t* op )
{
return op->test_done;
}
int libblis_test_util_is_disabled( test_op_t* op )
{
if ( op->ops->util_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l1v_is_disabled( test_op_t* op )
{
if ( op->ops->l1v_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l1m_is_disabled( test_op_t* op )
{
if ( op->ops->l1m_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l1f_is_disabled( test_op_t* op )
{
if ( op->ops->l1f_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l2_is_disabled( test_op_t* op )
{
if ( op->ops->l2_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l3ukr_is_disabled( test_op_t* op )
{
if ( op->ops->l3ukr_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_l3_is_disabled( test_op_t* op )
{
if ( op->ops->l3_over == DISABLE ) return TRUE;
else return FALSE;
}
int libblis_test_dt_str_has_sp_char( test_params_t* params )
{
return libblis_test_dt_str_has_sp_char_str( params->n_datatypes,
params->datatype_char );
}
int libblis_test_dt_str_has_sp_char_str( int n, char* str )
{
for ( int i = 0; i < n; ++i )
{
if ( str[i] == 's' ||
str[i] == 'c' ) return TRUE;
}
return FALSE;
}
int libblis_test_dt_str_has_dp_char( test_params_t* params )
{
return libblis_test_dt_str_has_dp_char_str( params->n_datatypes,
params->datatype_char );
}
int libblis_test_dt_str_has_dp_char_str( int n, char* str )
{
for ( int i = 0; i < n; ++i )
{
if ( str[i] == 'd' ||
str[i] == 'z' ) return TRUE;
}
return FALSE;
}
int libblis_test_dt_str_has_rd_char( test_params_t* params )
{
return libblis_test_dt_str_has_rd_char_str( params->n_datatypes,
params->datatype_char );
}
int libblis_test_dt_str_has_rd_char_str( int n, char* str )
{
for ( int i = 0; i < n; ++i )
{
if ( str[i] == 's' ||
str[i] == 'd' ) return TRUE;
}
return FALSE;
}
int libblis_test_dt_str_has_cd_char( test_params_t* params )
{
return libblis_test_dt_str_has_cd_char_str( params->n_datatypes,
params->datatype_char );
}
int libblis_test_dt_str_has_cd_char_str( int n, char* str )
{
for ( int i = 0; i < n; ++i )
{
if ( str[i] == 'c' ||
str[i] == 'z' ) return TRUE;
}
return FALSE;
}
unsigned int libblis_test_count_combos
(
unsigned int n_operands,
char* spec_str,
char** char_sets
)
{
unsigned int n_combos = 1;
for ( int i = 0; i < n_operands; ++i )
{
if ( spec_str[i] == '?' )
n_combos *= strlen( char_sets[i] );
}
return n_combos;
}
char libblis_test_proj_dtchar_to_precchar( char dt_char )
{
char r_val = dt_char;
if ( r_val == 'c' ) r_val = 's';
else if ( r_val == 'z' ) r_val = 'd';
return r_val;
}