Issue
I'm looking to use the LAPACKE library to make C/C++ calls to the LAPACK library. On multiple devices, I have tried to compile a simple program, but it appears LAPACKE is not linking correctly.
Here is my code, slightly modified from this example:
#include <cstdio>
extern "C"
{
#include "lapacke.h"
}
// extern "C" {
// // LU decomoposition of a general matrix
// void LAPACK_dgetrf(int* M, int *N, double* A, int* lda, int* IPIV, int* INFO);
// // generate inverse of a matrix given its LU decomposition
// void LAPACK_dgetri(int* N, double* A, int* lda, int* IPIV, double* WORK, int* lwork, int* INFO);
// }
extern "C"
{
#include <lapacke.h>
}
void inverse(double* A, int N)
{
int *IPIV = new int[N];
int LWORK = N*N;
double *WORK = new double[LWORK];
int INFO;
dgetrf_(&N,&N,A,&N,IPIV,&INFO);
dgetri_(&N,A,&N,IPIV,WORK,&LWORK,&INFO);
delete[] IPIV;
delete[] WORK;
}
int main(){
double A [2*2] = {
1,2,
3,4
};
inverse(A, 2);
printf("%f %f\n", A[0], A[1]);
printf("%f %f\n", A[2], A[3]);
return 0;
}
I have installed blas, lapack and lapacke using the apt package manager:
sudo apt-get install libblas-dev liblapack-dev liblapacke-dev
I am compiling with:
g++ -lblas -llapack -llapacke -I /usr/include main.cpp
the -I shouldn't be neccisary as far as I know, but I put it in anyway to be sure. I get the following error:
'/usr/bin/ld: /tmp/ccJSTpTf.o: in function `inverse(double*, int)':
main.cpp:(.text+0x9f): undefined reference to `dgetrf_'
/usr/bin/ld: main.cpp:(.text+0xc8): undefined reference to `dgetri_'
collect2: error: ld returned 1 exit status
This problem persists regardless if I compile lapacke from source, import the entire header, declare the functions themselves as extern, or change the names of the function to any of the following: dgetrf(), dgetrf_(), or LAPACK_dgetrf(), all common names I have seen for LAPACK-sytle calls.
Looking through the Lapacke header, it looks like LAPACK_dgetrf() translates to a lapack function call dgetrf_(). Unwrapping the static archives to look for dgetrf, I can find that liblapack.a has a function object dgetrf.o, and liblapacke.a has a function lapack_dgetrf.o. I'm thinking the root of the problem is that LAPACK_dgetrf() is basically dgetrf_(), and the linker cannot find dgetrf_(), because LAPACK has the function called dgetrf(), not dgetrf_(). I'm very confused though, as the compiler did not complain that any of the linked libraries didn't exist, and nobody else seems to have this issue on their devices, while I've had it now on 3 separate ones (all ubuntu based).
What do I need to do to get LAPACKE to compile, not just for C, but for C++?
Solution
I am compiling with:
g++ -lblas -llapack -llapacke -I /usr/include main.cpp
That command line is wrong. Do this instead:
g++ main.cpp -llapacke -llapack -lblas
To understand why the order of sources and libraries matters, read this.
Answered By - Employed Russian