2

Let's say I want to use LAPACK to solve a system of linear equations in C (GCC). I set up the problem as follows:

/* Want to solve Ax=b */
int n = ...;      // size
double *A = ...;  // nxn matrix
double *b = ...;  // length-n vector
int m = 1;        // number of columns in b (needs to be in a variable)
double *pivot;    // records pivoting
int info;         // return value

Now it seems I can use one of three functions to solve this problem. The first one is this:

dgesv_( &n, &m, A, &n, pivot, b, &n, &info );

I was surprised to see that this did not require any #includes, which seems... weird.

The second function has almost the same signature, except for the prefix LAPACK_ which I think causes less ambiguity and is possibly less error-prone:

#include <lapack/lapacke.h>
LAPACK_dgesv( &n, &m, A, &n, pivot, b, &n, &info );

Note that this requires me to include lapacke.h.

The third function changes the signature somewhat by returning info and not taking all arguments as pointers:

#include <lapack/lapacke.h>
info = LAPACKE_dgesv( LAPACK_COL_MAJOR, n, m, A, n, pivot, b, n);

Again, this function requires lapacke.h. It also requires linking to an extra library with -llapacke. All three functions need -llapack.

I'm trying to figure out the differences between these functions. I did some snooping around and I found the following macros in lapacke.h and related header files:

#define LAPACK_GLOBAL(name,NAME) name##_
#define LAPACK_dgesv LAPACK_GLOBAL(dgesv,DGESV)

So it seems that LAPACK_dgesv() and dgesv_() are different names for the exact same function. However, it appears LAPACKE_dgesv() is something else with possibly a different implementation, especially considering the fact it needs an extra library.

So my question is: what are the differences between these two functions? The documentation says LAPACKE is a C interface for LAPACK, but then what about the function dgesv_()? Clearly I can use it normally without needing LAPACKE and without compiling anything in Fortran, so how is that different?

Thanks.


Update

Curiously, the function dgemm_() (matrix multiplication) does not have any LAPACK_dgemm() equivalent. What's going on?

jadhachem
  • 1,123
  • 2
  • 11
  • 19
  • 2
    DGEMM is not a LAPACK routine. DGESV_ is the Fortran symbol assuming single underscore convention. You must use the right size integer for Fortran to call this. – Jeff Hammond Jul 02 '15 at 04:10

1 Answers1

2
  • Notice that LAPACKE_dgesv() features an additional flag which can be LAPACK_COL_MAJOR (usual fortran order) or LAPACK_ROW_MAJOR (usual c order). In case of LAPACK_COL_MAJOR, it just calls LAPACK_dgesv() directly. In case of LAPACK_ROW_MAJOR, LAPACKE_dgesv() will transpose the matrix before calling LAPACK_dgesv(). It is not a new implementation of dgesv_(). Take a look at lapack-3.5.0/lapacke/src/dgesv_work.c In this file, there are minor additional changes about error handling.

  • LAPACK_dgesv() is defined in the header lapacke.h as LAPACK_GLOBAL(dgesv,DGESV). The macro LAPACK_GLOBAL is defined in lapacke_mangling.h : it just wraps dgesv_ and cares for naming convention if other conventions are used.

So, basically, the function LAPACK_dgesv() just requires the headers of lapacke. Compared to dgesv_, some problems related to naming conventions in libraries may be avoided. But LAPACK_dgesv() is exactly the same as dgesv_(). The function LAPACKE_dgesv() enlarges the scope of LAPACK_dgesv() to handle usual c matrix.But it still calls dgesv_ in the end.

The function dgemm() is part of the BLAS library. A wrapped c version cblas_dgemm() can be found in CBLAS . Again, an additionnal flag CBLAS_ORDER is required, with possible values CblasRowMajor and CblasColMajor.

francis
  • 9,525
  • 2
  • 25
  • 41
  • Ah, I guess that makes sense now. Calling LAPACKE a "C interface for LAPACK" confused me, but I guess that just means the functions are more C-friendly. So does this mean that the performance difference is negligible? (assuming LAPACKE uses column-major order at least) – jadhachem Jul 02 '15 at 19:38
  • 1
    Yes, the performance difference is negligible as `LAPACK_COL_MAJOR` is used. Regarding `LAPACK_ROW_MAJOR` there are additionnal memory requirements due to the transposed matrices. The complexity of the transpose operation is [O(n^2)](http://cs.stackexchange.com/questions/10081/what-is-the-complexity-of-this-matrix-transposition) and the complexity of dgesv is [O(n^3)](http://stackoverflow.com/questions/12660052/time-complexity-of-scipy-linalg-solve-lapack-gesv-on-large-matrix). So the performance difference can be neglected even if `LAPACK_ROW_MAJOR` is used. – francis Jul 02 '15 at 19:50