Linking Problems

I am new to CUDA programming and am having some trouble with my first attempts at linking a simple project.

I have my main program in a file main.c:

__host__ double EV(double T, void * p);

  ...

int main()

{

  ...

  EV(T,p);

  ...

}

The host function EV() is defined in a .cu file, EV.cu:

...

__host__ double EV (double T, void * p) 

{

  ...

  EValue<<<4,512>>>(...);

  ...

}

__global__ void EValue(...)

{

        ...           

}

Both main.c and EV.cu compile into objects main.o and EV.o using nvcc. However, when I attempt to link them, I get the following error:

$ nvcc -o main main.o EV.o  -lgsl -lgslcblas -lm -lcuda -lcudart

main.o: In function `main':

main.c:(.text+0x195): undefined reference to `EV'

collect2: ld returned 1 exit status

I expected that if I have the function EV() forward defined in main.c and defined in the compiled EV.o that the linking should proceed without this error. Is there something I am missing?

CUDA does not have a linker for device code, so kernel call and kernel code have to be in the same compilation unit (=source file).

The CUDA compiler basically has a C++ frontend. This means function names in the object code will be decorated versions of the function name in the source code. C does not use the C++ decorations, so the two names that look identical at source level are in fact not the same at object file level, which is why the linker can’t make the match.

To successfully link the function in your CUDA file with the C code, add

extern "C"

to the function prototype in the CUDA code. This instructs the compiler to refrain from adding C++ decorations for the function name emitted into the object file.

Thanks–both for providing the solution and for providing an explanation of the problem. Much appreciated!

My code now compiles, links, and even runs.