Skip to content

Commit 0dc64b5

Browse files
committed
Fix BLAS and LAPACK symbol mapping
1 parent 03f3882 commit 0dc64b5

3 files changed

Lines changed: 138 additions & 56 deletions

File tree

CMakeLists.txt

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -376,24 +376,52 @@ if(NRGLJUBLJANA_BLAS_ILP64)
376376
endif()
377377
find_package(LAPACK REQUIRED) # also looks up BLAS
378378
include(CheckCXXSourceCompiles)
379-
set(CMAKE_REQUIRED_LIBRARIES ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})
380-
set(CMAKE_REQUIRED_FLAGS ${LAPACK_LINKER_FLAGS} ${BLAS_LINKER_FLAGS})
381-
unset(NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_TRAILING_UNDERSCORE CACHE)
382-
unset(NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_NO_SUFFIX CACHE)
383-
check_cxx_source_compiles("extern \"C\" void dgemm_(); int main() { dgemm_(); return 0; }" NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_TRAILING_UNDERSCORE)
384-
if(NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_TRAILING_UNDERSCORE)
379+
if(TARGET BLAS::BLAS)
380+
set(NRGLJUBLJANA_BLAS_REQUIRED_LIBRARIES BLAS::BLAS)
381+
else()
382+
set(NRGLJUBLJANA_BLAS_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
383+
endif()
384+
if(TARGET LAPACK::LAPACK)
385+
set(NRGLJUBLJANA_LAPACK_REQUIRED_LIBRARIES LAPACK::LAPACK)
386+
else()
387+
set(NRGLJUBLJANA_LAPACK_REQUIRED_LIBRARIES ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})
388+
endif()
389+
390+
set(CMAKE_REQUIRED_LIBRARIES ${NRGLJUBLJANA_BLAS_REQUIRED_LIBRARIES})
391+
set(CMAKE_REQUIRED_LINK_OPTIONS ${BLAS_LINKER_FLAGS})
392+
unset(NRGLJUBLJANA_BLAS_DGEMM_UNDERSCORE CACHE)
393+
unset(NRGLJUBLJANA_BLAS_DGEMM_NO_SUFFIX CACHE)
394+
check_cxx_source_compiles("extern \"C\" void dgemm_(); int main() { dgemm_(); return 0; }" NRGLJUBLJANA_BLAS_DGEMM_UNDERSCORE)
395+
if(NRGLJUBLJANA_BLAS_DGEMM_UNDERSCORE)
385396
set(NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX "underscore")
386397
else()
387-
check_cxx_source_compiles("extern \"C\" void dgemm(); int main() { dgemm(); return 0; }" NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_NO_SUFFIX)
388-
if(NRGLJUBLJANA_BLAS_SYMBOLS_HAVE_NO_SUFFIX)
398+
check_cxx_source_compiles("extern \"C\" void dgemm(); int main() { dgemm(); return 0; }" NRGLJUBLJANA_BLAS_DGEMM_NO_SUFFIX)
399+
if(NRGLJUBLJANA_BLAS_DGEMM_NO_SUFFIX)
389400
set(NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX "none")
390401
else()
391-
message(FATAL_ERROR "Could not determine BLAS/LAPACK symbol naming convention: neither dgemm_ nor dgemm links")
402+
message(FATAL_ERROR "Could not determine BLAS symbol naming convention: neither dgemm_ nor dgemm links")
403+
endif()
404+
endif()
405+
406+
set(CMAKE_REQUIRED_LIBRARIES ${NRGLJUBLJANA_LAPACK_REQUIRED_LIBRARIES})
407+
set(CMAKE_REQUIRED_LINK_OPTIONS ${LAPACK_LINKER_FLAGS} ${BLAS_LINKER_FLAGS})
408+
unset(NRGLJUBLJANA_LAPACK_DSYEV_UNDERSCORE CACHE)
409+
unset(NRGLJUBLJANA_LAPACK_DSYEV_NO_SUFFIX CACHE)
410+
check_cxx_source_compiles("extern \"C\" void dsyev_(); int main() { dsyev_(); return 0; }" NRGLJUBLJANA_LAPACK_DSYEV_UNDERSCORE)
411+
if(NRGLJUBLJANA_LAPACK_DSYEV_UNDERSCORE)
412+
set(NRGLJUBLJANA_LAPACK_SYMBOL_SUFFIX "underscore")
413+
else()
414+
check_cxx_source_compiles("extern \"C\" void dsyev(); int main() { dsyev(); return 0; }" NRGLJUBLJANA_LAPACK_DSYEV_NO_SUFFIX)
415+
if(NRGLJUBLJANA_LAPACK_DSYEV_NO_SUFFIX)
416+
set(NRGLJUBLJANA_LAPACK_SYMBOL_SUFFIX "none")
417+
else()
418+
message(FATAL_ERROR "Could not determine LAPACK symbol naming convention: neither dsyev_ nor dsyev links")
392419
endif()
393420
endif()
394421
unset(CMAKE_REQUIRED_LIBRARIES)
395-
unset(CMAKE_REQUIRED_FLAGS)
396-
message(STATUS "BLAS/LAPACK symbol suffix: ${NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX}")
422+
unset(CMAKE_REQUIRED_LINK_OPTIONS)
423+
message(STATUS "BLAS symbol suffix: ${NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX}")
424+
message(STATUS "LAPACK symbol suffix: ${NRGLJUBLJANA_LAPACK_SYMBOL_SUFFIX}")
397425
add_library(blas_lapack INTERFACE)
398426
set(NRGLJUBLJANA_HAVE_MKL OFF)
399427
set(NRGLJUBLJANA_HAVE_OPENBLAS OFF)
@@ -464,7 +492,8 @@ target_compile_definitions(blas_lapack INTERFACE
464492
"NRG_BLAS_VENDOR=\"${NRGLJUBLJANA_BLAS_VENDOR_ESCAPED}\""
465493
NRG_HAVE_MKL=$<BOOL:${NRGLJUBLJANA_HAVE_MKL}>
466494
NRG_HAVE_OPENBLAS=$<BOOL:${NRGLJUBLJANA_HAVE_OPENBLAS}>
467-
$<$<STREQUAL:${NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX},none>:NRG_LAPACK_SYMBOL_SUFFIX_NONE>
495+
$<$<STREQUAL:${NRGLJUBLJANA_BLAS_SYMBOL_SUFFIX},none>:NRG_BLAS_SYMBOL_SUFFIX_NONE>
496+
$<$<STREQUAL:${NRGLJUBLJANA_LAPACK_SYMBOL_SUFFIX},none>:NRG_LAPACK_SYMBOL_SUFFIX_NONE>
468497
"NRG_MKL_THREADING_LAYER=\"${NRGLJUBLJANA_EFFECTIVE_MKL_THREADING_LAYER}\""
469498
NRG_MKL_REQUIRES_OPENMP=$<BOOL:${NRGLJUBLJANA_MKL_REQUIRES_OPENMP}>
470499
)

c++/blas_gemm.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ void call_gemm(const char *transa, const char *transb, const lapack_int *m, cons
4545
if constexpr (std::is_same_v<T, double>) {
4646
LAPACK_dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
4747
} else {
48-
LAPACK_zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
48+
LAPACK_zgemm(transa, transb, m, n, k, reinterpret_cast<const double *>(alpha), reinterpret_cast<const double *>(a), lda,
49+
reinterpret_cast<const double *>(b), ldb, reinterpret_cast<const double *>(beta), reinterpret_cast<double *>(c), ldc);
4950
}
5051
}
5152

c++/linalg.hpp

Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,61 +14,113 @@ using lapack_int = int;
1414
using lapack_logical = lapack_int;
1515
using lapack_complex_double = std::complex<double>;
1616

17+
#define NRG_APPEND_UNDERSCORE(name) name##_
18+
19+
#if defined(NRG_BLAS_SYMBOL_SUFFIX_NONE)
20+
#define NRG_BLAS_SYMBOL(name) name
21+
#else
22+
#define NRG_BLAS_SYMBOL(name) NRG_APPEND_UNDERSCORE(name)
23+
#endif
24+
25+
#if defined(NRG_LAPACK_SYMBOL_SUFFIX_NONE)
26+
#define NRG_LAPACK_SYMBOL(name) name
27+
#else
28+
#define NRG_LAPACK_SYMBOL(name) NRG_APPEND_UNDERSCORE(name)
29+
#endif
30+
31+
#if defined(__APPLE__)
32+
#define LAPACK_dgemm NRG_BLAS_SYMBOL(dgemm)
33+
#define LAPACK_zgemm NRG_BLAS_SYMBOL(zgemm)
34+
#define LAPACK_dsyev NRG_LAPACK_SYMBOL(dsyev)
35+
#define LAPACK_dsyevd NRG_LAPACK_SYMBOL(dsyevd)
36+
#define LAPACK_dsyevr NRG_LAPACK_SYMBOL(dsyevr)
37+
#define LAPACK_zheev NRG_LAPACK_SYMBOL(zheev)
38+
#define LAPACK_zheevd NRG_LAPACK_SYMBOL(zheevd)
39+
#define LAPACK_zheevr NRG_LAPACK_SYMBOL(zheevr)
40+
#else
41+
#define NRG_LINALG_STRINGIFY_IMPL(name) #name
42+
#define NRG_LINALG_STRINGIFY(name) NRG_LINALG_STRINGIFY_IMPL(name)
43+
#define NRG_BLAS_ASM_SYMBOL(name) NRG_LINALG_STRINGIFY(NRG_BLAS_SYMBOL(name))
44+
#define NRG_LAPACK_ASM_SYMBOL(name) NRG_LINALG_STRINGIFY(NRG_LAPACK_SYMBOL(name))
1745
#define LAPACK_dgemm NRG_LAPACK_dgemm
1846
#define LAPACK_zgemm NRG_LAPACK_zgemm
19-
2047
#define LAPACK_dsyev NRG_LAPACK_dsyev
2148
#define LAPACK_dsyevd NRG_LAPACK_dsyevd
2249
#define LAPACK_dsyevr NRG_LAPACK_dsyevr
2350
#define LAPACK_zheev NRG_LAPACK_zheev
2451
#define LAPACK_zheevd NRG_LAPACK_zheevd
2552
#define LAPACK_zheevr NRG_LAPACK_zheevr
26-
27-
#if defined(NRG_LAPACK_SYMBOL_SUFFIX_NONE)
28-
#define NRG_LAPACK_SYMBOL(name) #name
29-
#else
30-
#define NRG_LAPACK_SYMBOL(name) #name "_"
3153
#endif
3254

3355
extern "C" {
3456

35-
void NRG_LAPACK_dgemm(const char *transa, const char *transb, const lapack_int *m, const lapack_int *n, const lapack_int *k,
36-
const double *alpha, const double *a, const lapack_int *lda, const double *b, const lapack_int *ldb,
37-
const double *beta, double *c, const lapack_int *ldc) __asm__(NRG_LAPACK_SYMBOL(dgemm));
38-
39-
void NRG_LAPACK_zgemm(const char *transa, const char *transb, const lapack_int *m, const lapack_int *n, const lapack_int *k,
40-
const lapack_complex_double *alpha, const lapack_complex_double *a, const lapack_int *lda,
41-
const lapack_complex_double *b, const lapack_int *ldb, const lapack_complex_double *beta,
42-
lapack_complex_double *c, const lapack_int *ldc) __asm__(NRG_LAPACK_SYMBOL(zgemm));
43-
44-
void NRG_LAPACK_dsyev(const char *jobz, const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, double *w,
45-
double *work, const lapack_int *lwork, lapack_int *info) __asm__(NRG_LAPACK_SYMBOL(dsyev));
46-
47-
void NRG_LAPACK_dsyevd(const char *jobz, const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, double *w,
48-
double *work, const lapack_int *lwork, lapack_int *iwork, const lapack_int *liwork, lapack_int *info)
49-
__asm__(NRG_LAPACK_SYMBOL(dsyevd));
50-
51-
void NRG_LAPACK_dsyevr(const char *jobz, const char *range, const char *uplo, const lapack_int *n, double *a,
52-
const lapack_int *lda, const double *vl, const double *vu, const lapack_int *il,
53-
const lapack_int *iu, const double *abstol, lapack_int *m, double *w, double *z,
54-
const lapack_int *ldz, lapack_int *isuppz, double *work, const lapack_int *lwork,
55-
lapack_int *iwork, const lapack_int *liwork, lapack_int *info) __asm__(NRG_LAPACK_SYMBOL(dsyevr));
56-
57-
void NRG_LAPACK_zheev(const char *jobz, const char *uplo, const lapack_int *n, lapack_complex_double *a,
58-
const lapack_int *lda, double *w, lapack_complex_double *work, const lapack_int *lwork,
59-
double *rwork, lapack_int *info) __asm__(NRG_LAPACK_SYMBOL(zheev));
60-
61-
void NRG_LAPACK_zheevd(const char *jobz, const char *uplo, const lapack_int *n, lapack_complex_double *a,
62-
const lapack_int *lda, double *w, lapack_complex_double *work, const lapack_int *lwork,
63-
double *rwork, const lapack_int *lrwork, lapack_int *iwork, const lapack_int *liwork,
64-
lapack_int *info) __asm__(NRG_LAPACK_SYMBOL(zheevd));
65-
66-
void NRG_LAPACK_zheevr(const char *jobz, const char *range, const char *uplo, const lapack_int *n, lapack_complex_double *a,
67-
const lapack_int *lda, const double *vl, const double *vu, const lapack_int *il,
68-
const lapack_int *iu, const double *abstol, lapack_int *m, double *w, lapack_complex_double *z,
69-
const lapack_int *ldz, lapack_int *isuppz, lapack_complex_double *work, const lapack_int *lwork,
70-
double *rwork, const lapack_int *lrwork, lapack_int *iwork, const lapack_int *liwork,
71-
lapack_int *info) __asm__(NRG_LAPACK_SYMBOL(zheevr));
57+
int LAPACK_dgemm(const char *transa, const char *transb, const lapack_int *m, const lapack_int *n, const lapack_int *k,
58+
const double *alpha, const double *a, const lapack_int *lda, const double *b, const lapack_int *ldb,
59+
const double *beta, double *c, const lapack_int *ldc)
60+
#if !defined(__APPLE__)
61+
__asm__(NRG_BLAS_ASM_SYMBOL(dgemm))
62+
#endif
63+
;
64+
65+
int LAPACK_zgemm(const char *transa, const char *transb, const lapack_int *m, const lapack_int *n, const lapack_int *k,
66+
const double *alpha, const double *a, const lapack_int *lda, const double *b, const lapack_int *ldb,
67+
const double *beta, double *c, const lapack_int *ldc)
68+
#if !defined(__APPLE__)
69+
__asm__(NRG_BLAS_ASM_SYMBOL(zgemm))
70+
#endif
71+
;
72+
73+
void LAPACK_dsyev(const char *jobz, const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, double *w,
74+
double *work, const lapack_int *lwork, lapack_int *info)
75+
#if !defined(__APPLE__)
76+
__asm__(NRG_LAPACK_ASM_SYMBOL(dsyev))
77+
#endif
78+
;
79+
80+
void LAPACK_dsyevd(const char *jobz, const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, double *w,
81+
double *work, const lapack_int *lwork, lapack_int *iwork, const lapack_int *liwork, lapack_int *info)
82+
#if !defined(__APPLE__)
83+
__asm__(NRG_LAPACK_ASM_SYMBOL(dsyevd))
84+
#endif
85+
;
86+
87+
void LAPACK_dsyevr(const char *jobz, const char *range, const char *uplo, const lapack_int *n, double *a,
88+
const lapack_int *lda, const double *vl, const double *vu, const lapack_int *il,
89+
const lapack_int *iu, const double *abstol, lapack_int *m, double *w, double *z,
90+
const lapack_int *ldz, lapack_int *isuppz, double *work, const lapack_int *lwork,
91+
lapack_int *iwork, const lapack_int *liwork, lapack_int *info)
92+
#if !defined(__APPLE__)
93+
__asm__(NRG_LAPACK_ASM_SYMBOL(dsyevr))
94+
#endif
95+
;
96+
97+
void LAPACK_zheev(const char *jobz, const char *uplo, const lapack_int *n, lapack_complex_double *a,
98+
const lapack_int *lda, double *w, lapack_complex_double *work, const lapack_int *lwork,
99+
double *rwork, lapack_int *info)
100+
#if !defined(__APPLE__)
101+
__asm__(NRG_LAPACK_ASM_SYMBOL(zheev))
102+
#endif
103+
;
104+
105+
void LAPACK_zheevd(const char *jobz, const char *uplo, const lapack_int *n, lapack_complex_double *a,
106+
const lapack_int *lda, double *w, lapack_complex_double *work, const lapack_int *lwork,
107+
double *rwork, const lapack_int *lrwork, lapack_int *iwork, const lapack_int *liwork,
108+
lapack_int *info)
109+
#if !defined(__APPLE__)
110+
__asm__(NRG_LAPACK_ASM_SYMBOL(zheevd))
111+
#endif
112+
;
113+
114+
void LAPACK_zheevr(const char *jobz, const char *range, const char *uplo, const lapack_int *n, lapack_complex_double *a,
115+
const lapack_int *lda, const double *vl, const double *vu, const lapack_int *il,
116+
const lapack_int *iu, const double *abstol, lapack_int *m, double *w, lapack_complex_double *z,
117+
const lapack_int *ldz, lapack_int *isuppz, lapack_complex_double *work, const lapack_int *lwork,
118+
double *rwork, const lapack_int *lrwork, lapack_int *iwork, const lapack_int *liwork,
119+
lapack_int *info)
120+
#if !defined(__APPLE__)
121+
__asm__(NRG_LAPACK_ASM_SYMBOL(zheevr))
122+
#endif
123+
;
72124

73125
}
74126

0 commit comments

Comments
 (0)