Skip to content
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Unreleased
- Added `blas_symbol_suffix` option (and `BLAS_FORTRAN_SUFFIX` compile
define) for linking against BLAS libraries whose Fortran symbols carry
a suffix, e.g. OpenBLAS built with `INTERFACE64=1 SYMBOLSUFFIX=64_`
exports `dgemm_64_`. Empty (default) preserves existing behavior. When
set, the OpenBLAS search probe links `-lopenblas${blas_symbol_suffix}`.
Supported by both the CMake and Make (`configure.py`) builds.
- The OpenBLAS search now also probes `-lopenblas64`, so the ILP64 build
Debian/Ubuntu ship as `libopenblas64` is found automatically.

2025.05.28 (ABI 2.0.0)
- Added Level 1 BLAS GPU wrappers
- Added is_complex_v
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ set_property(
CACHE blas_int PROPERTY STRINGS
"auto" "int (LP64)" "int64_t (ILP64)" )

set( blas_symbol_suffix "" CACHE STRING
"Suffix appended to BLAS symbol names after Fortran mangling, e.g. '64_' for OpenBLAS built with INTERFACE64=1 SYMBOLSUFFIX=64_. Empty (default) preserves existing behavior." )

set( blas_threaded "auto" CACHE STRING
"Multi-threaded BLAS?" )
set_property(
Expand All @@ -146,6 +149,7 @@ BLA_VENDOR = ${BLA_VENDOR}
blas = ${blas}
blas_fortran = ${blas_fortran}
blas_int = ${blas_int}
blas_symbol_suffix = ${blas_symbol_suffix}
blas_threaded = ${blas_threaded}
lapack = ${lapack}
build_tests = ${build_tests}
Expand Down
26 changes: 24 additions & 2 deletions cmake/BLASFinder.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,17 @@ if (test_openblas)
# todo: OPENBLAS_?(ROOT|DIR)
list( APPEND blas_name_list "OpenBLAS" )
list( APPEND blas_libs_list "-lopenblas" )
# Debian/Ubuntu ship the ILP64 build as libopenblas64, with standard
# (unsuffixed) dgemm_ symbols, so it needs only the -lopenblas64 name.
list( APPEND blas_name_list "OpenBLAS (ILP64, -lopenblas64)" )
list( APPEND blas_libs_list "-lopenblas64" )
# OpenBLAS built with SYMBOLSUFFIX (e.g. conda-forge's libopenblas64_,
# exporting dgemm_64_) follows the same naming; blas_symbol_suffix adds
# both the suffixed link name and the BLAS_FORTRAN_SUFFIX define (below).
if (blas_symbol_suffix)
list( APPEND blas_name_list "OpenBLAS (symbol suffix '${blas_symbol_suffix}')" )
list( APPEND blas_libs_list "-lopenblas${blas_symbol_suffix}" )
endif()
debug_print_list( "openblas" )
endif()

Expand Down Expand Up @@ -420,6 +431,14 @@ endif()
set( BLAS_FOUND false )
unset( blaspp_defs_ CACHE )

# Extra define to forward to the link/run probes when the user has
# requested a BLAS symbol suffix. Kept separate from the mangling
# loop because it is orthogonal to UPPER/LOWER/ADD_.
set( blas_symbol_suffix_def "" )
if (blas_symbol_suffix)
set( blas_symbol_suffix_def "-DBLAS_FORTRAN_SUFFIX=${blas_symbol_suffix}" )
endif()

set( i 0 )
foreach (blas_name IN LISTS blas_name_list)
message( TRACE "i: ${i}" )
Expand Down Expand Up @@ -454,7 +473,7 @@ foreach (blas_name IN LISTS blas_name_list)
LINK_LIBRARIES
${blas_libs} ${openmp_lib} # not "..." quoted; screws up OpenMP
COMPILE_DEFINITIONS
"${mangling} ${int_size}"
"${mangling} ${int_size} ${blas_symbol_suffix_def}"
OUTPUT_VARIABLE
link_output
)
Expand All @@ -475,7 +494,7 @@ foreach (blas_name IN LISTS blas_name_list)
LINK_LIBRARIES
${blas_libs} ${openmp_lib} # not "..." quoted; screws up OpenMP
COMPILE_DEFINITIONS
"${mangling} ${int_size}"
"${mangling} ${int_size} ${blas_symbol_suffix_def}"
COMPILE_OUTPUT_VARIABLE
compile_output
RUN_OUTPUT_VARIABLE
Expand Down Expand Up @@ -518,6 +537,9 @@ foreach (blas_name IN LISTS blas_name_list)
if (int_size MATCHES "[^ ]") # non-empty
list( APPEND blaspp_defs_ "${int_size}" )
endif()
if (blas_symbol_suffix_def MATCHES "[^ ]") # non-empty
list( APPEND blaspp_defs_ "${blas_symbol_suffix_def}" )
endif()
if (int_size MATCHES "ILP64")
set( blaspp_int "int64" )
else()
Expand Down
10 changes: 9 additions & 1 deletion config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@
#define FORTRAN_NAME( lower, UPPER ) lower
#else
// default is ADD_
#define FORTRAN_NAME( lower, UPPER ) lower ## _
#ifdef BLAS_FORTRAN_SUFFIX
// Suffix-aware variant for libraries like OpenBLAS with SYMBOLSUFFIX=64_.
#define FORTRAN_CONCAT_( a, b ) a##b
#define FORTRAN_CONCAT( a, b ) FORTRAN_CONCAT_( a, b )
#define FORTRAN_NAME( lower, UPPER ) \
FORTRAN_CONCAT( lower##_, BLAS_FORTRAN_SUFFIX )
#else
#define FORTRAN_NAME( lower, UPPER ) lower ## _
#endif
#endif

//------------------------------------------------------------------------------
Expand Down
13 changes: 13 additions & 0 deletions config/lapack.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,19 @@ def blas():
#-------------------- OpenBLAS
if (test_openblas):
choices.append( ['OpenBLAS', {'LIBS': '-lopenblas'}])
# Debian/Ubuntu ship the ILP64 build as libopenblas64, with standard
# (unsuffixed) dgemm_ symbols, so it needs only the -lopenblas64 name.
choices.append( ['OpenBLAS (ILP64, -lopenblas64)',
{'LIBS': '-lopenblas64'}])
# OpenBLAS built with SYMBOLSUFFIX (e.g. conda-forge's libopenblas64_,
# exporting dgemm_64_) needs both the suffixed name and the matching
# BLAS_FORTRAN_SUFFIX so blaspp mangles its calls to dgemm_64_.
blas_symbol_suffix = config.environ['blas_symbol_suffix']
if (blas_symbol_suffix):
choices.append(
['OpenBLAS (symbol suffix ' + blas_symbol_suffix + ')',
{'LIBS': '-lopenblas' + blas_symbol_suffix,
'CXXFLAGS': define( 'FORTRAN_SUFFIX', blas_symbol_suffix )}])

#-------------------- BLIS (also used by AMD AOCL)
if (test_blis):
Expand Down
30 changes: 25 additions & 5 deletions include/blas/mangling.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,33 @@
// define FORTRAN_LOWER for lowercase (IBM xlf),
// else the default is lowercase with appended underscore
// (GNU gcc, Intel icc, PGI pgfortan, Cray ftn).
//
// BLAS_FORTRAN_SUFFIX, if defined, is appended to every mangled symbol.
// Used to link against BLAS libraries that suffix their symbols, e.g.,
// OpenBLAS built with INTERFACE64=1 SYMBOLSUFFIX=64_ exports `dgemm_64_`.
// Pass via CMake's `blas_symbol_suffix` option.
#ifndef BLAS_FORTRAN_NAME
#if defined(BLAS_FORTRAN_UPPER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) UPPER
#elif defined(BLAS_FORTRAN_LOWER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) lower
#ifdef BLAS_FORTRAN_SUFFIX
#define BLAS_FORTRAN_CONCAT_( a, b ) a##b
#define BLAS_FORTRAN_CONCAT( a, b ) BLAS_FORTRAN_CONCAT_( a, b )
#if defined(BLAS_FORTRAN_UPPER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) \
BLAS_FORTRAN_CONCAT( UPPER, BLAS_FORTRAN_SUFFIX )
#elif defined(BLAS_FORTRAN_LOWER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) \
BLAS_FORTRAN_CONCAT( lower, BLAS_FORTRAN_SUFFIX )
#else
#define BLAS_FORTRAN_NAME( lower, UPPER ) \
BLAS_FORTRAN_CONCAT( lower##_, BLAS_FORTRAN_SUFFIX )
#endif
#else
#define BLAS_FORTRAN_NAME( lower, UPPER ) lower##_
#if defined(BLAS_FORTRAN_UPPER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) UPPER
#elif defined(BLAS_FORTRAN_LOWER)
#define BLAS_FORTRAN_NAME( lower, UPPER ) lower
#else
#define BLAS_FORTRAN_NAME( lower, UPPER ) lower##_
#endif
#endif
#endif

Expand Down