err_t bli_check_scalar_object( obj_t* a ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_length( *a ) < 0 || bli_obj_width( *a ) < 0 ) return BLIS_NEGATIVE_DIMENSION; if ( bli_obj_length( *a ) != 1 || bli_obj_width( *a ) != 1 ) return BLIS_EXPECTED_SCALAR_OBJECT; return e_val; }
void bli_unpackm_blk_var2( obj_t* p, obj_t* c, unpackm_t* cntl ) { num_t dt_cp = bli_obj_datatype( *c ); // Normally we take the parameters from the source argument. But here, // the packm/unpackm framework is not yet solidified enough for us to // assume that at this point struc(P) == struc(C), (ie: since // densification may have marked P's structure as dense when the root // is upper or lower). So, we take the struc field from C, not P. struc_t strucc = bli_obj_struc( *c ); doff_t diagoffc = bli_obj_diag_offset( *c ); diag_t diagc = bli_obj_diag( *c ); uplo_t uploc = bli_obj_uplo( *c ); // Again, normally the trans argument is on the source matrix. But we // know that the packed matrix is not transposed. If there is to be a // transposition, it is because C was originally transposed when packed. // Thus, we query C for the trans status, not P. Also, we only query // the trans status (not the conjugation status), since we probably // don't want to un-conjugate if the original matrix was conjugated // when packed. trans_t transc = bli_obj_onlytrans_status( *c ); dim_t m_c = bli_obj_length( *c ); dim_t n_c = bli_obj_width( *c ); dim_t m_panel = bli_obj_panel_length( *c ); dim_t n_panel = bli_obj_panel_width( *c ); void* buf_p = bli_obj_buffer_at_off( *p ); inc_t rs_p = bli_obj_row_stride( *p ); inc_t cs_p = bli_obj_col_stride( *p ); dim_t pd_p = bli_obj_panel_dim( *p ); inc_t ps_p = bli_obj_panel_stride( *p ); void* buf_c = bli_obj_buffer_at_off( *c ); inc_t rs_c = bli_obj_row_stride( *c ); inc_t cs_c = bli_obj_col_stride( *c ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_cp]; // Invoke the function. f( strucc, diagoffc, diagc, uploc, transc, m_c, n_c, m_panel, n_panel, buf_p, rs_p, cs_p, pd_p, ps_p, buf_c, rs_c, cs_c ); }
void bli_dupl_unb_var1( obj_t* b, obj_t* bd ) { num_t dt_b = bli_obj_datatype( *b ); dim_t k; void* buf_b = bli_obj_buffer_at_off( *b ); void* buf_bd = bli_obj_buffer_at_off( *bd ); FUNCPTR_T f; // The k dimension is the one that is "perpendicular" to the // storage dimension. if ( bli_obj_is_row_stored( *b ) ) k = bli_obj_length( *b ); else k = bli_obj_width( *b ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_b]; // Invoke the function. f( k, buf_b, buf_bd ); }
void bli_norm1m_unb_var1( obj_t* x, obj_t* norm ) { num_t dt_x = bli_obj_datatype( *x ); doff_t diagoffx = bli_obj_diag_offset( *x ); uplo_t diagx = bli_obj_diag( *x ); uplo_t uplox = bli_obj_uplo( *x ); dim_t m = bli_obj_length( *x ); dim_t n = bli_obj_width( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); void* buf_norm = bli_obj_buffer_at_off( *norm ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x]; // Invoke the function. f( diagoffx, diagx, uplox, m, n, buf_x, rs_x, cs_x, buf_norm ); }
void libblis_test_gemm_impl ( iface_t iface, obj_t* alpha, obj_t* a, obj_t* b, obj_t* beta, obj_t* c ) { switch ( iface ) { case BLIS_TEST_SEQ_FRONT_END: #if 0 //bli_printm( "alpha", alpha, "%5.2f", "" ); //bli_printm( "beta", beta, "%5.2f", "" ); bli_printm( "a", a, "%5.2f", "" ); bli_printm( "b", b, "%5.2f", "" ); bli_printm( "c", c, "%5.2f", "" ); #endif //if ( bli_obj_length( b ) == 16 && // bli_obj_stor3_from_strides( c, a, b ) == BLIS_CRR ) //bli_printm( "c before", c, "%6.3f", "" ); bli_gemm( alpha, a, b, beta, c ); #if 0 if ( bli_obj_length( c ) == 12 && bli_obj_stor3_from_strides( c, a, b ) == BLIS_RRR ) bli_printm( "c after", c, "%6.3f", "" ); #endif break; default: libblis_test_printf_error( "Invalid interface type.\n" ); } }
void bli_setid_unb_var1( obj_t* beta, obj_t* x ) { num_t dt_xr = bli_obj_datatype_proj_to_real( *x ); num_t dt_x = bli_obj_datatype( *x ); doff_t diagoffx = bli_obj_diag_offset( *x ); dim_t m = bli_obj_length( *x ); dim_t n = bli_obj_width( *x ); void* buf_beta = bli_obj_buffer_for_1x1( dt_xr, *beta ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x]; // Invoke the function. f( diagoffx, m, n, buf_beta, buf_x, rs_x, cs_x ); }
void bli_gemv_unb_var2( obj_t* alpha, obj_t* a, obj_t* x, obj_t* beta, obj_t* y, gemv_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 ); conj_t transa = bli_obj_conjtrans_status( *a ); conj_t conjx = bli_obj_conj_status( *x ); dim_t m = bli_obj_length( *a ); dim_t n = bli_obj_width( *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_scalar_buffer( dt_alpha, *alpha ); // The datatype of beta MUST be the same as the datatype of y. dt_beta = dt_y; buf_beta = bli_obj_scalar_buffer( 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( transa, conjx, m, n, buf_alpha, buf_a, rs_a, cs_a, buf_x, incx, buf_beta, buf_y, incy ); }
void libblis_test_xpbym_check ( test_params_t* params, 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_length( y ); dim_t n = bli_obj_width( 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 := beta * y_orig + conjx(x) // // is functioning correctly if // // normf( y - ( beta * y_orig + conjx(x) ) ) // // is negligible. // bli_obj_scalar_init_detached( dt_real, &norm ); bli_obj_create( dt, m, n, 0, 0, &x_temp ); bli_obj_create( dt, m, n, 0, 0, &y_temp ); bli_copym( x, &x_temp ); bli_copym( y_orig, &y_temp ); bli_scalm( beta, &y_temp ); bli_addm( &x_temp, &y_temp ); bli_subm( &y_temp, y ); bli_normfm( y, &norm ); bli_getsc( &norm, resid, &junk ); bli_obj_free( &x_temp ); bli_obj_free( &y_temp ); }
err_t bli_check_square_object( obj_t* a ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_length( *a ) != bli_obj_width( *a ) ) e_val = BLIS_EXPECTED_SQUARE_OBJECT; return e_val; }
err_t bli_check_object_length_equals( obj_t* a, dim_t m ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_length( *a ) != m ) e_val = BLIS_UNEXPECTED_OBJECT_LENGTH; return e_val; }
void bli_packm_unb_var1( obj_t* c, obj_t* p, packm_thrinfo_t* thread ) { num_t dt_cp = bli_obj_datatype( *c ); struc_t strucc = bli_obj_struc( *c ); doff_t diagoffc = bli_obj_diag_offset( *c ); diag_t diagc = bli_obj_diag( *c ); uplo_t uploc = bli_obj_uplo( *c ); trans_t transc = bli_obj_conjtrans_status( *c ); dim_t m_p = bli_obj_length( *p ); dim_t n_p = bli_obj_width( *p ); dim_t m_max_p = bli_obj_padded_length( *p ); dim_t n_max_p = bli_obj_padded_width( *p ); void* buf_c = bli_obj_buffer_at_off( *c ); inc_t rs_c = bli_obj_row_stride( *c ); inc_t cs_c = bli_obj_col_stride( *c ); void* buf_p = bli_obj_buffer_at_off( *p ); inc_t rs_p = bli_obj_row_stride( *p ); inc_t cs_p = bli_obj_col_stride( *p ); void* buf_kappa; FUNCPTR_T f; // This variant assumes that the computational kernel will always apply // the alpha scalar of the higher-level operation. Thus, we use BLIS_ONE // for kappa so that the underlying packm implementation does not scale // during packing. buf_kappa = bli_obj_buffer_for_const( dt_cp, BLIS_ONE ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_cp]; if( thread_am_ochief( thread ) ) { // Invoke the function. f( strucc, diagoffc, diagc, uploc, transc, m_p, n_p, m_max_p, n_max_p, buf_kappa, buf_c, rs_c, cs_c, buf_p, rs_p, cs_p ); } }
err_t bli_check_matrix_object( obj_t* a ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_length( *a ) < 0 || bli_obj_width( *a ) < 0 ) e_val = BLIS_NEGATIVE_DIMENSION; return e_val; }
void bli_scalm_unb_var1( obj_t* alpha, obj_t* x, cntx_t* cntx ) { num_t dt_x = bli_obj_datatype( *x ); doff_t diagoffx = bli_obj_diag_offset( *x ); uplo_t diagx = bli_obj_diag( *x ); uplo_t uplox = bli_obj_uplo( *x ); dim_t m = bli_obj_length( *x ); dim_t n = bli_obj_width( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); void* buf_alpha; obj_t x_local; FUNCPTR_T f; // Alias x to x_local so we can apply alpha if it is non-unit. bli_obj_alias_to( *x, x_local ); // If alpha is non-unit, apply it to the scalar attached to x. if ( !bli_obj_equals( alpha, &BLIS_ONE ) ) { bli_obj_scalar_apply_scalar( alpha, &x_local ); } // Grab the address of the internal scalar buffer for the scalar // attached to x. buf_alpha_x = bli_obj_internal_scalar_buffer( *x ); // Index into the type combination array to extract the correct // function pointer. // NOTE: We use dt_x for both alpha and x because alpha was obtained // from the attached scalar of x, which is guaranteed to be of the // same datatype as x. f = ftypes[dt_x][dt_x]; // Invoke the function. // NOTE: We unconditionally pass in BLIS_NO_CONJUGATE for alpha // because it would have already been conjugated by the front-end. f( BLIS_NO_CONJUGATE, diagoffx, diagx, uplox, m, n, buf_alpha, buf_x, rs_x, cs_x ); }
void libblis_test_scalm_check( 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_length( *y ); dim_t n = bli_obj_width( *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, n, 0, 0, &y2 ); bli_copym( 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_scalm( &nbeta, &y2 ); bli_addm( &y2, y ); bli_normfm( y, &norm_y_r ); bli_getsc( &norm_y_r, resid, &junk ); bli_obj_free( &y2 ); }
void bli_trsm_rl_ker_var2( obj_t* alpha, obj_t* a, obj_t* b, obj_t* beta, obj_t* c, trsm_t* cntl ) { num_t dt_exec = bli_obj_execution_datatype( *c ); doff_t diagoffb = bli_obj_diag_offset( *b ); dim_t m = bli_obj_length( *c ); dim_t n = bli_obj_width( *c ); dim_t k = bli_obj_width( *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 ); inc_t ps_a = bli_obj_panel_stride( *a ); void* buf_b = bli_obj_buffer_at_off( *b ); inc_t rs_b = bli_obj_row_stride( *b ); inc_t cs_b = bli_obj_col_stride( *b ); inc_t ps_b = bli_obj_panel_stride( *b ); void* buf_c = bli_obj_buffer_at_off( *c ); inc_t rs_c = bli_obj_row_stride( *c ); inc_t cs_c = bli_obj_col_stride( *c ); num_t dt_alpha; void* buf_alpha; FUNCPTR_T f; // If alpha is a scalar constant, use dt_exec 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_exec, dt_alpha, buf_alpha ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_exec]; // Invoke the function. f( diagoffb, m, n, k, buf_alpha, buf_a, rs_a, cs_a, ps_a, buf_b, rs_b, cs_b, ps_b, buf_c, rs_c, cs_c ); }
void bli_gemmtrsm_ukr_make_subparts( dim_t k, obj_t* a, obj_t* b, obj_t* a1x, obj_t* a11, obj_t* bx1, obj_t* b11 ) { dim_t mr = bli_obj_length( *a ); dim_t nr = bli_obj_width( *b ); dim_t off_a1x, off_a11; dim_t off_bx1, off_b11; if ( bli_obj_is_lower( *a ) ) { off_a1x = 0; off_a11 = k; off_bx1 = 0; off_b11 = k; } else { off_a1x = mr; off_a11 = 0; off_bx1 = mr; off_b11 = 0; } bli_obj_init_subpart_from( *a, *a1x ); bli_obj_set_dims( mr, k, *a1x ); bli_obj_inc_offs( 0, off_a1x, *a1x ); bli_obj_init_subpart_from( *a, *a11 ); bli_obj_set_dims( mr, mr, *a11 ); bli_obj_inc_offs( 0, off_a11, *a11 ); bli_obj_init_subpart_from( *b, *bx1 ); bli_obj_set_dims( k, nr, *bx1 ); bli_obj_inc_offs( off_bx1, 0, *bx1 ); bli_obj_init_subpart_from( *b, *b11 ); bli_obj_set_dims( mr, nr, *b11 ); bli_obj_inc_offs( off_b11, 0, *b11 ); // Mark a1x as having general structure (which overwrites the triangular // property it inherited from a). bli_obj_set_struc( BLIS_GENERAL, *a1x ); // Set the diagonal offset of a11 to 0 (which overwrites the diagonal // offset value it inherited from a). bli_obj_set_diag_offset( 0, *a11 ); }
err_t bli_check_object_buffer( obj_t* a ) { err_t e_val = BLIS_SUCCESS; // We are only concerned with NULL buffers in objects where BOTH // dimensions are non-zero. if ( bli_obj_buffer( *a ) == NULL ) if ( bli_obj_length( *a ) > 0 && bli_obj_width( *a ) > 0 ) e_val = BLIS_EXPECTED_NONNULL_OBJECT_BUFFER; return e_val; }
void bli_ger_unb_var2( obj_t* alpha, obj_t* x, obj_t* y, obj_t* a, cntx_t* cntx, ger_t* cntl ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); num_t dt_a = bli_obj_datatype( *a ); conj_t conjx = bli_obj_conj_status( *x ); conj_t conjy = bli_obj_conj_status( *y ); dim_t m = bli_obj_length( *a ); dim_t n = bli_obj_width( *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 ); 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 ); num_t dt_alpha; void* buf_alpha; 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_buffer_for_1x1( dt_alpha, *alpha ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_a]; // Invoke the function. f( conjx, conjy, m, n, buf_alpha, buf_x, incx, buf_y, incy, buf_a, rs_a, cs_a, cntx ); }
void bli_her2_unb_var1( conj_t conjh, obj_t* alpha, obj_t* alpha_conj, obj_t* x, obj_t* y, obj_t* c, her2_t* cntl ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); num_t dt_c = bli_obj_datatype( *c ); uplo_t uplo = bli_obj_uplo( *c ); conj_t conjx = bli_obj_conj_status( *x ); conj_t conjy = bli_obj_conj_status( *y ); dim_t m = bli_obj_length( *c ); 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 ); void* buf_c = bli_obj_buffer_at_off( *c ); inc_t rs_c = bli_obj_row_stride( *c ); inc_t cs_c = bli_obj_col_stride( *c ); num_t dt_alpha; void* buf_alpha; FUNCPTR_T f; // The datatype of alpha MUST be the type union of the datatypes of x and y. dt_alpha = bli_datatype_union( dt_x, dt_y ); buf_alpha = bli_obj_buffer_for_1x1( dt_alpha, *alpha ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x][dt_y][dt_c]; // Invoke the function. f( uplo, conjx, conjy, conjh, m, buf_alpha, buf_x, incx, buf_y, incy, buf_c, rs_c, cs_c ); }
err_t bli_check_vector_object( obj_t* a ) { err_t e_val = BLIS_SUCCESS; if ( bli_obj_length( *a ) < 0 || bli_obj_width( *a ) < 0 ) return BLIS_NEGATIVE_DIMENSION; if ( !bli_obj_is_vector( *a ) ) return BLIS_EXPECTED_VECTOR_OBJECT; return e_val; }
siz_t bli_thread_get_range_weighted_b2t ( thrinfo_t* thr, obj_t* a, blksz_t* bmult, dim_t* start, dim_t* end ) { siz_t area; // This function assigns area-weighted ranges in the m dimension // where the total range spans 0 to m-1 with 0 at the bottom end and // m-1 at the top end. if ( bli_obj_intersects_diag( *a ) && bli_obj_is_upper_or_lower( *a ) ) { doff_t diagoff = bli_obj_diag_offset( *a ); uplo_t uplo = bli_obj_uplo( *a ); dim_t m = bli_obj_length( *a ); dim_t n = bli_obj_width( *a ); dim_t bf = bli_blksz_get_def_for_obj( a, bmult ); // Support implicit transposition. if ( bli_obj_has_trans( *a ) ) { bli_reflect_about_diag( diagoff, uplo, m, n ); } bli_reflect_about_diag( diagoff, uplo, m, n ); bli_rotate180_trapezoid( diagoff, uplo ); area = bli_thread_get_range_weighted_sub ( thr, diagoff, uplo, m, n, bf, TRUE, start, end ); } else // if dense or zeros { area = bli_thread_get_range_b2t ( thr, a, bmult, start, end ); } return area; }
void bli_obj_print( char* label, obj_t* obj ) { FILE* file = stdout; if ( bli_error_checking_is_enabled() ) bli_obj_print_check( label, obj ); fprintf( file, "\n" ); fprintf( file, "%s\n", label ); fprintf( file, "\n" ); fprintf( file, " m x n %lu x %lu\n", ( unsigned long int )bli_obj_length( *obj ), ( unsigned long int )bli_obj_width( *obj ) ); fprintf( file, "\n" ); fprintf( file, " offm, offn %lu, %lu\n", ( unsigned long int )bli_obj_row_off( *obj ), ( unsigned long int )bli_obj_col_off( *obj ) ); fprintf( file, " diagoff %ld\n", ( signed long int )bli_obj_diag_offset( *obj ) ); fprintf( file, "\n" ); fprintf( file, " buf %p\n", ( void* )bli_obj_buffer( *obj ) ); fprintf( file, " elem size %lu\n", ( unsigned long int )bli_obj_elem_size( *obj ) ); fprintf( file, " rs, cs %ld, %ld\n", ( signed long int )bli_obj_row_stride( *obj ), ( signed long int )bli_obj_col_stride( *obj ) ); fprintf( file, " is %ld\n", ( signed long int )bli_obj_imag_stride( *obj ) ); fprintf( file, " m_padded %lu\n", ( unsigned long int )bli_obj_padded_length( *obj ) ); fprintf( file, " n_padded %lu\n", ( unsigned long int )bli_obj_padded_width( *obj ) ); fprintf( file, " ps %lu\n", ( unsigned long int )bli_obj_panel_stride( *obj ) ); fprintf( file, "\n" ); fprintf( file, " info %lX\n", ( unsigned long int )(*obj).info ); fprintf( file, " - is complex %lu\n", ( unsigned long int )bli_obj_is_complex( *obj ) ); fprintf( file, " - is d. prec %lu\n", ( unsigned long int )bli_obj_is_double_precision( *obj ) ); fprintf( file, " - datatype %lu\n", ( unsigned long int )bli_obj_datatype( *obj ) ); fprintf( file, " - target dt %lu\n", ( unsigned long int )bli_obj_target_datatype( *obj ) ); fprintf( file, " - exec dt %lu\n", ( unsigned long int )bli_obj_execution_datatype( *obj ) ); fprintf( file, " - has trans %lu\n", ( unsigned long int )bli_obj_has_trans( *obj ) ); fprintf( file, " - has conj %lu\n", ( unsigned long int )bli_obj_has_conj( *obj ) ); fprintf( file, " - unit diag? %lu\n", ( unsigned long int )bli_obj_has_unit_diag( *obj ) ); fprintf( file, " - struc type %lu\n", ( unsigned long int )bli_obj_struc( *obj ) >> BLIS_STRUC_SHIFT ); fprintf( file, " - uplo type %lu\n", ( unsigned long int )bli_obj_uplo( *obj ) >> BLIS_UPLO_SHIFT ); fprintf( file, " - is upper %lu\n", ( unsigned long int )bli_obj_is_upper( *obj ) ); fprintf( file, " - is lower %lu\n", ( unsigned long int )bli_obj_is_lower( *obj ) ); fprintf( file, " - is dense %lu\n", ( unsigned long int )bli_obj_is_dense( *obj ) ); fprintf( file, " - pack schema %lu\n", ( unsigned long int )bli_obj_pack_schema( *obj ) >> BLIS_PACK_SCHEMA_SHIFT ); fprintf( file, " - packinv diag? %lu\n", ( unsigned long int )bli_obj_has_inverted_diag( *obj ) ); fprintf( file, " - pack ordifup %lu\n", ( unsigned long int )bli_obj_is_pack_rev_if_upper( *obj ) ); fprintf( file, " - pack ordiflo %lu\n", ( unsigned long int )bli_obj_is_pack_rev_if_lower( *obj ) ); fprintf( file, " - packbuf type %lu\n", ( unsigned long int )bli_obj_pack_buffer_type( *obj ) >> BLIS_PACK_BUFFER_SHIFT ); fprintf( file, "\n" ); }
void bli_obj_alloc_buffer_check( inc_t rs, inc_t cs, obj_t* obj ) { err_t e_val; e_val = bli_check_matrix_strides( bli_obj_length( *obj ), bli_obj_width( *obj ), rs, cs ); bli_check_error_code( e_val ); e_val = bli_check_null_pointer( obj ); bli_check_error_code( e_val ); }
void libblis_test_normfm_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_length( *x ); dim_t n = bli_obj_width( *x ); obj_t m_r, n_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 * n ) // // where m and n are the dimensions of x. // bli_obj_scalar_init_detached( dt_real, &temp_r ); bli_obj_scalar_init_detached( dt_real, &m_r ); bli_obj_scalar_init_detached( dt_real, &n_r ); bli_setsc( ( double )m, 0.0, &m_r ); bli_setsc( ( double )n, 0.0, &n_r ); bli_absqsc( beta, &temp_r ); bli_mulsc( &m_r, &temp_r ); bli_mulsc( &n_r, &temp_r ); bli_sqrtsc( &temp_r, &temp_r ); bli_subsc( &temp_r, norm ); bli_getsc( norm, resid, &junk ); }
void bli_axpym_unb_var1( obj_t* alpha, obj_t* x, obj_t* y, cntx_t* cntx ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); doff_t diagoffx = bli_obj_diag_offset( *x ); diag_t diagx = bli_obj_diag( *x ); uplo_t uplox = bli_obj_uplo( *x ); trans_t transx = bli_obj_conjtrans_status( *x ); dim_t m = bli_obj_length( *y ); dim_t n = bli_obj_width( *y ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t rs_y = bli_obj_row_stride( *y ); inc_t cs_y = bli_obj_col_stride( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); 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_alpha][dt_x][dt_y]; // Invoke the function. f( diagoffx, diagx, uplox, transx, m, n, buf_alpha, buf_x, rs_x, cs_x, buf_y, rs_y, cs_y ); }
void bli_fprintm( FILE* file, char* s1, obj_t* x, char* format, char* s2 ) { num_t dt_x = bli_obj_datatype( *x ); dim_t m = bli_obj_length( *x ); dim_t n = bli_obj_width( *x ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); FUNCPTR_T f; if ( bli_error_checking_is_enabled() ) bli_fprintm_check( file, s1, x, format, s2 ); // Handle constants up front. if ( dt_x == BLIS_CONSTANT ) { float* sp = bli_obj_buffer_for_const( BLIS_FLOAT, *x ); double* dp = bli_obj_buffer_for_const( BLIS_DOUBLE, *x ); scomplex* cp = bli_obj_buffer_for_const( BLIS_SCOMPLEX, *x ); dcomplex* zp = bli_obj_buffer_for_const( BLIS_DCOMPLEX, *x ); gint_t* ip = bli_obj_buffer_for_const( BLIS_INT, *x ); fprintf( file, "%s\n", s1 ); fprintf( file, " float: %9.2e\n", bli_sreal( *sp ) ); fprintf( file, " double: %9.2e\n", bli_dreal( *dp ) ); fprintf( file, " scomplex: %9.2e + %9.2e\n", bli_creal( *cp ), bli_cimag( *cp ) ); fprintf( file, " dcomplex: %9.2e + %9.2e\n", bli_zreal( *zp ), bli_zimag( *zp ) ); fprintf( file, " int: %ld\n", *ip ); fprintf( file, "\n" ); return; } // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x]; // Invoke the function. f( file, s1, m, n, buf_x, rs_x, cs_x, format, s2 ); }
void bli_trmv_unf_var2( obj_t* alpha, obj_t* a, obj_t* x, cntx_t* cntx, trmv_t* cntl ) { num_t dt_a = bli_obj_datatype( *a ); num_t dt_x = bli_obj_datatype( *x ); uplo_t uplo = bli_obj_uplo( *a ); trans_t trans = bli_obj_conjtrans_status( *a ); diag_t diag = bli_obj_diag( *a ); 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 ); num_t dt_alpha; void* buf_alpha; 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 ); // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_a][dt_x]; // Invoke the function. f( uplo, trans, diag, m, buf_alpha, buf_a, rs_a, cs_a, buf_x, incx ); }
void bli_unpackm_unb_var1 ( obj_t* p, obj_t* c, cntx_t* cntx, cntl_t* cntl, thrinfo_t* thread ) { num_t dt_pc = bli_obj_datatype( *p ); doff_t diagoffp = bli_obj_diag_offset( *p ); uplo_t uplop = bli_obj_uplo( *p ); trans_t transc = bli_obj_onlytrans_status( *c ); dim_t m_c = bli_obj_length( *c ); dim_t n_c = bli_obj_width( *c ); void* buf_p = bli_obj_buffer_at_off( *p ); inc_t rs_p = bli_obj_row_stride( *p ); inc_t cs_p = bli_obj_col_stride( *p ); void* buf_c = bli_obj_buffer_at_off( *c ); inc_t rs_c = bli_obj_row_stride( *c ); inc_t cs_c = bli_obj_col_stride( *c ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_pc]; // Invoke the function. f( diagoffp, uplop, transc, m_c, n_c, buf_p, rs_p, cs_p, buf_c, rs_c, cs_c, cntx ); }
void bli_addm_unb_var1( obj_t* x, obj_t* y, cntx_t* cntx ) { num_t dt_x = bli_obj_datatype( *x ); num_t dt_y = bli_obj_datatype( *y ); doff_t diagoffx = bli_obj_diag_offset( *x ); diag_t diagx = bli_obj_diag( *x ); uplo_t uplox = bli_obj_uplo( *x ); trans_t transx = bli_obj_conjtrans_status( *x ); dim_t m = bli_obj_length( *y ); dim_t n = bli_obj_width( *y ); inc_t rs_x = bli_obj_row_stride( *x ); inc_t cs_x = bli_obj_col_stride( *x ); void* buf_x = bli_obj_buffer_at_off( *x ); inc_t rs_y = bli_obj_row_stride( *y ); inc_t cs_y = bli_obj_col_stride( *y ); void* buf_y = bli_obj_buffer_at_off( *y ); FUNCPTR_T f; // Index into the type combination array to extract the correct // function pointer. f = ftypes[dt_x][dt_y]; // Invoke the function. f( diagoffx, diagx, uplox, transx, m, n, buf_x, rs_x, cs_x, buf_y, rs_y, cs_y ); }
double libblis_test_gemm_flops ( obj_t* a, obj_t* b, obj_t* c ) { bool_t a_is_real = bli_obj_is_real( a ); bool_t a_is_complex = bli_obj_is_complex( a ); bool_t b_is_real = bli_obj_is_real( b ); bool_t b_is_complex = bli_obj_is_complex( b ); bool_t c_is_real = bli_obj_is_real( c ); bool_t c_is_complex = bli_obj_is_complex( c ); double m = ( double )bli_obj_length( c ); double n = ( double )bli_obj_width( c ); double k = ( double )bli_obj_width( a ); double flops; if ( ( c_is_complex && a_is_complex && b_is_complex ) ) { flops = 8.0 * m * n * k; } else if ( ( c_is_complex && a_is_complex && b_is_real ) || ( c_is_complex && a_is_real && b_is_complex ) || ( c_is_real && a_is_complex && b_is_complex ) ) { flops = 4.0 * m * n * k; } else { flops = 2.0 * m * n * k; } return flops; }