Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul error handling in the core framework #633

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions addon/gemmd/attic/bli_gemm_ex.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,10 @@ void bli_gemm_ex
// Initialize a local runtime with global settings if necessary. Note
// that in the case that a runtime is passed in, we make a local copy.
rntm_t rntm_l;
if ( rntm == NULL ) { bli_rntm_init_from_global( &rntm_l ); rntm = &rntm_l; }
else { rntm_l = *rntm; rntm = &rntm_l; }
bli_rntm_init_if_null( &rntm, &rntm_l );

// Obtain a valid (native) context from the gks if necessary.
if ( cntx == NULL ) cntx = bli_gks_query_cntx();
bli_gks_query_cntx_if_null( ( const cntx_t** )&cntx ); \

// Check the operands.
if ( bli_error_checking_is_enabled() )
Expand Down
5 changes: 2 additions & 3 deletions addon/gemmd/bao_gemmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ void bao_gemmd_ex
// Initialize a local runtime with global settings if necessary. Note
// that in the case that a runtime is passed in, we make a local copy.
rntm_t rntm_l;
if ( rntm == NULL ) { bli_rntm_init_from_global( &rntm_l ); rntm = &rntm_l; }
else { rntm_l = *rntm; rntm = &rntm_l; }
bli_rntm_init_if_null( &rntm, &rntm_l );

// Obtain a valid (native) context from the gks if necessary.
// NOTE: This must be done before calling the _check() function, since
// that function assumes the context pointer is valid.
if ( cntx == NULL ) cntx = bli_gks_query_cntx();
bli_gks_query_cntx_if_null( ( const cntx_t** )&cntx ); \

// Check parameters.
if ( bli_error_checking_is_enabled() )
Expand Down
14 changes: 14 additions & 0 deletions build/bli_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@
#define BLIS_DISABLE_SBA_POOLS
#endif

#if @enable_error_checking@
#define BLIS_ENABLE_ERROR_CHECKING
#else
#define BLIS_DISABLE_ERROR_CHECKING
#endif

#if @enable_error_return@
#define BLIS_ENABLE_ERROR_RETURN
#endif

#if @enable_error_abort@
#define BLIS_ENABLE_ERROR_ABORT
#endif

#if @enable_mem_tracing@
#define BLIS_ENABLE_MEM_TRACING
#else
Expand Down
6 changes: 4 additions & 2 deletions build/detect/config/config_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@

int main( int argc, char** argv )
{
arch_t id = bli_cpuid_query_id();
const char* s = bli_arch_string( id );
const char* s;

arch_t id = bli_cpuid_query_id();
err_t r_val = bli_arch_string( id, &s );

printf( "%s\n", s );

Expand Down
92 changes: 83 additions & 9 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,30 @@ print_usage()
echo " it no longer needs to call malloc() or free(), even"
echo " across many separate level-3 operation invocations."
echo " "
echo " --enable-error-checking, --disable-error-checking"
echo " "
echo " Disable (enabled by default) runtime error checking. This"
echo " includes checking for things such as inconsistent object"
echo " properties, memory allocation errors, and configuration"
echo " errors. When enabled, BLIS will report an error via the"
echo " method specified by the --error-handling-mode option."
echo " When disabled, any function that is set up to return an"
echo " error code will return \"success\" unconditionally."
echo " "
echo " --error-handling-mode=[return|abort]"
echo " "
echo " Specify the way that BLIS reacts to errors. The 'return'"
echo " mode causes BLIS to return an error code all the way up"
echo " the function stack to the caller, which may then be used"
echo " to query a human-readable error string. The 'abort' mode"
echo " causes BLIS to output the aforementioned error string and"
echo " then call abort(), which facilitates debugging (e.g. via"
echo " a debugger's backtrace feature). By default, the 'abort'"
echo " mode is used."
echo " "
echo " --enable-mem-tracing, --disable-mem-tracing"
echo " "
echo " Enable (disable by default) output to stdout that traces"
echo " Enable (disabled by default) output to stdout that traces"
echo " the allocation and freeing of memory, including the names"
echo " of the functions that triggered the allocation/freeing."
echo " Enabling this option WILL NEGATIVELY IMPACT PERFORMANCE."
Expand Down Expand Up @@ -339,8 +360,8 @@ print_usage()
echo " these division instructions within the microkernel will"
echo " incur a performance penalty, but numerical robustness will"
echo " improve for certain cases involving denormal numbers that"
echo " would otherwise result in overflow in the pre-inverted"
echo " values."
echo " would otherwise result in overflow if pre-inversion were"
echo " employed."
echo " "
echo " --force-version=STRING"
echo " "
Expand All @@ -356,14 +377,14 @@ print_usage()
echo " a sanity check to make sure these lists are constituted"
echo " as expected."
echo " "
echo " --complex-return=gnu|intel"
echo " --complex-return=[gnu|intel]"
echo " "
echo " Specify the way in which complex numbers are returned"
echo " from Fortran functions, either \"gnu\" (return in"
echo " registers) or \"intel\" (return via hidden argument)."
echo " from Fortran functions, either 'gnu' (return in"
echo " registers) or 'intel' (return via hidden argument)."
echo " If not specified and the environment variable FC is set,"
echo " attempt to determine the return type from the compiler."
echo " Otherwise, the default is \"gnu\"."
echo " Otherwise, the default is 'gnu'."
echo " "
echo " -q, --quiet Suppress informational output. By default, configure"
echo " is verbose. (NOTE: -q is not yet implemented)"
Expand Down Expand Up @@ -2451,6 +2472,10 @@ main()
quiet_flag=''
show_config_list=''

# Error-related flags.
enable_error_checking='yes'
error_handling_mode='abort'

# Additional flags.
enable_verbose='no'
enable_arg_max_hack='no'
Expand Down Expand Up @@ -2602,6 +2627,15 @@ main()
disable-system)
enable_system='no'
;;
enable-error-checking)
enable_error_checking='yes'
;;
disable-error-checking)
enable_error_checking='no'
;;
error-handling-mode=*)
error_handling_mode=${OPTARG#*=}
;;
enable-threading=*)
threading_model=${OPTARG#*=}
;;
Expand Down Expand Up @@ -3465,7 +3499,7 @@ main()
exit 1
fi

# Convert 'yes' and 'no' flags to booleans.
# Check if we are enabling memory pools for large or small blocks.
if [ "x${enable_pba_pools}" = "xyes" ]; then
echo "${script_name}: internal memory pools for packing blocks are enabled."
enable_pba_pools_01=1
Expand All @@ -3480,13 +3514,40 @@ main()
echo "${script_name}: internal memory pools for small blocks are disabled."
enable_sba_pools_01=0
fi

# Check if we are enabling error checking.
if [ "x${enable_error_checking}" = "xyes" ]; then
echo "${script_name}: error checking is enabled."
enable_error_checking_01=1
else
echo "${script_name}: error checking is disabled."
enable_error_checking_01=0
fi

# Check the error handling mode.
enable_error_return_01=0
enable_error_abort_01=0
if [ "x${error_handling_mode}" = "xreturn" ]; then
echo "${script_name}: requesting that error codes be returned to caller."
enable_error_return_01=1
elif [ "x${error_handling_mode}" = "xabort" ]; then
echo "${script_name}: requesting that errors trigger a message followed by abort()."
enable_error_abort_01=1
else
echo "${script_name}: *** Unsupported mode of error handling: ${error_handling_mode}."
exit 1
fi

# Check if we are enabling memory tracing output.
if [ "x${enable_mem_tracing}" = "xyes" ]; then
echo "${script_name}: memory tracing output is enabled."
enable_mem_tracing_01=1
else
echo "${script_name}: memory tracing output is disabled."
enable_mem_tracing_01=0
fi

# Check if we are enabling support for libmemkind.
if [ "x${has_memkind}" = "xyes" ]; then
if [ "x${enable_memkind}" = "x" ]; then
# If no explicit option was given for libmemkind one way or the other,
Expand Down Expand Up @@ -3514,13 +3575,17 @@ main()
enable_memkind="no"
enable_memkind_01=0
fi

# Check if we are enabling #pragma omp simd.
if [ "x${pragma_omp_simd}" = "xyes" ]; then
echo "${script_name}: compiler appears to support #pragma omp simd."
enable_pragma_omp_simd_01=1
else
echo "${script_name}: compiler appears to not support #pragma omp simd."
enable_pragma_omp_simd_01=0
fi

# Check if we are enabling the BLAS/CBLAS compatibility layers.
if [ "x${enable_blas}" = "xyes" ]; then
echo "${script_name}: the BLAS compatibility layer is enabled."
enable_blas_01=1
Expand All @@ -3537,6 +3602,8 @@ main()
echo "${script_name}: the CBLAS compatibility layer is disabled."
enable_cblas_01=0
fi

# Check if we are enabling mixed datatype support.
if [ "x${enable_mixed_dt}" = "xyes" ]; then
echo "${script_name}: mixed datatype support is enabled."

Expand All @@ -3555,13 +3622,17 @@ main()
enable_mixed_dt_extra_mem_01=0
enable_mixed_dt_01=0
fi

# Check if we are enabling skinny/unpacked (sup) matrix handling.
if [ "x${enable_sup_handling}" = "xyes" ]; then
echo "${script_name}: small matrix handling is enabled."
enable_sup_handling_01=1
else
echo "${script_name}: small matrix handling is disabled."
enable_sup_handling_01=0
fi

# Check if we are enabling pre-inversion of diagonal elements for trsm.
if [ "x${enable_trsm_preinversion}" = "xyes" ]; then
echo "${script_name}: trsm diagonal element pre-inversion is enabled."
enable_trsm_preinversion_01=1
Expand Down Expand Up @@ -3713,7 +3784,7 @@ main()
exit 1
fi

echo "${script_name}: configuring complex return type as \"${complex_return}\"."
echo "${script_name}: configuring complex return type as '${complex_return}'."

# Variables that may contain forward slashes, such as paths, need extra
# escaping when used in sed commands. We insert those extra escape
Expand Down Expand Up @@ -3896,6 +3967,9 @@ main()
| sed -e "s/@enable_jrir_rr@/${enable_jrir_rr_01}/g" \
| sed -e "s/@enable_pba_pools@/${enable_pba_pools_01}/g" \
| sed -e "s/@enable_sba_pools@/${enable_sba_pools_01}/g" \
| sed -e "s/@enable_error_checking@/${enable_error_checking_01}/g" \
| sed -e "s/@enable_error_return@/${enable_error_return_01}/g" \
| sed -e "s/@enable_error_abort@/${enable_error_abort_01}/g" \
| sed -e "s/@enable_mem_tracing@/${enable_mem_tracing_01}/g" \
| sed -e "s/@int_type_size@/${int_type_size}/g" \
| sed -e "s/@blas_int_type_size@/${blas_int_type_size}/g" \
Expand Down
20 changes: 10 additions & 10 deletions docs/BLISObjectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,9 @@ The expert interface contains two additional parameters: a `cntx_t*` and `rntm_t

In general, it is permissible to pass in `NULL` for a `cntx_t*` parameter when calling an expert interface such as `bli_gemm_ex()`. However, there are cases where `NULL` values are not accepted and may result in a segmentation fault. Specifically, the `cntx_t*` argument appears in the interfaces to the `gemm`, `trsm`, and `gemmtrsm` [level-3 microkernels](KernelsHowTo.md#level-3) along with all [level-1v](KernelsHowTo.md#level-1v) and [level-1f](KernelsHowTo.md#level-1f) kernels. There, as a general rule, a valid pointer must be passed in. Whenever a valid context is needed, the developer may query a default context from the global kernel structure (if a context is not already available in the current scope):
```c
cntx_t* bli_gks_query_cntx( void );
err_t bli_gks_query_cntx( cntx** cntx );
```
When BLIS is configured to target a configuration family (e.g. `intel64`, `x86_64`), `bli_gks_query_cntx()` will use `cpuid` or an equivalent heuristic to select and and return the appropriate context. When BLIS is configured to target a singleton sub-configuration (e.g. `haswell`, `skx`), `bli_gks_query_cntx()` will unconditionally return a pointer to the context appropriate for the targeted configuration.
When BLIS is configured to target a configuration family (e.g. `intel64`, `x86_64`), `bli_gks_query_cntx()` will use `cpuid` or an equivalent heuristic to provide the appropriate context. When BLIS is configured to target a singleton sub-configuration (e.g. `haswell`, `skx`), `bli_gks_query_cntx()` will unconditionally provide a pointer to the context appropriate for the targeted configuration.

## Runtime type

Expand Down Expand Up @@ -2288,15 +2288,15 @@ char* bli_info_get_version_str( void );

## Specific configuration

The following routine returns a unique ID of type `arch_t` that identifies the current current active configuration:
The following routine determines a unique ID of type `arch_t` that identifies the current current active configuration:
```c
arch_t bli_arch_query_id( void );
err_t bli_arch_query_id( arch_t* id );
```
This is most useful when BLIS is configured with multiple configurations. (When linking to multi-configuration builds of BLIS, you don't know for sure which configuration will be used until runtime since the configuration-specific parameters are not loaded until after calling a hueristic to detect the hardware--usually based the `CPUID` instruction.)

Once the configuration's ID is known, it can be used to query a string that contains the name of the configuration:
```c
char* bli_arch_string( arch_t id );
err_t bli_arch_string( arch_t id, const char** str );
```

## General configuration
Expand Down Expand Up @@ -2328,11 +2328,11 @@ gint_t bli_info_get_blas_int_type_size( void );
The following routines allow the caller to obtain a string that identifies the implementation type of each microkernel that is currently active (ie: part of the current active configuration, as identified bi `bli_arch_query_id()`).

```c
char* bli_info_get_gemm_ukr_impl_string( ind_t method, num_t dt )
char* bli_info_get_gemmtrsm_l_ukr_impl_string( ind_t method, num_t dt )
char* bli_info_get_gemmtrsm_u_ukr_impl_string( ind_t method, num_t dt )
char* bli_info_get_trsm_l_ukr_impl_string( ind_t method, num_t dt )
char* bli_info_get_trsm_u_ukr_impl_string( ind_t method, num_t dt )
err_t bli_info_get_gemm_ukr_impl_string( ind_t method, num_t dt, char** str )
err_t bli_info_get_gemmtrsm_l_ukr_impl_string( ind_t method, num_t dt, char** str )
err_t bli_info_get_gemmtrsm_u_ukr_impl_string( ind_t method, num_t dt, char** str )
err_t bli_info_get_trsm_l_ukr_impl_string( ind_t method, num_t dt, char** str )
err_t bli_info_get_trsm_u_ukr_impl_string( ind_t method, num_t dt, char** str )
```

Possible implementation (ie: the `ind_t method` argument) types are:
Expand Down
Loading