You will be running into some trouble with code written in FORTRAN and interfacing to it from C or C++.
Example 1: BLAS called from within C, you should be able to compile this with -lblas
Code:
#include <stdio.h>
// FORTRAN adds _ after all the function names
// and all variables are called by reference
double ddot_( const int *N, const double *a, const int *inca, const double *b, const int *incb );
int main( int argc, char** argv ){
// you can define the arrays in one of two ways
// on the heap
double *a = (double*) malloc( 3 * sizeof(double) );
a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
// on the stack
double b[3] = { 4.0, 5.0, 6.0 };
int N = 3, one = 1; // one really doesn't look good in C
double dot_product = ddot_( &N, a, &one, b, &one );
printf(" The dot product is: %f \n",dot_product );
return 0;
};
Example 2: BLAS called from within C with a custom interface, you should be able to compile this with -lblas
Code:
#include <stdio.h>
// FORTRAN adds _ after all the function names
// and all variables are called by reference
double ddot_( const int *N, const double *a, const int *inca, const double *b, const int *incb );
double ddot( int N, double *a, int inca, double *b, int incb ){
return ddot_( &N, a, &inca, b, &incb );
};
int main( int argc, char** argv ){
// you can define the arrays in one of two ways
// on the heap
double *a = (double*) malloc( 3 * sizeof(double) );
a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
// on the stack
double b[3] = { 4.0, 5.0, 6.0 };
double dot_product = ddot( 3, a, 1, b, 1 );
printf(" The dot product is: %f \n",dot_product );
return 0;
};
Example 3: BLAS called from within C++ with a custom interface, you should be able to compile this with -lblas
Code:
#include <iostream>
using namespace std;
// C++ calls functions in a different way, so you need to change specify that this is a C/FORTRAN function call
extern "C"{
// FORTRAN adds _ after all the function names
// and all variables are called by reference
double ddot_( const int *N, const double *a, const int *inca, const double *b, const int *incb );
}
double ddot( int N, double *a, int inca, double *b, int incb ){
return ddot_( &N, a, &inca, b, &incb );
};
int main( int argc, char** argv ){
// you can define the arrays in one of two ways
// on the heap
double *a = new double[3];
a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
// on the stack
double b[3] = { 4.0, 5.0, 6.0 };
double dot_product = ddot( 3, a, 1, b, 1 );
cout <<" The dot product is: " << dot_product << endl;
return 0;
};
There exists a standard called CBLAS, which creates an interface between BLAS and C. This isn't always available and isn't that widely used, but here is an example.
Example 4: CBLAS called from within C, you should be able to compile this with -lcblas (assuming you have cblas installed)
Code:
#include <stdio.h>
#include <cblas.h>
int main( int argc, char** argv ){
// you can define the arrays in one of two ways
// on the heap
double *a = (double*) malloc( 3 * sizeof(double) );
a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
// on the stack
double b[3] = { 4.0, 5.0, 6.0 };
double dot_product = cblas_ddot( 3, a, 1, b, 1 );
printf(" The dot product is: %f \n",dot_product );
return 0;
};
If you have an AMD CPU, you should get ACML form them (it is free as in no money, but it is not free as in freedom). ACML is optimized BLAS and LAPACK specially done for AMD CPUs. They also have what I call "sane" interface for C.
Example 5: ACML called from within C, you should be able to compile this with -lacml -lacml_mv (assuming you have acml installed and all the paths set)
Code:
#include <stdio.h>
#include <acml.h>
int main( int argc, char** argv ){
// you can define the arrays in one of two ways
// on the heap
double *a = (double*) malloc( 3 * sizeof(double) );
a[0] = 1.0; a[1] = 2.0; a[2] = 3.0;
// on the stack
double b[3] = { 4.0, 5.0, 6.0 };
double dot_product = ddot( 3, a, 1, b, 1 );
printf(" The dot product is: %f \n",dot_product );
return 0;
};
NOTE: if you have ACML installed, you can use the code in Examples 1 - 3 and compile it with "-lacml -lacml_mv" instead of "-lblas" and it will work just fine.
Intel has their MKL library, however, it is not free. Also, I think MKL only comes with the standard BLAS interface, which means that you will have to use the code form Examples 1 - 3.
LAPACK works the same way as BLAS. It is a separate library so you need to compile with "-llapack -lblas" (or just "-lacml -lacml_mv" or "-lmkl"), but the interface to it is the same.
Bookmarks