user3350851
user3350851

Reputation: 13

Cuda/c++ - Fortran - Undefined reference to Cuda functions

I'm really sorry if this was already solved somewhere, but I cannot find any solutions anywhere. I'm trying to compile a Fortran-based code using cuda. I stumbled on weird errors that I was able to reproduce using the simple example from this page.

It's a simple operation, we have the cuda code:

cudatest.cu

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cuda.h>
#include <cuda_runtime.h>

// function called from main fortran program
extern "C" void kernel_wrapper_(float *a, int *Np)
{
   float  *a_d;  // declare GPU vector copy
   int N = *Np;        // N threads on GPU

   // Allocate memory on GPU
   cudaMalloc( (void **)&a_d, sizeof(float) * N );

   // free GPU memory
   cudaFree(a_d);
   return;
}

The fortran code:

fortest.f95

  PROGRAM fortest

  IMPLICIT NONE

  integer*4 :: i
  integer*4, parameter :: N=8
  real*4, Dimension(N) :: a

  DO i=1,N
     a(i)=i*1.0
   END DO

  print *, 'a = ', (a(i), i=1,N)
  CALL kernel_wrapper(a, N)
  print *, 'a = ', (a(i), i=1,N)

END PROGRAM fortest

And the makefile:

Test: fortest.f95 cudatest.o
    gfortran -L/usr/local/cuda-5.5/lib64 -I/usr/local/cuda-5.5/include -lcudart -lcuda fortest.f95 cudatest.o 
cudatest.o: cudatest.cu 
    nvcc -c -O3 cudatest.cu
clean:
    rm a.out cudatest.o cudatest.linkinfo

While trying to compile through make, I'm getting the following errors:

nvcc -c cudatest.cu
gfortran -L /usr/local/cuda-5.5/lib64 -lcudart fortest.f95 cudatest.o 
cudatest.o: In function `kernel_wrapper_':
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x31): undefined reference to `cudaMalloc'
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x3d): undefined reference to `cudaFree'
cudatest.o: In function `__cudaUnregisterBinaryUtil()':
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x71): undefined reference to `__cudaUnregisterFatBinary'
cudatest.o: In function `__sti____cudaRegisterAll_43_tmpxft_00004a32_00000000_6_cudatest_cpp1_ii_3bf9bcb9()':
tmpxft_00004a32_00000000-3_cudatest.cudafe1.cpp:(.text+0x9a): undefined reference to `__cudaRegisterFatBinary'
collect2: error: ld returned 1 exit status
make: *** [Test] Erreur 1

So basically, gfortran doesn't realize it now knows cuda. I found some people with the same problems, but it seems adding the cuda runtime library (-lcudart) was the solution for all of them. I noticed that if I change the name of the cuda include directory to anything, the compiler doesn't really notice and spout out the same errors (e.g. "cuda-5.5/include" to "cuda-banana/include")

I'm using gfortran 4.8.1 and Cuda 5.5 which I just installed. The cuda code compiles well on its own.

Again, if the solution is already somewhere, I apologize. I may have already found it but not understood it. Thank you in advance !

EDIT: I simplified the overall program so the issue can be clearer.

Upvotes: 1

Views: 1378

Answers (1)

This Makefile works for me with gcc 4.6 and CUDA 4.2. The main point is linking with nvcc.

Test: fortest.o cudatest.o
        nvcc -lgfortran -lgfortranbegin -L/usr/local/cuda-5.5/lib64 -I/usr/local/cuda-5.5/include -lcudart -lcuda fortest.o cudatest.o
fortest.o: fortest.f95
        gfortran -c -O5 fortest.f95 -o fortest.o
cudatest.o: cudatest.cu
        nvcc -c -O3 cudatest.cu
clean:
        rm a.out cudatest.o fortest.o cudatest.linkinfo

This works too, the cure is to have the order right. First the files that contain the references to the library functions and then the libraries with the functions (adjust the path to the libraries):

Test: fortest.f95 cudatest.o
    gfortran fortest.f95 cudatest.o -L/usr/local/cuda/lib64 -lcuda -lcudart
cudatest.o: cudatest.cu 
    nvcc -c -O3 cudatest.cu
clean:
    rm a.out cudatest.o cudatest.linkinfo

Output of your program:

./a.out 
 a =    1.0000000       2.0000000       3.0000000       4.0000000       5.0000000       6.0000000       7.0000000       8.0000000    
 a =    1.0000000       2.0000000       3.0000000       4.0000000       5.0000000       6.0000000       7.0000000       8.0000000  

Upvotes: 1

Related Questions