Lapack and Blas in Windows using C++

Back to Blog

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.

Calling Fortran from C++ or C

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 name mangling

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.

Examples of name mangling schemes

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.

Armadillo’s approach on name-mangling

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

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.

Fortran calling conventions

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);
}

Obtaining Lapack and Blas libraries

To obtain the Lapack and Blas libraries for Windows, you can either obtain the libraries prebuilt by someone else, or build them yourself.

Dependencies

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

MinGW64

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.

Todo

This page is incomplete. I will write more when I learn more:)