0
votes

I've been working on a Fortran routine that makes a call to a C++ method. I'm getting the following error when I try to make it:

make -f makefile_gcc

Error:

gfortran -O3 -o tgemm tgemm.o mytimer.o dgemmf.o -lblas -dgemmkernel.o
dgemmf.o: In function `dgemmf_':
dgemmf.f:(.text+0x135): undefined reference to `gemmkernel_'
collect2: ld returned 1 exit status
make: *** [tgemm] Error 1

This is my makefile:

  `FC=gfortran
    CC=gcc
    FFLAGS = -O3
    CFLAGS = -O5
    BLASF=dgemmf.o
    BLASFSRC=dgemmf.f
    TIMER=mytimer.o

    TGEMM=tgemm
    ALL= $(TGEMM)

    LIBS = -lblas -dgemmkernel.o

    all: $(ALL)

    $(TGEMM): dgemmkernel.o tgemm.o $(TIMER) $(BLASF)
        $(FC) $(FFLAGS) -o $(TGEMM) tgemm.o $(TIMER) $(BLASF) $(LIBS)

    dgemmkernel.o: dgemmkernel.cpp  
        $(CC) $(CFLAGS) -c dgemmkernel.cpp

    tgemm.o: tgemm.f $(INCLUDE)
        $(FC) $(FFLAGS) -c tgemm.f
    clean:
        rm -rf *.o $(ALL) 

Here is my Fortran code:

             SUBROUTINE DGEMMF( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB,
         $                   BETA, C, LDC )
    *     .. Scalar Arguments ..
          CHARACTER*1        TRANSA, TRANSB
          INTEGER            M, N, K, LDA, LDB, LDC
          DOUBLE PRECISION   ALPHA, BETA
    *     .. Array Arguments ..
          DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * )
    *     .. External Functions ..
          LOGICAL            LSAME
          EXTERNAL           LSAME
    *     .. Local Scalars ..
          LOGICAL            NOTA, NOTB
          INTEGER            I, J, L
    *     .. Parameters ..
          DOUBLE PRECISION   ONE         , ZERO
          PARAMETER        ( ONE = 1.0D+0, ZERO = 0.0D+0 )
    *     ..
    *     .. Executable Statements ..
    *
    *     Set  NOTA  and  NOTB  as  true if  A  and  B  respectively are not transposed 
    *
          NOTA  = LSAME( TRANSA, 'N' )
          NOTB  = LSAME( TRANSB, 'N' )
    *
    *     We only want C = A°B
    *
          IF ((ALPHA.NE.ONE).OR.( BETA.NE.ZERO).OR.
         $    (.NOT.NOTA).OR.(.NOT.NOTB)) STOP
    *
    *     Start the operations.
      CALL gemmkernel( M, N, K, A, LDA, B, LDB, C, LDC)
      RETURN

*     End of DGEMM.
*
      END

And here is the C++ bit that I'm trying to call

 void gemmkernel_(int * M, int * N, int * K,
                    double * a, int * LDA, 
                    double * b, int * LDB,
                    double * c, int * LDC) 

All of the .o files do get created, however the executable is never completed. I suspect that the error is with my makefile because every source I've found so far suggests to me that my Fortran/C++ code is correct.

1
LIBS = -lblas -dgemmkernel.o This looks suspicious; are you sure the dash should be there before dgemmkernel.o? - eriktous
You probably hitting name mangling from the C++ compiler, and there is no gemmkernel_ in the object file, but rather something like __Z10gemmkernelPiS_S_PdS_S0_S_S0_S_ - talonmies

1 Answers

1
votes

Your make fails at link time. dgemmkernel.o should be in the list of object files. I assume you want this line:

$(FC) $(FFLAGS) -o $(TGEMM) tgemm.o $(TIMER) $(BLASF) $(LIBS)

to be:

$(FC) $(FFLAGS) -o $(TGEMM) tgemm.o dgemmkernel.o $(TIMER) $(BLASF) $(LIBS)

and

LIBS = -lblas -dgemmkernel.o    

to be:

LIBS = -lblas