void libblis_test_axpyv_check ( test_params_t* params, obj_t* alpha, obj_t* x, obj_t* y, obj_t* y_orig, double* resid ) { num_t dt = bli_obj_dt( y ); num_t dt_real = bli_obj_dt_proj_to_real( y ); dim_t m = bli_obj_vector_dim( y ); obj_t x_temp, y_temp; obj_t norm; double junk; // // Pre-conditions: // - x is randomized. // - y_orig is randomized. // Note: // - alpha should have a non-zero imaginary component in the complex // cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := y_orig + alpha * conjx(x) // // is functioning correctly if // // normf( y - ( y_orig + alpha * conjx(x) ) ) // // is negligible. // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_create( dt, m, 1, 0, 0, &x_temp ); bli_obj_create( dt, m, 1, 0, 0, &y_temp ); bli_copyv( x, &x_temp ); bli_copyv( y_orig, &y_temp ); bli_scalv( alpha, &x_temp ); bli_addv( &x_temp, &y_temp ); bli_subv( &y_temp, y ); bli_normfv( y, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &x_temp ); bli_obj_free( &y_temp ); }
void libblis_test_hemv_check( obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y, obj_t* y_orig, double* resid ) { num_t dt = bli_obj_datatype( *y ); num_t dt_real = bli_obj_datatype_proj_to_real( *y ); dim_t m = bli_obj_vector_dim( *y ); obj_t v; obj_t norm; double junk; // // Pre-conditions: // - a is randomized and Hermitian. // - x is randomized. // - y_orig is randomized. // Note: // - alpha and beta should have non-zero imaginary components in the // complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := beta * y_orig + alpha * conja(A) * conjx(x) // // is functioning correctly if // // normf( y - v ) // // is negligible, where // // v = beta * y_orig + alpha * conja(A_dense) * x // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_copyv( y_orig, &v ); bli_mkherm( a ); bli_obj_set_struc( BLIS_GENERAL, *a ); bli_obj_set_uplo( BLIS_DENSE, *a ); bli_gemv( alpha, a, x, beta, &v ); bli_subv( &v, y ); bli_normfv( y, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &v ); }
void libblis_test_scalv_check ( test_params_t* params, obj_t* beta, obj_t* y, obj_t* y_orig, double* resid ) { num_t dt = bli_obj_dt( y ); num_t dt_real = bli_obj_dt_proj_to_real( y ); dim_t m = bli_obj_vector_dim( y ); obj_t norm_y_r; obj_t nbeta; obj_t y2; double junk; // // Pre-conditions: // - y_orig is randomized. // Note: // - beta should have a non-zero imaginary component in the complex // cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := conjbeta(beta) * y_orig // // is functioning correctly if // // normf( y + -conjbeta(beta) * y_orig ) // // is negligible. // bli_obj_create( dt, m, 1, 0, 0, &y2 ); bli_copyv( y_orig, &y2 ); bli_obj_scalar_init_detached( dt, &nbeta ); bli_obj_scalar_init_detached( dt_real, &norm_y_r ); bli_copysc( beta, &nbeta ); bli_mulsc( &BLIS_MINUS_ONE, &nbeta ); bli_scalv( &nbeta, &y2 ); bli_addv( &y2, y ); bli_normfv( y, &norm_y_r ); bli_getsc( &norm_y_r, resid, &junk ); bli_obj_free( &y2 ); }
void libblis_test_scalv_experiment ( test_params_t* params, test_op_t* op, iface_t iface, char* dc_str, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = DBL_MAX; double time; num_t datatype; dim_t m; conj_t conjbeta; obj_t beta, y; obj_t y_save; // Use the datatype of the first char in the datatype combination string. bli_param_map_char_to_blis_dt( dc_str[0], &datatype ); // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conjbeta ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &beta ); // Create test operands (vectors and/or matrices). libblis_test_vobj_create( params, datatype, sc_str[0], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[0], m, &y_save ); // Set beta. if ( bli_obj_is_real( &y ) ) bli_setsc( -2.0, 0.0, &beta ); else bli_setsc( 0.0, -2.0, &beta ); // Randomize and save y. libblis_test_vobj_randomize( params, FALSE, &y ); bli_copyv( &y, &y_save ); // Apply the parameters. bli_obj_set_conj( conjbeta, &beta ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copyv( &y_save, &y ); time = bli_clock(); libblis_test_scalv_impl( iface, &beta, &y ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 1.0 * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( &y ) ) *perf *= 6.0; // Perform checks. libblis_test_scalv_check( params, &beta, &y, &y_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); // Free the test objects. bli_obj_free( &y ); bli_obj_free( &y_save ); }
void libblis_test_gemv_check( obj_t* kappa, obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y, obj_t* y_orig, double* resid ) { num_t dt = bli_obj_datatype( *y ); num_t dt_real = bli_obj_datatype_proj_to_real( *y ); conj_t conja = bli_obj_conj_status( *a ); dim_t n_x = bli_obj_vector_dim( *x ); dim_t m_y = bli_obj_vector_dim( *y ); dim_t min_m_n = bli_min( m_y, n_x ); obj_t x_temp, y_temp; obj_t kappac, norm; obj_t xT_temp, yT_temp, yT; double junk; // // Pre-conditions: // - a is initialized to kappa along the diagonal. // - x is randomized. // - y_orig is randomized. // Note: // - alpha, beta, and kappa should have non-zero imaginary components in // the complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := beta * y_orig + alpha * transa(A) * conjx(x) // // is functioning correctly if // // normf( y - z ) // // is negligible, where // // z = beta * y_orig + alpha * conja(kappa) * x // bli_obj_scalar_init_detached_copy_of( dt, conja, kappa, &kappac ); bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_create( dt, n_x, 1, 0, 0, &x_temp ); bli_obj_create( dt, m_y, 1, 0, 0, &y_temp ); bli_copyv( x, &x_temp ); bli_copyv( y_orig, &y_temp ); bli_acquire_vpart_f2b( BLIS_SUBPART1, 0, min_m_n, &x_temp, &xT_temp ); bli_acquire_vpart_f2b( BLIS_SUBPART1, 0, min_m_n, &y_temp, &yT_temp ); bli_acquire_vpart_f2b( BLIS_SUBPART1, 0, min_m_n, y, &yT ); bli_scalv( &kappac, &xT_temp ); bli_scalv( beta, &yT_temp ); bli_axpyv( alpha, &xT_temp, &yT_temp ); bli_subv( &yT_temp, &yT ); bli_normfv( &yT, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &x_temp ); bli_obj_free( &y_temp ); }
void libblis_test_gemv_experiment( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m, n; trans_t transa; conj_t conjx; obj_t kappa; obj_t alpha, a, x, beta, y; obj_t y_save; // Map the dimension specifier to actual dimensions. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); n = libblis_test_get_dim_from_prob_size( op->dim_spec[1], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_trans( pc_str[0], &transa ); bli_param_map_char_to_blis_conj( pc_str[1], &conjx ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &kappa ); bli_obj_scalar_init_detached( datatype, &alpha ); bli_obj_scalar_init_detached( datatype, &beta ); // Create test operands (vectors and/or matrices). libblis_test_mobj_create( params, datatype, transa, sc_str[0], m, n, &a ); libblis_test_vobj_create( params, datatype, sc_str[1], n, &x ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y_save ); // Set alpha and beta. if ( bli_obj_is_real( y ) ) { bli_setsc( 2.0, 0.0, &alpha ); bli_setsc( -1.0, 0.0, &beta ); } else { bli_setsc( 0.0, 2.0, &alpha ); bli_setsc( 0.0, -1.0, &beta ); } // Initialize diagonal of matrix A. bli_setsc( 2.0, -1.0, &kappa ); bli_setm( &BLIS_ZERO, &a ); bli_setd( &kappa, &a ); // Randomize x and y, and save y. bli_randv( &x ); bli_randv( &y ); bli_copyv( &y, &y_save ); // Apply the parameters. bli_obj_set_conjtrans( transa, a ); bli_obj_set_conj( conjx, x ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copym( &y_save, &y ); time = bli_clock(); libblis_test_gemv_impl( iface, &alpha, &a, &x, &beta, &y ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m * n ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( y ) ) *perf *= 4.0; // Perform checks. libblis_test_gemv_check( &kappa, &alpha, &a, &x, &beta, &y, &y_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); // Free the test objects. bli_obj_free( &a ); bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &y_save ); }
void libblis_test_dotaxpyv_check( obj_t* alpha, obj_t* xt, obj_t* x, obj_t* y, obj_t* rho, obj_t* z, obj_t* z_orig, double* resid ) { num_t dt = bli_obj_datatype( *z ); num_t dt_real = bli_obj_datatype_proj_to_real( *z ); dim_t m = bli_obj_vector_dim( *z ); obj_t rho_temp; obj_t z_temp; obj_t norm_z; double resid1, resid2; double junk; // // Pre-conditions: // - x is randomized. // - y is randomized. // - z_orig is randomized. // - xt is an alias to x. // Note: // - alpha should have a non-zero imaginary component in the complex // cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // rho := conjxt(x^T) conjy(y) // z := z_orig + alpha * conjx(x) // // is functioning correctly if // // ( rho - rho_temp ) // // and // // normf( z - z_temp ) // // are negligible, where rho_temp and z_temp contain rho and z as // computed by dotv and axpyv, respectively. // bli_obj_scalar_init_detached( dt, &rho_temp ); bli_obj_scalar_init_detached( dt_real, &norm_z ); bli_obj_create( dt, m, 1, 0, 0, &z_temp ); bli_copyv( z_orig, &z_temp ); bli_dotv( xt, y, &rho_temp ); bli_axpyv( alpha, x, &z_temp ); bli_subsc( rho, &rho_temp ); bli_getsc( &rho_temp, &resid1, &junk ); bli_subv( &z_temp, z ); bli_normfv( z, &norm_z ); bli_getsc( &norm_z, &resid2, &junk ); *resid = bli_fmaxabs( resid1, resid2 ); bli_obj_free( &z_temp ); }
int main( int argc, char** argv ) { obj_t alpha, beta, gamma; obj_t x, y, z, w, a; num_t dt; dim_t m, n; inc_t rs, cs; // // This file demonstrates working with vector objects and the level-1v // operations. // // // Example 1: Create vector objects and then broadcast (copy) scalar // values to all elements. // printf( "\n#\n# -- Example 1 --\n#\n\n" ); // Create a few vectors to work with. We make them all of the same length // so that we can perform operations between them. // NOTE: We've chosen to use row vectors here (1x4) instead of column // vectors (4x1) to allow for easier reading of standard output (less // scrolling). dt = BLIS_DOUBLE; m = 1; n = 4; rs = 0; cs = 0; bli_obj_create( dt, m, n, rs, cs, &x ); bli_obj_create( dt, m, n, rs, cs, &y ); bli_obj_create( dt, m, n, rs, cs, &z ); bli_obj_create( dt, m, n, rs, cs, &w ); bli_obj_create( dt, m, n, rs, cs, &a ); // Let's also create and initialize some scalar objects. bli_obj_create_1x1( dt, &alpha ); bli_obj_create_1x1( dt, &beta ); bli_obj_create_1x1( dt, &gamma ); bli_setsc( 2.0, 0.0, &alpha ); bli_setsc( 0.2, 0.0, &beta ); bli_setsc( 3.0, 0.0, &gamma ); bli_printm( "alpha:", &alpha, "%4.1f", "" ); bli_printm( "beta:", &beta, "%4.1f", "" ); bli_printm( "gamma:", &gamma, "%4.1f", "" ); // Vectors can set by "broadcasting" a constant to every element. bli_setv( &BLIS_ONE, &x ); bli_setv( &alpha, &y ); bli_setv( &BLIS_ZERO, &z ); // Note that we can use printv or printm to print vectors since vectors // are also matrices. We choose to use printm because it honors the // orientation of the vector (row or column) when printing, whereas // printv always prints vectors as column vectors regardless of their // they are 1 x n or n x 1. bli_printm( "x := 1.0", &x, "%4.1f", "" ); bli_printm( "y := alpha", &y, "%4.1f", "" ); bli_printm( "z := 0.0", &z, "%4.1f", "" ); // // Example 2: Randomize a vector object. // printf( "\n#\n# -- Example 2 --\n#\n\n" ); // Set a vector to random values. bli_randv( &w ); bli_printm( "w := randv()", &w, "%4.1f", "" ); // // Example 3: Perform various element-wise operations on vector objects. // printf( "\n#\n# -- Example 3 --\n#\n\n" ); // Copy a vector. bli_copyv( &w, &a ); bli_printm( "a := w", &a, "%4.1f", "" ); // Add and subtract vectors. bli_addv( &y, &a ); bli_printm( "a := a + y", &a, "%4.1f", "" ); bli_subv( &w, &a ); bli_printm( "a := a - w", &a, "%4.1f", "" ); // Scale a vector (destructive). bli_scalv( &beta, &a ); bli_printm( "a := beta * a", &a, "%4.1f", "" ); // Scale a vector (non-destructive). bli_scal2v( &gamma, &a, &z ); bli_printm( "z := gamma * a", &z, "%4.1f", "" ); // Scale and accumulate between vectors. bli_axpyv( &alpha, &w, &x ); bli_printm( "x := x + alpha * w", &x, "%4.1f", "" ); bli_xpbyv( &w, &BLIS_MINUS_ONE, &x ); bli_printm( "x := -1.0 * x + w", &x, "%4.1f", "" ); // Invert a vector element-wise. bli_invertv( &y ); bli_printm( "y := 1 / y", &y, "%4.1f", "" ); // Swap two vectors. bli_swapv( &x, &y ); bli_printm( "x (after swapping with y)", &x, "%4.1f", "" ); bli_printm( "y (after swapping with x)", &y, "%4.1f", "" ); // // Example 4: Perform contraction-like operations on vector objects. // printf( "\n#\n# -- Example 4 --\n#\n\n" ); // Perform a dot product. bli_dotv( &a, &z, &gamma ); bli_printm( "gamma := a * z (dot product)", &gamma, "%5.2f", "" ); // Perform an extended dot product. bli_dotxv( &alpha, &a, &z, &BLIS_ONE, &gamma ); bli_printm( "gamma := 1.0 * gamma + alpha * a * z (accumulate scaled dot product)", &gamma, "%5.2f", "" ); // Free the objects. bli_obj_free( &alpha ); bli_obj_free( &beta ); bli_obj_free( &gamma ); bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &z ); bli_obj_free( &w ); bli_obj_free( &a ); return 0; }
void libblis_test_symv_experiment ( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = DBL_MAX; double time; dim_t m; uplo_t uploa; conj_t conja; conj_t conjx; obj_t alpha, a, x, beta, y; obj_t y_save; // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_uplo( pc_str[0], &uploa ); bli_param_map_char_to_blis_conj( pc_str[1], &conja ); bli_param_map_char_to_blis_conj( pc_str[2], &conjx ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha ); bli_obj_scalar_init_detached( datatype, &beta ); // Create test operands (vectors and/or matrices). libblis_test_mobj_create( params, datatype, BLIS_NO_TRANSPOSE, sc_str[0], m, m, &a ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &x ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y_save ); // Set alpha and beta. if ( bli_obj_is_real( &y ) ) { bli_setsc( 1.0, 0.0, &alpha ); bli_setsc( -1.0, 0.0, &beta ); } else { bli_setsc( 0.5, 0.5, &alpha ); bli_setsc( -0.5, 0.5, &beta ); } // Set the structure and uplo properties of A. bli_obj_set_struc( BLIS_SYMMETRIC, &a ); bli_obj_set_uplo( uploa, &a ); // Randomize A, make it densely symmetric, and zero the unstored triangle // to ensure the implementation reads only from the stored region. libblis_test_mobj_randomize( params, TRUE, &a ); bli_mksymm( &a ); bli_mktrim( &a ); // Randomize x and y, and save y. libblis_test_vobj_randomize( params, TRUE, &x ); libblis_test_vobj_randomize( params, TRUE, &y ); bli_copyv( &y, &y_save ); // Apply the remaining parameters. bli_obj_set_conj( conja, &a ); bli_obj_set_conj( conjx, &x ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copym( &y_save, &y ); time = bli_clock(); libblis_test_symv_impl( iface, &alpha, &a, &x, &beta, &y ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 1.0 * m * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( &y ) ) *perf *= 4.0; // Perform checks. libblis_test_symv_check( params, &alpha, &a, &x, &beta, &y, &y_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); // Free the test objects. bli_obj_free( &a ); bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &y_save ); }
void libblis_test_axpyv_experiment( test_params_t* params, test_op_t* op, mt_impl_t impl, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m; conj_t conjx; obj_t alpha, x, y; obj_t y_save; // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conjx ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha ); // Create test operands (vectors and/or matrices). libblis_test_vobj_create( params, datatype, sc_str[0], m, &x ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &y_save ); // Set alpha. //bli_setsc( sqrt(2.0)/2.0, sqrt(2.0)/2.0, &alpha ); //bli_copysc( &BLIS_TWO, &alpha ); if ( bli_obj_is_real( y ) ) bli_setsc( -2.0, 0.0, &alpha ); else bli_setsc( 0.0, -2.0, &alpha ); // Randomize x and y, and save y. bli_randv( &x ); bli_randv( &y ); bli_copyv( &y, &y_save ); // Apply the parameters. bli_obj_set_conj( conjx, x ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copyv( &y_save, &y ); time = bli_clock(); libblis_test_axpyv_impl( impl, &alpha, &x, &y ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( y ) ) *perf *= 4.0; // Perform checks. libblis_test_axpyv_check( &alpha, &x, &y, &y_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); // Free the test objects. bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &y_save ); }
void bli_hemv_unf_var3( conj_t conjh, obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y, hemv_t* cntl ) { num_t dt_a = bli_obj_datatype( *a ); num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); uplo_t uplo = bli_obj_uplo( *a ); conj_t conja = bli_obj_conj_status( *a ); conj_t conjx = bli_obj_conj_status( *x ); dim_t m = bli_obj_length( *a ); void* buf_a = bli_obj_buffer_at_off( *a ); inc_t rs_a = bli_obj_row_stride( *a ); inc_t cs_a = bli_obj_col_stride( *a ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t incx = bli_obj_vector_inc( *x ); void* buf_y = bli_obj_buffer_at_off( *y ); inc_t incy = bli_obj_vector_inc( *y ); num_t dt_alpha; void* buf_alpha; num_t dt_beta; void* buf_beta; FUNCPTR_T f; // The datatype of alpha MUST be the type union of a and x. This is to // prevent any unnecessary loss of information during computation. dt_alpha = bli_datatype_union( dt_a, dt_x ); buf_alpha = bli_obj_buffer_for_1x1( dt_alpha, *alpha ); // The datatype of beta MUST be the same as the datatype of y. dt_beta = dt_y; buf_beta = bli_obj_buffer_for_1x1( dt_beta, *beta ); #if 0 obj_t x_copy, y_copy; bli_obj_create( dt_x, m, 1, 0, 0, &x_copy ); bli_obj_create( dt_y, m, 1, 0, 0, &y_copy ); bli_copyv( x, &x_copy ); bli_copyv( y, &y_copy ); buf_x = bli_obj_buffer_at_off( x_copy ); buf_y = bli_obj_buffer_at_off( y_copy ); incx = 1; incy = 1; #endif // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_a][dt_x][dt_y]; // Invoke the function. f( uplo, conja, conjx, conjh, m, buf_alpha, buf_a, rs_a, cs_a, buf_x, incx, buf_beta, buf_y, incy ); #if 0 bli_copyv( &y_copy, y ); bli_obj_free( &x_copy ); bli_obj_free( &y_copy ); #endif }
void libblis_test_axpy2v_check( obj_t* alpha1, obj_t* alpha2, obj_t* x, obj_t* y, obj_t* z, obj_t* z_orig, double* resid ) { num_t dt = bli_obj_datatype( *z ); num_t dt_real = bli_obj_datatype_proj_to_real( *z ); dim_t m = bli_obj_vector_dim( *z ); obj_t x_temp, y_temp, z_temp; obj_t norm; double junk; // // Pre-conditions: // - x is randomized. // - y is randomized. // - z_orig is randomized. // Note: // - alpha1, alpha2 should have a non-zero imaginary component in the // complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // z := z_orig + alpha1 * conjx(x) + alpha2 * conjy(y) // // is functioning correctly if // // normf( z - v ) // // is negligible, where v contains z as computed by two calls to axpyv. // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_create( dt, m, 1, 0, 0, &x_temp ); bli_obj_create( dt, m, 1, 0, 0, &y_temp ); bli_obj_create( dt, m, 1, 0, 0, &z_temp ); bli_copyv( x, &x_temp ); bli_copyv( y, &y_temp ); bli_copyv( z_orig, &z_temp ); bli_scalv( alpha1, &x_temp ); bli_scalv( alpha2, &y_temp ); bli_addv( &x_temp, &z_temp ); bli_addv( &y_temp, &z_temp ); bli_subv( &z_temp, z ); bli_normfv( z, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &x_temp ); bli_obj_free( &y_temp ); bli_obj_free( &z_temp ); }
void libblis_test_axpy2v_experiment( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m; conj_t conjx, conjy; obj_t alpha1, alpha2, x, y, z; obj_t z_save; cntx_t cntx; // Initialize a context. bli_axpy2v_cntx_init( &cntx ); // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conjx ); bli_param_map_char_to_blis_conj( pc_str[1], &conjy ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha1 ); bli_obj_scalar_init_detached( datatype, &alpha2 ); // Create test operands (vectors and/or matrices). libblis_test_vobj_create( params, datatype, sc_str[0], m, &x ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &z ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &z_save ); // Set alpha. if ( bli_obj_is_real( z ) ) { bli_setsc( -1.0, 0.0, &alpha1 ); bli_setsc( -0.9, 0.0, &alpha2 ); } else { bli_setsc( 0.0, -1.0, &alpha1 ); bli_setsc( 0.0, -0.9, &alpha2 ); } // Randomize x and y, and save y. bli_randv( &x ); bli_randv( &y ); bli_randv( &z ); bli_copyv( &z, &z_save ); // Apply the parameters. bli_obj_set_conj( conjx, x ); bli_obj_set_conj( conjy, y ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copyv( &z_save, &z ); time = bli_clock(); libblis_test_axpy2v_impl( iface, &alpha1, &alpha2, &x, &y, &z, &cntx ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m + 2.0 * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( z ) ) *perf *= 4.0; // Perform checks. libblis_test_axpy2v_check( &alpha1, &alpha2, &x, &y, &z, &z_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &z, perf, resid ); // Free the test objects. bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &z ); bli_obj_free( &z_save ); // Finalize the context. bli_axpy2v_cntx_finalize( &cntx ); }
void libblis_test_dotxaxpyf_experiment ( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m, b_n; conj_t conjat, conja, conjw, conjx; obj_t alpha, at, a, w, x, beta, y, z; obj_t y_save, z_save; cntx_t cntx; // Initialize a context. bli_dotxaxpyf_cntx_init( &cntx ); // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Query the operation's fusing factor for the current datatype. b_n = bli_cntx_get_blksz_def_dt( datatype, BLIS_XF, &cntx ); // Store the fusing factor so that the driver can retrieve the value // later when printing results. op->dim_aux[0] = b_n; // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conjat ); bli_param_map_char_to_blis_conj( pc_str[1], &conja ); bli_param_map_char_to_blis_conj( pc_str[2], &conjw ); bli_param_map_char_to_blis_conj( pc_str[3], &conjx ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha ); bli_obj_scalar_init_detached( datatype, &beta ); // Create test operands (vectors and/or matrices). libblis_test_mobj_create( params, datatype, BLIS_NO_TRANSPOSE, sc_str[0], m, b_n, &a ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &w ); libblis_test_vobj_create( params, datatype, sc_str[2], b_n, &x ); libblis_test_vobj_create( params, datatype, sc_str[3], b_n, &y ); libblis_test_vobj_create( params, datatype, sc_str[3], b_n, &y_save ); libblis_test_vobj_create( params, datatype, sc_str[4], m, &z ); libblis_test_vobj_create( params, datatype, sc_str[4], m, &z_save ); // Set alpha. if ( bli_obj_is_real( y ) ) { bli_setsc( 1.2, 0.0, &alpha ); bli_setsc( -1.0, 0.0, &beta ); } else { bli_setsc( 1.2, 0.1, &alpha ); bli_setsc( -1.0, -0.1, &beta ); } // Randomize A, w, x, y, and z, and save y and z. libblis_test_mobj_randomize( params, FALSE, &a ); libblis_test_vobj_randomize( params, FALSE, &w ); libblis_test_vobj_randomize( params, FALSE, &x ); libblis_test_vobj_randomize( params, FALSE, &y ); libblis_test_vobj_randomize( params, FALSE, &z ); bli_copyv( &y, &y_save ); bli_copyv( &z, &z_save ); // Create an alias to a for at. (Note that it should NOT actually be // marked for transposition since the transposition is part of the dotxf // subproblem.) bli_obj_alias_to( a, at ); // Apply the parameters. bli_obj_set_conj( conjat, at ); bli_obj_set_conj( conja, a ); bli_obj_set_conj( conjw, w ); bli_obj_set_conj( conjx, x ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copyv( &y_save, &y ); bli_copyv( &z_save, &z ); time = bli_clock(); libblis_test_dotxaxpyf_impl( iface, &alpha, &at, &a, &w, &x, &beta, &y, &z, &cntx ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m * b_n + 2.0 * m * b_n ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( y ) ) *perf *= 4.0; // Perform checks. libblis_test_dotxaxpyf_check( params, &alpha, &at, &a, &w, &x, &beta, &y, &z, &y_save, &z_save, resid ); // Zero out performance and residual if either output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); libblis_test_check_empty_problem( &z, perf, resid ); // Free the test objects. bli_obj_free( &a ); bli_obj_free( &w ); bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &z ); bli_obj_free( &y_save ); bli_obj_free( &z_save ); // Finalize the context. bli_dotxaxpyf_cntx_finalize( &cntx ); }
void libblis_test_trmm3_check( side_t side, obj_t* alpha, obj_t* a, obj_t* b, obj_t* beta, obj_t* c, obj_t* c_orig, double* resid ) { num_t dt = bli_obj_datatype( *c ); num_t dt_real = bli_obj_datatype_proj_to_real( *c ); dim_t m = bli_obj_length( *c ); dim_t n = bli_obj_width( *c ); obj_t kappa, norm; obj_t t, v, w, z; double junk; // // Pre-conditions: // - a is randomized and triangular. // - b is randomized. // - c_orig is randomized. // Note: // - alpha and beta should have non-zero imaginary components in the // complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // C := beta * C_orig + alpha * transa(A) * transb(B) (side = left) // C := beta * C_orig + alpha * transb(B) * transa(A) (side = right) // // is functioning correctly if // // fnorm( v - z ) // // is negligible, where // // v = C * t // // z = ( beta * C_orig + alpha * transa(A) * transb(B) ) * t (side = left) // = beta * C_orig * t + alpha * transa(A) * transb(B) * t // = beta * C_orig * t + alpha * transa(A) * w // = beta * C_orig * t + z // // z = ( beta * C_orig + alpha * transb(B) * transa(A) ) * t (side = right) // = beta * C_orig * t + alpha * transb(B) * transa(A) * t // = beta * C_orig * t + alpha * transb(B) * w // = beta * C_orig * t + z bli_obj_scalar_init_detached( dt, &kappa ); bli_obj_scalar_init_detached( dt_real, &norm ); if ( bli_is_left( side ) ) { bli_obj_create( dt, n, 1, 0, 0, &t ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_obj_create( dt, m, 1, 0, 0, &w ); bli_obj_create( dt, m, 1, 0, 0, &z ); } else // else if ( bli_is_left( side ) ) { bli_obj_create( dt, n, 1, 0, 0, &t ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_obj_create( dt, n, 1, 0, 0, &w ); bli_obj_create( dt, m, 1, 0, 0, &z ); } bli_randv( &t ); bli_setsc( 1.0/( double )n, 0.0, &kappa ); bli_scalv( &kappa, &t ); bli_gemv( &BLIS_ONE, c, &t, &BLIS_ZERO, &v ); if ( bli_is_left( side ) ) { bli_gemv( &BLIS_ONE, b, &t, &BLIS_ZERO, &w ); bli_trmv( alpha, a, &w ); bli_copyv( &w, &z ); } else { bli_copyv( &t, &w ); bli_trmv( &BLIS_ONE, a, &w ); bli_gemv( alpha, b, &w, &BLIS_ZERO, &z ); } bli_gemv( beta, c_orig, &t, &BLIS_ONE, &z ); bli_subv( &z, &v ); bli_fnormv( &v, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &t ); bli_obj_free( &v ); bli_obj_free( &w ); bli_obj_free( &z ); }
void libblis_test_dotxaxpyf_check ( test_params_t* params, obj_t* alpha, obj_t* at, obj_t* a, obj_t* w, obj_t* x, obj_t* beta, obj_t* y, obj_t* z, obj_t* y_orig, obj_t* z_orig, double* resid ) { num_t dt = bli_obj_datatype( *y ); num_t dt_real = bli_obj_datatype_proj_to_real( *y ); dim_t m = bli_obj_vector_dim( *z ); dim_t b_n = bli_obj_vector_dim( *y ); dim_t i; obj_t a1, chi1, psi1, v, q; obj_t alpha_chi1; obj_t norm; double resid1, resid2; double junk; // // Pre-conditions: // - a is randomized. // - w is randomized. // - x is randomized. // - y is randomized. // - z is randomized. // - at is an alias to a. // Note: // - alpha and beta should have a non-zero imaginary component in the // complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := beta * y_orig + alpha * conjat(A^T) * conjw(w) // z := z_orig + alpha * conja(A) * conjx(x) // // is functioning correctly if // // normf( y - v ) // // and // // normf( z - q ) // // are negligible, where v and q contain y and z as computed by repeated // calls to dotxv and axpyv, respectively. // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_scalar_init_detached( dt, &alpha_chi1 ); bli_obj_create( dt, b_n, 1, 0, 0, &v ); bli_obj_create( dt, m, 1, 0, 0, &q ); bli_copyv( y_orig, &v ); bli_copyv( z_orig, &q ); // v := beta * v + alpha * conjat(at) * conjw(w) for ( i = 0; i < b_n; ++i ) { bli_acquire_mpart_l2r( BLIS_SUBPART1, i, 1, at, &a1 ); bli_acquire_vpart_f2b( BLIS_SUBPART1, i, 1, &v, &psi1 ); bli_dotxv( alpha, &a1, w, beta, &psi1 ); } // q := q + alpha * conja(a) * conjx(x) for ( i = 0; i < b_n; ++i ) { bli_acquire_mpart_l2r( BLIS_SUBPART1, i, 1, a, &a1 ); bli_acquire_vpart_f2b( BLIS_SUBPART1, i, 1, x, &chi1 ); bli_copysc( &chi1, &alpha_chi1 ); bli_mulsc( alpha, &alpha_chi1 ); bli_axpyv( &alpha_chi1, &a1, &q ); } bli_subv( y, &v ); bli_normfv( &v, &norm ); bli_getsc( &norm, &resid1, &junk ); bli_subv( z, &q ); bli_normfv( &q, &norm ); bli_getsc( &norm, &resid2, &junk ); *resid = bli_fmaxabs( resid1, resid2 ); bli_obj_free( &v ); bli_obj_free( &q ); }
void libblis_test_axpyf_experiment( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m, b_n; conj_t conja, conjx; obj_t alpha, a, x, y; obj_t y_save; // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Query the operation's fusing factor for the current datatype. b_n = bli_axpyf_fusefac( datatype ); // Store the fusing factor so that the driver can retrieve the value // later when printing results. op->dim_aux[0] = b_n; // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conja ); bli_param_map_char_to_blis_conj( pc_str[1], &conjx ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha ); // Create test operands (vectors and/or matrices). libblis_test_mobj_create( params, datatype, BLIS_NO_TRANSPOSE, sc_str[0], m, b_n, &a ); libblis_test_vobj_create( params, datatype, sc_str[1], b_n, &x ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &y_save ); // Set alpha. if ( bli_obj_is_real( y ) ) { bli_setsc( -1.0, 0.0, &alpha ); } else { bli_setsc( 0.0, -1.0, &alpha ); } // Randomize A, x, and y, and save y. bli_randm( &a ); bli_randv( &x ); bli_randv( &y ); bli_copyv( &y, &y_save ); // Apply the parameters. bli_obj_set_conj( conja, a ); bli_obj_set_conj( conjx, x ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copyv( &y_save, &y ); time = bli_clock(); libblis_test_axpyf_impl( iface, &alpha, &a, &x, &y ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m * b_n ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( y ) ) *perf *= 4.0; // Perform checks. libblis_test_axpyf_check( &alpha, &a, &x, &y, &y_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &y, perf, resid ); // Free the test objects. bli_obj_free( &a ); bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &y_save ); }
void libblis_test_trsm_check ( test_params_t* params, side_t side, obj_t* alpha, obj_t* a, obj_t* b, obj_t* b_orig, double* resid ) { num_t dt = bli_obj_datatype( *b ); num_t dt_real = bli_obj_datatype_proj_to_real( *b ); dim_t m = bli_obj_length( *b ); dim_t n = bli_obj_width( *b ); obj_t norm; obj_t t, v, w, z; double junk; // // Pre-conditions: // - a is randomized and triangular. // - b_orig is randomized. // Note: // - alpha should have a non-zero imaginary component in the // complex cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // B := alpha * inv(transa(A)) * B_orig (side = left) // B := alpha * B_orig * inv(transa(A)) (side = right) // // is functioning correctly if // // normf( v - z ) // // is negligible, where // // v = B * t // // z = ( alpha * inv(transa(A)) * B ) * t (side = left) // = alpha * inv(transa(A)) * B * t // = alpha * inv(transa(A)) * w // // z = ( alpha * B * inv(transa(A)) ) * t (side = right) // = alpha * B * tinv(ransa(A)) * t // = alpha * B * w bli_obj_scalar_init_detached( dt_real, &norm ); if ( bli_is_left( side ) ) { bli_obj_create( dt, n, 1, 0, 0, &t ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_obj_create( dt, m, 1, 0, 0, &w ); bli_obj_create( dt, m, 1, 0, 0, &z ); } else // else if ( bli_is_left( side ) ) { bli_obj_create( dt, n, 1, 0, 0, &t ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_obj_create( dt, n, 1, 0, 0, &w ); bli_obj_create( dt, m, 1, 0, 0, &z ); } libblis_test_vobj_randomize( params, TRUE, &t ); bli_gemv( &BLIS_ONE, b, &t, &BLIS_ZERO, &v ); if ( bli_is_left( side ) ) { bli_gemv( alpha, b_orig, &t, &BLIS_ZERO, &w ); bli_trsv( &BLIS_ONE, a, &w ); bli_copyv( &w, &z ); } else { bli_copyv( &t, &w ); bli_trsv( &BLIS_ONE, a, &w ); bli_gemv( alpha, b_orig, &w, &BLIS_ZERO, &z ); } bli_subv( &z, &v ); bli_normfv( &v, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &t ); bli_obj_free( &v ); bli_obj_free( &w ); bli_obj_free( &z ); }
void libblis_test_axpyf_check( obj_t* alpha, obj_t* a, obj_t* x, obj_t* y, obj_t* y_orig, double* resid ) { num_t dt = bli_obj_datatype( *y ); num_t dt_real = bli_obj_datatype_proj_to_real( *y ); dim_t m = bli_obj_vector_dim( *y ); dim_t b_n = bli_obj_width( *a ); dim_t i; obj_t a1, chi1, v; obj_t alpha_chi1; obj_t norm; double junk; // // Pre-conditions: // - a is randomized. // - x is randomized. // - y is randomized. // Note: // - alpha should have a non-zero imaginary component in the complex // cases in order to more fully exercise the implementation. // // Under these conditions, we assume that the implementation for // // y := y_orig + alpha * conja(A) * conjx(x) // // is functioning correctly if // // normf( y - v ) // // is negligible, where v contains y as computed by repeated calls to // axpyv. // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_scalar_init_detached( dt, &alpha_chi1 ); bli_obj_create( dt, m, 1, 0, 0, &v ); bli_copyv( y_orig, &v ); for ( i = 0; i < b_n; ++i ) { bli_acquire_mpart_l2r( BLIS_SUBPART1, i, 1, a, &a1 ); bli_acquire_vpart_f2b( BLIS_SUBPART1, i, 1, x, &chi1 ); bli_copysc( &chi1, &alpha_chi1 ); bli_mulsc( alpha, &alpha_chi1 ); bli_axpyv( &alpha_chi1, &a1, &v ); } bli_subv( y, &v ); bli_normfv( &v, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &v ); }
void libblis_test_trmv_experiment( test_params_t* params, test_op_t* op, mt_impl_t impl, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m; uplo_t uploa; trans_t transa; diag_t diaga; obj_t kappa; obj_t alpha, a, x; obj_t x_save; // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_uplo( pc_str[0], &uploa ); bli_param_map_char_to_blis_trans( pc_str[1], &transa ); bli_param_map_char_to_blis_diag( pc_str[2], &diaga ); // Create test scalars. bli_obj_init_scalar( datatype, &alpha ); bli_obj_init_scalar( datatype, &kappa ); // Create test operands (vectors and/or matrices). libblis_test_mobj_create( params, datatype, BLIS_NO_TRANSPOSE, sc_str[0], m, m, &a ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &x ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &x_save ); // Set alpha. if ( bli_obj_is_real( x ) ) bli_setsc( -1.0, 0.0, &alpha ); else bli_setsc( 0.0, -1.0, &alpha ); // Set the structure and uplo properties of A. bli_obj_set_struc( BLIS_TRIANGULAR, a ); bli_obj_set_uplo( uploa, a ); // Randomize A, make it densely triangular. bli_randm( &a ); bli_mktrim( &a ); // Randomize x and save. bli_randv( &x ); bli_copyv( &x, &x_save ); // Normalize vectors by m. bli_setsc( 1.0/( double )m, 0.0, &kappa ); bli_scalv( &kappa, &x ); bli_scalv( &kappa, &x_save ); // Apply the remaining parameters. bli_obj_set_conjtrans( transa, a ); bli_obj_set_diag( diaga, a ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copym( &x_save, &x ); time = bli_clock(); libblis_test_trmv_impl( impl, &alpha, &a, &x ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 1.0 * m * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( x ) ) *perf *= 4.0; // Perform checks. libblis_test_trmv_check( &alpha, &a, &x, &x_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &x, perf, resid ); // Free the test objects. bli_obj_free( &a ); bli_obj_free( &x ); bli_obj_free( &x_save ); }
void libblis_test_dotaxpyv_experiment( test_params_t* params, test_op_t* op, iface_t iface, num_t datatype, char* pc_str, char* sc_str, unsigned int p_cur, double* perf, double* resid ) { unsigned int n_repeats = params->n_repeats; unsigned int i; double time_min = 1e9; double time; dim_t m; conj_t conjxt, conjx, conjy; conj_t conjconjxty; obj_t alpha, xt, x, y, rho, z; obj_t z_save; // Map the dimension specifier to an actual dimension. m = libblis_test_get_dim_from_prob_size( op->dim_spec[0], p_cur ); // Map parameter characters to BLIS constants. bli_param_map_char_to_blis_conj( pc_str[0], &conjxt ); bli_param_map_char_to_blis_conj( pc_str[1], &conjx ); bli_param_map_char_to_blis_conj( pc_str[2], &conjy ); // Create test scalars. bli_obj_scalar_init_detached( datatype, &alpha ); bli_obj_scalar_init_detached( datatype, &rho ); // Create test operands (vectors and/or matrices). libblis_test_vobj_create( params, datatype, sc_str[0], m, &x ); libblis_test_vobj_create( params, datatype, sc_str[1], m, &y ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &z ); libblis_test_vobj_create( params, datatype, sc_str[2], m, &z_save ); // Set alpha. if ( bli_obj_is_real( z ) ) { bli_setsc( -0.8, 0.0, &alpha ); } else { bli_setsc( 0.0, -0.8, &alpha ); } // Randomize x and z, and save z. bli_randv( &x ); bli_randv( &z ); bli_copyv( &z, &z_save ); // Create an alias to x for xt. (Note that it doesn't actually need to be // transposed.) bli_obj_alias_to( x, xt ); // Determine whether to make a copy of x with or without conjugation. // // conjx conjy ~conjx^conjy y is initialized as // n n c y = conj(x) // n c n y = x // c n n y = x // c c c y = conj(x) // conjconjxty = bli_apply_conj( conjxt, conjy ); conjconjxty = bli_conj_toggled( conjconjxty ); bli_obj_set_conj( conjconjxty, xt ); bli_copyv( &xt, &y ); // Apply the parameters. bli_obj_set_conj( conjxt, xt ); bli_obj_set_conj( conjx, x ); bli_obj_set_conj( conjy, y ); // Repeat the experiment n_repeats times and record results. for ( i = 0; i < n_repeats; ++i ) { bli_copysc( &BLIS_MINUS_ONE, &rho ); bli_copyv( &z_save, &z ); time = bli_clock(); libblis_test_dotaxpyv_impl( iface, &alpha, &xt, &x, &y, &rho, &z ); time_min = bli_clock_min_diff( time_min, time ); } // Estimate the performance of the best experiment repeat. *perf = ( 2.0 * m + 2.0 * m ) / time_min / FLOPS_PER_UNIT_PERF; if ( bli_obj_is_complex( z ) ) *perf *= 4.0; // Perform checks. libblis_test_dotaxpyv_check( &alpha, &xt, &x, &y, &rho, &z, &z_save, resid ); // Zero out performance and residual if output vector is empty. libblis_test_check_empty_problem( &z, perf, resid ); // Free the test objects. bli_obj_free( &x ); bli_obj_free( &y ); bli_obj_free( &z ); bli_obj_free( &z_save ); }