Skip to content

Commit b1dc3d8

Browse files
committed
Add suffix_hint parameter to lbt_forward()
If a dual-interface library is being loaded, any heuristic will always choose the first interface it finds, so we add `suffix_hint` to allow biasing the interface detection toward a known-good suffix. This allows for loading dual-interface MKL (If using v2022+) by first loading one interface, then the other without clearing in between.
1 parent 2d8358c commit b1dc3d8

File tree

5 files changed

+28
-12
lines changed

5 files changed

+28
-12
lines changed

src/autodetection.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* We are primarily concerned with the FORTRAN names, so we automatically append
66
* an underscore to the end, as is standard.
77
*/
8-
const char * autodetect_symbol_suffix(void * handle) {
8+
const char * autodetect_symbol_suffix(void * handle, const char * suffix_hint) {
99
// We auto-detect the symbol suffix of the given library by searching for common
1010
// BLAS and LAPACK symbols, combined with various suffixes that we know of.
1111
const char * symbol_names[] = {
@@ -15,14 +15,26 @@ const char * autodetect_symbol_suffix(void * handle) {
1515
"dpotrf_",
1616
};
1717
const char * suffixes[] = {
18-
// First, LP64-mangling suffixes: No underscore, single underscore, double underscore
18+
// Possibly-NULL suffix that we should search over
19+
suffix_hint,
20+
21+
// Search for ILP64-mangling suffixes first, as in the rare case that we want to
22+
// load a library that exports both, we prefer to bind to the namespaced symbols first
23+
"64", "64_", "_64__", "__64___",
24+
25+
// Next, LP64-mangling suffixes
1926
"", "_", "__",
20-
// Next, ILP64-mangling suffixes: the same, but with the suffix prepended as well:
21-
"64_", "_64__", "__64___",
2227
};
28+
29+
// If the suffix hint is NULL, just skip it when calling `lookup_symbol()`.
30+
int suffix_start_idx = 0;
31+
if (suffix_hint == NULL) {
32+
suffix_start_idx = 1;
33+
}
34+
2335
char symbol_name[MAX_SYMBOL_LEN];
2436
for (int symbol_idx=0; symbol_idx<sizeof(symbol_names)/sizeof(const char *); symbol_idx++) {
25-
for (int suffix_idx=0; suffix_idx<sizeof(suffixes)/sizeof(const char *); suffix_idx++) {
37+
for (int suffix_idx=suffix_start_idx; suffix_idx<sizeof(suffixes)/sizeof(const char *); suffix_idx++) {
2638
sprintf(symbol_name, "%s%s", symbol_names[symbol_idx], suffixes[suffix_idx]);
2739
if (lookup_symbol(handle, symbol_name) != NULL) {
2840
return suffixes[suffix_idx];

src/libblastrampoline.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ LBT_DLLEXPORT int32_t lbt_set_forward(const char * symbol_name, const void * add
147147
/*
148148
* Load `libname`, clearing previous mappings if `clear` is set.
149149
*/
150-
LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t verbose) {
150+
LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t verbose, const char * suffix_hint) {
151151
if (verbose) {
152152
printf("Generating forwards to %s\n", libname);
153153
}
@@ -161,7 +161,7 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
161161

162162
// Once we have the BLAS/LAPACK library loaded, we need to autodetect a few things about it.
163163
// First, we are going to figure out its name-mangling suffix:
164-
const char * lib_suffix = autodetect_symbol_suffix(handle);
164+
const char * lib_suffix = autodetect_symbol_suffix(handle, suffix_hint);
165165
if (lib_suffix == NULL) {
166166
fprintf(stderr, "Unable to autodetect symbol suffix of \"%s\"\n", libname);
167167
return 0;
@@ -340,7 +340,7 @@ __attribute__((constructor)) void init(void) {
340340
curr_lib_start++;
341341

342342
// Load functions from this library, clearing only the first time.
343-
lbt_forward(curr_lib, clear, verbose);
343+
lbt_forward(curr_lib, clear, verbose, NULL);
344344
clear = 0;
345345
}
346346
}

src/libblastrampoline.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,12 @@ typedef struct {
106106
* support in the system libc for more details.
107107
*
108108
* If `verbose` is set to a non-zero value, it will print out debugging information.
109+
*
110+
* If `suffix_hint` is set to a non-NULL value, it is the first suffix that is used to search for
111+
* BLAS/LAPACK symbols within the library. This is useful in case a library contains within it both
112+
* LP64 and ILP64 symbols, and you want to prefer one set of symbols over the other.
109113
*/
110-
LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t verbose);
114+
LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t verbose, const char * suffix_hint);
111115

112116
/*
113117
* Returns a structure describing the currently-loaded libraries as well as the build configuration

src/libblastrampoline_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void * lookup_symbol(const void * lib_handle, const char * symbol_name);
7373
void close_library(void * handle);
7474

7575
// Functions in `autodetection.c`
76-
const char * autodetect_symbol_suffix(void * handle);
76+
const char * autodetect_symbol_suffix(void * handle, const char * suffix_hint);
7777
int32_t autodetect_blas_interface(void * isamax_addr);
7878
int32_t autodetect_lapack_interface(void * dpotrf_addr);
7979
int32_t autodetect_interface(void * handle, const char * suffix);

test/utils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ struct lbt_config_t
102102
end
103103
const LBT_BUILDFLAGS_F2C_CAPABLE = 0x02
104104

105-
function lbt_forward(handle, path; clear::Bool = false, verbose::Bool = false)
106-
ccall(dlsym(handle, :lbt_forward), Int32, (Cstring, Int32, Int32), path, clear ? 1 : 0, verbose ? 1 : 0)
105+
function lbt_forward(handle, path; clear::Bool = false, verbose::Bool = false, suffix_hint::Union{Nothing,String} = nothing)
106+
ccall(dlsym(handle, :lbt_forward), Int32, (Cstring, Int32, Int32, Cstring), path, clear ? 1 : 0, verbose ? 1 : 0, something(suffix_hint, C_NULL))
107107
end
108108

109109
function lbt_get_config(handle)

0 commit comments

Comments
 (0)