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:
Field G. Van Zee
2015-06-11 18:52:12 -05:00
parent ee129c6b02
commit 5f93cbe870
16 changed files with 187 additions and 92 deletions

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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];
}

View File

@@ -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 );

View File

@@ -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();

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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 )

View File

@@ -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 );

View File

@@ -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;
}

View File

@@ -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 );

View File

@@ -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 ]);

View File

@@ -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;
}
// -----------------------------------------------------------------------------

View File

@@ -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 );

View File

@@ -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;
}