Getting started with ATLAS, BLAS and LAPACK

I decided to experiment with Atlas (Automatically Tuned Linear Algebra Software) because it contains a parallel BLAS library. For those that don’t have access to the Intel math kernel library Atlas is a good choice for obtaining an automatically optimized BLAS library. It also provides a nice C interface to BLAS, hence there are two ways to go about using the library. On my Fedora 18 the Atlas build is found under “/usr/lib64/atlas/”. I’ll start with a short example of how to scale a vector.

Without cblas.h

#include <stdio.h>

int
main ()
{
  int i, j, n, one;
  double coefficient;
  double x[] = { 1, 1, 1 };

  coefficient = 4.323;
  one = 1;
  n = 3;

  dscal_(&n, &coefficient, &x[0], &one);

  for (i = 0; i < 3; ++i)
    printf ("%f\n", x[i]);

  return 0;
}

Calling Fortran from C

The Fortran compiler appends an underscore after subroutinenames (subroutine is Fortran-speak for “function”). So bearing in mind that BLAS is written in Fortran, to call the subroutine “dscal()” from C one must write “dscal_()”. Similarly if a C function is named “myfunc_(…)”, it may be called from Fortran using “myfunc(…)’. In addition, C passes arguments by value whereas Fortran passes arguments by reference, so to call a Fortran subroutine from C one must pass the memory address of the arguments by using the ampersand and not something like “dscal_(3, 4.323, &x[0], 1);”.
To compile we must link with the atlas libraries.

[michael@michael lin]$ gcc example.c -o example -L /usr/lib64/atlas -lf77blas 
[michael@michael lin]$ ./testblas 
4.323000
4.323000
4.323000

With cblas.h

#include <stdio.h>
#include <cblas.h>

int
main ()
{
  int i;
  double x[] = { 1, 1, 1 };


  cblas_dscal(3, 4.323, x, 1);

  for (i = 0; i < 3; ++i)
    printf ("%f\n", x[i]);

  return 0;
}

The main difference here is that instead of an “_” suffix there is a “cblas_” prefix, the cblas header has been included and that the arguments are passed by value than by reference. To compile this we link against the cblas library instead of the blas library.

[michael@michael lin]$ gcc testblasc.c -o testblas -L /usr/lib64/atlas -lcblas -latlas
[michael@michael lin]$ ./testblas 
4.323000
4.323000
4.323000

Compiling with C++

There are further modifications to the code if you want to write in C++ rather than C. The first is instead of “#include ” one must write

extern "C"
{
	   #include <cblas.h>
}

I’ve now rewritten the above example using the vectors library and making use of cpp’s input/output.

#include <cstdlib>
#include <vector>
#include <iostream>

extern "C"
{
	   #include <cblas.h>
}

using namespace std;
int main ()
{
  int i;
  vector<double> x(3,1);

  cblas_dscal (x.size(), 4.323, &x[0], 1);

  for (i = 0; i < x.size(); ++i)
	cout << x[i] << endl;
  return 0;
}

The advantages of the vector class instead of a C array is that now one doesn’t need an extra variable to store the length of the array. Link against -lcblas this time than -lf77blas. All atlas libraries can be found here.

  • mano

    $ gcc testblasc.c -o testblas -L /usr/lib64/atlas -lcblas
    should read
    $ gcc testblasc.c -o testblas -L /usr/lib64/atlas -lcblas -latlas
    or
    $ gcc testblasc.c -o testblas -L /usr/lib64/atlas -lblas

    • admin

      Thanks 🙂

    • daemondave

      Only on Ubuntu, on Fedora
      -lsatlas

      Best to use pkg-config to find options:

      ATLAS_CFLAGS=$(pkg-config –cflags atlas)
      ATLAS_CFLAGS+=$(pkg-config –cflags blas-atlas)
      ATLAS_CFLAGS+=$(pkg-config –cflags lapack-atlas)
      ATLAS_LDFLAGS=$(pkg-config –libs atlas)
      ATLAS_LDFLAGS+=$(pkg-config –libs blas-atlas)
      ATLAS_LDFLAGS+=$(pkg-config –libs lapack-atlas)

      that gets them on Debian and Redhat distro variants.

  • FoadSF

    I used you example here and also collected dozens of other examples in this repository: :
    https://github.com/Foadsf/Cmathtuts
    with complete instructions for compiling and using BLAS, CBLAS, LAPACK, LAPACKE, CLAPACK…
    hope it will be usefull