LAPACK Linking Issue (despite USE_LAPACK = false)

Issue #365 wontfix
Phil created an issue

I am using plain blaze without any external LAPACK. As I understand it, certain operations (like matrix Inversion) should work nonetheless, as blaze includes its own basic features (though they may not be optimised).

However, the below script fails to compile:

#include <blaze/Blaze.h>

using namespace blaze;

int main()
{
    DynamicMatrix<double> M{ {4,2,-5}, {6,2,99},{1,2,3} };
    invert(M);

    return 0;
}

Errors:

LINK Pass 1: command "...\bin\Hostx64\x64\link.exe /nologo CMakeFiles\Source1.dir\src\Source1.cpp.obj /out:Source1.exe /implib:Source1.lib /pdb:Source1.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\Source1.dir/intermediate.manifest CMakeFiles\Source1.dir/manifest.res" failed (exit code 1120) with the following output:
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dpotrf_ referenced in function "void __cdecl blaze::potrf(char,int,double *,int,int *)" (?potrf@blaze@@YAXDHPEANHPEAH@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dgetrf_ referenced in function "void __cdecl blaze::getrf(int,int,double *,int,int *,int *)" (?getrf@blaze@@YAXHHPEANHPEAH1@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dgetri_ referenced in function "void __cdecl blaze::getri(int,double *,int,int const *,double *,int,int *)" (?getri@blaze@@YAXHPEANHPEBH0HPEAH@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dpotri_ referenced in function "void __cdecl blaze::potri(char,int,double *,int,int *)" (?potri@blaze@@YAXDHPEANHPEAH@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dsytrf_ referenced in function "void __cdecl blaze::sytrf(char,int,double *,int,int *,double *,int,int *)" (?sytrf@blaze@@YAXDHPEANHPEAH0H1@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dsytri_ referenced in function "void __cdecl blaze::sytri(char,int,double *,int,int const *,double *,int *)" (?sytri@blaze@@YAXDHPEANHPEBH0PEAH@Z)
...\blaze\out\build\x64-Debug\Source1.cpp.obj : error LNK2019: unresolved external symbol dtrtri_ referenced in function "void __cdecl blaze::trtri(char,char,int,double *,int,int *)" (?trtri@blaze@@YAXDDHPEANHPEAH@Z)
...\blaze\out\build\x64-Debug\Source1.exe : fatal error LNK1120: 7 unresolved externals

I also tried adding set(USE_LAPACK false)in line 70 of CMakeLists.txt or in setting #define BLAZE_USE_BLAS_MATRIX_MATRIX_MULTIPLICATION 0 (which is 1 by default) in blaze/config/BLAS.h but no change.

Comments (3)

  1. Klaus Iglberger

    Hi Phil!

    Thank you for taking the time to report this potential defect. This is highly appreciated.

    In this particular case the described behavior is the expected behavior. As the wiki states:

    Also note that the functions invert the dense matrix by means of LAPACK kernels. Thus the functions can only be used if a fitting LAPACK library is available and linked to the executable. Otherwise a linker error will be created.

    Unfortunately Blaze requires a LAPACK backend for the matrix inversion. The same is true for several other operations, like matrix decomposition, eigenvalue and singular value computations. The USE_LAPACK setting merely configures the CMake setup to not try to find a LAPACK library.

    I hope this explains the problem. Thanks again for creating this issue,

    Best regards,

    Klaus!

  2. Phil reporter

    Thanks, Klaus.

    Just to double-check, the wiki say “Both the inv() and the invert() functions will automatically select the most suited matrix inversion algorithm depending on the size and type of the given matrix“. How does blaze do that without a LAPACK? Or does blaze only pre-select the “best” inversion algorithm and then calls that algorithm from the LAPACK? If so, could you point me to the code, where this pre-selection happens?

    Perhaps slightly off-topic, but do most LAPACKs have a “standard API” (if one can call it that) such that one can literally drop in any LAPACK & it’ll just work with blaze? Or is there always a manual integration step?

  3. Klaus Iglberger

    Hi Phil!

    Blaze dispatches both based on the size of the matrix (see for instance the invert() function for dense matrices) and on its type (i.e. symmetric, Hermitian, lower triangular, upper triangular, etc.; see for instance invertNxN()). For performance reasons Blaze implements its own kernels for matrices up to 6x6. For larger matrices, it relies on LAPACK kernels. Since the dispatch based on the size is a runtime issue, Blaze always requires LAPACK, even if the matrix can be inverted without LAPACK calls.

    There is indeed some sort of standard for LAPACK functions. You can use any LAPACK implementation, e.g. OpenBLAS, MKL, ATLAS, …, by just linking the according library.

    Best regards,

    Klaus!

  4. Log in to comment