arrayfire
arrayfire copied to clipboard
More robust CBLAS / LAPACKE detection
As discussed privately with @pavanky, detection of CBLAS and LAPACKE could get some love. I tried a few things but getting something generic enough proved to be quite tricky. I am opening this issue as a thread to explore the use cases and possible scenarii that the detection should cover.
CMake already has detection for the BLAS and LAPACK but lacks CBLAS / LAPACKE. The following blog post provides some background as to how they all relate to each other. In a nutshell, one should absolutely use the CBLAS wrapper specific to the desired BLAS vendor, but this restriction is relaxed for LAPACKE (which not all vendor provides btw).
Another thing to consider is the way distributions handle multiple vendors of BLAS / LAPACK. Debian uses a set of symlinks to switch between different BLAS vendors at runtime and uses netlib's LAPACKE regardless, whilst other distros have separated or mutually exclusive install paths for each vendor. Finally, some vendors (mkl, openblas) can bundle everything (BLAS / CBLAS, LAPACK/LAPACKE) in a single binary as opposed to separate ones for BLAS and LAPACK.
I can see 3 use-cases possible:
- Detection of a custom installation of BLAS (all patforms).
- Detection of a system-installed version via
pkg-config(likearch-linuxprovides). - Detection of a system-installed version without
pkg-config(symlinks alaDebian).
For (1), we can roll our own (bad), or use find_package(BLAS) and find_package(LAPACK) with the BLA_VENDOR parameter and existing support for lookup in LIB (Windows), DYLD_LIBRARY_PATH (Apple) and LD_LIBRARY_PATH (Linux). Then, we can look for the location of the vendor specific headers based on the path to the libraries and the value of BLA_VENDOR.
For (2), just use the pkg-config results directly (like we currently do).
For (3), use find_package(BLAS) and find_package(LAPACK) and look for the path to cblas.h and lapacke.h as in (1).
Thoughts?
- (2) and (3) sound fine, but I think (1) should take precedence when both are available.
- (1) does not sound too different from our existing setup does it ?
but I think (1) should take precedence when both are available.
Indeed, I numbered 1, 2, 3 in order of priority.
(1) does not sound too different from our existing setup does it ?
The existing setup looks like a modified copy of upstream CMake FindBLAS / FindLAPACK.
From a maintenance perspective, I wonder whether it would just be simpler to call upstream FindBLAS / FindLAPACK directly and wrap it with the necessary logic to find the extra CBLAS / LAPACKE headers and (optional) wrapper libraries.
@ghisvail that sounds simpler yes :)
Have you made any progress on this or do you want us to look at implementing it as well ?
I am in the process to, I just wanted to validate the logic with you guys first. That will be a good learning exercise on my end, since I need to implement something similar for a different project.
@ghisvail It'll be nice if you can get a clean enough implementation that you can upstream to CMake itself :)
It is painful to see each scientific computing library implementing their own versions of these files!
if you can get a clean enough implementation that you can upstream to CMake
That is the plan indeed.
It is painful to see each scientific computing library implementing their own versions of these files!
Agreed.
@ghisvail, @umar456 is working on cleaning up cmake files in arrayfire in https://github.com/arrayfire/arrayfire/pull/1861. If you have any feedback on how to improve cblas and lapacke detection, please leave a comment there.
@pavanky thanks for the heads-up. I have not started working on packaging 3.5.x yet, so I don't have much feedback to provide at the moment. I'll make sure to forward any quirks to the issue you mentioned.
I'm trying to compile Arrayfire with MKL, and getting CBLAS not found, but arrayfire does find MKL. Any tips on how to resolve? thanks!
Use -DUSE_CPU_MKL=ON and -DUSE_OPENCL_MKL=ON when running CMake
I'm interested in this capability for numerical/scientific software in general, and I think its goal may overlap somewhat with that of BLAS++ and its sister project LAPACK++. I've encountered multiple hard-to-debug problems due to libraries making incorrect assumptions about an implementation-defined BLAS/LAPACK library interface. (The classic example is SDOT using Apple's vecLib, whose ABI uses a different fortran calling convention than most fortran compilers default to.)
I tried "-DUSE_CPU_MKL=ON and -DUSE_OPENCL_MKL=ON when running CMake" and it found BLAS -- Found BLAS: /opt/intel/mkl/lib/intel64/libmkl_intel_lp64.so;/opt/intel/mkl/lib/intel64/libmkl_sequential.so;/opt/intel/mkl/lib/intel64/libmkl_core.so;-lm;-ldl
But then I got messages: -- Could NOT find BLAS (missing: BLAS_LIBRARIES) -- Could NOT find LAPACK (missing: LAPACK_LIBRARIES)
Also, I have latest oneAPI so previous intel parameters, like "Intel10_64lp" will not work.
Any help? Thanks.