ISSUE: Using LAPACK in C++ code

Open discussion regarding features, bugs, issues, vendors, etc.

ISSUE: Using LAPACK in C++ code

Postby Orion_PKFD » Mon Oct 14, 2013 3:12 pm

Hi folks,

Can anyone tell me how use LAPACK in C++ code in Ubuntu 12.04?

I saw in Synaptic that I have the llapack an lbas packages installed (although I dont know if those are for fortran...), but I don't now what I need to include in the C++ code (apart from the zgesv parameters) and how to compile/run it in the command line.

The code (with dgesv!) from this website works: http://www.physics.utah.edu/~detar/phys ... apack.html
(I compiled using "g++ -c myprog.cc" and then "g++ myprog.o -o myprog -L/usr/local/lib64 -llapack -lblas -lgfortran -lm" as shown in the same site)

But if I do the same for zgesv I get some errors...
I made the modification from the dgesv as:
Code: Select all
extern "C" {
     void zgesv_(int *Nmatrix, int *nrhs,  complex<double> *Matrix,  int  *lda, 
           int *ipvt, complex<double> *Vector, int *ldb, int *info);
}


and after that

Code: Select all
   int nrhs = 1;
   int lda = Nmatrix;
   int ldb = Nmatrix;
   int ipvt[Nmatrix];
   int info;

   zgesv_(&Nmatrix, &nrhs, &Matrix, &lda, ipvt, &Vector, &ldb, &info);


And I get these errors when compiling using g++:

...path...$ g++ -c maincode.cxx functions.cxx
maincode.cxx: In function ‘int main()’:
maincode.cxx:97:67: error: cannot convert ‘std::complex<double> (*)[(((long unsigned int)(((long int)Nmatrix) + -0x00000000000000001)) + 1)][(((long unsigned int)(((long int)Nmatrix) + -0x00000000000000001)) + 1)]’ to ‘std::complex<double>*’ for argument ‘3’ to ‘void zgesv_(int*, int*, std::complex<double>*, int*, int*, std::complex<double>*, int*, int*)’


What am I doing wrong?

Best regards
Orion_PKFD
 
Posts: 1
Joined: Mon Oct 14, 2013 2:50 pm

Re: ISSUE: Using LAPACK in C++ code

Postby admin » Wed Dec 04, 2013 11:10 pm

You should use LAPACKE instead of calling directly Fortran from C.
There is a DGESV example in the LAPACK package - see lapack-3.5.0/lapacke/example.

Here is a working code for ZGESV
Code: Select all
#include  <iostream>
#include <lapacke.h>

using namespace std;

int main()
{
   complex<double> Matrix[1]={1};
   complex<double> Vector[1]={.5};
   int Nmatrix=1;
   int nrhs = 1;
   int lda = Nmatrix;
   int ldb = Nmatrix;
   int ipvt[Nmatrix];
   int info;


//CALL ZGESV( N, NRHS, A, LDA, IPIV, B, LDB, INFO )
   info = LAPACKE_zgesv(LAPACK_ROW_MAJOR, Nmatrix, nrhs, Matrix, lda, ipvt, Vector, ldb);

   cout << "Info = "<< info << "\n";

if (info ==0)
{
   cout << "Solution: \n";
   for (int i=0; i<Nmatrix; i++) cout << "X["<< i <<"] = " << Vector[i];
   cout << std::endl;
}

return(info);
}


And the Makefile
LIBS=-L/Users/julie/opt/mylib -llapacke -llapack -lrefcblas -lrefblas
IDIR =/Users/julie/opt/mylib
CXX=g++
CXXFLAGS=-I$(IDIR) -DHAVE_LAPACK_CONFIG_H -DLAPACK_COMPLEX_CPP
DEPS = lapacke.h
OBJ = prog.o

%.o: %.cpp $(DEPS)
$(CXX) -c -o $@ $< $(CXXFLAGS)

prog.exe: $(OBJ)
gfortran -o $@ $^ $(CXXFLAGS) $(LIBS) -lc++

run : prog.exe
./prog.exe

clean:
rm -f *.o *.exe *~ core


Extract from LAPACK README:
-------------------------------------------------------------------------------
Handling Complex Types
-------------------------------------------------------------------------------

The interface uses complex types lapack_complex_float/lapack_complex_double.
You have several options to define them:

1) C99 complex types (default):

#define lapack_complex_float float _Complex
#define lapack_complex_double double _Complex

2) C structure option (set by enabling in the configuration file):
-DHAVE_LAPACK_CONFIG_H -DLAPACK_COMPLEX_STRUCTURE

typedef struct { float real, imag; } _lapack_complex_float;
typedef struct { double real, imag; } _lapack_complex_double;
#define lapack_complex_float _lapack_complex_float
#define lapack_complex_double _lapack_complex_double

3) C++ complex types (set by enabling in the configuration file):
-DHAVE_LAPACK_CONFIG_H -DLAPACK_COMPLEX_CPP

#define lapack_complex_float std::complex<float>
#define lapack_complex_double std::complex<double>

You have to compile the interface with C++ compiler with C++ types.

4) Custom complex types:
-DLAPACK_COMPLEX_CUSTOM

To use custom complex types, you need to:
- Define lapack_complex_float/lapack_complex_double types on your own.
- Optionally define lapack_make_complex_float/lapack_make_complex_double_real
functions if you want to build the testing suite supplied. Use these
functions for the testing system. Their purpose is to make a complex value of
a real part re, imaginary part im. The prototypes are as follows:

lapack_complex_float lapack_make_complex_float( float re, float im );
lapack_complex_double lapack_make_complex_double( double re, double im );

-
admin
Site Admin
 
Posts: 468
Joined: Wed Dec 08, 2004 7:07 pm


Return to User Discussion

Who is online

Users browsing this forum: ytfgreybut and 2 guests

cron