mirror of
https://github.com/amd/blis.git
synced 2026-07-03 05:37:51 +00:00
Introduced API-level initialization.
Details: - Added API-level initialization state to _const, _error, _mem, _thread, _ind, and _cntl APIs. While this functionality will mostly go unused, adding miniscule overhead at init-time, there will be at least once instance in the near future where, in order to avoid an infinite loop, a certain portion of the initialization will call a query function that itself attempts to call bli_init(). API-level initialization will allow this later stage to verify that an earlier stage of initialization has completed, even if the overall call to bli_init() has not yet returned. - Added _is_initialized() functions for each API, setting the underlying bool_t during _init() and unsetting it during _finalize(). - Comment, whitespace changes.
This commit is contained in:
@@ -34,9 +34,6 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
// These globally-declared obj_t's are used to store the so-called
|
||||
// "global scalar constants" for commonly-used 1x1 values.
|
||||
|
||||
obj_t BLIS_TWO;
|
||||
obj_t BLIS_ONE;
|
||||
obj_t BLIS_ONE_HALF;
|
||||
@@ -45,6 +42,8 @@ obj_t BLIS_MINUS_ONE_HALF;
|
||||
obj_t BLIS_MINUS_ONE;
|
||||
obj_t BLIS_MINUS_TWO;
|
||||
|
||||
static bool_t bli_const_is_init = FALSE;
|
||||
|
||||
void bli_const_init( void )
|
||||
{
|
||||
bli_obj_create_const( 2.0, &BLIS_TWO );
|
||||
@@ -54,6 +53,9 @@ void bli_const_init( void )
|
||||
bli_obj_create_const( -0.5, &BLIS_MINUS_ONE_HALF );
|
||||
bli_obj_create_const( -1.0, &BLIS_MINUS_ONE );
|
||||
bli_obj_create_const( -2.0, &BLIS_MINUS_TWO );
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_const_is_init = TRUE;
|
||||
}
|
||||
|
||||
void bli_const_finalize( void )
|
||||
@@ -65,5 +67,13 @@ void bli_const_finalize( void )
|
||||
bli_obj_free( &BLIS_MINUS_ONE_HALF );
|
||||
bli_obj_free( &BLIS_MINUS_ONE );
|
||||
bli_obj_free( &BLIS_MINUS_TWO );
|
||||
|
||||
// Mark API as uninitialized.
|
||||
bli_const_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_const_is_initialized( void )
|
||||
{
|
||||
return bli_const_is_init;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
*/
|
||||
|
||||
void bli_const_init( void );
|
||||
void bli_const_finalize( void );
|
||||
void bli_const_init( void );
|
||||
void bli_const_finalize( void );
|
||||
bool_t bli_const_is_initialized( void );
|
||||
|
||||
|
||||
@@ -34,59 +34,33 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
// Current error checking level.
|
||||
static errlev_t bli_err_chk_level = BLIS_FULL_ERROR_CHECKING;
|
||||
static bool_t bli_error_is_init = FALSE;
|
||||
|
||||
void bli_error_init( void )
|
||||
{
|
||||
bli_error_init_msgs();
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_error_is_init = TRUE;
|
||||
}
|
||||
|
||||
void bli_error_finalize( void )
|
||||
{
|
||||
// Mark API as uninitialized.
|
||||
bli_error_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_error_is_initialized( void )
|
||||
{
|
||||
return bli_error_is_init;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Internal array to hold error strings.
|
||||
static char bli_error_string[BLIS_MAX_NUM_ERR_MSGS][BLIS_MAX_ERR_MSG_LENGTH];
|
||||
|
||||
|
||||
errlev_t bli_error_checking_level()
|
||||
{
|
||||
return bli_err_chk_level;
|
||||
}
|
||||
|
||||
errlev_t bli_error_checking_level_set( errlev_t new_level )
|
||||
{
|
||||
err_t e_val;
|
||||
errlev_t old_level;
|
||||
|
||||
e_val = bli_check_valid_error_level( new_level );
|
||||
bli_check_error_code( e_val );
|
||||
|
||||
old_level = bli_err_chk_level;
|
||||
|
||||
bli_err_chk_level = new_level;
|
||||
|
||||
return old_level;
|
||||
}
|
||||
|
||||
bool_t bli_error_checking_is_enabled()
|
||||
{
|
||||
return bli_error_checking_level() != BLIS_NO_ERROR_CHECKING;
|
||||
}
|
||||
|
||||
char* bli_error_string_for_code( gint_t code )
|
||||
{
|
||||
return bli_error_string[-code];
|
||||
}
|
||||
|
||||
void bli_abort( void )
|
||||
{
|
||||
fprintf( stderr, "libblis: Aborting.\n" );
|
||||
//raise( SIGABRT );
|
||||
abort();
|
||||
}
|
||||
|
||||
void bli_print_msg( char* str, char* file, guint_t line )
|
||||
{
|
||||
fprintf( stderr, "\n" );
|
||||
fprintf( stderr, "libblis: %s (line %lu):\n", file, ( long unsigned int )line );
|
||||
fprintf( stderr, "libblis: %s\n", str );
|
||||
fflush( stderr );
|
||||
}
|
||||
|
||||
void bli_error_init( void )
|
||||
void bli_error_init_msgs( void )
|
||||
{
|
||||
sprintf( bli_error_string_for_code(BLIS_INVALID_ERROR_CHECKING_LEVEL),
|
||||
"Invalid error checking level." );
|
||||
@@ -196,8 +170,53 @@ void bli_error_init( void )
|
||||
"Expected object to be alias." );
|
||||
}
|
||||
|
||||
void bli_error_finalize( void )
|
||||
void bli_print_msg( char* str, char* file, guint_t line )
|
||||
{
|
||||
// Nothing to do.
|
||||
fprintf( stderr, "\n" );
|
||||
fprintf( stderr, "libblis: %s (line %lu):\n", file, ( long unsigned int )line );
|
||||
fprintf( stderr, "libblis: %s\n", str );
|
||||
fflush( stderr );
|
||||
}
|
||||
|
||||
void bli_abort( void )
|
||||
{
|
||||
fprintf( stderr, "libblis: Aborting.\n" );
|
||||
//raise( SIGABRT );
|
||||
abort();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Current error checking level.
|
||||
static errlev_t bli_err_chk_level = BLIS_FULL_ERROR_CHECKING;
|
||||
|
||||
errlev_t bli_error_checking_level( void )
|
||||
{
|
||||
return bli_err_chk_level;
|
||||
}
|
||||
|
||||
errlev_t bli_error_checking_level_set( errlev_t new_level )
|
||||
{
|
||||
err_t e_val;
|
||||
errlev_t old_level;
|
||||
|
||||
e_val = bli_check_valid_error_level( new_level );
|
||||
bli_check_error_code( e_val );
|
||||
|
||||
old_level = bli_err_chk_level;
|
||||
|
||||
bli_err_chk_level = new_level;
|
||||
|
||||
return old_level;
|
||||
}
|
||||
|
||||
bool_t bli_error_checking_is_enabled( void )
|
||||
{
|
||||
return bli_error_checking_level() != BLIS_NO_ERROR_CHECKING;
|
||||
}
|
||||
|
||||
char* bli_error_string_for_code( gint_t code )
|
||||
{
|
||||
return bli_error_string[-code];
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
*/
|
||||
|
||||
|
||||
void bli_error_init( void );
|
||||
void bli_error_finalize( void );
|
||||
bool_t bli_error_is_initialized( void );
|
||||
|
||||
void bli_error_init_msgs( void );
|
||||
void bli_print_msg( char* str, char* file, guint_t line );
|
||||
void bli_abort( void );
|
||||
|
||||
errlev_t bli_error_checking_level( void );
|
||||
errlev_t bli_error_checking_level_set( errlev_t new_level );
|
||||
|
||||
@@ -40,9 +48,4 @@ bool_t bli_error_checking_is_enabled( void );
|
||||
|
||||
char* bli_error_string_for_code( gint_t code );
|
||||
|
||||
void bli_abort( void );
|
||||
void bli_print_msg( char* str, char* file, guint_t line );
|
||||
|
||||
void bli_error_init( void );
|
||||
void bli_error_finalize( void );
|
||||
|
||||
|
||||
@@ -38,22 +38,22 @@
|
||||
pthread_mutex_t initialize_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static bool_t bli_initialized = FALSE;
|
||||
static bool_t bli_is_init = FALSE;
|
||||
|
||||
|
||||
err_t bli_init( void )
|
||||
{
|
||||
err_t r_val = BLIS_FAILURE;
|
||||
|
||||
// If bli_initialized is TRUE, then we know without a doubt that
|
||||
// If bli_is_init is TRUE, then we know without a doubt that
|
||||
// BLIS is presently initialized, and thus we can return early.
|
||||
if ( bli_initialized == TRUE ) return r_val;
|
||||
if ( bli_is_init == TRUE ) return r_val;
|
||||
|
||||
// NOTE: if bli_initialized is FALSE, we cannot be certain that BLIS
|
||||
// NOTE: if bli_is_init is FALSE, we cannot be certain that BLIS
|
||||
// is ready to be initialized; it may be the case that a thread is
|
||||
// inside the critical section below and is already in the process
|
||||
// of initializing BLIS, but has not yet finished and updated
|
||||
// bli_initialized accordingly. This boolean asymmetry is important!
|
||||
// bli_is_init accordingly. This boolean asymmetry is important!
|
||||
|
||||
// We enclose the bodies of bli_init() and bli_finalize() in a
|
||||
// critical section (both with the same name) so that they can be
|
||||
@@ -75,10 +75,10 @@ err_t bli_init( void )
|
||||
// Proceed with initialization only if BLIS is presently uninitialized.
|
||||
// Since we bli_init() and bli_finalize() use the same named critical
|
||||
// section, we can be sure that no other thread is either (a) updating
|
||||
// bli_initialized, or (b) testing bli_initialized within the critical
|
||||
// bli_is_init, or (b) testing bli_is_init within the critical
|
||||
// section (for the purposes of deciding whether to perform the
|
||||
// necessary initialization subtasks).
|
||||
if ( bli_initialized == FALSE )
|
||||
if ( bli_is_init == FALSE )
|
||||
{
|
||||
// Initialize various sub-APIs.
|
||||
bli_const_init();
|
||||
@@ -89,7 +89,7 @@ err_t bli_init( void )
|
||||
bli_thread_init();
|
||||
|
||||
// After initialization is complete, mark BLIS as initialized.
|
||||
bli_initialized = TRUE;
|
||||
bli_is_init = TRUE;
|
||||
|
||||
// Only the thread that actually performs the initialization will
|
||||
// return "success".
|
||||
@@ -109,15 +109,15 @@ err_t bli_finalize( void )
|
||||
{
|
||||
err_t r_val = BLIS_FAILURE;
|
||||
|
||||
// If bli_initialized is FALSE, then we know without a doubt that
|
||||
// If bli_is_init is FALSE, then we know without a doubt that
|
||||
// BLIS is presently uninitialized, and thus we can return early.
|
||||
if ( bli_initialized == FALSE ) return r_val;
|
||||
if ( bli_is_init == FALSE ) return r_val;
|
||||
|
||||
// NOTE: if bli_initialized is TRUE, we cannot be certain that BLIS
|
||||
// NOTE: if bli_is_init is TRUE, we cannot be certain that BLIS
|
||||
// is ready to be finalized; it may be the case that a thread is
|
||||
// inside the critical section below and is already in the process
|
||||
// of finalizing BLIS, but has not yet finished and updated
|
||||
// bli_initialized accordingly. This boolean asymmetry is important!
|
||||
// bli_is_init accordingly. This boolean asymmetry is important!
|
||||
|
||||
// We enclose the bodies of bli_init() and bli_finalize() in a
|
||||
// critical section (both with the same name) so that they can be
|
||||
@@ -139,10 +139,10 @@ err_t bli_finalize( void )
|
||||
// Proceed with finalization only if BLIS is presently initialized.
|
||||
// Since we bli_init() and bli_finalize() use the same named critical
|
||||
// section, we can be sure that no other thread is either (a) updating
|
||||
// bli_initialized, or (b) testing bli_initialized within the critical
|
||||
// bli_is_init, or (b) testing bli_is_init within the critical
|
||||
// section (for the purposes of deciding whether to perform the
|
||||
// necessary finalization subtasks).
|
||||
if ( bli_initialized == TRUE )
|
||||
if ( bli_is_init == TRUE )
|
||||
{
|
||||
// Finalize various sub-APIs.
|
||||
bli_const_finalize();
|
||||
@@ -153,7 +153,7 @@ err_t bli_finalize( void )
|
||||
bli_thread_finalize();
|
||||
|
||||
// After finalization is complete, mark BLIS as uninitialized.
|
||||
bli_initialized = FALSE;
|
||||
bli_is_init = FALSE;
|
||||
|
||||
// Only the thread that actually performs the finalization will
|
||||
// return "success".
|
||||
@@ -173,6 +173,11 @@ err_t bli_finalize( void )
|
||||
return r_val;
|
||||
}
|
||||
|
||||
bool_t bli_is_initialized( void )
|
||||
{
|
||||
return bli_is_init;
|
||||
}
|
||||
|
||||
void bli_init_auto( err_t* init_result )
|
||||
{
|
||||
*init_result = bli_init();
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
|
||||
*/
|
||||
|
||||
err_t bli_init( void );
|
||||
err_t bli_finalize( void );
|
||||
err_t bli_init( void );
|
||||
err_t bli_finalize( void );
|
||||
bool_t bli_is_initialized( void );
|
||||
|
||||
void bli_init_auto( err_t* init_result );
|
||||
void bli_finalize_auto( err_t init_result );
|
||||
void bli_init_auto( err_t* init_result );
|
||||
void bli_finalize_auto( err_t init_result );
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
static bool_t bli_mem_is_init = FALSE;
|
||||
|
||||
#ifdef BLIS_ENABLE_PTHREADS
|
||||
pthread_mutex_t mem_manager_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
@@ -259,7 +261,7 @@ void bli_mem_acquire_v( siz_t req_size,
|
||||
|
||||
|
||||
|
||||
void bli_mem_init()
|
||||
void bli_mem_init( void )
|
||||
{
|
||||
dim_t index_a;
|
||||
dim_t index_b;
|
||||
@@ -307,6 +309,9 @@ void bli_mem_init()
|
||||
#ifdef BLIS_ENABLE_PTHREADS
|
||||
pthread_mutex_unlock( &mem_manager_mutex );
|
||||
#endif
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_mem_is_init = TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +364,7 @@ void bli_mem_init_pool( char* pool_mem,
|
||||
|
||||
|
||||
|
||||
void bli_mem_finalize()
|
||||
void bli_mem_finalize( void )
|
||||
{
|
||||
|
||||
#ifdef BLIS_ENABLE_OPENMP
|
||||
@@ -383,5 +388,12 @@ void bli_mem_finalize()
|
||||
pthread_mutex_destroy( &mem_manager_mutex );
|
||||
#endif
|
||||
|
||||
// Mark API as uninitialized.
|
||||
bli_mem_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_mem_is_initialized( void )
|
||||
{
|
||||
return bli_mem_is_init;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
|
||||
*/
|
||||
|
||||
void bli_mem_init( void );
|
||||
void bli_mem_finalize( void );
|
||||
bool_t bli_mem_is_initialized( void );
|
||||
|
||||
|
||||
void bli_mem_acquire_m( siz_t req_size,
|
||||
packbuf_t buf_type,
|
||||
mem_t* mem );
|
||||
@@ -41,9 +46,6 @@ void bli_mem_acquire_v( siz_t req_size,
|
||||
|
||||
void bli_mem_release( mem_t* mem );
|
||||
|
||||
void bli_mem_init( void );
|
||||
void bli_mem_finalize( void );
|
||||
|
||||
void bli_mem_init_pool( char* pool_mem,
|
||||
siz_t block_size,
|
||||
dim_t n_blocks,
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
static bool_t bli_thread_is_init = FALSE;
|
||||
|
||||
packm_thrinfo_t BLIS_PACKM_SINGLE_THREADED;
|
||||
gemm_thrinfo_t BLIS_GEMM_SINGLE_THREADED;
|
||||
herk_thrinfo_t BLIS_HERK_SINGLE_THREADED;
|
||||
@@ -46,13 +48,24 @@ void bli_thread_init( void )
|
||||
bli_setup_packm_single_threaded_info( &BLIS_PACKM_SINGLE_THREADED );
|
||||
bli_setup_gemm_single_threaded_info( &BLIS_GEMM_SINGLE_THREADED );
|
||||
bli_setup_herk_single_threaded_info( &BLIS_HERK_SINGLE_THREADED );
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_thread_is_init = TRUE;
|
||||
}
|
||||
|
||||
void bli_thread_finalize( void )
|
||||
{
|
||||
// Nothing to do.
|
||||
// Mark API as uninitialized.
|
||||
bli_thread_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_thread_is_initialized( void )
|
||||
{
|
||||
return bli_thread_is_init;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
//*********** Stuff Specific to single-threaded *************
|
||||
#ifndef BLIS_ENABLE_MULTITHREADING
|
||||
void bli_barrier( thread_comm_t* communicator, dim_t t_id )
|
||||
|
||||
@@ -89,6 +89,7 @@ typedef struct thread_comm_s thread_comm_t;
|
||||
|
||||
void bli_thread_init( void );
|
||||
void bli_thread_finalize( void );
|
||||
bool_t bli_thread_is_initialized( void );
|
||||
|
||||
// Thread Communicator Interface Definitions
|
||||
void bli_setup_communicator( thread_comm_t* communicator, dim_t n_threads );
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
static bool_t bli_cntl_is_init = FALSE;
|
||||
|
||||
void bli_cntl_init( void )
|
||||
{
|
||||
// Level-1
|
||||
@@ -61,6 +63,9 @@ void bli_cntl_init( void )
|
||||
|
||||
// Level-3 induced
|
||||
bli_ind_cntl_init();
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_cntl_is_init = TRUE;
|
||||
}
|
||||
|
||||
void bli_cntl_finalize( void )
|
||||
@@ -90,5 +95,13 @@ void bli_cntl_finalize( void )
|
||||
|
||||
// Level-3 induced
|
||||
bli_ind_cntl_finalize();
|
||||
|
||||
// Mark API as uninitialized.
|
||||
bli_cntl_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_cntl_is_initialized( void )
|
||||
{
|
||||
return bli_cntl_is_init;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,5 +32,6 @@
|
||||
|
||||
*/
|
||||
|
||||
void bli_cntl_init( void );
|
||||
void bli_cntl_finalize( void );
|
||||
void bli_cntl_init( void );
|
||||
void bli_cntl_finalize( void );
|
||||
bool_t bli_cntl_is_initialized( void );
|
||||
|
||||
@@ -169,7 +169,8 @@ blksz_t* bli_bsv_get_blksz( bszid_t bsv, ind_t method )
|
||||
{
|
||||
// Initialize BLIS, if it isn't already initialized. This is
|
||||
// needed because we have to ensure that the blksz_t objects
|
||||
// have been created.
|
||||
// have been created, otherwise this function could return a
|
||||
// NULL (or garbage) address.
|
||||
bli_init();
|
||||
|
||||
return *(bli_bsizes[ method ][ bsv ]);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "blis.h"
|
||||
|
||||
static bool_t bli_ind_is_init = FALSE;
|
||||
|
||||
static void* bli_ind_oper_fp[BLIS_NUM_IND_METHODS][BLIS_NUM_LEVEL3_OPS] =
|
||||
{
|
||||
@@ -220,11 +221,20 @@ void bli_ind_init( void )
|
||||
#ifdef BLIS_ENABLE_INDUCED_DCOMPLEX
|
||||
bli_ind_enable_dt( BLIS_4M1A, BLIS_DCOMPLEX );
|
||||
#endif
|
||||
|
||||
// Mark API as initialized.
|
||||
bli_ind_is_init = TRUE;
|
||||
}
|
||||
|
||||
void bli_ind_finalize( void )
|
||||
{
|
||||
// Nothing to do.
|
||||
// Mark API as uninitialized.
|
||||
bli_ind_is_init = FALSE;
|
||||
}
|
||||
|
||||
bool_t bli_ind_is_initialized( void )
|
||||
{
|
||||
return bli_ind_is_init;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -84,6 +84,7 @@ char* bli_ind_oper_get_avail_impl_string( opid_t oper, num_t dt );
|
||||
|
||||
void bli_ind_init( void );
|
||||
void bli_ind_finalize( void );
|
||||
bool_t bli_ind_is_initialized( void );
|
||||
|
||||
void bli_ind_enable( ind_t method );
|
||||
void bli_ind_disable( ind_t method );
|
||||
|
||||
@@ -205,7 +205,8 @@ func_t* bli_ukr_get_funcs( l3ukr_t ukr, ind_t method )
|
||||
// have been created (and thus contain valid function pointers).
|
||||
bli_init();
|
||||
|
||||
// Avoid dereferencing NULL pointers.
|
||||
// Avoid dereferencing NULL pointers. (A NULL pointer indicates that
|
||||
// there is no kernel for the requested kernel type and method.)
|
||||
if ( p == NULL ) return NULL;
|
||||
else return *p;
|
||||
}
|
||||
@@ -219,7 +220,8 @@ func_t* bli_ukr_get_ref_funcs( l3ukr_t ukr )
|
||||
// have been created (and thus contain valid function pointers).
|
||||
bli_init();
|
||||
|
||||
// Avoid dereferencing NULL pointers.
|
||||
// Avoid dereferencing NULL pointers. (A NULL pointer indicates that
|
||||
// there is no reference kernel for the requested kernel type.)
|
||||
if ( p == NULL ) return NULL;
|
||||
else return *p;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user