Skip to content

Commit 526b722

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 526b722

File tree

6 files changed

+122
-38
lines changed

6 files changed

+122
-38
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

+45
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,51 @@ 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+
#ifdef FLEXIBLAS_INTEGER8
217+
int64_t n = 2;
218+
int64_t one = 1;
219+
#else
220+
int32_t n = 2;
221+
int32_t one = 1;
222+
#endif
223+
if (intel_interface) {
224+
#ifdef FLEXIBLAS_INTEGER8
225+
void (*sdot)(float *, int64_t *, float *, int64_t *, float *, int64_t *);
226+
#else
227+
void (*sdot)(float *, int32_t *, float *, int32_t *, float *, int32_t *);
228+
#endif
229+
230+
sdot(&retval, &n, x, &one, y, &one);
231+
} else {
232+
#ifdef FLEXIBLAS_INTEGER8
233+
float (*sdot)(int64_t *, float *, int64_t *, float *, int64_t *);
234+
#else
235+
float (*sdot)(int32_t *, float *, int32_t *, float *, int32_t *);
236+
#endif
237+
238+
retval = sdot(&n, x, &one, y, &one);
239+
}
240+
241+
if (retval == 11.0)
242+
return 0;
243+
else
244+
return 1;
245+
}
246+
202247
HIDDEN flexiblas_interface_t __flexiblas_get_interface(void *handle)
203248
{
204249
if (handle == NULL) {

src/wrapper_blas_gnu.c

+43-26
Original file line numberDiff line numberDiff line change
@@ -6601,24 +6601,31 @@ void flexiblas_chain_scopy(void* n, void* sx, void* incx, void* sy, void* incy){
66016601
#endif
66026602

66036603

6604+
#define SDOT_INTERN(ret_type) \
6605+
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
6606+
ret_type (*fn_hook) (void* n, void* sx, void* incx, void* sy, void* incy); \
6607+
if ( current_backend->post_init != 0 ) { \
6608+
__flexiblas_backend_init(current_backend); \
6609+
current_backend->post_init = 0; \
6610+
} \
6611+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
6612+
*(void **) &fn_hook = __flexiblas_hooks->sdot.f77_hook_function[0]; \
6613+
hook_pos_sdot = 0; \
6614+
if ( fn_hook != NULL) { \
6615+
ret = fn_hook((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy); \
6616+
} else { \
6617+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy); \
6618+
}
6619+
66046620
static TLS_STORE uint8_t hook_pos_sdot = 0;
66056621

66066622
float FC_GLOBAL(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, blasint* incy)
66076623
{
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);
66106624
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);
6625+
if (current_backend->info.float_function_defect) {
6626+
SDOT_INTERN(double)
66206627
} else {
6621-
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6628+
SDOT_INTERN(float)
66226629
}
66236630
return ret;
66246631
}
@@ -6636,14 +6643,20 @@ float FC_GLOBAL3(sdot,SDOT)(blasint* n, float* sx, blasint* incx, float* sy, bla
66366643
#endif
66376644

66386645

6646+
#define REAL_SDOT_INTERN(ret_type) \
6647+
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
6648+
\
6649+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
6650+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
66396651

66406652
float flexiblas_real_sdot_(void* n, void* sx, void* incx, void* sy, void* incy)
66416653
{
6642-
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
66436654
float ret;
6644-
6645-
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6646-
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
6655+
if (current_backend->info.float_function_defect) {
6656+
REAL_SDOT_INTERN(double)
6657+
} else {
6658+
REAL_SDOT_INTERN(float)
6659+
}
66476660

66486661
return ret;
66496662
}
@@ -6653,22 +6666,26 @@ float flexiblas_real_sdot(void* n, void* sx, void* incx, void* sy, void* incy) _
66536666
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);}
66546667
#endif
66556668

6669+
#define CHAIN_SDOT_INTERN(ret_type) \
6670+
ret_type (*fn) (void* n, void* sx, void* incx, void* sy, void* incy); \
6671+
\
6672+
hook_pos_sdot++; \
6673+
if ( hook_pos_sdot < __flexiblas_hooks->sdot.nhook ) { \
6674+
*(void **) &fn = __flexiblas_hooks->sdot.f77_hook_function[hook_pos_sdot]; \
6675+
} else { \
6676+
hook_pos_sdot = 0; \
6677+
*(void **) &fn = current_backend->blas.sdot.f77_blas_function; \
6678+
} \
6679+
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
66566680

66576681
float flexiblas_chain_sdot_(void* n, void* sx, void* incx, void* sy, void* incy)
66586682
{
6659-
float (*fn) (void* n, void* sx, void* incx, void* sy, void* incy);
66606683
float ret;
6661-
6662-
6663-
6664-
hook_pos_sdot++;
6665-
if ( hook_pos_sdot < __flexiblas_hooks->sdot.nhook ) {
6666-
*(void **) &fn = __flexiblas_hooks->sdot.f77_hook_function[hook_pos_sdot];
6684+
if (current_backend->info.float_function_defect) {
6685+
CHAIN_SDOT_INTERN(double)
66676686
} else {
6668-
hook_pos_sdot = 0;
6669-
*(void **) &fn = current_backend->blas.sdot.f77_blas_function;
6687+
CHAIN_SDOT_INTERN(float)
66706688
}
6671-
ret = fn((void*) n, (void*) sx, (void*) incx, (void*) sy, (void*) incy);
66726689

66736690
return ret;
66746691
}

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)