In this section I will tell you about my experiences on trying to get Lapack and Blas to work under Windows using C++. There is an official dedicated page to this problem in here. However, the devil is in the details.
Lapack and Blas are written in the Fortran language. If you are using C++ or C, can you use Lapack and Blas at all? The answer is yes, but with caution. The following is for background, and is usually handled by a wrapper library, such as the Armadillo C++ library.
Fortran functions in object files can be called like C code, provided you know how the used Fortran compiler mangles the names of functions. The need for name-mangling in Fortran arises mostly because Fortran is case-insensitive. Therefore, for the object file there needs to a normalized name for a function.
Unfortunately, name-mangling in Fortran is not standardized, and depends on the compiler. According to Wikipedia, some of the existing name-mangling schemes mangle the function-name Some_Function
as follows:
Compiler | Platform | Mangled name |
---|---|---|
GNU g77 | Linux | some_function__ |
GNU Fortran | Linux | some_function_ |
Intel Fortran | Linux | some_function_ |
Intel Fortran | Windows | SOME_FUNCTION |
? | AIX, HP-UX | some_function |
Mostly the schemes vary on whether to append an underscore, and whether to make letters UPPERSCORE or underscore.
The Armadillo C++ library — which wraps Lapack and Blas functionality — solves the name-mangling problem for Blas manually by the defines #define ARMA_BLAS_UNDERSCORE
and #define ARMA_BLAS_CAPITALS
, which covers most of the cases. It is unfortunate that the used name-mangling has to be manually specified for each environment.
Modules — introduced in Fortran 90 — are another feature that affect name mangling: the module-name must be appended to the symbol name to disambiguate it from a symbol of the same in another module.
The Fortran calling convention is mostly compatible with C. However, Fortran passes everything by pointers, including native integers. Here’s a (slightly simplified) example of a C-declaration of a Blas function from the Armadillo library:
extern "C"
{
float sdot_(blas_int* n, const float* x, blas_int* incx, const float* y, blas_int* incy);
}
To obtain the Lapack and Blas libraries for Windows, you can either obtain the libraries prebuilt by someone else, or build them yourself.
To build on Windows, there are two options: either gfortran packaged with MinGW64 (free), or Intel Fortran (not free). This will create dll-dependencies to either MinGW64, or Intel Fortran run-time. To make your executable run, the dependent dlls need to be either supplied together with the executables (in the same directory), or they need to be on the Windows path.
Compiler | Dependencies (.lib/.dll) |
---|---|
gfortran (MinGW64 4.0.2 32-bit) | libgfortran-3, libgcc_s_dw2-1, libquadmath-0, libwinpthread-1 |
gfortran (MinGW64 4.0.2 64-bit) | libgfortran-3, libgcc_s_seh-1, libquadmath-0, libwinpthread-1 |
Inter Fortran | Intel restributable libraries |
It is important to notice that MinGW64 can be installed as either 32-bit, or 64-bit, but not both. Since the bitness is selected at installation, and the 32-bit version is the default choice, this is easy to miss. While the dll and library names are the same, the libraries are not the same in MinGW64 32-bit and 64-bit.
This page is incomplete. I will write more when I learn more:)