Skip to content

WIP: Handle defective implementations of float functions. #68

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions src/flexiblas.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ static void flexiblas_load_info(void *library, flexiblas_backend_t *backend)

#endif

/* Check if functions return the correct type (real) */
backend->info.float_function_defect = __flexiblas_check_float_function(library, backend->info.intel_interface);

/* Get the Integer size of the backend */
flexiblas_interface_t interface = __flexiblas_get_interface(library);
if ( interface == FLEXIBLAS_INTERFACE_LP64 )
Expand Down
1 change: 1 addition & 0 deletions src/flexiblas.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ int __flexiblas_load_fortran_function( void * handle , struct flexiblas_blasfn *
int __flexiblas_load_blas_hooks(flexiblas_hook_t *backend, void *hook_handle);
void * __flexiblas_lookup_fortran_function(void * handle, const char *name);
flexiblas_complex_interface_t __flexiblas_get_complex_interface(void *handle);
int __flexiblas_check_float_function(void *handle, int intel_interface);
flexiblas_interface_t __flexiblas_get_interface(void *handle);

void __flexiblas_backend_init( flexiblas_backend_t * backend);
Expand Down
1 change: 1 addition & 0 deletions src/flexiblas_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern "C" {
int flexiblas_integer_size;
int backend_integer_size;
int intel_interface;
int float_function_defect;
int post_init;
} flexiblas_info_t;

Expand Down
45 changes: 45 additions & 0 deletions src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,51 @@ HIDDEN flexiblas_complex_interface_t __flexiblas_get_complex_interface(void *han
#endif
}

HIDDEN int __flexiblas_check_float_function(void *handle, int intel_interface)
{
if (handle == NULL) {
return 0;
}
void *sdot_ptr = __flexiblas_lookup_fortran_function(handle, "sdot");
if ( sdot_ptr == NULL) {
DPRINTF(2, "Could not check for defect of functions with real return value. SDOT not found.\n");
return 0;
}

float retval = 0.0;
float x[2] = {1.0, 2.0};
float y[2] = {3.0, 4.0};
#ifdef FLEXIBLAS_INTEGER8
int64_t n = 2;
int64_t one = 1;
#else
int32_t n = 2;
int32_t one = 1;
#endif
if (intel_interface) {
#ifdef FLEXIBLAS_INTEGER8
void (*sdot)(float *, int64_t *, float *, int64_t *, float *, int64_t *);
#else
void (*sdot)(float *, int32_t *, float *, int32_t *, float *, int32_t *);
#endif

sdot(&retval, &n, x, &one, y, &one);
Comment on lines +223 to +230
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (intel_interface) this could just return 0, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how many implementations of BLAS/LAPACK could potentially have this defect. The only one I know for sure is Apple Accelerate (that doesn't use the Intel calling convention afaict).

I figured that the safest would be to check in any case. But if you feel confident that no implementation that uses the Intel calling convention could potentially be affected, you could remove the test from that branch.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Thanks for the explanation!

} else {
#ifdef FLEXIBLAS_INTEGER8
float (*sdot)(int64_t *, float *, int64_t *, float *, int64_t *);
#else
float (*sdot)(int32_t *, float *, int32_t *, float *, int32_t *);
#endif

retval = sdot(&n, x, &one, y, &one);
}

if (retval == 11.0)
return 0;
else
return 1;
}

HIDDEN flexiblas_interface_t __flexiblas_get_interface(void *handle)
{
if (handle == NULL) {
Expand Down
69 changes: 43 additions & 26 deletions src/wrapper_blas_gnu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6601,24 +6601,31 @@ void flexiblas_chain_scopy(void* n, void* sx, void* incx, void* sy, void* incy){
#endif


#define SDOT_INTERN(ret_type) \
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
ret_type (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy); \
if ( current_backend->post_init != 0 ) { \
__flexiblas_backend_init(current_backend); \
current_backend->post_init = 0; \
} \
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0]; \
hook_pos_sdot = 0; \
if ( fn_hook != NULL) { \
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy); \
} else { \
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy); \
}

static TLS_STORE uint8_t hook_pos_sdot = 0;

float FC_GLOBAL(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, blasint* incy)
{
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
float ret;
if ( current_backend->post_init != 0 ) {
__flexiblas_backend_init(current_backend);
current_backend->post_init = 0;
}
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
hook_pos_sdot = 0;
if ( fn_hook != NULL) {
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
if (current_backend->info.float_function_defect) {
SDOT_INTERN(double)
} else {
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
SDOT_INTERN(float)
}
return ret;
}
Expand All @@ -6636,14 +6643,20 @@ float FC_GLOBAL3(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, bla
#endif


#define REAL_SDOT_INTERN(ret_type) \
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
\
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);

float flexiblas_real_sdot_(void* n, void* sx, void* incx, void* sy, void* incy)
{
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
float ret;

*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
if (current_backend->info.float_function_defect) {
REAL_SDOT_INTERN(double)
} else {
REAL_SDOT_INTERN(float)
}

return ret;
}
Expand All @@ -6653,22 +6666,26 @@ float flexiblas_real_sdot(void* n, void* sx, void* incx, void* sy, void* incy) _
float flexiblas_real_sdot(void* n, void* sx, void* incx, void* sy, void* incy){return flexiblas_real_sdot_((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);}
#endif

#define CHAIN_SDOT_INTERN(ret_type) \
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
\
hook_pos_sdot++; \
if ( hook_pos_sdot < __flexiblas_hooks->sdot.nhook ) { \
*(void **) &fn = __flexiblas_hooks->sdot.f77_hook_function[hook_pos_sdot]; \
} else { \
hook_pos_sdot = 0; \
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
} \
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);

float flexiblas_chain_sdot_(void* n, void* sx, void* incx, void* sy, void* incy)
{
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
float ret;



hook_pos_sdot++;
if ( hook_pos_sdot < __flexiblas_hooks->sdot.nhook ) {
*(void **) &fn = __flexiblas_hooks->sdot.f77_hook_function[hook_pos_sdot];
if (current_backend->info.float_function_defect) {
CHAIN_SDOT_INTERN(double)
} else {
hook_pos_sdot = 0;
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
CHAIN_SDOT_INTERN(float)
}
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);

return ret;
}
Expand Down
41 changes: 29 additions & 12 deletions src/wrapper_blas_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -6607,20 +6607,37 @@ static TLS_STORE uint8_t hook_pos_sdot = 0;

float FC_GLOBAL(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, blasint* incy)
{
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
float ret;
if ( current_backend->post_init != 0 ) {
__flexiblas_backend_init(current_backend);
current_backend->post_init = 0;
}
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
hook_pos_sdot = 0;
if ( fn_hook != NULL) {
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
if (current_backend->info.float_function_defect) {
double (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
double (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
if ( current_backend->post_init != 0 ) {
__flexiblas_backend_init(current_backend);
current_backend->post_init = 0;
}
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
hook_pos_sdot = 0;
if ( fn_hook != NULL) {
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
} else {
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
}
} else {
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
if ( current_backend->post_init != 0 ) {
__flexiblas_backend_init(current_backend);
current_backend->post_init = 0;
}
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
hook_pos_sdot = 0;
if ( fn_hook != NULL) {
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
} else {
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
}
}
return ret;
}
Expand Down