void libblis_test_subv_check( obj_t* alpha, obj_t* beta, obj_t* x, obj_t* y, double* resid ) { num_t dt = bli_obj_datatype( *x ); num_t dt_real = bli_obj_datatype_proj_to_real( *x ); dim_t m = bli_obj_vector_dim( *x ); conj_t conjx = bli_obj_conj_status( *x ); obj_t aminusb; obj_t alpha_conj; obj_t norm_r, m_r, temp_r; double junk; // // Pre-conditions: // - x is set to alpha. // - y_orig is set to beta. // 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 := y_orig - conjx(x) // // is functioning correctly if // // normfv(y) - sqrt( absqsc( beta - conjx(alpha) ) * m ) // // is negligible. // bli_obj_scalar_init_detached( dt, &aminusb ); bli_obj_scalar_init_detached( dt_real, &temp_r ); bli_obj_scalar_init_detached( dt_real, &norm_r ); bli_obj_scalar_init_detached( dt_real, &m_r ); bli_obj_scalar_init_detached_copy_of( dt, conjx, alpha, &alpha_conj ); bli_normfv( y, &norm_r ); bli_copysc( beta, &aminusb ); bli_subsc( &alpha_conj, &aminusb ); bli_setsc( ( double )m, 0.0, &m_r ); bli_absqsc( &aminusb, &temp_r ); bli_mulsc( &m_r, &temp_r ); bli_sqrtsc( &temp_r, &temp_r ); bli_subsc( &temp_r, &norm_r ); bli_getsc( &norm_r, resid, &junk ); }
void bli_her2_basic_check( conj_t conjh, obj_t* alpha, obj_t* x, obj_t* y, obj_t* c ) { err_t e_val; // Check object datatypes. e_val = bli_check_noninteger_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( x ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( y ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( c ); bli_check_error_code( e_val ); // Check object dimensions. e_val = bli_check_scalar_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( x ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( y ); bli_check_error_code( e_val ); e_val = bli_check_matrix_object( c ); bli_check_error_code( e_val ); e_val = bli_check_square_object( c ); bli_check_error_code( e_val ); e_val = bli_check_object_length_equals( c, bli_obj_vector_dim( *x ) ); bli_check_error_code( e_val ); e_val = bli_check_object_length_equals( c, bli_obj_vector_dim( *y ) ); bli_check_error_code( e_val ); }
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_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 ); }
err_t bli_check_vector_dim_equals( obj_t* a, dim_t n ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_vector_dim( *a ) != n ) e_val = BLIS_UNEXPECTED_VECTOR_DIM; return e_val; }
void bli_dotxv_unb_var1( obj_t* alpha, obj_t* x, obj_t* y, obj_t* beta, obj_t* rho ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); num_t dt_rho = bli_obj_datatype( *rho ); conj_t conjx = bli_obj_conj_status( *x ); conj_t conjy = bli_obj_conj_status( *y ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t inc_y = bli_obj_vector_inc( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); void* buf_rho = bli_obj_buffer_at_off( *rho ); 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 x and y. This is to // prevent any unnecessary loss of information during computation. dt_alpha = bli_datatype_union( dt_x, dt_y ); buf_alpha = bli_obj_scalar_buffer( dt_alpha, *alpha ); // The datatype of beta MUST be the same as the datatype of rho. dt_beta = dt_rho; buf_beta = bli_obj_scalar_buffer( dt_beta, *beta ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x][dt_y][dt_rho]; // Invoke the function. f( conjx, conjy, n, buf_alpha, buf_x, inc_x, buf_y, inc_y, buf_beta, buf_rho ); }
void bli_dotaxpyv_kernel( obj_t* alpha, obj_t* xt, obj_t* x, obj_t* y, obj_t* rho, obj_t* z ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); num_t dt_z = bli_obj_datatype( *z ); conj_t conjxt = bli_obj_conj_status( *xt ); conj_t conjx = bli_obj_conj_status( *x ); conj_t conjy = bli_obj_conj_status( *y ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t inc_y = bli_obj_vector_inc( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); inc_t inc_z = bli_obj_vector_inc( *z ); void* buf_z = bli_obj_buffer_at_off( *z ); void* buf_rho = bli_obj_buffer_at_off( *rho ); num_t dt_alpha; void* buf_alpha; FUNCPTR_T f; // If alpha is a scalar constant, use dt_x to extract the address of the // corresponding constant value; otherwise, use the datatype encoded // within the alpha object and extract the buffer at the alpha offset. bli_set_scalar_dt_buffer( alpha, dt_x, dt_alpha, buf_alpha ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x][dt_y][dt_z]; // Invoke the function. f( conjxt, conjx, conjy, n, buf_alpha, buf_x, inc_x, buf_y, inc_y, buf_rho, buf_z, inc_z ); }
void bli_hemv_basic_check( obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y ) { err_t e_val; // Check object datatypes. e_val = bli_check_noninteger_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_noninteger_object( beta ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( a ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( x ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( y ); bli_check_error_code( e_val ); // Check object dimensions. e_val = bli_check_scalar_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_scalar_object( beta ); bli_check_error_code( e_val ); e_val = bli_check_matrix_object( a ); bli_check_error_code( e_val ); e_val = bli_check_square_object( a ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( x ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( y ); bli_check_error_code( e_val ); e_val = bli_check_object_length_equals( a, bli_obj_vector_dim( *x ) ); bli_check_error_code( e_val ); e_val = bli_check_equal_vector_lengths( x, y ); bli_check_error_code( e_val ); }
void libblis_test_normfv_check ( test_params_t* params, obj_t* beta, obj_t* x, obj_t* norm, double* resid ) { num_t dt_real = bli_obj_datatype_proj_to_real( *x ); dim_t m = bli_obj_vector_dim( *x ); obj_t m_r, temp_r; double junk; // // Pre-conditions: // - x is set to beta. // 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 // // norm := normf( x ) // // is functioning correctly if // // norm = sqrt( absqsc( beta ) * m ) // // where m is the length of x. // bli_obj_scalar_init_detached( dt_real, &temp_r ); bli_obj_scalar_init_detached( dt_real, &m_r ); bli_setsc( ( double )m, 0.0, &m_r ); bli_absqsc( beta, &temp_r ); bli_mulsc( &m_r, &temp_r ); bli_sqrtsc( &temp_r, &temp_r ); bli_subsc( &temp_r, norm ); bli_getsc( norm, resid, &junk ); }
void bli_randv_unb_var1( obj_t* x ) { num_t dt_x = bli_obj_datatype( *x ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x]; // Invoke the function. f( n, buf_x, inc_x ); }
void bli_axpy2v_ker( obj_t* alpha1, obj_t* alpha2, obj_t* x, obj_t* y, obj_t* z ) { num_t dt = bli_obj_datatype( *z ); conj_t conjx = bli_obj_conj_status( *x ); conj_t conjy = bli_obj_conj_status( *y ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t inc_y = bli_obj_vector_inc( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); inc_t inc_z = bli_obj_vector_inc( *z ); void* buf_z = bli_obj_buffer_at_off( *z ); void* buf_alpha1 = bli_obj_buffer_for_1x1( dt, *alpha1 ); void* buf_alpha2 = bli_obj_buffer_for_1x1( dt, *alpha2 ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt]; // Invoke the function. f( conjx, conjy, n, buf_alpha1, buf_alpha2, buf_x, inc_x, buf_y, inc_y, buf_z, inc_z ); }
void libblis_test_randv_check ( test_params_t* params, obj_t* x, double* resid ) { num_t dt_real = bli_obj_datatype_proj_to_real( *x ); dim_t m_x = bli_obj_vector_dim( *x ); obj_t sum; *resid = 0.0; // // The two most likely ways that randv would fail is if all elements // were zero, or if all elements were greater than or equal to one. // We check both of these conditions by computing the sum of the // absolute values of the elements of x. // bli_obj_scalar_init_detached( dt_real, &sum ); bli_norm1v( x, &sum ); if ( bli_is_float( dt_real ) ) { float* sum_x = bli_obj_buffer_at_off( sum ); if ( *sum_x == *bli_d0 ) *resid = 1.0; else if ( *sum_x >= 2.0 * m_x ) *resid = 2.0; } else // if ( bli_is_double( dt_real ) ) { double* sum_x = bli_obj_buffer_at_off( sum ); if ( *sum_x == *bli_d0 ) *resid = 1.0; else if ( *sum_x >= 2.0 * m_x ) *resid = 2.0; } }
void bli_fprintv( FILE* file, char* s1, obj_t* x, char* format, char* s2 ) { num_t dt_x = bli_obj_datatype( *x ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x]; // Invoke the function. f( file, s1, n, buf_x, inc_x, format, s2 ); }
void bli_scal2v_unb_var1( obj_t* beta, obj_t* x, obj_t* y ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); conj_t conjx = bli_obj_conj_status( *x ); dim_t n = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t inc_y = bli_obj_vector_inc( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); num_t dt_beta; void* buf_beta; FUNCPTR_T f; // If beta is a scalar constant, use dt_x to extract the address of the // corresponding constant value; otherwise, use the datatype encoded // within the beta object and extract the buffer at the beta offset. bli_set_scalar_dt_buffer( beta, dt_x, dt_beta, buf_beta ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_beta][dt_x][dt_y]; // Invoke the function. f( conjx, n, buf_beta, buf_x, inc_x, buf_y, inc_y ); }
void libblis_test_trmv_check( obj_t* alpha, obj_t* a, obj_t* x, obj_t* x_orig, double* resid ) { num_t dt = bli_obj_datatype( *x ); num_t dt_real = bli_obj_datatype_proj_to_real( *x ); dim_t m = bli_obj_vector_dim( *x ); uplo_t uploa = bli_obj_uplo( *a ); trans_t transa = bli_obj_conjtrans_status( *a ); obj_t a_local, y; obj_t norm; double junk; // // Pre-conditions: // - a is randomized and triangular. // - x 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 // // x := alpha * transa(A) * x_orig // // is functioning correctly if // // fnorm( y - x ) // // is negligible, where // // y = alpha * conja(A_dense) * x_orig // bli_obj_init_scalar( dt_real, &norm ); bli_obj_create( dt, m, 1, 0, 0, &y ); bli_obj_create( dt, m, m, 0, 0, &a_local ); bli_obj_set_struc( BLIS_TRIANGULAR, a_local ); bli_obj_set_uplo( uploa, a_local ); bli_obj_toggle_uplo_if_trans( transa, a_local ); bli_copym( a, &a_local ); bli_mktrim( &a_local ); bli_obj_set_struc( BLIS_GENERAL, a_local ); bli_obj_set_uplo( BLIS_DENSE, a_local ); bli_gemv( alpha, &a_local, x_orig, &BLIS_ZERO, &y ); bli_subv( x, &y ); bli_fnormv( &y, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &y ); bli_obj_free( &a_local ); }
void libblis_test_randv_check( obj_t* x, double* resid ) { dim_t m_x = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); *resid = 0.0; // // The two most likely ways that randv would fail is if all elements // were zero, or if all elements were greater than or equal to one. // We check both of these conditions by computing the sum of the // absolute values of the elements of x. // if ( bli_obj_is_float( *x ) ) { float sum_x; bli_sabsumv( m_x, buf_x, inc_x, &sum_x ); if ( sum_x == *bli_s0 ) *resid = 1.0; else if ( sum_x >= 1.0 * m_x ) *resid = 2.0; } else if ( bli_obj_is_double( *x ) ) { double sum_x; bli_dabsumv( m_x, buf_x, inc_x, &sum_x ); if ( sum_x == *bli_d0 ) *resid = 1.0; else if ( sum_x >= 1.0 * m_x ) *resid = 2.0; } else if ( bli_obj_is_scomplex( *x ) ) { float sum_x; bli_cabsumv( m_x, buf_x, inc_x, &sum_x ); if ( sum_x == *bli_s0 ) *resid = 1.0; else if ( sum_x >= 2.0 * m_x ) *resid = 2.0; } else // if ( bli_obj_is_dcomplex( *x ) ) { double sum_x; bli_zabsumv( m_x, buf_x, inc_x, &sum_x ); if ( sum_x == *bli_d0 ) *resid = 1.0; else if ( sum_x >= 2.0 * m_x ) *resid = 2.0; } }
// // Define object-based interface. // void bli_dotxf( obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y ) { num_t dt = bli_obj_datatype( *x ); conj_t conja = bli_obj_conj_status( *a ); conj_t conjx = bli_obj_conj_status( *x ); dim_t m = bli_obj_vector_dim( *y ); dim_t b_n = bli_obj_vector_dim( *x ); 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 inc_x = bli_obj_vector_inc( *x ); void* buf_y = bli_obj_buffer_at_off( *y ); inc_t inc_y = bli_obj_vector_inc( *y ); obj_t alpha_local; void* buf_alpha; obj_t beta_local; void* buf_beta; FUNCPTR_T f = ftypes[dt]; if ( bli_error_checking_is_enabled() ) bli_dotxf_check( alpha, a, x, beta, y ); // Create local copy-casts of the scalars (and apply internal conjugation // if needed). bli_obj_scalar_init_detached_copy_of( dt, BLIS_NO_CONJUGATE, alpha, &alpha_local ); bli_obj_scalar_init_detached_copy_of( dt, BLIS_NO_CONJUGATE, beta, &beta_local ); // Extract the scalar buffers. buf_alpha = bli_obj_buffer_for_1x1( dt, alpha_local ); buf_beta = bli_obj_buffer_for_1x1( dt, beta_local ); // Support cases where matrix A requires a transposition. if ( bli_obj_has_trans( *a ) ) { bli_swap_incs( rs_a, cs_a ); } // Invoke the void pointer-based function. f( conja, conjx, m, b_n, buf_alpha, buf_a, rs_a, cs_a, buf_x, inc_x, buf_beta, buf_y, inc_y ); }
void libblis_test_symv_check ( test_params_t* params, 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_dt( y ); num_t dt_real = bli_obj_dt_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 symmetric. // - 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_mksymm( 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_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 ); }
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_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_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 bli_dotxaxpyf_check( obj_t* alpha, obj_t* at, obj_t* a, obj_t* w, obj_t* x, obj_t* beta, obj_t* y, obj_t* z ) { err_t e_val; // Check object datatypes. e_val = bli_check_noninteger_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( at ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( a ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( w ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( x ); bli_check_error_code( e_val ); e_val = bli_check_noninteger_object( beta ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( y ); bli_check_error_code( e_val ); e_val = bli_check_floating_object( z ); bli_check_error_code( e_val ); // Check object dimensions. e_val = bli_check_scalar_object( alpha ); bli_check_error_code( e_val ); e_val = bli_check_matrix_object( at ); bli_check_error_code( e_val ); e_val = bli_check_matrix_object( a ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( w ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( x ); bli_check_error_code( e_val ); e_val = bli_check_scalar_object( beta ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( y ); bli_check_error_code( e_val ); e_val = bli_check_vector_object( z ); bli_check_error_code( e_val ); e_val = bli_check_equal_vector_lengths( w, z ); bli_check_error_code( e_val ); e_val = bli_check_equal_vector_lengths( x, y ); bli_check_error_code( e_val ); e_val = bli_check_conformal_dims( at, a ); bli_check_error_code( e_val ); e_val = bli_check_object_length_equals( at, bli_obj_vector_dim( *w ) ); bli_check_error_code( e_val ); e_val = bli_check_object_width_equals( at, bli_obj_vector_dim( *y ) ); bli_check_error_code( e_val ); e_val = bli_check_object_length_equals( a, bli_obj_vector_dim( *z ) ); bli_check_error_code( e_val ); e_val = bli_check_object_width_equals( a, bli_obj_vector_dim( *x ) ); bli_check_error_code( e_val ); // Check object aliases. e_val = bli_check_object_alias_of( at, a ); bli_check_error_code( e_val ); // Check object buffers (for non-NULLness). e_val = bli_check_object_buffer( alpha ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( at ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( a ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( w ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( x ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( beta ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( y ); bli_check_error_code( e_val ); e_val = bli_check_object_buffer( z ); bli_check_error_code( e_val ); }
siz_t bli_packv_init_pack ( pack_t schema, bszid_t bmult_id, obj_t* a, obj_t* p, cntx_t* cntx ) { num_t dt = bli_obj_dt( a ); dim_t dim_a = bli_obj_vector_dim( a ); dim_t bmult = bli_cntx_get_blksz_def_dt( dt, bmult_id, cntx ); membrk_t* membrk = bli_cntx_membrk( cntx ); #if 0 mem_t* mem_p; #endif dim_t m_p_pad; siz_t size_p; inc_t rs_p, cs_p; void* buf; // We begin by copying the basic fields of c. bli_obj_alias_to( a, p ); // Update the dimensions. bli_obj_set_dims( dim_a, 1, p ); // Reset the view offsets to (0,0). bli_obj_set_offs( 0, 0, p ); // Set the pack schema in the p object to the value in the control tree // node. bli_obj_set_pack_schema( schema, p ); // Compute the dimensions padded by the dimension multiples. m_p_pad = bli_align_dim_to_mult( bli_obj_vector_dim( p ), bmult ); // Compute the size of the packed buffer. size_p = m_p_pad * 1 * bli_obj_elem_size( p ); #if 0 // Extract the address of the mem_t object within p that will track // properties of the packed buffer. mem_p = bli_obj_pack_mem( *p ); if ( bli_mem_is_unalloc( mem_p ) ) { // If the mem_t object of p has not yet been allocated, then acquire // a memory block suitable for a vector. bli_membrk_acquire_v( membrk, size_p, mem_p ); } else { // If the mem_t object has already been allocated, then release and // re-acquire the memory so there is sufficient space. if ( bli_mem_size( mem_p ) < size_p ) { bli_membrk_release( mem_p ); bli_membrk_acquire_v( membrk, size_p, mem_p ); } } // Grab the buffer address from the mem_t object and copy it to the // main object buffer field. (Sometimes this buffer address will be // copied when the value is already up-to-date, because it persists // in the main object buffer field across loop iterations.) buf = bli_mem_buffer( mem_p ); bli_obj_set_buffer( buf, p ); #endif // Save the padded (packed) dimensions into the packed object. bli_obj_set_padded_dims( m_p_pad, 1, p ); // Set the row and column strides of p based on the pack schema. if ( schema == BLIS_PACKED_VECTOR ) { // Set the strides to reflect a column-stored vector. Note that the // column stride may never be used, and is only useful to determine // how much space beyond the vector would need to be zero-padded, if // zero-padding was needed. rs_p = 1; cs_p = bli_obj_padded_length( p ); bli_obj_set_strides( rs_p, cs_p, p ); } return size_p; }
void libblis_test_setv_check( obj_t* beta, obj_t* x, double* resid ) { num_t dt_x = bli_obj_datatype( *x ); dim_t m_x = bli_obj_vector_dim( *x ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); void* buf_beta = bli_obj_buffer_for_1x1( dt_x, *beta ); dim_t i; *resid = 0.0; // // The easiest way to check that setv was successful is to confirm // that each element of x is equal to beta. // if ( bli_obj_is_float( *x ) ) { float* chi1 = buf_x; float* beta_cast = buf_beta; for ( i = 0; i < m_x; ++i ) { if ( !bli_seq( *chi1, *beta_cast ) ) { *resid = 1.0; return; } chi1 += inc_x; } } else if ( bli_obj_is_double( *x ) ) { double* chi1 = buf_x; double* beta_cast = buf_beta; for ( i = 0; i < m_x; ++i ) { if ( !bli_deq( *chi1, *beta_cast ) ) { *resid = 1.0; return; } chi1 += inc_x; } } else if ( bli_obj_is_scomplex( *x ) ) { scomplex* chi1 = buf_x; scomplex* beta_cast = buf_beta; for ( i = 0; i < m_x; ++i ) { if ( !bli_ceq( *chi1, *beta_cast ) ) { *resid = 1.0; return; } chi1 += inc_x; } } else // if ( bli_obj_is_dcomplex( *x ) ) { dcomplex* chi1 = buf_x; dcomplex* beta_cast = buf_beta; for ( i = 0; i < m_x; ++i ) { if ( !bli_zeq( *chi1, *beta_cast ) ) { *resid = 1.0; return; } chi1 += inc_x; } } }
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 bli_dotxaxpyf_unb_var2( obj_t* alpha, obj_t* at, obj_t* a, obj_t* w, obj_t* x, obj_t* beta, obj_t* y, obj_t* z ) { num_t dt_a = bli_obj_datatype( *a ); num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); conj_t conjat = bli_obj_conj_status( *at ); conj_t conja = bli_obj_conj_status( *a ); conj_t conjw = bli_obj_conj_status( *w ); conj_t conjx = bli_obj_conj_status( *x ); dim_t m = bli_obj_vector_dim( *z ); dim_t b_n = bli_obj_vector_dim( *y ); 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 ); inc_t inc_w = bli_obj_vector_inc( *w ); void* buf_w = bli_obj_buffer_at_off( *w ); inc_t inc_x = bli_obj_vector_inc( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t inc_y = bli_obj_vector_inc( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); inc_t inc_z = bli_obj_vector_inc( *z ); void* buf_z = bli_obj_buffer_at_off( *z ); 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 ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_a][dt_x][dt_y]; // Invoke the function. f( conjat, conja, conjw, conjx, m, b_n, buf_alpha, buf_a, rs_a, cs_a, buf_w, inc_w, buf_x, inc_x, buf_beta, buf_y, inc_y, buf_z, inc_z ); }