4

To call a Fortran routine from c++ I have been using: extern "C" void routinename_(...) with the appended underscore making this compatible with a Fortran subroutine name "ROUTINENAME".

When I link c++ with BLAS or LAPACK it only works WITHOUT the underscore. What is the difference between linking c++ with these libraries, which are written in Fortran, that makes the underscore unnecessary?

user99439
  • 41
  • 2
  • Did you hear of `LAPACKE` (the C interface to Lapack)? There is also a C interface to BLAS. – Stefan Aug 13 '13 at 08:33

2 Answers2

0

I might be wrong, given that there's very little information to go on, but...

From here: the first F77 compilers appended an _ to the names of functions in the ABI. This behavior is unlike C, which simply takes the function name and uses that as the name in the ABI.

Some F77 compilers behaved differently, instead upper-casing the entire subroutine name, so that foo() became FOO() when seen by C. UNIX Fortran compilers mimicked C behavior and just copy-pasta'd the name so that foo() was foo() in the ABI too.

If you look at the BLAS bindings to C for the reference implementation here, though, you'll see that they're handling trailing underscores when dealing with F77. I'd wager the underscores were a far more common feature of the F77 ABI in the past than not having them.

Later on, Fortran 2003 introduced interoperability with C (see here). This made the function naming scheme the same when certain Fortran constructs were used (see here).

I'm going to, thus, make the wild guess that this has something to do with ABI differences across Fortran versions. Or even just across compilers, given that different compilers seem to have different behaviors in Fortran.

So, again, I'm not sure if this is matched up with your situation, given that there's not much to go on in your question, but I couldn't fit this all into a comment so here it is as an 'answer'.

AND IF I'M WRONG TELL ME SO I CAN CORRECT MAH' POST.

tl;dr: because compiler versions

user
  • 4,920
  • 3
  • 25
  • 38
-1

I'm putting a general answer for linking BLAS not only this question, the answer for this question at the end below.

first you need to ensure you have BLAS installed using(+lapack)

$ sudo apt-get install libblas-dev liblapack-dev

then you can link using -lblas after your program files. or you can use a make file.

for example: g++ test.o dmatrix_denseCM.o mmio.o -o output -lblas

from my side I prefer to use OpenBlas instead, you can use the following in a makefile.

  1. www.openblas.net, get the tar.gz copy it in your directory
  2. extract it : tar -zxvf OpenBLAS-0.2.20.tar.gz
  3. compile it : cd OpenBLAS-0.2.20 make

When it is done you should have the file libopenblas.a, the openblas library

  • BLASLIB = OpenBLAS/libopenblas.a -lpthread then add it to the file linked together as: $(BLASLIB)

this directory OpenBLAS/libopenblas.a should be in the same working directory.

example code in .cc file:

extern "C"{
  void dgemm_( const char &TRANSA, const char &TRANSB, const int &M, const int  &N, const int & K,  const double & ALPHA,  const double *A, const int & LDA, const double *B,  const int &LDB, const double &BETA, double *C, const int & LDC);
}

Moreover,When calling LAPACK or BLAS routines from C, be aware that because the Fortran language is case-insensitive, the routine names can be both upper-case or lower-case, with or without the trailing underscore. For example, the following names are equivalent:

LAPACK: dgetrf, DGETRF, dgetrf_, and DGETRF_

BLAS: dgemm, DGEMM, dgemm_, and DGEMM_ Intel® Math Kernel Library 11.3 Update 4 Developer Guide

you can add more information about the FORTRAN compiler you used to compile BLAS, for example:

Compile the Fortran program with the -U option, which tells the compiler to preserve existing uppercase/lowercase distinctions on function/subprogram names.

The Fortran compiler normally appends an underscore (_) to the names of subprograms appearing both at entry point definition and in calls. This convention differs from C procedures or external variables with the same user-assigned name. here

the Name mangling in C++ makes a problem in C. as C doesn't support overloading then we have to use extern "c"{}.

Ibrahim zawra
  • 317
  • 1
  • 2
  • 11