Skip to content

Commit 77227d2

Browse files
committed
Allow for overriding workarounds even when autodetection is unavailable
If a user wants to use MKL on i686, we unfortunately need some workarounds for certain function calls. Until we come up with an autodetection strategy that works on i686 as well as x86_64, we can make use of the new environment variable-based overrides to make things work. Let's test that on i686 on CI.
1 parent a59ca22 commit 77227d2

File tree

5 files changed

+32
-49
lines changed

5 files changed

+32
-49
lines changed

src/Makefile

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,9 @@ MAIN_OBJS += win_utils.o
2525
endif
2626

2727
# If we're on an architecture that supports f2c autodetection, compile that in!
28-
ifeq ($(F2C_AUTODETECTION),1)
2928
MAIN_OBJS += f2c_adapters.o
30-
endif
31-
32-
ifeq ($(CBLAS_DIVERGENCE_AUTODETECTION),1)
3329
MAIN_OBJS += cblas_adapters.o
34-
endif
35-
36-
ifeq ($(COMPLEX_RETSTYLE_AUTODETECTION),1)
3730
MAIN_OBJS += complex_return_style_adapters.o
38-
endif
3931

4032
# Place the `.o` files into `$(builddir)`
4133
MAIN_OBJS := $(addprefix $(builddir)/,$(MAIN_OBJS))

src/autodetection.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ int32_t autodetect_interface(void * handle, const char * suffix) {
206206
return LBT_INTERFACE_UNKNOWN;
207207
}
208208

209-
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
210209
int32_t autodetect_complex_return_style(void * handle, const char * suffix) {
211210
if (env_lowercase_match("LBT_FORCE_RETSTYLE", "normal")) {
212211
return LBT_COMPLEX_RETSTYLE_NORMAL;
@@ -217,6 +216,8 @@ int32_t autodetect_complex_return_style(void * handle, const char * suffix) {
217216
if (env_lowercase_match("LBT_FORCE_RETSTYLE", "fnda")) {
218217
return LBT_COMPLEX_RETSTYLE_FNDA;
219218
}
219+
220+
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
220221
char symbol_name[MAX_SYMBOL_LEN];
221222

222223
build_symbol_name(symbol_name, "zdotc_", suffix);
@@ -300,22 +301,21 @@ int32_t autodetect_complex_return_style(void * handle, const char * suffix) {
300301
(creal(retval_float) == 0.0f && cimag(retval_float) == 0.0f)) {
301302
return LBT_COMPLEX_RETSTYLE_NORMAL;
302303
}
304+
#endif // COMPLEX_RETSTYLE_AUTODETECTION
303305

304306
// If we get here, zdotc and cdotc are being uncooperative and we
305307
// do not appreciate it at all, not we don't my precious.
306308
return LBT_COMPLEX_RETSTYLE_UNKNOWN;
307309
}
308-
#endif // COMPLEX_RETSTYLE_AUTODETECTION
309310

310-
#ifdef F2C_AUTODETECTION
311311
int32_t autodetect_f2c(void * handle, const char * suffix) {
312312
if (env_lowercase_match("LBT_FORCE_F2C", "plain")) {
313313
return LBT_F2C_PLAIN;
314314
}
315315
if (env_lowercase_match("LBT_FORCE_F2C", "required")) {
316316
return LBT_F2C_REQUIRED;
317317
}
318-
318+
#ifdef F2C_AUTODETECTION
319319
char symbol_name[MAX_SYMBOL_LEN];
320320

321321
// Attempt BLAS `sdot()` test
@@ -346,12 +346,12 @@ int32_t autodetect_f2c(void * handle, const char * suffix) {
346346
// It's an f2c style calling convention
347347
return LBT_F2C_REQUIRED;
348348
}
349+
#endif // F2C_AUTODETECTION
350+
349351
// We have no idea what happened; nothing works and everything is broken
350352
return LBT_F2C_UNKNOWN;
351353
}
352-
#endif // F2C_AUTODETECTION
353354

354-
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
355355
int32_t autodetect_cblas_divergence(void * handle, const char * suffix) {
356356
if (env_lowercase_match("LBT_FORCE_CBLAS", "conformant")) {
357357
return LBT_CBLAS_CONFORMANT;
@@ -360,6 +360,7 @@ int32_t autodetect_cblas_divergence(void * handle, const char * suffix) {
360360
return LBT_CBLAS_DIVERGENT;
361361
}
362362

363+
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
363364
char symbol_name[MAX_SYMBOL_LEN];
364365

365366
build_symbol_name(symbol_name, "zdotc_", suffix);
@@ -382,7 +383,8 @@ int32_t autodetect_cblas_divergence(void * handle, const char * suffix) {
382383
return LBT_CBLAS_DIVERGENT;
383384
}
384385
}
386+
#endif // CBLAS_DIVERGENCE_AUTODETECTION
387+
385388
// If we can't even find `zdotc_64`, we don't know what this is.
386389
return LBT_CBLAS_UNKNOWN;
387390
}
388-
#endif // CBLAS_DIVERGENCE_AUTODETECTION

src/libblastrampoline.c

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
#include "libblastrampoline_internal.h"
22
#include "libblastrampoline_trampdata.h"
3-
4-
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
53
#include "libblastrampoline_complex_retdata.h"
6-
#endif
7-
#ifdef F2C_AUTODETECTION
84
#include "libblastrampoline_f2cdata.h"
9-
#endif
10-
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
115
#include "libblastrampoline_cblasdata.h"
12-
#endif
136

147
// Sentinel to tell us if we've got a deepbindless workaround active or not
158
#define DEEPBINDLESS_INTERFACE_LP64_LOADED 0x01
@@ -69,7 +62,6 @@ int32_t set_forward_by_index(int32_t symbol_idx, const void * addr, int32_t inte
6962
}
7063
}
7164

72-
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
7365
for (int array_idx=0; array_idx < sizeof(cmplxret_func_idxs)/sizeof(int *); ++array_idx) {
7466
if ((complex_retstyle == LBT_COMPLEX_RETSTYLE_ARGUMENT) ||
7567
((complex_retstyle == LBT_COMPLEX_RETSTYLE_FNDA) && array_idx == 1)) {
@@ -96,7 +88,6 @@ int32_t set_forward_by_index(int32_t symbol_idx, const void * addr, int32_t inte
9688
}
9789
}
9890
}
99-
#endif // COMPLEX_RETSTYLE_AUTODETECTION
10091

10192
#ifdef F2C_AUTODETECTION
10293
if (f2c == LBT_F2C_REQUIRED) {
@@ -224,11 +215,12 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
224215

225216
// Next, let's figure out what the complex return style is:
226217
int complex_retstyle = LBT_COMPLEX_RETSTYLE_UNKNOWN;
227-
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
228218
complex_retstyle = autodetect_complex_return_style(handle, lib_suffix);
229219
if (complex_retstyle == LBT_COMPLEX_RETSTYLE_UNKNOWN) {
230-
fprintf(stderr, "Unable to autodetect complex return style of \"%s\"\n", libname);
231-
return 0;
220+
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
221+
fprintf(stderr, "Unable to autodetect complex return style of \"%s\"\n", libname);
222+
return 0;
223+
#endif // COMPLEX_RETSTYLE_AUTODETECTION
232224
}
233225
if (verbose) {
234226
if (complex_retstyle == LBT_COMPLEX_RETSTYLE_NORMAL) {
@@ -238,16 +230,16 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
238230
printf(" -> Autodetected argument-passing complex return style\n");
239231
}
240232
}
241-
#endif // COMPLEX_RETSTYLE_AUTODETECTION
242233

243234
int f2c = LBT_F2C_PLAIN;
244-
#ifdef F2C_AUTODETECTION
245235
// Next, we need to probe to see if this is an f2c-style calling convention library
246236
// The only major example of this that we know of is Accelerate on macOS
247237
f2c = autodetect_f2c(handle, lib_suffix);
248238
if (f2c == LBT_F2C_UNKNOWN) {
249-
fprintf(stderr, "Unable to autodetect calling convention of \"%s\"\n", libname);
250-
return 0;
239+
#ifdef F2C_AUTODETECTION
240+
fprintf(stderr, "Unable to autodetect f2c calling convention of \"%s\"\n", libname);
241+
return 0;
242+
#endif // F2C_AUTODETECTION
251243
}
252244
if (verbose) {
253245
if (f2c == LBT_F2C_REQUIRED) {
@@ -257,10 +249,8 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
257249
printf(" -> Autodetected gfortran calling convention\n");
258250
}
259251
}
260-
#endif // F2C_AUTODETECTION
261252

262253
int cblas = LBT_CBLAS_UNKNOWN;
263-
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
264254
// Next, we need to probe to see if this is MKL v2022 with missing ILP64-suffixed
265255
// CBLAS symbols, but only if it's an ILP64 library.
266256
if (interface == LBT_INTERFACE_ILP64) {
@@ -274,7 +264,9 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
274264
printf(" -> Autodetected CBLAS-divergent library!\n");
275265
break;
276266
case LBT_CBLAS_UNKNOWN:
277-
printf(" -> CBLAS not found\n");
267+
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
268+
printf(" -> CBLAS not found/autodetection unavailable\n");
269+
#endif // CBLAS_DIVERGENCE_AUTODETECTION
278270
break;
279271
default:
280272
printf(" -> ERROR: Impossible CBLAS detection result: %d\n", cblas);
@@ -283,7 +275,6 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
283275
}
284276
}
285277
}
286-
#endif // CBLAS_DIVERGENCE_AUTODETECTION
287278

288279
/*
289280
* Now, if we are opening a 64-bit library with 32-bit names (e.g. suffix == ""),
@@ -367,7 +358,6 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
367358
}
368359
}
369360

370-
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
371361
// If we're loading a divergent CBLAS library, we need to scan through all
372362
// CBLAS symbols, and forward them to wrappers which will convert them to
373363
// the FORTRAN equivalents.
@@ -390,7 +380,6 @@ LBT_DLLEXPORT int32_t lbt_forward(const char * libname, int32_t clear, int32_t v
390380
}
391381
}
392382
}
393-
#endif // CBLAS_DIVERGENCE_AUTODETECTION
394383

395384
record_library_load(libname, handle, lib_suffix, &forwards[0], interface, complex_retstyle, f2c, cblas);
396385
if (verbose) {

src/libblastrampoline_internal.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,9 @@ const char * autodetect_symbol_suffix(void * handle, const char * suffix_hint);
8787
int32_t autodetect_blas_interface(void * isamax_addr);
8888
int32_t autodetect_lapack_interface(void * dpotrf_addr);
8989
int32_t autodetect_interface(void * handle, const char * suffix);
90-
#ifdef COMPLEX_RETSTYLE_AUTODETECTION
9190
int32_t autodetect_complex_return_style(void * handle, const char * suffix);
92-
#endif
93-
94-
#ifdef F2C_AUTODETECTION
9591
int32_t autodetect_f2c(void * handle, const char * suffix);
96-
#endif
97-
#ifdef CBLAS_DIVERGENCE_AUTODETECTION
9892
int32_t autodetect_cblas_divergence(void * handle, const char * suffix);
99-
#endif
10093

10194
// Functions in deepbindless_surrogates.c
10295
uint8_t push_fake_lsame();

test/runtests.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using Pkg, Artifacts, Base.BinaryPlatforms, Libdl, Test
44
include("utils.jl")
55

66
# Compile `dgemm_test.c` and `sgesv_test.c` against the given BLAS/LAPACK
7-
function run_test((test_name, test_expected_outputs, expect_success), libblas_name, libdirs, interface, backing_libs)
7+
function run_test((test_name, test_expected_outputs, expect_success), libblas_name, libdirs, interface, backing_libs; extra_env = Dict())
88
# We need to configure this C build a bit
99
cflags = String[
1010
"-g",
@@ -50,6 +50,7 @@ function run_test((test_name, test_expected_outputs, expect_success), libblas_na
5050
"LBT_DEFAULT_LIBS" => backing_libs,
5151
"LBT_STRICT" => 1,
5252
"LBT_VERBOSE" => 1,
53+
pairs(extra_env)...,
5354
)
5455
cmd = `$(dir)/$(test_name)`
5556
p, output = capture_output(addenv(cmd, env))
@@ -101,9 +102,9 @@ cdotc = ("cdotc_test", (
101102

102103
# Helper function to run all the tests with the given arguments
103104
# Does not include `dgemmt` because that's MKL-only
104-
function run_all_tests(args...; tests = [dgemm, dpstrf, sgesv, sdot, cdotc])
105+
function run_all_tests(args...; tests = [dgemm, dpstrf, sgesv, sdot, cdotc], kwargs...)
105106
for test in tests
106-
run_test(test, args...)
107+
run_test(test, args...; kwargs...)
107108
end
108109
end
109110

@@ -158,17 +159,23 @@ end
158159

159160
# Test against MKL_jll using `libmkl_rt`, which is :LP64 by default
160161
if MKL_jll.is_available()
162+
# On i686, we can't do complex return style autodetection, so we manually set it,
163+
# knowing that MKL is argument-style.
164+
extra_env = Dict{String,String}()
165+
if Sys.ARCH == :i686
166+
extra_env["LBT_FORCE_RETSTYLE"] = "ARGUMENT"
167+
end
161168
@testset "LBT -> MKL_jll (LP64)" begin
162169
libdirs = unique(vcat(lbt_dir, MKL_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
163-
run_all_tests(blastrampoline_link_name(), libdirs, :LP64, MKL_jll.libmkl_rt_path; tests = [dgemm, dgemmt, dpstrf, sgesv, sdot, cdotc])
170+
run_all_tests(blastrampoline_link_name(), libdirs, :LP64, MKL_jll.libmkl_rt_path; tests = [dgemm, dgemmt, dpstrf, sgesv, sdot, cdotc], extra_env)
164171
end
165172

166173
# Test that we can set MKL's interface via an environment variable to select ILP64, and LBT detects it properly
167174
if Sys.WORD_SIZE == 64
168175
@testset "LBT -> MKL_jll (ILP64, via env)" begin
169176
withenv("MKL_INTERFACE_LAYER" => "ILP64") do
170177
libdirs = unique(vcat(lbt_dir, MKL_jll.LIBPATH_list..., CompilerSupportLibraries_jll.LIBPATH_list...))
171-
run_all_tests(blastrampoline_link_name(), libdirs, :ILP64, MKL_jll.libmkl_rt_path; tests = [dgemm, dgemmt, dpstrf, sgesv, sdot, cdotc])
178+
run_all_tests(blastrampoline_link_name(), libdirs, :ILP64, MKL_jll.libmkl_rt_path; tests = [dgemm, dgemmt, dpstrf, sgesv, sdot, cdotc], extra_env)
172179
end
173180
end
174181
end

0 commit comments

Comments
 (0)