Skip to content

Commit 1710c58

Browse files
committed
WIP: Handle defective implementations of float functions.
This is a very crude attempt to check whether BLAS functions that should return single-precision floating point values actually do that. Some implementations (like Apple Accelerate) don't do that. See mpimd-csc#65. This is mainly meant for early feedback.
1 parent ac4300b commit 1710c58

File tree

6 files changed

+101
-24
lines changed

6 files changed

+101
-24
lines changed

src/flexiblas.c

+3
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ static void flexiblas_load_info(void *library, flexiblas_backend_t *backend)
216216

217217
#endif
218218

219+
/* Check if functions return the correct type (real) */
220+
backend->info.float_function_defect = __flexiblas_check_float_function(library, backend->info.intel_interface);
221+
219222
/* Get the Integer size of the backend */
220223
flexiblas_interface_t interface = __flexiblas_get_interface(library);
221224
if ( interface == FLEXIBLAS_INTERFACE_LP64 )

src/flexiblas.h

+1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ int __flexiblas_load_fortran_function( void * handle , struct flexiblas_blasfn *
145145
int __flexiblas_load_blas_hooks(flexiblas_hook_t *backend, void *hook_handle);
146146
void * __flexiblas_lookup_fortran_function(void * handle, const char *name);
147147
flexiblas_complex_interface_t __flexiblas_get_complex_interface(void *handle);
148+
int __flexiblas_check_float_function(void *handle, int intel_interface);
148149
flexiblas_interface_t __flexiblas_get_interface(void *handle);
149150

150151
void __flexiblas_backend_init( flexiblas_backend_t * backend);

src/flexiblas_backend.h

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ extern "C" {
5353
int flexiblas_integer_size;
5454
int backend_integer_size;
5555
int intel_interface;
56+
int float_function_defect;
5657
int post_init;
5758
} flexiblas_info_t;
5859

src/loader.c

+38
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,44 @@ HIDDEN flexiblas_complex_interface_t __flexiblas_get_complex_interface(void *han
199199
#endif
200200
}
201201

202+
HIDDEN int __flexiblas_check_float_function(void *handle, int intel_interface)
203+
{
204+
if (handle == NULL) {
205+
return 0;
206+
}
207+
void *sdot_ptr = __flexiblas_lookup_fortran_function(handle, "sdot");
208+
if ( sdot_ptr == NULL) {
209+
DPRINTF(2, "Could not check for defect of functions with real return value. SDOT not found.\n");
210+
return 0;
211+
}
212+
213+
float retval = 0.0;
214+
float x[2] = {1.0, 2.0};
215+
float y[2] = {3.0, 4.0};
216+
if (intel_interface) {
217+
#ifdef FLEXIBLAS_INTEGER8
218+
void (*sdot)(float *, int64_t *, float *, int64_t *, float *, int64_t *);
219+
#else
220+
void (*sdot)(float *, int32_t *, float *, int32_t *, float *, int32_t *);
221+
#endif
222+
223+
sdot(&retval, 2, x, 1, y, 1);
224+
} else {
225+
#ifdef FLEXIBLAS_INTEGER8
226+
float (*sdot)(int64_t *, float *, int64_t *, float *, int64_t *);
227+
#else
228+
float (*sdot)(int32_t *, float *, int32_t *, float *, int32_t *);
229+
#endif
230+
231+
retval = sdot(2, x, 1, y, 1);
232+
}
233+
234+
if (retval == 11.0)
235+
return 0;
236+
else
237+
return 1;
238+
}
239+
202240
HIDDEN flexiblas_interface_t __flexiblas_get_interface(void *handle)
203241
{
204242
if (handle == NULL) {

src/wrapper_blas_gnu.c

+29-12
Original file line numberDiff line numberDiff line change
@@ -6605,20 +6605,37 @@ static TLS_STORE uint8_t hook_pos_sdot = 0;
66056605

66066606
float FC_GLOBAL(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, blasint* incy)
66076607
{
6608-
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6609-
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
66106608
float ret;
6611-
if ( current_backend->post_init != 0 ) {
6612-
__flexiblas_backend_init(current_backend);
6613-
current_backend->post_init = 0;
6614-
}
6615-
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6616-
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6617-
hook_pos_sdot = 0;
6618-
if ( fn_hook != NULL) {
6619-
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6609+
if (current_backend->info.float_function_defect) {
6610+
double (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6611+
double (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
6612+
if ( current_backend->post_init != 0 ) {
6613+
__flexiblas_backend_init(current_backend);
6614+
current_backend->post_init = 0;
6615+
}
6616+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6617+
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6618+
hook_pos_sdot = 0;
6619+
if ( fn_hook != NULL) {
6620+
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6621+
} else {
6622+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6623+
}
66206624
} else {
6621-
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6625+
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6626+
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
6627+
if ( current_backend->post_init != 0 ) {
6628+
__flexiblas_backend_init(current_backend);
6629+
current_backend->post_init = 0;
6630+
}
6631+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6632+
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6633+
hook_pos_sdot = 0;
6634+
if ( fn_hook != NULL) {
6635+
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6636+
} else {
6637+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6638+
}
66226639
}
66236640
return ret;
66246641
}

src/wrapper_blas_intel.c

+29-12
Original file line numberDiff line numberDiff line change
@@ -6607,20 +6607,37 @@ static TLS_STORE uint8_t hook_pos_sdot = 0;
66076607

66086608
float FC_GLOBAL(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, blasint* incy)
66096609
{
6610-
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6611-
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
66126610
float ret;
6613-
if ( current_backend->post_init != 0 ) {
6614-
__flexiblas_backend_init(current_backend);
6615-
current_backend->post_init = 0;
6616-
}
6617-
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6618-
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6619-
hook_pos_sdot = 0;
6620-
if ( fn_hook != NULL) {
6621-
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6611+
if (current_backend->info.float_function_defect) {
6612+
double (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6613+
double (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
6614+
if ( current_backend->post_init != 0 ) {
6615+
__flexiblas_backend_init(current_backend);
6616+
current_backend->post_init = 0;
6617+
}
6618+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6619+
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6620+
hook_pos_sdot = 0;
6621+
if ( fn_hook != NULL) {
6622+
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6623+
} else {
6624+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6625+
}
66226626
} else {
6623-
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6627+
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
6628+
float (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy);
6629+
if ( current_backend->post_init != 0 ) {
6630+
__flexiblas_backend_init(current_backend);
6631+
current_backend->post_init = 0;
6632+
}
6633+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6634+
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0];
6635+
hook_pos_sdot = 0;
6636+
if ( fn_hook != NULL) {
6637+
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6638+
} else {
6639+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6640+
}
66246641
}
66256642
return ret;
66266643
}

0 commit comments

Comments
 (0)