SCALAPACK function undefined reference

Post here if you have a question about linking your program with LAPACK or ScaLAPACK library

SCALAPACK function undefined reference

Postby shaw22[] » Wed Jun 05, 2013 10:19 pm

I am trying to test a simple C++ code for solving a tridiagonal system with Scalapack. However the compiler does not find the functions pddttrf and pddttrs. The other BLACS functions compiles fine. I don't know why? is that because the two functions are in fortran? have I not linked an appropriate library?
I get this error:
test.o: In function `main':
test.cpp:(.text+0x2d3): undefined reference to `pddttrf'
test.cpp:(.text+0x341): undefined reference to `pddttrs'

My Makefile is:
CXX= mpicxx
CC = mpicc
CXXFLAGS= -c

SOURCES= test.cpp
OBJECTS= $(SOURCES:.cpp=.o)
LDFLAGS=
EXE= simulation

SCALAPACK_LIB = /home/root/scalapack-2.0.2/libscalapack.a
LAPACK_LIB = /home/root/lapack_for_scalapack/lapack-3.3.0/lapack_LINUX.a
BLAS_LIB = /home/root/lapack_for_scalapack/lapack-3.3.0/blas_LINUX.a
LIBS = $(SCALAPACK_LIB) $(LAPACK_LIB) $(BLAS_LIB)

all : $(SOURCES) $(EXE)

$(EXE) : $(OBJECTS)
$(CXX) -o $(EXE) $(OBJECTS) $(LIBS)

.cpp.o:
$(CXX) $(CXXFLAGS) $< -o $@ $(LIBS)

clean :
rm -rf *.o *.dat *.bin $(EXE) *.out.*

My program is:
#include <stdio.h>
#include <math.h>
#include "mpi.h"

extern "C" {
/* Cblacs declarations */
void Cblacs_pinfo(int*, int*);
void Cblacs_get(int, int, int*);
void Cblacs_gridinit(int*, const char*, int, int);
void Cblacs_gridexit(int);
void Cblacs_exit(int);
void pddttrf(int*, double*, double*, double*, int*, int*, double*, int*, double*, int*, int*);
void pddttrs(char*, int*, int*, double*, double*, double*, int*, int*, double*, int*, int*, double*, int*, double*, int*, int*);
}

main()
{

int context, desca[9], descb[9], ib, info, ja, laf, lda, ldb,
lwork, mb, mype, n, nb, npcol, npe, nprow, nrhs;
double b[4], d[4], dl[4], du[4];
double *af, *work;
char trans='N';

/* Set array dimensions and blocking */

n = 8; /* dimension of the problem */
lda = 4; /* leading dimension of A */
ldb = 4; /* leading dimension of B */
nrhs = 1; /* number of right-hand sides */
npcol = 2; /* number of processor columns */
ja = 1; /* offset for A */
ib = ja; /* offset for B */
mb = 4; /* blocking */
nb = 4; /* blocking */

laf = 12*npcol+3*nb;
af = new double [laf];
lwork = 10*npcol+4*nrhs;
work = new double [lwork];

/* Start BLACS */

Cblacs_pinfo( &mype, &npe );
Cblacs_get( 0, 0, &context );
Cblacs_gridinit( &context, "R", 1, npe );

if ( mype == 0 ){
/* PE = 0 gets D(1:4), DL(1:4), DU(1:4) and B(1:4) */
d[0] = 1.8180; d[1] = 1.6602; d[2] = 1.3420; d[3] = 1.2897;
dl[0] = 0.0000; dl[1] = 0.8385; dl[2] = 0.5681; dl[3] = 0.3704;
du[0] = 0.6946; du[1] = 0.4449; du[2] = 0.5466; du[3] = 0.7027;
b[0] = 1.0; b[1] = 2.0; b[2] = 3.0; b[3] = 4.0;

}
else if ( mype == 1 ){
/* PE = 1 gets D(5:8), DL(5:8), DU(5:8) and B(5:8) */
d[0] = 1.3412; d[1] = 1.5341; d[2] = 1.7271; d[3] = 1.3093;
dl[0] = 0.7027; dl[1] = 0.5466; dl[2] = 0.4449; dl[3] = 0.6946;
du[0] = 0.3704; du[1] = 0.5681; du[2] = 0.8385; du[3] = 0.0000;
b[0] = 5.0; b[1] = 6.0; b[2] = 7.0; b[3] = 8.0;
}

/* Array descriptor for A (D, DL and DU) */

desca[0] = 501; desca[1] = context; desca[2] = n; desca[3] = nb;
desca[4] = 0; desca[5] = lda; desca[6] = 0;

/* Array descriptor for B */

descb[0] = 502; descb[1] = context; descb[2] = n; descb[3] = nb;
descb[4] = 0; descb[5] = ldb; descb[6] = 0;

/* Factorization */

pddttrf( &n, dl, d, du, &ja, desca, af, &laf, work, &lwork, &info );

/* Solution */

pddttrs( &trans, &n, &nrhs, dl, d, du, &ja, desca, b, &ib, descb,
af, &laf, work, &lwork, &info );

printf( "MYPE=%i: x[:] = %7.4f %7.4f %7.4f %7.4f\n",
mype, b[0], b[1], b[2], b[3]);

Cblacs_gridexit( context );
Cblacs_exit( 0 );

}

Thanks for your help!
shaw22[]
 
Posts: 3
Joined: Wed Jun 05, 2013 9:05 pm

Re: SCALAPACK function undefined reference

Postby admin » Thu Jun 06, 2013 2:17 pm

Because you are calling from C, you have to modify the name of the Fortran routine (add _ usually do the trick) - Google "Mixing Fortran and C" for more info.

To be sure of the name to use, you can do "nm /home/root/scalapack-2.0.2/libscalapack.a | grep -i pddttrf" and check the symbol used.

Hope it helps
Julie
admin
Site Admin
 
Posts: 608
Joined: Wed Dec 08, 2004 7:07 pm

Re: SCALAPACK function undefined reference

Postby shaw22[] » Thu Jun 06, 2013 2:40 pm

Thanks a lot! it worked, but I now get another error which I guess is from inside the library. I get:

/home/root/scalapack-2.0.2/libscalapack.a(pxerbla.o): In function `pxerbla_':
pxerbla.f:(.text+0x67): undefined reference to `for_write_seq_fmt'
pxerbla.f:(.text+0x84): undefined reference to `for_write_seq_fmt_xmit'
pxerbla.f:(.text+0xa3): undefined reference to `for_write_seq_fmt_xmit'
pxerbla.f:(.text+0xbf): undefined reference to `for_write_seq_fmt_xmit'
/home/root/lapack_for_scalapack/lapack-3.3.0/lapack_LINUX.a(xerbla.o): In function `xerbla_':
xerbla.f:(.text+0x13): undefined reference to `for_len_trim'
xerbla.f:(.text+0x58): undefined reference to `for_write_seq_fmt'
xerbla.f:(.text+0x73): undefined reference to `for_write_seq_fmt_xmit'
xerbla.f:(.text+0x90): undefined reference to `for_stop_core'

Do I have any control on these functions? What should I do?
Thanks a lot.
shaw22[]
 
Posts: 3
Joined: Wed Jun 05, 2013 9:05 pm

Re: SCALAPACK function undefined reference

Postby admin » Thu Jun 06, 2013 3:57 pm

You need the Fortran library at linking time, usually to add -lifcore (libifcore.a) or add -lgfortran solve the issue.
admin
Site Admin
 
Posts: 608
Joined: Wed Dec 08, 2004 7:07 pm

Re: SCALAPACK function undefined reference

Postby shaw22[] » Thu Jun 06, 2013 4:04 pm

Thanks a lot that worked! :)
shaw22[]
 
Posts: 3
Joined: Wed Jun 05, 2013 9:05 pm


Return to Linking Problem

Who is online

Users browsing this forum: No registered users and 2 guests